mirror of
https://github.com/nxp-imx/mwifiex.git
synced 2024-11-20 00:51:44 +00:00
f9c1ec6000
Signed-off-by: Meet Patel <meet.patel@nxp.com>
2711 lines
68 KiB
C
2711 lines
68 KiB
C
/** @file mlanutl.c
|
|
*
|
|
* @brief Program to control parameters in the mlandriver
|
|
*
|
|
*
|
|
* Copyright 2011-2020 NXP
|
|
*
|
|
* This software file (the File) is distributed by NXP
|
|
* under the terms of the GNU General Public License Version 2, June 1991
|
|
* (the License). You may use, redistribute and/or modify the File in
|
|
* accordance with the terms and conditions of the License, a copy of which
|
|
* is available by writing to the Free Software Foundation, Inc.,
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
|
|
* worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
|
|
*
|
|
* THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE EXPRESSLY DISCLAIMED. The License provides additional details about
|
|
* this warranty disclaimer.
|
|
*
|
|
*/
|
|
/************************************************************************
|
|
Change log:
|
|
11/04/2011: initial version
|
|
************************************************************************/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <string.h>
|
|
#include <ctype.h>
|
|
#include <signal.h>
|
|
#include <time.h>
|
|
#include <sys/time.h>
|
|
#include <getopt.h>
|
|
|
|
#include <sys/socket.h>
|
|
#include <linux/netlink.h>
|
|
#include <linux/if.h>
|
|
#include <sys/stat.h>
|
|
#include <net/ethernet.h>
|
|
|
|
#include "mlanutl.h"
|
|
|
|
/** Supported stream modes */
|
|
#define HT_STREAM_MODE_1X1 0x11
|
|
#define HT_STREAM_MODE_2X2 0x22
|
|
|
|
/** mlanutl version number */
|
|
#define MLANUTL_VER "M1.3.02"
|
|
|
|
/** Initial number of total private ioctl calls */
|
|
#define IW_INIT_PRIV_NUM 128
|
|
/** Maximum number of total private ioctl calls supported */
|
|
#define IW_MAX_PRIV_NUM 1024
|
|
|
|
/** Termination flag */
|
|
int terminate_flag = 0;
|
|
|
|
/********************************************************
|
|
Local Variables
|
|
********************************************************/
|
|
#define BAND_B (1U << 0)
|
|
#define BAND_G (1U << 1)
|
|
#define BAND_A (1U << 2)
|
|
#define BAND_GN (1U << 3)
|
|
#define BAND_AN (1U << 4)
|
|
#define BAND_GAC (1U << 5)
|
|
#define BAND_AAC (1U << 6)
|
|
#define BAND_GAX (1U << 8)
|
|
#define BAND_AAX (1U << 9)
|
|
|
|
/** Stringification of rateId enumeration */
|
|
const char *rateIdStr[] = {"1", "2", "5.5", "11", "--", "6", "9", "12",
|
|
"18", "24", "36", "48", "54", "--", "M0", "M1",
|
|
"M2", "M3", "M4", "M5", "M6", "M7", "H0", "H1",
|
|
"H2", "H3", "H4", "H5", "H6", "H7"};
|
|
|
|
#ifdef DEBUG_LEVEL1
|
|
#define MMSG MBIT(0)
|
|
#define MFATAL MBIT(1)
|
|
#define MERROR MBIT(2)
|
|
#define MDATA MBIT(3)
|
|
#define MCMND MBIT(4)
|
|
#define MEVENT MBIT(5)
|
|
#define MINTR MBIT(6)
|
|
#define MIOCTL MBIT(7)
|
|
|
|
#define MREG_D MBIT(9)
|
|
|
|
#define MMPA_D MBIT(15)
|
|
#define MDAT_D MBIT(16)
|
|
#define MCMD_D MBIT(17)
|
|
#define MEVT_D MBIT(18)
|
|
#define MFW_D MBIT(19)
|
|
#define MIF_D MBIT(20)
|
|
|
|
#define MENTRY MBIT(28)
|
|
#define MWARN MBIT(29)
|
|
#define MINFO MBIT(30)
|
|
#define MHEX_DUMP MBIT(31)
|
|
#endif
|
|
|
|
static int process_version(int argc, char *argv[]);
|
|
static int process_verext(int argc, char *argv[]);
|
|
static int process_hostcmd(int argc, char *argv[]);
|
|
#ifdef DEBUG_LEVEL1
|
|
static int process_drvdbg(int argc, char *argv[]);
|
|
#endif
|
|
static int process_datarate(int argc, char *argv[]);
|
|
static int process_getlog(int argc, char *argv[]);
|
|
static int process_get_txpwrlimit(int argc, char *argv[]);
|
|
#ifdef STA_SUPPORT
|
|
static int process_get_signal(int argc, char *argv[]);
|
|
static int process_get_signal_ext(int argc, char *argv[]);
|
|
static int process_signalext_cfg(int argc, char *argv[]);
|
|
#endif
|
|
static int process_vhtcfg(int argc, char *argv[]);
|
|
static int process_dyn_bw(int argc, char *argv[]);
|
|
static int process_httxcfg(int argc, char *argv[]);
|
|
static int process_htcapinfo(int argc, char *argv[]);
|
|
static int process_addbapara(int argc, char *argv[]);
|
|
static int process_aggrpriotbl(int argc, char *argv[]);
|
|
static int process_addbareject(int argc, char *argv[]);
|
|
|
|
struct command_node command_list[] = {
|
|
{"version", process_version},
|
|
{"verext", process_verext},
|
|
{"hostcmd", process_hostcmd},
|
|
#ifdef DEBUG_LEVEL1
|
|
{"drvdbg", process_drvdbg},
|
|
#endif
|
|
{"getdatarate", process_datarate},
|
|
{"getlog", process_getlog},
|
|
{"get_txpwrlimit", process_get_txpwrlimit},
|
|
#ifdef STA_SUPPORT
|
|
{"getsignal", process_get_signal},
|
|
{"getsignalext", process_get_signal_ext},
|
|
{"getsignalextv2", process_get_signal_ext},
|
|
{"signalextcfg", process_signalext_cfg},
|
|
#endif
|
|
{"vhtcfg", process_vhtcfg},
|
|
{"dyn_bw", process_dyn_bw},
|
|
{"addbapara", process_addbapara},
|
|
{"aggrpriotbl", process_aggrpriotbl},
|
|
{"addbareject", process_addbareject},
|
|
{"httxcfg", process_httxcfg},
|
|
{"htcapinfo", process_htcapinfo},
|
|
};
|
|
|
|
static char *usage[] = {
|
|
"Usage: ",
|
|
" mlanutl -v (version)",
|
|
" mlanutl <ifname> <cmd> [...]",
|
|
" where",
|
|
" ifname : wireless network interface name, such as mlanX or uapX",
|
|
" cmd :",
|
|
" version",
|
|
" verext",
|
|
" hostcmd",
|
|
#ifdef DEBUG_LEVEL1
|
|
" drvdbg",
|
|
#endif
|
|
" getdatarate",
|
|
" getlog",
|
|
" get_txpwrlimit",
|
|
#ifdef STA_SUPPORT
|
|
" getsignal",
|
|
" signalextcfg",
|
|
" getsignalext",
|
|
" getsignalextv2",
|
|
#endif
|
|
" vhtcfg",
|
|
" dyn_bw",
|
|
" httxcfg",
|
|
" htcapinfo",
|
|
" aggrpriotbl",
|
|
" addbapara",
|
|
" addbareject",
|
|
};
|
|
|
|
/** Socket */
|
|
t_s32 sockfd;
|
|
/** Device name */
|
|
char dev_name[IFNAMSIZ + 1];
|
|
#define HOSTCMD "hostcmd"
|
|
|
|
static char *config_get_line(char *s, int size, FILE *stream, int *line,
|
|
char **_pos);
|
|
#define BSSID_FILTER 1
|
|
#define SSID_FILTER 2
|
|
/********************************************************
|
|
Global Variables
|
|
********************************************************/
|
|
|
|
int setuserscan_filter = 0;
|
|
int num_ssid_filter = 0;
|
|
/********************************************************
|
|
Local Functions
|
|
********************************************************/
|
|
/**
|
|
* @brief Convert char to hex integer
|
|
*
|
|
* @param chr Char to convert
|
|
* @return Hex integer or 0
|
|
*/
|
|
int hexval(t_s32 chr)
|
|
{
|
|
if (chr >= '0' && chr <= '9')
|
|
return chr - '0';
|
|
if (chr >= 'A' && chr <= 'F')
|
|
return chr - 'A' + 10;
|
|
if (chr >= 'a' && chr <= 'f')
|
|
return chr - 'a' + 10;
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* @brief Hump hex data
|
|
*
|
|
* @param prompt A pointer prompt buffer
|
|
* @param p A pointer to data buffer
|
|
* @param len The len of data buffer
|
|
* @param delim Delim char
|
|
* @return Hex integer
|
|
*/
|
|
t_void hexdump(char *prompt, t_void *p, t_s32 len, char delim)
|
|
{
|
|
t_s32 i;
|
|
t_u8 *s = p;
|
|
|
|
if (prompt) {
|
|
printf("%s: len=%d\n", prompt, (int)len);
|
|
}
|
|
for (i = 0; i < len; i++) {
|
|
if (i != len - 1)
|
|
printf("%02x%c", *s++, delim);
|
|
else
|
|
printf("%02x\n", *s);
|
|
if ((i + 1) % 16 == 0)
|
|
printf("\n");
|
|
}
|
|
printf("\n");
|
|
}
|
|
|
|
/**
|
|
* @brief Convert char to hex integer
|
|
*
|
|
* @param chr Char
|
|
* @return Hex integer
|
|
*/
|
|
t_u8 hexc2bin(char chr)
|
|
{
|
|
if (chr >= '0' && chr <= '9')
|
|
chr -= '0';
|
|
else if (chr >= 'A' && chr <= 'F')
|
|
chr -= ('A' - 10);
|
|
else if (chr >= 'a' && chr <= 'f')
|
|
chr -= ('a' - 10);
|
|
|
|
return chr;
|
|
}
|
|
|
|
/**
|
|
* @brief Convert string to hex integer
|
|
*
|
|
* @param s A pointer string buffer
|
|
* @return Hex integer
|
|
*/
|
|
t_u32 a2hex(char *s)
|
|
{
|
|
t_u32 val = 0;
|
|
|
|
if (!strncasecmp("0x", s, 2)) {
|
|
s += 2;
|
|
}
|
|
|
|
while (*s && isxdigit((unsigned char)*s)) {
|
|
val = (val << 4) + hexc2bin(*s++);
|
|
}
|
|
|
|
return val;
|
|
}
|
|
|
|
/*
|
|
* @brief Convert String to integer
|
|
*
|
|
* @param value A pointer to string
|
|
* @return Integer
|
|
*/
|
|
t_u32 a2hex_or_atoi(char *value)
|
|
{
|
|
if (value[0] == '0' && (value[1] == 'X' || value[1] == 'x')) {
|
|
return a2hex(value + 2);
|
|
} else {
|
|
return (t_u32)atoi(value);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Convert string to hex
|
|
*
|
|
* @param ptr A pointer to data buffer
|
|
* @param chr A pointer to return integer
|
|
* @return A pointer to next data field
|
|
*/
|
|
char *convert2hex(char *ptr, t_u8 *chr)
|
|
{
|
|
t_u8 val;
|
|
|
|
for (val = 0; *ptr && isxdigit((unsigned char)*ptr); ptr++) {
|
|
val = (val * 16) + hexval(*ptr);
|
|
}
|
|
|
|
*chr = val;
|
|
|
|
return ptr;
|
|
}
|
|
|
|
/**
|
|
* @brief Check the Hex String
|
|
* @param s A pointer to the string
|
|
* @return MLAN_STATUS_SUCCESS --HexString, MLAN_STATUS_FAILURE --not
|
|
* HexString
|
|
*/
|
|
int ishexstring(char *s)
|
|
{
|
|
int ret = MLAN_STATUS_FAILURE;
|
|
t_s32 tmp;
|
|
|
|
if (!strncasecmp("0x", s, 2)) {
|
|
s += 2;
|
|
}
|
|
while (*s) {
|
|
tmp = toupper((unsigned char)*s);
|
|
if (((tmp >= 'A') && (tmp <= 'F')) ||
|
|
((tmp >= '0') && (tmp <= '9'))) {
|
|
ret = MLAN_STATUS_SUCCESS;
|
|
} else {
|
|
ret = MLAN_STATUS_FAILURE;
|
|
break;
|
|
}
|
|
s++;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief Convert String to Integer
|
|
* @param buf A pointer to the string
|
|
* @return Integer
|
|
*/
|
|
int atoval(char *buf)
|
|
{
|
|
if (!strncasecmp(buf, "0x", 2))
|
|
return a2hex(buf + 2);
|
|
else if (!ishexstring(buf))
|
|
return a2hex(buf);
|
|
else
|
|
return atoi(buf);
|
|
}
|
|
|
|
/**
|
|
* @brief Display usage
|
|
*
|
|
* @return NA
|
|
*/
|
|
static t_void display_usage(t_void)
|
|
{
|
|
t_u32 i;
|
|
for (i = 0; i < NELEMENTS(usage); i++)
|
|
fprintf(stderr, "%s\n", usage[i]);
|
|
}
|
|
|
|
/**
|
|
* @brief Find and execute command
|
|
*
|
|
* @param argc Number of arguments
|
|
* @param argv A pointer to arguments array
|
|
* @return MLAN_STATUS_SUCCESS for success, otherwise failure
|
|
*/
|
|
static int process_command(int argc, char *argv[])
|
|
{
|
|
int i = 0, ret = MLAN_STATUS_NOTFOUND;
|
|
struct command_node *node = NULL;
|
|
|
|
for (i = 0; i < (int)NELEMENTS(command_list); i++) {
|
|
node = &command_list[i];
|
|
if (!strcasecmp(node->name, argv[2])) {
|
|
ret = node->handler(argc, argv);
|
|
break;
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief Converts a string to hex value
|
|
*
|
|
* @param str A pointer to the string
|
|
* @param raw A pointer to the raw data buffer
|
|
* @return Number of bytes read
|
|
**/
|
|
int string2raw(char *str, unsigned char *raw)
|
|
{
|
|
int len = (strlen(str) + 1) / 2;
|
|
|
|
do {
|
|
if (!isxdigit((unsigned char)*str)) {
|
|
return -1;
|
|
}
|
|
*str = toupper((unsigned char)*str);
|
|
*raw = CHAR2INT(*str) << 4;
|
|
++str;
|
|
*str = toupper((unsigned char)*str);
|
|
if (*str == '\0')
|
|
break;
|
|
*raw |= CHAR2INT(*str);
|
|
++raw;
|
|
} while (*++str != '\0');
|
|
return len;
|
|
}
|
|
|
|
/**
|
|
* @brief Prepare command buffer
|
|
* @param buffer Command buffer to be filled
|
|
* @param cmd Command id
|
|
* @param num Number of arguments
|
|
* @param args Arguments list
|
|
* @return MLAN_STATUS_SUCCESS
|
|
*/
|
|
static int prepare_buffer(t_u8 *buffer, char *cmd, t_u32 num, char *args[])
|
|
{
|
|
t_u8 *pos = NULL;
|
|
unsigned int i = 0;
|
|
|
|
memset(buffer, 0, BUFFER_LENGTH);
|
|
|
|
/* Flag it for our use */
|
|
pos = buffer;
|
|
strncpy((char *)pos, CMD_NXP, strlen(CMD_NXP));
|
|
pos += (strlen(CMD_NXP));
|
|
|
|
/* Insert command */
|
|
strncpy((char *)pos, (char *)cmd, strlen(cmd));
|
|
pos += (strlen(cmd));
|
|
|
|
/* Insert arguments */
|
|
for (i = 0; i < num; i++) {
|
|
strncpy((char *)pos, args[i], strlen(args[i]));
|
|
pos += strlen(args[i]);
|
|
if (i < (num - 1)) {
|
|
strncpy((char *)pos, " ", strlen(" "));
|
|
pos += 1;
|
|
}
|
|
}
|
|
|
|
return MLAN_STATUS_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
* @brief Signal handler
|
|
*
|
|
* @param sig Received signal number
|
|
*
|
|
* @return N/A
|
|
*/
|
|
void sig_handler(int sig)
|
|
{
|
|
printf("Stopping application.\n");
|
|
terminate_flag = 1;
|
|
}
|
|
|
|
/**
|
|
* @brief Trims leading and traling spaces only
|
|
* @param str A pointer to argument string
|
|
* @return pointer to trimmed string
|
|
*/
|
|
char *trim_spaces(char *str)
|
|
{
|
|
char *str_end = NULL;
|
|
|
|
if (!str)
|
|
return NULL;
|
|
|
|
/* Trim leading spaces */
|
|
while (!*str && isspace((unsigned char)*str))
|
|
str++;
|
|
|
|
if (*str == 0) /* All spaces? */
|
|
return str;
|
|
|
|
/* Trim trailing spaces */
|
|
str_end = str + strlen(str) - 1;
|
|
while (str_end > str && isspace((unsigned char)*str_end))
|
|
str_end--;
|
|
|
|
/* null terminate the string */
|
|
*(str_end + 1) = '\0';
|
|
|
|
return str;
|
|
}
|
|
|
|
/**
|
|
* @brief Process version
|
|
* @param argc Number of arguments
|
|
* @param argv A pointer to arguments array
|
|
* @return MLAN_STATUS_SUCCESS--success, otherwise--fail
|
|
*/
|
|
static int process_version(int argc, char *argv[])
|
|
{
|
|
t_u8 *buffer = NULL;
|
|
struct eth_priv_cmd *cmd = NULL;
|
|
struct ifreq ifr;
|
|
|
|
/* Initialize buffer */
|
|
buffer = (t_u8 *)malloc(BUFFER_LENGTH);
|
|
if (!buffer) {
|
|
printf("ERR:Cannot allocate buffer for command!\n");
|
|
return MLAN_STATUS_FAILURE;
|
|
}
|
|
|
|
prepare_buffer(buffer, argv[2], 0, NULL);
|
|
|
|
cmd = (struct eth_priv_cmd *)malloc(sizeof(struct eth_priv_cmd));
|
|
if (!cmd) {
|
|
printf("ERR:Cannot allocate buffer for command!\n");
|
|
free(buffer);
|
|
return MLAN_STATUS_FAILURE;
|
|
}
|
|
|
|
/* Fill up buffer */
|
|
#ifdef USERSPACE_32BIT_OVER_KERNEL_64BIT
|
|
memset(cmd, 0, sizeof(struct eth_priv_cmd));
|
|
memcpy(&cmd->buf, &buffer, sizeof(buffer));
|
|
#else
|
|
cmd->buf = buffer;
|
|
#endif
|
|
cmd->used_len = 0;
|
|
cmd->total_len = BUFFER_LENGTH;
|
|
|
|
/* Perform IOCTL */
|
|
memset(&ifr, 0, sizeof(struct ifreq));
|
|
strncpy(ifr.ifr_ifrn.ifrn_name, dev_name, strlen(dev_name));
|
|
ifr.ifr_ifru.ifru_data = (void *)cmd;
|
|
|
|
if (ioctl(sockfd, MLAN_ETH_PRIV, &ifr)) {
|
|
perror("mlanutl");
|
|
fprintf(stderr, "mlanutl: version fail\n");
|
|
if (cmd)
|
|
free(cmd);
|
|
if (buffer)
|
|
free(buffer);
|
|
return MLAN_STATUS_FAILURE;
|
|
}
|
|
|
|
/* Process result */
|
|
printf("Version string received: %s\n", buffer);
|
|
|
|
if (buffer)
|
|
free(buffer);
|
|
if (cmd)
|
|
free(cmd);
|
|
|
|
return MLAN_STATUS_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
* @brief Process extended version
|
|
* @param argc Number of arguments
|
|
* @param argv A pointer to arguments array
|
|
* @return MLAN_STATUS_SUCCESS--success, otherwise--fail
|
|
*/
|
|
static int process_verext(int argc, char *argv[])
|
|
{
|
|
int ret = 0;
|
|
t_u8 *buffer = NULL;
|
|
struct eth_priv_cmd *cmd = NULL;
|
|
struct ifreq ifr;
|
|
|
|
/* Initialize buffer */
|
|
buffer = (t_u8 *)malloc(BUFFER_LENGTH);
|
|
if (!buffer) {
|
|
printf("ERR:Cannot allocate buffer for command!\n");
|
|
ret = MLAN_STATUS_FAILURE;
|
|
goto done;
|
|
}
|
|
memset(buffer, 0, BUFFER_LENGTH);
|
|
|
|
/* Sanity tests */
|
|
if (argc < 3 || argc > 4) {
|
|
printf("Error: invalid no of arguments\n");
|
|
printf("mlanutl mlanX verext [#]\n");
|
|
ret = MLAN_STATUS_FAILURE;
|
|
goto done;
|
|
}
|
|
|
|
prepare_buffer(buffer, argv[2], (argc - 3), &argv[3]);
|
|
|
|
cmd = (struct eth_priv_cmd *)malloc(sizeof(struct eth_priv_cmd));
|
|
if (!cmd) {
|
|
printf("ERR:Cannot allocate buffer for command!\n");
|
|
ret = MLAN_STATUS_FAILURE;
|
|
goto done;
|
|
}
|
|
|
|
/* Fill up buffer */
|
|
#ifdef USERSPACE_32BIT_OVER_KERNEL_64BIT
|
|
memset(cmd, 0, sizeof(struct eth_priv_cmd));
|
|
memcpy(&cmd->buf, &buffer, sizeof(buffer));
|
|
#else
|
|
cmd->buf = buffer;
|
|
#endif
|
|
cmd->used_len = 0;
|
|
cmd->total_len = BUFFER_LENGTH;
|
|
|
|
/* Perform IOCTL */
|
|
memset(&ifr, 0, sizeof(struct ifreq));
|
|
strncpy(ifr.ifr_ifrn.ifrn_name, dev_name, strlen(dev_name));
|
|
ifr.ifr_ifru.ifru_data = (void *)cmd;
|
|
|
|
if (ioctl(sockfd, MLAN_ETH_PRIV, &ifr)) {
|
|
perror("mlanutl");
|
|
fprintf(stderr, "mlanutl: verext fail\n");
|
|
ret = MLAN_STATUS_FAILURE;
|
|
goto done;
|
|
}
|
|
|
|
/* Process result */
|
|
if (cmd->used_len)
|
|
printf("Extended Version string received: %s\n", buffer);
|
|
|
|
done:
|
|
if (buffer)
|
|
free(buffer);
|
|
if (cmd)
|
|
free(cmd);
|
|
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief Get one line from the File
|
|
*
|
|
* @param fp File handler
|
|
* @param str Storage location for data.
|
|
* @param size Maximum number of characters to read.
|
|
* @param lineno A pointer to return current line number
|
|
* @return returns string or NULL
|
|
*/
|
|
char *mlan_config_get_line(FILE *fp, char *str, t_s32 size, int *lineno)
|
|
{
|
|
char *start, *end;
|
|
int out, next_line;
|
|
|
|
if (!fp || !str)
|
|
return NULL;
|
|
|
|
do {
|
|
read_line:
|
|
if (!fgets(str, size, fp))
|
|
break;
|
|
start = str;
|
|
start[size - 1] = '\0';
|
|
end = start + strlen(str);
|
|
(*lineno)++;
|
|
|
|
out = 1;
|
|
while (out && (start < end)) {
|
|
next_line = 0;
|
|
/* Remove empty lines and lines starting with # */
|
|
switch (start[0]) {
|
|
case ' ': /* White space */
|
|
case '\t': /* Tab */
|
|
start++;
|
|
break;
|
|
case '#':
|
|
case '\n':
|
|
case '\0':
|
|
next_line = 1;
|
|
break;
|
|
case '\r':
|
|
if (start[1] == '\n')
|
|
next_line = 1;
|
|
else
|
|
start++;
|
|
break;
|
|
default:
|
|
out = 0;
|
|
break;
|
|
}
|
|
if (next_line)
|
|
goto read_line;
|
|
}
|
|
|
|
/* Remove # comments unless they are within a double quoted
|
|
* string. Remove trailing white space. */
|
|
end = strstr(start, "\"");
|
|
if (end) {
|
|
end = strstr(end + 1, "\"");
|
|
if (!end)
|
|
end = start;
|
|
} else
|
|
end = start;
|
|
|
|
end = strstr(end + 1, "#");
|
|
if (end)
|
|
*end-- = '\0';
|
|
else
|
|
end = start + strlen(start) - 1;
|
|
|
|
out = 1;
|
|
while (out && (start < end)) {
|
|
switch (*end) {
|
|
case ' ': /* White space */
|
|
case '\t': /* Tab */
|
|
case '\n':
|
|
case '\r':
|
|
*end = '\0';
|
|
end--;
|
|
break;
|
|
default:
|
|
out = 0;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (*start == '\0')
|
|
continue;
|
|
|
|
return start;
|
|
} while (1);
|
|
|
|
return NULL;
|
|
}
|
|
|
|
/**
|
|
* @brief Parse function for a configuration line
|
|
*
|
|
* @param s Storage buffer for data
|
|
* @param size Maximum size of data
|
|
* @param stream File stream pointer
|
|
* @param line Pointer to current line within the file
|
|
* @param _pos Output string or NULL
|
|
* @return String or NULL
|
|
*/
|
|
static char *config_get_line(char *s, int size, FILE *stream, int *line,
|
|
char **_pos)
|
|
{
|
|
*_pos = mlan_config_get_line(stream, s, size, line);
|
|
return *_pos;
|
|
}
|
|
|
|
/**
|
|
* @brief get hostcmd data
|
|
*
|
|
* @param ln A pointer to line number
|
|
* @param buf A pointer to hostcmd data
|
|
* @param size A pointer to the return size of hostcmd buffer
|
|
* @return MLAN_STATUS_SUCCESS
|
|
*/
|
|
static int mlan_get_hostcmd_data(FILE *fp, int *ln, t_u8 *buf, t_u16 *size)
|
|
{
|
|
t_s32 errors = 0, i;
|
|
char line[512], *pos, *pos1, *pos2, *pos3;
|
|
t_u16 len;
|
|
|
|
while ((pos = mlan_config_get_line(fp, line, sizeof(line), ln))) {
|
|
(*ln)++;
|
|
if (strcmp(pos, "}") == 0) {
|
|
break;
|
|
}
|
|
|
|
pos1 = strchr(pos, ':');
|
|
if (pos1 == NULL) {
|
|
printf("Line %d: Invalid hostcmd line '%s'\n", *ln,
|
|
pos);
|
|
errors++;
|
|
continue;
|
|
}
|
|
*pos1++ = '\0';
|
|
|
|
pos2 = strchr(pos1, '=');
|
|
if (pos2 == NULL) {
|
|
printf("Line %d: Invalid hostcmd line '%s'\n", *ln,
|
|
pos);
|
|
errors++;
|
|
continue;
|
|
}
|
|
*pos2++ = '\0';
|
|
|
|
len = a2hex_or_atoi(pos1);
|
|
if (len < 1 || len > BUFFER_LENGTH) {
|
|
printf("Line %d: Invalid hostcmd line '%s'\n", *ln,
|
|
pos);
|
|
errors++;
|
|
continue;
|
|
}
|
|
|
|
*size += len;
|
|
|
|
if (*pos2 == '"') {
|
|
pos2++;
|
|
pos3 = strchr(pos2, '"');
|
|
if (pos3 == NULL) {
|
|
printf("Line %d: invalid quotation '%s'\n", *ln,
|
|
pos);
|
|
errors++;
|
|
continue;
|
|
}
|
|
*pos3 = '\0';
|
|
memset(buf, 0, len);
|
|
memmove(buf, pos2, MIN(strlen(pos2), len));
|
|
buf += len;
|
|
} else if (*pos2 == '\'') {
|
|
pos2++;
|
|
pos3 = strchr(pos2, '\'');
|
|
if (pos3 == NULL) {
|
|
printf("Line %d: invalid quotation '%s'\n", *ln,
|
|
pos);
|
|
errors++;
|
|
continue;
|
|
}
|
|
*pos3 = ',';
|
|
for (i = 0; i < len; i++) {
|
|
pos3 = strchr(pos2, ',');
|
|
if (pos3 != NULL) {
|
|
*pos3 = '\0';
|
|
*buf++ = (t_u8)a2hex_or_atoi(pos2);
|
|
pos2 = pos3 + 1;
|
|
} else
|
|
*buf++ = 0;
|
|
}
|
|
} else if (*pos2 == '{') {
|
|
t_u16 tlvlen = 0, tmp_tlvlen;
|
|
mlan_get_hostcmd_data(fp, ln, buf + len, &tlvlen);
|
|
tmp_tlvlen = tlvlen;
|
|
while (len--) {
|
|
*buf++ = (t_u8)(tmp_tlvlen & 0xff);
|
|
tmp_tlvlen >>= 8;
|
|
}
|
|
*size += tlvlen;
|
|
buf += tlvlen;
|
|
} else {
|
|
t_u32 value = a2hex_or_atoi(pos2);
|
|
while (len--) {
|
|
*buf++ = (t_u8)(value & 0xff);
|
|
value >>= 8;
|
|
}
|
|
}
|
|
}
|
|
return MLAN_STATUS_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
* @brief Prepare host-command buffer
|
|
* @param fp File handler
|
|
* @param cmd_name Command name
|
|
* @param buf A pointer to comand buffer
|
|
* @return MLAN_STATUS_SUCCESS--success, otherwise--fail
|
|
*/
|
|
int prepare_host_cmd_buffer(FILE *fp, char *cmd_name, t_u8 *buf)
|
|
{
|
|
char line[256], cmdname[256], *pos, cmdcode[10];
|
|
HostCmd_DS_GEN *hostcmd;
|
|
t_u32 hostcmd_size = 0;
|
|
int ln = 0;
|
|
int cmdname_found = 0, cmdcode_found = 0;
|
|
|
|
hostcmd = (HostCmd_DS_GEN *)(buf + sizeof(t_u32));
|
|
hostcmd->command = 0xffff;
|
|
|
|
snprintf(cmdname, sizeof(cmdname), "%s={", cmd_name);
|
|
cmdname_found = 0;
|
|
while ((pos = mlan_config_get_line(fp, line, sizeof(line), &ln))) {
|
|
if (strcmp(pos, cmdname) == 0) {
|
|
cmdname_found = 1;
|
|
snprintf(cmdcode, sizeof(cmdcode), "CmdCode=");
|
|
cmdcode_found = 0;
|
|
while ((pos = mlan_config_get_line(
|
|
fp, line, sizeof(line), &ln))) {
|
|
if (strncmp(pos, cmdcode, strlen(cmdcode)) ==
|
|
0) {
|
|
t_u16 len = 0;
|
|
cmdcode_found = 1;
|
|
hostcmd->command = a2hex_or_atoi(
|
|
pos + strlen(cmdcode));
|
|
hostcmd->size = S_DS_GEN;
|
|
mlan_get_hostcmd_data(
|
|
fp, &ln,
|
|
buf + sizeof(t_u32) +
|
|
hostcmd->size,
|
|
&len);
|
|
hostcmd->size += len;
|
|
break;
|
|
}
|
|
}
|
|
if (!cmdcode_found) {
|
|
fprintf(stderr,
|
|
"mlanutl: CmdCode not found in conf file\n");
|
|
return MLAN_STATUS_FAILURE;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!cmdname_found) {
|
|
fprintf(stderr,
|
|
"mlanutl: cmdname '%s' is not found in conf file\n",
|
|
cmd_name);
|
|
return MLAN_STATUS_FAILURE;
|
|
}
|
|
|
|
hostcmd->seq_num = 0;
|
|
hostcmd->result = 0;
|
|
hostcmd->command = cpu_to_le16(hostcmd->command);
|
|
hostcmd->size = cpu_to_le16(hostcmd->size);
|
|
|
|
hostcmd_size = (t_u32)(hostcmd->size);
|
|
memcpy(buf, (t_u8 *)&hostcmd_size, sizeof(t_u32));
|
|
|
|
return MLAN_STATUS_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
* @brief Process hostcmd command
|
|
* @param argc Number of arguments
|
|
* @param argv A pointer to arguments array
|
|
* @return MLAN_STATUS_SUCCESS--success, otherwise--fail
|
|
*/
|
|
static int process_hostcmd(int argc, char *argv[])
|
|
{
|
|
t_u8 *buffer = NULL, *raw_buf = NULL;
|
|
struct eth_priv_cmd *cmd = NULL;
|
|
FILE *fp = NULL;
|
|
FILE *fp_raw = NULL;
|
|
FILE *fp_dtsi = NULL;
|
|
char cmdname[256];
|
|
boolean call_ioctl = TRUE;
|
|
t_u32 buf_len = 0, i, j, k;
|
|
char *line = NULL, *pos = NULL;
|
|
int li = 0, blk_count = 0, ob = 0;
|
|
int ret = MLAN_STATUS_SUCCESS;
|
|
|
|
struct cmd_node {
|
|
char cmd_string[256];
|
|
struct cmd_node *next;
|
|
};
|
|
struct cmd_node *command = NULL, *header = NULL, *new_node = NULL;
|
|
|
|
if (argc < 5) {
|
|
printf("Error: invalid no of arguments\n");
|
|
printf("Syntax: ./mlanutl mlanX hostcmd <hostcmd.conf> generate_raw <raw_data_file>\n");
|
|
ret = MLAN_STATUS_FAILURE;
|
|
goto done;
|
|
}
|
|
|
|
snprintf(cmdname, sizeof(cmdname), "%s", argv[4]);
|
|
|
|
if (!strcmp(cmdname, "generate_raw")) {
|
|
call_ioctl = FALSE;
|
|
}
|
|
if (call_ioctl) {
|
|
printf("Error: invalid no of arguments\n");
|
|
printf("Syntax: ./mlanutl mlanX hostcmd <hostcmd.conf> generate_raw <raw_data_file>\n");
|
|
ret = MLAN_STATUS_FAILURE;
|
|
goto done;
|
|
}
|
|
if (!call_ioctl && argc != 6) {
|
|
printf("Error: invalid no of arguments\n");
|
|
printf("Syntax: ./mlanutl mlanX hostcmd <hostcmd.conf> %s <raw_data_file>\n",
|
|
cmdname);
|
|
ret = MLAN_STATUS_FAILURE;
|
|
goto done;
|
|
}
|
|
|
|
fp = fopen(argv[3], "r");
|
|
if (fp == NULL) {
|
|
fprintf(stderr, "Cannot open file %s\n", argv[3]);
|
|
ret = MLAN_STATUS_FAILURE;
|
|
goto done;
|
|
}
|
|
|
|
/* Initialize buffer */
|
|
buffer = (t_u8 *)malloc(BUFFER_LENGTH);
|
|
if (!buffer) {
|
|
printf("ERR:Cannot allocate buffer for command!\n");
|
|
fclose(fp);
|
|
ret = MLAN_STATUS_FAILURE;
|
|
goto done;
|
|
}
|
|
memset(buffer, 0, BUFFER_LENGTH);
|
|
|
|
{
|
|
line = (char *)malloc(MAX_CONFIG_LINE);
|
|
if (!line) {
|
|
printf("ERR:Cannot allocate memory for line\n");
|
|
fclose(fp);
|
|
ret = MLAN_STATUS_FAILURE;
|
|
goto done;
|
|
}
|
|
memset(line, 0, MAX_CONFIG_LINE);
|
|
|
|
while (config_get_line(line, MAX_CONFIG_LINE, fp, &li, &pos)) {
|
|
line = trim_spaces(line);
|
|
if (line[strlen(line) - 1] == '{') {
|
|
if (ob == 0) {
|
|
new_node = (struct cmd_node *)malloc(
|
|
sizeof(struct cmd_node));
|
|
if (!new_node) {
|
|
printf("ERR:Cannot allocate memory for cmd_node\n");
|
|
fclose(fp);
|
|
ret = MLAN_STATUS_FAILURE;
|
|
goto done;
|
|
}
|
|
memset(new_node, 0,
|
|
sizeof(struct cmd_node));
|
|
new_node->next = NULL;
|
|
if (blk_count == 0) {
|
|
header = new_node;
|
|
command = new_node;
|
|
} else {
|
|
command->next = new_node;
|
|
command = new_node;
|
|
}
|
|
strncpy(command->cmd_string, line,
|
|
(strchr(line, '=') - line));
|
|
memmove(command->cmd_string,
|
|
trim_spaces(
|
|
command->cmd_string),
|
|
strlen(trim_spaces(
|
|
command->cmd_string)) +
|
|
1);
|
|
}
|
|
ob++;
|
|
continue; /* goto while() */
|
|
}
|
|
if (line[strlen(line) - 1] == '}') {
|
|
ob--;
|
|
if (ob == 0)
|
|
blk_count++;
|
|
continue; /* goto while() */
|
|
}
|
|
}
|
|
|
|
rewind(fp); /* Set the source file pointer to the beginning
|
|
again */
|
|
command = header; /* Set 'command' at the beginning of the
|
|
command list */
|
|
|
|
fp_raw = fopen(argv[5], "w");
|
|
if (fp_raw == NULL) {
|
|
fprintf(stderr,
|
|
"Cannot open the destination raw_data file %s\n",
|
|
argv[5]);
|
|
fclose(fp);
|
|
ret = MLAN_STATUS_FAILURE;
|
|
goto done;
|
|
}
|
|
|
|
/* prepare .dtsi output */
|
|
snprintf(cmdname, sizeof(cmdname), "%s.dtsi", argv[5]);
|
|
fp_dtsi = fopen(cmdname, "w");
|
|
if (fp_dtsi == NULL) {
|
|
fprintf(stderr, "Cannot open the destination file %s\n",
|
|
cmdname);
|
|
fclose(fp);
|
|
fclose(fp_raw);
|
|
ret = MLAN_STATUS_FAILURE;
|
|
goto done;
|
|
}
|
|
|
|
for (k = 0; k < blk_count && command != NULL; k++) {
|
|
if (MLAN_STATUS_FAILURE ==
|
|
prepare_host_cmd_buffer(fp, command->cmd_string,
|
|
buffer))
|
|
memset(buffer, 0, BUFFER_LENGTH);
|
|
|
|
memcpy(&buf_len, buffer, sizeof(t_u32));
|
|
if (buf_len) {
|
|
raw_buf = buffer + sizeof(t_u32); /* raw_buf
|
|
points to
|
|
start of
|
|
actual <raw
|
|
data> */
|
|
printf("buf_len = %d\n", (int)buf_len);
|
|
if (k > 0)
|
|
fprintf(fp_raw, "\n\n");
|
|
fprintf(fp_raw, "%s={\n", command->cmd_string);
|
|
fprintf(fp_dtsi,
|
|
"/ {\n\tmarvell_cfgdata {\n\t\tmarvell,%s = /bits/ 8 <\n",
|
|
command->cmd_string);
|
|
i = j = 0;
|
|
while (i < buf_len) {
|
|
for (j = 0; j < 16; j++) {
|
|
fprintf(fp_raw, "%02x ",
|
|
*(raw_buf + i));
|
|
if (i >= 8) {
|
|
fprintf(fp_dtsi,
|
|
"0x%02x",
|
|
*(raw_buf + i));
|
|
if ((j < 16 - 1) &&
|
|
(i < buf_len - 1))
|
|
fprintf(fp_dtsi,
|
|
" ");
|
|
}
|
|
if (++i >= buf_len)
|
|
break;
|
|
}
|
|
fputc('\n', fp_raw);
|
|
fputc('\n', fp_dtsi);
|
|
}
|
|
fprintf(fp_raw, "}");
|
|
fprintf(fp_dtsi, "\t\t>;\n\t};\n};\n");
|
|
}
|
|
command = command->next;
|
|
rewind(fp);
|
|
}
|
|
|
|
fclose(fp_dtsi);
|
|
fclose(fp_raw);
|
|
fclose(fp);
|
|
}
|
|
|
|
done:
|
|
while (header) {
|
|
command = header;
|
|
header = header->next;
|
|
free(command);
|
|
}
|
|
if (line)
|
|
free(line);
|
|
if (buffer)
|
|
free(buffer);
|
|
if (cmd)
|
|
free(cmd);
|
|
return ret;
|
|
}
|
|
|
|
#ifdef DEBUG_LEVEL1
|
|
/**
|
|
* @brief Process driver debug configuration
|
|
* @param argc number of arguments
|
|
* @param argv A pointer to arguments array
|
|
* @return MLAN_STATUS_SUCCESS--success, otherwise--fail
|
|
*/
|
|
static int process_drvdbg(int argc, char *argv[])
|
|
{
|
|
t_u8 *buffer = NULL;
|
|
struct eth_priv_cmd *cmd = NULL;
|
|
struct ifreq ifr;
|
|
t_u32 drvdbg;
|
|
|
|
/* Initialize buffer */
|
|
buffer = (t_u8 *)malloc(BUFFER_LENGTH);
|
|
if (!buffer) {
|
|
printf("ERR:Cannot allocate buffer for command!\n");
|
|
return MLAN_STATUS_FAILURE;
|
|
}
|
|
|
|
prepare_buffer(buffer, argv[2], (argc - 3), &argv[3]);
|
|
|
|
cmd = (struct eth_priv_cmd *)malloc(sizeof(struct eth_priv_cmd));
|
|
if (!cmd) {
|
|
printf("ERR:Cannot allocate buffer for command!\n");
|
|
free(buffer);
|
|
return MLAN_STATUS_FAILURE;
|
|
}
|
|
|
|
/* Fill up buffer */
|
|
#ifdef USERSPACE_32BIT_OVER_KERNEL_64BIT
|
|
memset(cmd, 0, sizeof(struct eth_priv_cmd));
|
|
memcpy(&cmd->buf, &buffer, sizeof(buffer));
|
|
#else
|
|
cmd->buf = buffer;
|
|
#endif
|
|
cmd->used_len = 0;
|
|
cmd->total_len = BUFFER_LENGTH;
|
|
|
|
/* Perform IOCTL */
|
|
memset(&ifr, 0, sizeof(struct ifreq));
|
|
strncpy(ifr.ifr_ifrn.ifrn_name, dev_name, strlen(dev_name));
|
|
ifr.ifr_ifru.ifru_data = (void *)cmd;
|
|
|
|
if (ioctl(sockfd, MLAN_ETH_PRIV, &ifr)) {
|
|
perror("mlanutl");
|
|
fprintf(stderr, "mlanutl: drvdbg config fail\n");
|
|
if (cmd)
|
|
free(cmd);
|
|
if (buffer)
|
|
free(buffer);
|
|
return MLAN_STATUS_FAILURE;
|
|
}
|
|
|
|
/* Process result */
|
|
if (argc == 3) {
|
|
memcpy(&drvdbg, buffer, sizeof(drvdbg));
|
|
printf("drvdbg: 0x%08x\n", drvdbg);
|
|
#ifdef DEBUG_LEVEL2
|
|
printf("MINFO (%08x) %s\n", MINFO,
|
|
(drvdbg & MINFO) ? "X" : "");
|
|
printf("MWARN (%08x) %s\n", MWARN,
|
|
(drvdbg & MWARN) ? "X" : "");
|
|
printf("MENTRY (%08x) %s\n", MENTRY,
|
|
(drvdbg & MENTRY) ? "X" : "");
|
|
#endif
|
|
printf("MMPA_D (%08x) %s\n", MMPA_D,
|
|
(drvdbg & MMPA_D) ? "X" : "");
|
|
printf("MIF_D (%08x) %s\n", MIF_D,
|
|
(drvdbg & MIF_D) ? "X" : "");
|
|
printf("MFW_D (%08x) %s\n", MFW_D,
|
|
(drvdbg & MFW_D) ? "X" : "");
|
|
printf("MEVT_D (%08x) %s\n", MEVT_D,
|
|
(drvdbg & MEVT_D) ? "X" : "");
|
|
printf("MCMD_D (%08x) %s\n", MCMD_D,
|
|
(drvdbg & MCMD_D) ? "X" : "");
|
|
printf("MDAT_D (%08x) %s\n", MDAT_D,
|
|
(drvdbg & MDAT_D) ? "X" : "");
|
|
printf("MREG_D (%08x) %s\n", MREG_D,
|
|
(drvdbg & MREG_D) ? "X" : "");
|
|
printf("MIOCTL (%08x) %s\n", MIOCTL,
|
|
(drvdbg & MIOCTL) ? "X" : "");
|
|
printf("MINTR (%08x) %s\n", MINTR,
|
|
(drvdbg & MINTR) ? "X" : "");
|
|
printf("MEVENT (%08x) %s\n", MEVENT,
|
|
(drvdbg & MEVENT) ? "X" : "");
|
|
printf("MCMND (%08x) %s\n", MCMND,
|
|
(drvdbg & MCMND) ? "X" : "");
|
|
printf("MDATA (%08x) %s\n", MDATA,
|
|
(drvdbg & MDATA) ? "X" : "");
|
|
printf("MERROR (%08x) %s\n", MERROR,
|
|
(drvdbg & MERROR) ? "X" : "");
|
|
printf("MFATAL (%08x) %s\n", MFATAL,
|
|
(drvdbg & MFATAL) ? "X" : "");
|
|
printf("MMSG (%08x) %s\n", MMSG, (drvdbg & MMSG) ? "X" : "");
|
|
}
|
|
|
|
if (buffer)
|
|
free(buffer);
|
|
if (cmd)
|
|
free(cmd);
|
|
|
|
return MLAN_STATUS_SUCCESS;
|
|
}
|
|
#endif
|
|
|
|
static char *rate_format[4] = {"LG", "HT", "VHT", "HE"};
|
|
static char *lg_rate[] = {"1 Mbps", "2 Mbps", "5.5 Mbps", "11 Mbps",
|
|
"6 Mbps", "9 Mbps", "12 Mbps", "18 Mbps",
|
|
"24 Mbps", "36 Mbps", "48 Mbps", "54 Mbps"};
|
|
|
|
/**
|
|
* @brief Process Get data rate
|
|
* @param argc Number of arguments
|
|
* @param argv A pointer to arguments array
|
|
* @return MLAN_STATUS_SUCCESS--success, otherwise--fail
|
|
*/
|
|
static int process_datarate(int argc, char *argv[])
|
|
{
|
|
t_u8 *buffer = NULL;
|
|
struct eth_priv_cmd *cmd = NULL;
|
|
struct eth_priv_data_rate *datarate = NULL;
|
|
struct ifreq ifr;
|
|
char *bw[] = {"20 MHz", "40 MHz", "80 MHz", "160 MHz"};
|
|
|
|
/* Initialize buffer */
|
|
buffer = (t_u8 *)malloc(BUFFER_LENGTH);
|
|
if (!buffer) {
|
|
printf("ERR:Cannot allocate buffer for command!\n");
|
|
return MLAN_STATUS_FAILURE;
|
|
}
|
|
|
|
prepare_buffer(buffer, argv[2], 0, NULL);
|
|
|
|
cmd = (struct eth_priv_cmd *)malloc(sizeof(struct eth_priv_cmd));
|
|
if (!cmd) {
|
|
printf("ERR:Cannot allocate buffer for command!\n");
|
|
free(buffer);
|
|
return MLAN_STATUS_FAILURE;
|
|
}
|
|
|
|
/* Fill up buffer */
|
|
#ifdef USERSPACE_32BIT_OVER_KERNEL_64BIT
|
|
memset(cmd, 0, sizeof(struct eth_priv_cmd));
|
|
memcpy(&cmd->buf, &buffer, sizeof(buffer));
|
|
#else
|
|
cmd->buf = buffer;
|
|
#endif
|
|
cmd->used_len = 0;
|
|
cmd->total_len = BUFFER_LENGTH;
|
|
|
|
/* Perform IOCTL */
|
|
memset(&ifr, 0, sizeof(struct ifreq));
|
|
strncpy(ifr.ifr_ifrn.ifrn_name, dev_name, strlen(dev_name));
|
|
ifr.ifr_ifru.ifru_data = (void *)cmd;
|
|
|
|
if (ioctl(sockfd, MLAN_ETH_PRIV, &ifr)) {
|
|
perror("mlanutl");
|
|
fprintf(stderr, "mlanutl: getdatarate fail\n");
|
|
if (cmd)
|
|
free(cmd);
|
|
if (buffer)
|
|
free(buffer);
|
|
return MLAN_STATUS_FAILURE;
|
|
}
|
|
|
|
/* Process result */
|
|
datarate = (struct eth_priv_data_rate *)buffer;
|
|
printf("Data Rate:\n");
|
|
printf(" TX: \n");
|
|
if (datarate->tx_rate_format <= 3) {
|
|
printf(" Type: %s\n", rate_format[datarate->tx_rate_format]);
|
|
if ((datarate->tx_rate_format == 0) &&
|
|
datarate->tx_data_rate <= 11)
|
|
/* LG */
|
|
printf(" Rate: %s\n",
|
|
lg_rate[datarate->tx_data_rate]);
|
|
else {
|
|
/* HT and VHT*/
|
|
if (datarate->tx_bw <= 3)
|
|
printf(" BW: %s\n", bw[datarate->tx_bw]);
|
|
if (datarate->tx_rate_format < 3) {
|
|
if (datarate->tx_gi == 0)
|
|
printf(" GI: Long\n");
|
|
else
|
|
printf(" GI: Short\n");
|
|
} else if (datarate->tx_rate_format == 3) {
|
|
switch (datarate->tx_gi) {
|
|
case 0:
|
|
printf(" GI: 1xHELTF + GI 0.8us \n");
|
|
break;
|
|
case 1:
|
|
printf(" GI: 2xHELTF + GI 0.8us \n");
|
|
break;
|
|
case 2:
|
|
printf(" GI: 2xHELTF + GI 1.6us \n");
|
|
break;
|
|
case 3:
|
|
printf(" GI: 4xHELTF + GI 0.8us DCM=0 and STBC=0 or\n"
|
|
" 4xHELTF + GI 3.2us Otherwise \n");
|
|
break;
|
|
}
|
|
}
|
|
if (datarate->tx_rate_format >= 2)
|
|
printf(" NSS: %d\n", datarate->tx_nss + 1);
|
|
if (datarate->tx_mcs_index != 0xFF)
|
|
printf(" MCS: MCS %d\n",
|
|
(int)datarate->tx_mcs_index);
|
|
else
|
|
printf(" MCS: Auto\n");
|
|
if (datarate->tx_rate_format < 3)
|
|
printf(" Rate: %f Mbps\n",
|
|
(float)datarate->tx_data_rate / 2);
|
|
}
|
|
}
|
|
|
|
printf(" RX: \n");
|
|
if (datarate->rx_rate_format <= 3) {
|
|
printf(" Type: %s\n", rate_format[datarate->rx_rate_format]);
|
|
if ((datarate->rx_rate_format == 0) &&
|
|
datarate->rx_data_rate <= 11)
|
|
/* LG */
|
|
printf(" Rate: %s\n",
|
|
lg_rate[datarate->rx_data_rate]);
|
|
else {
|
|
/* HT and VHT*/
|
|
if (datarate->rx_bw <= 3)
|
|
printf(" BW: %s\n", bw[datarate->rx_bw]);
|
|
if (datarate->rx_rate_format < 3) {
|
|
if (datarate->rx_gi == 0)
|
|
printf(" GI: Long\n");
|
|
else
|
|
printf(" GI: Short\n");
|
|
} else if (datarate->rx_rate_format == 3) {
|
|
switch (datarate->rx_gi) {
|
|
case 0:
|
|
printf(" GI: 1xHELTF + GI 0.8us \n");
|
|
break;
|
|
case 1:
|
|
printf(" GI: 2xHELTF + GI 0.8us \n");
|
|
break;
|
|
case 2:
|
|
printf(" GI: 2xHELTF + GI 1.6us \n");
|
|
break;
|
|
case 3:
|
|
printf(" GI: 4xHELTF + GI 0.8us DCM=0 and STBC=0 or\n"
|
|
" 4xHELTF + GI 3.2us Otherwise \n");
|
|
break;
|
|
}
|
|
}
|
|
if (datarate->rx_rate_format >= 2)
|
|
printf(" NSS: %d\n", datarate->rx_nss + 1);
|
|
if (datarate->rx_mcs_index != 0xFF)
|
|
printf(" MCS: MCS %d\n",
|
|
(int)datarate->rx_mcs_index);
|
|
else
|
|
printf(" MCS: Auto\n");
|
|
if (datarate->rx_rate_format < 3)
|
|
printf(" Rate: %f Mbps\n",
|
|
(float)datarate->rx_data_rate / 2);
|
|
}
|
|
}
|
|
|
|
if (buffer)
|
|
free(buffer);
|
|
if (cmd)
|
|
free(cmd);
|
|
|
|
return MLAN_STATUS_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
* @brief Process get wireless stats
|
|
* @param argc Number of arguments
|
|
* @param argv A pointer to arguments array
|
|
* @return MLAN_STATUS_SUCCESS--success, otherwise--fail
|
|
*/
|
|
static int process_getlog(int argc, char *argv[])
|
|
{
|
|
t_u8 *buffer = NULL;
|
|
struct eth_priv_cmd *cmd = NULL;
|
|
struct eth_priv_get_log *stats = NULL;
|
|
struct ifreq ifr;
|
|
struct timeval tv;
|
|
int i = 0;
|
|
|
|
/* Initialize buffer */
|
|
buffer = (t_u8 *)malloc(BUFFER_LENGTH);
|
|
if (!buffer) {
|
|
printf("ERR:Cannot allocate buffer for command!\n");
|
|
return MLAN_STATUS_FAILURE;
|
|
}
|
|
|
|
prepare_buffer(buffer, argv[2], (argc - 3), &argv[3]);
|
|
|
|
cmd = (struct eth_priv_cmd *)malloc(sizeof(struct eth_priv_cmd));
|
|
if (!cmd) {
|
|
printf("ERR:Cannot allocate buffer for command!\n");
|
|
free(buffer);
|
|
return MLAN_STATUS_FAILURE;
|
|
}
|
|
|
|
/* Fill up buffer */
|
|
#ifdef USERSPACE_32BIT_OVER_KERNEL_64BIT
|
|
memset(cmd, 0, sizeof(struct eth_priv_cmd));
|
|
memcpy(&cmd->buf, &buffer, sizeof(buffer));
|
|
#else
|
|
cmd->buf = buffer;
|
|
#endif
|
|
cmd->used_len = 0;
|
|
cmd->total_len = BUFFER_LENGTH;
|
|
|
|
/* Perform IOCTL */
|
|
memset(&ifr, 0, sizeof(struct ifreq));
|
|
strncpy(ifr.ifr_ifrn.ifrn_name, dev_name, strlen(dev_name));
|
|
ifr.ifr_ifru.ifru_data = (void *)cmd;
|
|
|
|
if (ioctl(sockfd, MLAN_ETH_PRIV, &ifr)) {
|
|
perror("mlanutl");
|
|
fprintf(stderr, "mlanutl: getlog fail\n");
|
|
if (cmd)
|
|
free(cmd);
|
|
if (buffer)
|
|
free(buffer);
|
|
return MLAN_STATUS_FAILURE;
|
|
}
|
|
|
|
gettimeofday(&tv, NULL);
|
|
|
|
/* Process results */
|
|
stats = (struct eth_priv_get_log *)buffer;
|
|
printf("Get log: timestamp %d.%06d sec\n", (int)tv.tv_sec,
|
|
(int)tv.tv_usec);
|
|
printf("dot11GroupTransmittedFrameCount %u\n"
|
|
"dot11FailedCount %u\n"
|
|
"dot11RetryCount %u\n"
|
|
"dot11MultipleRetryCount %u\n"
|
|
"dot11FrameDuplicateCount %u\n"
|
|
"dot11RTSSuccessCount %u\n"
|
|
"dot11RTSFailureCount %u\n"
|
|
"dot11ACKFailureCount %u\n"
|
|
"dot11ReceivedFragmentCount %u\n"
|
|
"dot11GroupReceivedFrameCount %u\n"
|
|
"dot11FCSErrorCount %u\n"
|
|
"dot11TransmittedFrameCount %u\n"
|
|
"wepicverrcnt-1 %u\n"
|
|
"wepicverrcnt-2 %u\n"
|
|
"wepicverrcnt-3 %u\n"
|
|
"wepicverrcnt-4 %u\n"
|
|
"beaconReceivedCount %u\n"
|
|
"beaconMissedCount %u\n",
|
|
stats->mcast_tx_frame, stats->failed, stats->retry,
|
|
stats->multi_retry, stats->frame_dup, stats->rts_success,
|
|
stats->rts_failure, stats->ack_failure, stats->rx_frag,
|
|
stats->mcast_rx_frame, stats->fcs_error, stats->tx_frame,
|
|
stats->wep_icv_error[0], stats->wep_icv_error[1],
|
|
stats->wep_icv_error[2], stats->wep_icv_error[3],
|
|
stats->bcn_rcv_cnt, stats->bcn_miss_cnt);
|
|
|
|
printf("rxStuckIssueCount-1 %u\n"
|
|
"rxStuckIssueCount-2 %u\n"
|
|
"rxStuckRecoveryCount %u\n"
|
|
"rxStuckTsf-1 %llu\n"
|
|
"rxStuckTsf-2 %llu\n"
|
|
"txWatchdogRecoveryCount %u\n"
|
|
"txWatchdogTsf-1 %llu\n"
|
|
"txWatchdogTsf-2 %llu\n"
|
|
"channelSwitchAnnouncementSent %u\n"
|
|
"channelSwitchState %u\n"
|
|
"registerClass %u\n"
|
|
"channelNumber %u\n"
|
|
"channelSwitchMode %u\n",
|
|
stats->rx_stuck_issue_cnt[0], stats->rx_stuck_issue_cnt[1],
|
|
stats->rx_stuck_recovery_cnt, stats->rx_stuck_tsf[0],
|
|
stats->rx_stuck_tsf[1], stats->tx_watchdog_recovery_cnt,
|
|
stats->tx_watchdog_tsf[0], stats->tx_watchdog_tsf[1],
|
|
stats->channel_switch_ann_sent, stats->channel_switch_state,
|
|
stats->reg_class, stats->channel_number,
|
|
stats->channel_switch_mode);
|
|
|
|
if (cmd->used_len == sizeof(struct eth_priv_get_log)) {
|
|
printf("dot11TransmittedFragmentCount %u\n",
|
|
stats->tx_frag_cnt);
|
|
printf("dot11QosTransmittedFragmentCount ");
|
|
for (i = 0; i < 8; i++) {
|
|
printf("%u ", stats->qos_tx_frag_cnt[i]);
|
|
}
|
|
printf("\ndot11QosFailedCount ");
|
|
for (i = 0; i < 8; i++) {
|
|
printf("%u ", stats->qos_failed_cnt[i]);
|
|
}
|
|
printf("\ndot11QosRetryCount ");
|
|
for (i = 0; i < 8; i++) {
|
|
printf("%u ", stats->qos_retry_cnt[i]);
|
|
}
|
|
printf("\ndot11QosMultipleRetryCount ");
|
|
for (i = 0; i < 8; i++) {
|
|
printf("%u ", stats->qos_multi_retry_cnt[i]);
|
|
}
|
|
printf("\ndot11QosFrameDuplicateCount ");
|
|
for (i = 0; i < 8; i++) {
|
|
printf("%u ", stats->qos_frm_dup_cnt[i]);
|
|
}
|
|
printf("\ndot11QosRTSSuccessCount ");
|
|
for (i = 0; i < 8; i++) {
|
|
printf("%u ", stats->qos_rts_suc_cnt[i]);
|
|
}
|
|
printf("\ndot11QosRTSFailureCount ");
|
|
for (i = 0; i < 8; i++) {
|
|
printf("%u ", stats->qos_rts_failure_cnt[i]);
|
|
}
|
|
printf("\ndot11QosACKFailureCount ");
|
|
for (i = 0; i < 8; i++) {
|
|
printf("%u ", stats->qos_ack_failure_cnt[i]);
|
|
}
|
|
printf("\ndot11QosReceivedFragmentCount ");
|
|
for (i = 0; i < 8; i++) {
|
|
printf("%u ", stats->qos_rx_frag_cnt[i]);
|
|
}
|
|
printf("\ndot11QosTransmittedFrameCount ");
|
|
for (i = 0; i < 8; i++) {
|
|
printf("%u ", stats->qos_tx_frm_cnt[i]);
|
|
}
|
|
printf("\ndot11QosDiscardedFrameCount ");
|
|
for (i = 0; i < 8; i++) {
|
|
printf("%u ", stats->qos_discarded_frm_cnt[i]);
|
|
}
|
|
printf("\ndot11QosMPDUsReceivedCount ");
|
|
for (i = 0; i < 8; i++) {
|
|
printf("%u ", stats->qos_mpdus_rx_cnt[i]);
|
|
}
|
|
printf("\ndot11QosRetriesReceivedCount ");
|
|
for (i = 0; i < 8; i++) {
|
|
printf("%u ", stats->qos_retries_rx_cnt[i]);
|
|
}
|
|
printf("\ndot11RSNAStatsCMACICVErrors %u\n"
|
|
"dot11RSNAStatsCMACReplays %u\n"
|
|
"dot11RSNAStatsRobustMgmtCCMPReplays %u\n"
|
|
"dot11RSNAStatsTKIPICVErrors %u\n"
|
|
"dot11RSNAStatsTKIPReplays %u\n"
|
|
"dot11RSNAStatsCCMPDecryptErrors %u\n"
|
|
"dot11RSNAstatsCCMPReplays %u\n"
|
|
"dot11TransmittedAMSDUCount %u\n"
|
|
"dot11FailedAMSDUCount %u\n"
|
|
"dot11RetryAMSDUCount %u\n"
|
|
"dot11MultipleRetryAMSDUCount %u\n"
|
|
"dot11TransmittedOctetsInAMSDUCount %llu\n"
|
|
"dot11AMSDUAckFailureCount %u\n"
|
|
"dot11ReceivedAMSDUCount %u\n"
|
|
"dot11ReceivedOctetsInAMSDUCount %llu\n"
|
|
"dot11TransmittedAMPDUCount %u\n"
|
|
"dot11TransmittedMPDUsInAMPDUCount %u\n"
|
|
"dot11TransmittedOctetsInAMPDUCount %llu\n"
|
|
"dot11AMPDUReceivedCount %u\n"
|
|
"dot11MPDUInReceivedAMPDUCount %u\n"
|
|
"dot11ReceivedOctetsInAMPDUCount %llu\n"
|
|
"dot11AMPDUDelimiterCRCErrorCount %u\n",
|
|
stats->cmacicv_errors, stats->cmac_replays,
|
|
stats->mgmt_ccmp_replays, stats->tkipicv_errors,
|
|
stats->tkip_replays, stats->ccmp_decrypt_errors,
|
|
stats->ccmp_replays, stats->tx_amsdu_cnt,
|
|
stats->failed_amsdu_cnt, stats->retry_amsdu_cnt,
|
|
stats->multi_retry_amsdu_cnt,
|
|
stats->tx_octets_in_amsdu_cnt,
|
|
stats->amsdu_ack_failure_cnt, stats->rx_amsdu_cnt,
|
|
stats->rx_octets_in_amsdu_cnt, stats->tx_ampdu_cnt,
|
|
stats->tx_mpdus_in_ampdu_cnt,
|
|
stats->tx_octets_in_ampdu_cnt, stats->ampdu_rx_cnt,
|
|
stats->mpdu_in_rx_ampdu_cnt,
|
|
stats->rx_octets_in_ampdu_cnt,
|
|
stats->ampdu_delimiter_crc_error_cnt);
|
|
}
|
|
|
|
if (buffer)
|
|
free(buffer);
|
|
if (cmd)
|
|
free(cmd);
|
|
|
|
return MLAN_STATUS_SUCCESS;
|
|
}
|
|
|
|
#ifdef STA_SUPPORT
|
|
/**
|
|
* @brief Get signal
|
|
* @param argc Number of arguments
|
|
* @param argv A pointer to arguments array
|
|
* @return MLAN_STATUS_SUCCESS--success, otherwise--fail
|
|
*/
|
|
static int process_get_signal(int argc, char *argv[])
|
|
{
|
|
#define DATA_SIZE 12
|
|
int ret = 0, data[DATA_SIZE], i = 0, copy_size = 0;
|
|
t_u8 *buffer = NULL;
|
|
struct eth_priv_cmd *cmd = NULL;
|
|
struct ifreq ifr;
|
|
|
|
memset(data, 0, sizeof(data));
|
|
/* Initialize buffer */
|
|
buffer = (t_u8 *)malloc(BUFFER_LENGTH);
|
|
if (!buffer) {
|
|
printf("ERR:Cannot allocate buffer for command!\n");
|
|
ret = MLAN_STATUS_FAILURE;
|
|
goto done;
|
|
}
|
|
memset(buffer, 0, BUFFER_LENGTH);
|
|
|
|
/* Sanity tests */
|
|
if (argc < 3 || argc > 5) {
|
|
printf("Error: invalid no of arguments\n");
|
|
printf("mlanutl mlanX getsignal [m] [n]\n");
|
|
ret = MLAN_STATUS_FAILURE;
|
|
goto done;
|
|
}
|
|
|
|
prepare_buffer(buffer, argv[2], (argc - 3), &argv[3]);
|
|
|
|
cmd = (struct eth_priv_cmd *)malloc(sizeof(struct eth_priv_cmd));
|
|
if (!cmd) {
|
|
printf("ERR:Cannot allocate buffer for command!\n");
|
|
ret = MLAN_STATUS_FAILURE;
|
|
goto done;
|
|
}
|
|
|
|
/* Fill up buffer */
|
|
#ifdef USERSPACE_32BIT_OVER_KERNEL_64BIT
|
|
memset(cmd, 0, sizeof(struct eth_priv_cmd));
|
|
memcpy(&cmd->buf, &buffer, sizeof(buffer));
|
|
#else
|
|
cmd->buf = buffer;
|
|
#endif
|
|
cmd->used_len = 0;
|
|
cmd->total_len = BUFFER_LENGTH;
|
|
|
|
/* Perform IOCTL */
|
|
memset(&ifr, 0, sizeof(struct ifreq));
|
|
strncpy(ifr.ifr_ifrn.ifrn_name, dev_name, strlen(dev_name));
|
|
ifr.ifr_ifru.ifru_data = (void *)cmd;
|
|
|
|
if (ioctl(sockfd, MLAN_ETH_PRIV, &ifr)) {
|
|
perror("mlanutl");
|
|
fprintf(stderr, "mlanutl: getsignal fail\n");
|
|
ret = MLAN_STATUS_FAILURE;
|
|
goto done;
|
|
}
|
|
|
|
/* Process result */
|
|
copy_size = MIN(cmd->used_len, DATA_SIZE * sizeof(int));
|
|
if (copy_size > 0)
|
|
memcpy(&data, buffer, copy_size);
|
|
printf("Get signal output is\t");
|
|
for (i = 0; i < (int)(copy_size / sizeof(int)); i++)
|
|
printf("%d\t", data[i]);
|
|
printf("\n");
|
|
|
|
done:
|
|
if (buffer)
|
|
free(buffer);
|
|
if (cmd)
|
|
free(cmd);
|
|
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief Set signalext cfg
|
|
* @param argc Number of arguments
|
|
* @param argv A pointer to arguments array
|
|
* @return MLAN_STATUS_SUCCESS--success, otherwise--fail
|
|
*/
|
|
static int process_signalext_cfg(int argc, char *argv[])
|
|
{
|
|
int ret = 0;
|
|
t_u8 *buffer = NULL;
|
|
struct eth_priv_cmd *cmd = NULL;
|
|
struct ifreq ifr;
|
|
|
|
/* Initialize buffer */
|
|
buffer = (t_u8 *)malloc(BUFFER_LENGTH);
|
|
if (!buffer) {
|
|
printf("ERR:Cannot allocate buffer for command!\n");
|
|
ret = MLAN_STATUS_FAILURE;
|
|
goto done;
|
|
}
|
|
memset(buffer, 0, BUFFER_LENGTH);
|
|
|
|
/* Sanity tests */
|
|
if (argc != 4) {
|
|
printf("Error: invalid no of arguments\n");
|
|
printf("mlanutl mlanX signalextcfg [#]\n");
|
|
ret = MLAN_STATUS_FAILURE;
|
|
goto done;
|
|
}
|
|
|
|
prepare_buffer(buffer, argv[2], (argc - 3), &argv[3]);
|
|
|
|
cmd = (struct eth_priv_cmd *)malloc(sizeof(struct eth_priv_cmd));
|
|
if (!cmd) {
|
|
printf("ERR:Cannot allocate buffer for command!\n");
|
|
ret = MLAN_STATUS_FAILURE;
|
|
goto done;
|
|
}
|
|
|
|
/* Fill up buffer */
|
|
#ifdef USERSPACE_32BIT_OVER_KERNEL_64BIT
|
|
memset(cmd, 0, sizeof(struct eth_priv_cmd));
|
|
memcpy(&cmd->buf, &buffer, sizeof(buffer));
|
|
#else
|
|
cmd->buf = buffer;
|
|
#endif
|
|
cmd->used_len = 0;
|
|
cmd->total_len = BUFFER_LENGTH;
|
|
|
|
/* Perform IOCTL */
|
|
memset(&ifr, 0, sizeof(struct ifreq));
|
|
strncpy(ifr.ifr_ifrn.ifrn_name, dev_name, strlen(dev_name));
|
|
ifr.ifr_ifru.ifru_data = (void *)cmd;
|
|
|
|
if (ioctl(sockfd, MLAN_ETH_PRIV, &ifr)) {
|
|
perror("mlanutl");
|
|
fprintf(stderr, "mlanutl: signalext cfg fail\n");
|
|
ret = MLAN_STATUS_FAILURE;
|
|
goto done;
|
|
}
|
|
|
|
done:
|
|
if (buffer)
|
|
free(buffer);
|
|
if (cmd)
|
|
free(cmd);
|
|
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief Get signal
|
|
* @param argc Number of arguments
|
|
* @param argv A pointer to arguments array
|
|
* @return MLAN_STATUS_SUCCESS--success, otherwise--fail
|
|
*/
|
|
static int process_get_signal_ext(int argc, char *argv[])
|
|
{
|
|
#define MAX_NUM_PATH 3
|
|
#define PATH_SIZE 13
|
|
#define PATH_A 1
|
|
#define PATH_B 2
|
|
#define PATH_AB 3
|
|
int ret = 0, data[PATH_SIZE * MAX_NUM_PATH] = {0};
|
|
int i = 0, copy_size = 0;
|
|
t_u8 *buffer = NULL;
|
|
struct eth_priv_cmd *cmd = NULL;
|
|
struct ifreq ifr;
|
|
t_u8 num_path = 0;
|
|
|
|
memset(data, 0, sizeof(data));
|
|
/* Initialize buffer */
|
|
buffer = (t_u8 *)malloc(BUFFER_LENGTH);
|
|
if (!buffer) {
|
|
printf("ERR:Cannot allocate buffer for command!\n");
|
|
ret = MLAN_STATUS_FAILURE;
|
|
goto done;
|
|
}
|
|
memset(buffer, 0, BUFFER_LENGTH);
|
|
|
|
/* Sanity tests */
|
|
if (argc != 3 && argc != 4) {
|
|
printf("Error: invalid no of arguments\n");
|
|
if (strncmp(argv[2], "getsignalextv2",
|
|
strlen("getsignalextv2")) == 0)
|
|
printf("mlanutl mlanX getsignalextv2 [m]\n");
|
|
else if (strncmp(argv[2], "getsignalext",
|
|
strlen("getsignalext")) == 0)
|
|
printf("mlanutl mlanX getsignalext [m]\n");
|
|
ret = MLAN_STATUS_FAILURE;
|
|
goto done;
|
|
}
|
|
|
|
prepare_buffer(buffer, argv[2], (argc - 3), &argv[3]);
|
|
|
|
cmd = (struct eth_priv_cmd *)malloc(sizeof(struct eth_priv_cmd));
|
|
if (!cmd) {
|
|
printf("ERR:Cannot allocate buffer for command!\n");
|
|
ret = MLAN_STATUS_FAILURE;
|
|
goto done;
|
|
}
|
|
|
|
/* Fill up buffer */
|
|
#ifdef USERSPACE_32BIT_OVER_KERNEL_64BIT
|
|
memset(cmd, 0, sizeof(struct eth_priv_cmd));
|
|
memcpy(&cmd->buf, &buffer, sizeof(buffer));
|
|
#else
|
|
cmd->buf = buffer;
|
|
#endif
|
|
cmd->used_len = 0;
|
|
cmd->total_len = BUFFER_LENGTH;
|
|
|
|
/* Perform IOCTL */
|
|
memset(&ifr, 0, sizeof(struct ifreq));
|
|
strncpy(ifr.ifr_ifrn.ifrn_name, dev_name, strlen(dev_name));
|
|
ifr.ifr_ifru.ifru_data = (void *)cmd;
|
|
|
|
if (ioctl(sockfd, MLAN_ETH_PRIV, &ifr)) {
|
|
perror("mlanutl");
|
|
fprintf(stderr, "mlanutl: getsignal fail\n");
|
|
ret = MLAN_STATUS_FAILURE;
|
|
goto done;
|
|
}
|
|
|
|
/* Process result */
|
|
copy_size = cmd->used_len;
|
|
if (copy_size > 0)
|
|
memcpy(&data, (int *)buffer, copy_size);
|
|
|
|
num_path = copy_size / sizeof(int) / PATH_SIZE;
|
|
for (i = 0; i < num_path; i++) {
|
|
if (data[i * PATH_SIZE] == PATH_A)
|
|
printf("PATH A: %d %d %d %d %d %d %d %d %d %d %d %d\n",
|
|
data[i * PATH_SIZE + 1], data[i * PATH_SIZE + 2],
|
|
data[i * PATH_SIZE + 3], data[i * PATH_SIZE + 4],
|
|
data[i * PATH_SIZE + 5], data[i * PATH_SIZE + 6],
|
|
data[i * PATH_SIZE + 7], data[i * PATH_SIZE + 8],
|
|
data[i * PATH_SIZE + 9],
|
|
data[i * PATH_SIZE + 10],
|
|
data[i * PATH_SIZE + 11],
|
|
data[i * PATH_SIZE + 12]);
|
|
else if (data[i * PATH_SIZE] == PATH_B)
|
|
printf("PATH B: %d %d %d %d %d %d %d %d %d %d %d %d\n",
|
|
data[i * PATH_SIZE + 1], data[i * PATH_SIZE + 2],
|
|
data[i * PATH_SIZE + 3], data[i * PATH_SIZE + 4],
|
|
data[i * PATH_SIZE + 5], data[i * PATH_SIZE + 6],
|
|
data[i * PATH_SIZE + 7], data[i * PATH_SIZE + 8],
|
|
data[i * PATH_SIZE + 9],
|
|
data[i * PATH_SIZE + 10],
|
|
data[i * PATH_SIZE + 11],
|
|
data[i * PATH_SIZE + 12]);
|
|
else if (data[i * PATH_SIZE] == PATH_AB)
|
|
printf("PATH A+B: %d %d %d %d %d %d %d %d %d %d %d %d\n",
|
|
data[i * PATH_SIZE + 1], data[i * PATH_SIZE + 2],
|
|
data[i * PATH_SIZE + 3], data[i * PATH_SIZE + 4],
|
|
data[i * PATH_SIZE + 5], data[i * PATH_SIZE + 6],
|
|
data[i * PATH_SIZE + 7], data[i * PATH_SIZE + 8],
|
|
data[i * PATH_SIZE + 9],
|
|
data[i * PATH_SIZE + 10],
|
|
data[i * PATH_SIZE + 11],
|
|
data[i * PATH_SIZE + 12]);
|
|
}
|
|
printf("\n");
|
|
|
|
done:
|
|
if (buffer)
|
|
free(buffer);
|
|
if (cmd)
|
|
free(cmd);
|
|
|
|
return ret;
|
|
}
|
|
#endif /* #ifdef STA_SUPPORT */
|
|
|
|
/**
|
|
* @brief Get txpwrlimit
|
|
*
|
|
* @param argc Number of arguments
|
|
* @param argv Pointer to the arguments array
|
|
*
|
|
* @return MLAN_STATUS_SUCCESS/MLAN_STATUS_FAILURE
|
|
*/
|
|
static int get_txpwrlimit(FILE *fp_raw, char *argv[], t_u16 sub_band,
|
|
t_u8 *buffer, t_u16 len, struct eth_priv_cmd *cmd)
|
|
{
|
|
struct ifreq ifr;
|
|
mlan_ds_misc_chan_trpc_cfg *trcp_cfg = NULL;
|
|
MrvlIETypes_ChanTRPCConfig_t *trpc_tlv = NULL;
|
|
MrvlIEtypes_Data_t *pTlvHdr;
|
|
int left_len;
|
|
int mod_num = 0;
|
|
int i = 0;
|
|
int j = 0;
|
|
t_u8 *pByte = NULL;
|
|
|
|
memset(buffer, 0, len);
|
|
/* Insert command */
|
|
strncpy((char *)buffer, argv[2], strlen(argv[2]));
|
|
trcp_cfg = (mlan_ds_misc_chan_trpc_cfg *)(buffer + strlen(argv[2]));
|
|
trcp_cfg->sub_band = sub_band;
|
|
if (cmd) {
|
|
/* Fill up buffer */
|
|
#ifdef USERSPACE_32BIT_OVER_KERNEL_64BIT
|
|
memset(cmd, 0, sizeof(struct eth_priv_cmd));
|
|
memcpy(&cmd->buf, &buffer, sizeof(buffer));
|
|
#else
|
|
cmd->buf = buffer;
|
|
#endif
|
|
cmd->used_len = 0;
|
|
cmd->total_len = len;
|
|
}
|
|
/* Perform IOCTL */
|
|
memset(&ifr, 0, sizeof(struct ifreq));
|
|
strncpy(ifr.ifr_ifrn.ifrn_name, dev_name, strlen(dev_name));
|
|
ifr.ifr_ifru.ifru_data = (void *)cmd;
|
|
|
|
if (ioctl(sockfd, MLAN_ETH_PRIV, &ifr)) {
|
|
perror("mlanutl");
|
|
fprintf(stderr, "mlanutl: get_txpwrlimit fail\n");
|
|
return MLAN_STATUS_FAILURE;
|
|
}
|
|
/* Process result */
|
|
printf("------------------------------------------------------------------------------------\n");
|
|
printf("Get txpwrlimit: sub_band=0x%x len=%d\n", trcp_cfg->sub_band,
|
|
trcp_cfg->length);
|
|
pByte = trcp_cfg->trpc_buf + S_DS_GEN + 4;
|
|
left_len = trcp_cfg->length - S_DS_GEN - 4;
|
|
while (left_len >= sizeof(pTlvHdr->header)) {
|
|
pTlvHdr = (MrvlIEtypes_Data_t *)pByte;
|
|
pTlvHdr->header.len = le16_to_cpu(pTlvHdr->header.len);
|
|
|
|
switch (le16_to_cpu(pTlvHdr->header.type)) {
|
|
case TLV_TYPE_CHAN_TRPC_CONFIG:
|
|
trpc_tlv = (MrvlIETypes_ChanTRPCConfig_t *)pTlvHdr;
|
|
printf("StartFreq: %d\n", trpc_tlv->start_freq);
|
|
printf("ChanWidth: %d\n", trpc_tlv->width);
|
|
printf("ChanNum: %d\n", trpc_tlv->chan_num);
|
|
mod_num = (pTlvHdr->header.len - 4) /
|
|
sizeof(mod_group_setting);
|
|
printf("Pwr:");
|
|
for (i = 0; i < mod_num; i++) {
|
|
if (i == (mod_num - 1))
|
|
printf("%d,%d",
|
|
trpc_tlv->mod_group[i].mod_group,
|
|
trpc_tlv->mod_group[i].power);
|
|
else
|
|
printf("%d,%d,",
|
|
trpc_tlv->mod_group[i].mod_group,
|
|
trpc_tlv->mod_group[i].power);
|
|
}
|
|
printf("\n");
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
left_len -= (pTlvHdr->header.len + sizeof(pTlvHdr->header));
|
|
pByte += pTlvHdr->header.len + sizeof(pTlvHdr->header);
|
|
}
|
|
if (fp_raw) {
|
|
switch (sub_band) {
|
|
case 0:
|
|
fprintf(fp_raw, "txpwrlimit_2g_get={\n");
|
|
break;
|
|
case 0x10:
|
|
fprintf(fp_raw, "txpwrlimit_5g_sub0_get={\n");
|
|
break;
|
|
case 0x11:
|
|
fprintf(fp_raw, "txpwrlimit_5g_sub1_get={\n");
|
|
break;
|
|
case 0x12:
|
|
fprintf(fp_raw, "txpwrlimit_5g_sub2_get={\n");
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
i = j = 0;
|
|
while (i < trcp_cfg->length) {
|
|
for (j = 0; j < 16; j++) {
|
|
fprintf(fp_raw, "%02x ", trcp_cfg->trpc_buf[i]);
|
|
if (++i >= trcp_cfg->length)
|
|
break;
|
|
}
|
|
fputc('\n', fp_raw);
|
|
}
|
|
fprintf(fp_raw, "}\n\n");
|
|
}
|
|
return MLAN_STATUS_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
* @brief Get txpwrlimit
|
|
*
|
|
* @param argc Number of arguments
|
|
* @param argv Pointer to the arguments array
|
|
*
|
|
* @return MLAN_STATUS_SUCCESS/MLAN_STATUS_FAILURE
|
|
*/
|
|
static int process_get_txpwrlimit(int argc, char *argv[])
|
|
{
|
|
t_u8 *buffer = NULL;
|
|
struct eth_priv_cmd *cmd = NULL;
|
|
int ret = MLAN_STATUS_SUCCESS;
|
|
t_u16 sub_band = 0;
|
|
FILE *fp_raw = NULL;
|
|
|
|
/* Initialize buffer */
|
|
buffer = (t_u8 *)malloc(sizeof(mlan_ds_misc_chan_trpc_cfg) +
|
|
strlen(argv[2]));
|
|
if (!buffer) {
|
|
printf("ERR:Cannot allocate buffer for command!\n");
|
|
ret = MLAN_STATUS_FAILURE;
|
|
goto done;
|
|
}
|
|
memset(buffer, 0, sizeof(mlan_ds_misc_chan_trpc_cfg) + strlen(argv[2]));
|
|
/* Sanity tests */
|
|
if (argc < 4) {
|
|
printf("Error: invalid no of arguments\n");
|
|
printf("mlanutl mlanX/uapX get_txpwrlimit [0/0x10/0x11/0x12/0x1f/0xff]\n");
|
|
ret = MLAN_STATUS_FAILURE;
|
|
goto done;
|
|
}
|
|
cmd = (struct eth_priv_cmd *)malloc(sizeof(struct eth_priv_cmd));
|
|
if (!cmd) {
|
|
printf("ERR:Cannot allocate buffer for command!\n");
|
|
ret = MLAN_STATUS_FAILURE;
|
|
goto done;
|
|
}
|
|
sub_band = a2hex_or_atoi(argv[3]);
|
|
if (argc == 5) {
|
|
fp_raw = fopen(argv[4], "w");
|
|
if (fp_raw == NULL) {
|
|
fprintf(stderr,
|
|
"Cannot open the destination raw_data file %s\n",
|
|
argv[4]);
|
|
ret = MLAN_STATUS_FAILURE;
|
|
goto done;
|
|
}
|
|
}
|
|
switch (sub_band) {
|
|
case 0:
|
|
case 0x10:
|
|
case 0x11:
|
|
case 0x12:
|
|
ret = get_txpwrlimit(fp_raw, argv, sub_band, buffer,
|
|
sizeof(mlan_ds_misc_chan_trpc_cfg) +
|
|
strlen(argv[2]),
|
|
cmd);
|
|
break;
|
|
case 0x1f:
|
|
ret = get_txpwrlimit(fp_raw, argv, 0x10, buffer,
|
|
sizeof(mlan_ds_misc_chan_trpc_cfg) +
|
|
strlen(argv[2]),
|
|
cmd);
|
|
ret = get_txpwrlimit(fp_raw, argv, 0x11, buffer,
|
|
sizeof(mlan_ds_misc_chan_trpc_cfg) +
|
|
strlen(argv[2]),
|
|
cmd);
|
|
ret = get_txpwrlimit(fp_raw, argv, 0x12, buffer,
|
|
sizeof(mlan_ds_misc_chan_trpc_cfg) +
|
|
strlen(argv[2]),
|
|
cmd);
|
|
break;
|
|
case 0xff:
|
|
ret = get_txpwrlimit(fp_raw, argv, 0, buffer,
|
|
sizeof(mlan_ds_misc_chan_trpc_cfg) +
|
|
strlen(argv[2]),
|
|
cmd);
|
|
ret = get_txpwrlimit(fp_raw, argv, 0x10, buffer,
|
|
sizeof(mlan_ds_misc_chan_trpc_cfg) +
|
|
strlen(argv[2]),
|
|
cmd);
|
|
ret = get_txpwrlimit(fp_raw, argv, 0x11, buffer,
|
|
sizeof(mlan_ds_misc_chan_trpc_cfg) +
|
|
strlen(argv[2]),
|
|
cmd);
|
|
ret = get_txpwrlimit(fp_raw, argv, 0x12, buffer,
|
|
sizeof(mlan_ds_misc_chan_trpc_cfg) +
|
|
strlen(argv[2]),
|
|
cmd);
|
|
break;
|
|
default:
|
|
printf("Error: invalid arguments\n");
|
|
printf("mlanutl mlanX/uapX get_txpwrlimit [0/0x10/0x11/0x12/0x1f/0xff]\n");
|
|
break;
|
|
}
|
|
done:
|
|
if (fp_raw)
|
|
fclose(fp_raw);
|
|
if (buffer)
|
|
free(buffer);
|
|
if (cmd)
|
|
free(cmd);
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief Process VHT configuration
|
|
* @param argc Number of arguments
|
|
* @param argv A pointer to arguments array
|
|
* @return MLAN_STATUS_SUCCESS--success, otherwise--fail
|
|
*/
|
|
static int process_vhtcfg(int argc, char *argv[])
|
|
{
|
|
t_u8 *buffer = NULL;
|
|
struct eth_priv_cmd *cmd = NULL;
|
|
struct eth_priv_vhtcfg vhtcfg;
|
|
struct ifreq ifr;
|
|
t_u8 i, num = 0;
|
|
|
|
/* Initialize buffer */
|
|
buffer = (t_u8 *)malloc(BUFFER_LENGTH);
|
|
if (!buffer) {
|
|
printf("ERR:Cannot allocate buffer for command!\n");
|
|
return MLAN_STATUS_FAILURE;
|
|
}
|
|
|
|
/* Sanity tests */
|
|
if (argc < 5) {
|
|
printf("Insufficient parameters\n");
|
|
printf("For STA interface: mlanutl mlanX vhtcfg <band> <txrx> [bwcfg] [vhtcap]\n");
|
|
printf("For uAP interface: mlanutl uapX vhtcfg <band> <txrx> [bwcfg] [vhtcap] [vht_tx_mcs] [vht_rx_mcs]\n");
|
|
free(buffer);
|
|
return MLAN_STATUS_FAILURE;
|
|
}
|
|
|
|
prepare_buffer(buffer, argv[2], (argc - 3), &argv[3]);
|
|
|
|
cmd = (struct eth_priv_cmd *)malloc(sizeof(struct eth_priv_cmd));
|
|
if (!cmd) {
|
|
printf("ERR:Cannot allocate buffer for command!\n");
|
|
free(buffer);
|
|
return MLAN_STATUS_FAILURE;
|
|
}
|
|
|
|
/* Fill up buffer */
|
|
#ifdef USERSPACE_32BIT_OVER_KERNEL_64BIT
|
|
memset(cmd, 0, sizeof(struct eth_priv_cmd));
|
|
memcpy(&cmd->buf, &buffer, sizeof(buffer));
|
|
#else
|
|
cmd->buf = buffer;
|
|
#endif
|
|
cmd->used_len = 0;
|
|
cmd->total_len = BUFFER_LENGTH;
|
|
|
|
/* Perform IOCTL */
|
|
memset(&ifr, 0, sizeof(struct ifreq));
|
|
strncpy(ifr.ifr_ifrn.ifrn_name, dev_name, strlen(dev_name));
|
|
ifr.ifr_ifru.ifru_data = (void *)cmd;
|
|
|
|
if (ioctl(sockfd, MLAN_ETH_PRIV, &ifr)) {
|
|
perror("mlanutl");
|
|
fprintf(stderr, "mlanutl: vhtcfg fail\n");
|
|
if (cmd)
|
|
free(cmd);
|
|
if (buffer)
|
|
free(buffer);
|
|
return MLAN_STATUS_FAILURE;
|
|
}
|
|
|
|
/* Process result */
|
|
/* the first attribute is the number of vhtcfg entries */
|
|
num = *buffer;
|
|
if (argc == 5) {
|
|
/* GET operation */
|
|
printf("11AC VHT Configuration: \n");
|
|
for (i = 0; i < num; i++) {
|
|
memcpy(&vhtcfg, buffer + 1 + i * sizeof(vhtcfg),
|
|
sizeof(vhtcfg));
|
|
/* Band */
|
|
if (vhtcfg.band == 1)
|
|
printf("Band: 2.4G\n");
|
|
else
|
|
printf("Band: 5G\n");
|
|
/* BW confi9 */
|
|
|
|
if (vhtcfg.bwcfg == 0)
|
|
printf(" BW config: Follow BW in the 11N config\n");
|
|
else
|
|
printf(" BW config: Follow BW in VHT Capabilities\n");
|
|
|
|
/* Tx/Rx */
|
|
if (vhtcfg.txrx & 0x1)
|
|
printf(" VHT operation for Tx: 0x%08x\n",
|
|
vhtcfg.vht_cap_info);
|
|
if (vhtcfg.txrx & 0x2)
|
|
/* VHT capabilities */
|
|
printf(" VHT Capabilities Info: 0x%08x\n",
|
|
vhtcfg.vht_cap_info);
|
|
/* MCS */
|
|
if (vhtcfg.txrx & 0x2) {
|
|
printf(" Tx MCS set: 0x%04x\n",
|
|
vhtcfg.vht_tx_mcs);
|
|
printf(" Rx MCS set: 0x%04x\n",
|
|
vhtcfg.vht_rx_mcs);
|
|
}
|
|
}
|
|
} else {
|
|
/* SET operation */
|
|
}
|
|
|
|
if (buffer)
|
|
free(buffer);
|
|
if (cmd)
|
|
free(cmd);
|
|
|
|
return MLAN_STATUS_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
* @brief Process dynamic bandwidth set/get
|
|
* @param argc Number of arguments
|
|
* @param argv A pointer to arguments array
|
|
* @return MLAN_STATUS_SUCCESS--success, otherwise--fail
|
|
*/
|
|
static int process_dyn_bw(int argc, char *argv[])
|
|
{
|
|
t_u8 *buffer = NULL;
|
|
struct eth_priv_cmd *cmd = NULL;
|
|
struct ifreq ifr;
|
|
int dyn_bw = 0;
|
|
|
|
/* Check arguments */
|
|
if (argc < 3 || argc > 4) {
|
|
printf("ERR:Incorrect number of arguments!\n");
|
|
printf("Syntax: ./mlanutl mlanX dyn_bw <bw>\n");
|
|
return MLAN_STATUS_FAILURE;
|
|
}
|
|
|
|
/* Initialize buffer */
|
|
buffer = (t_u8 *)malloc(BUFFER_LENGTH);
|
|
if (!buffer) {
|
|
printf("ERR:Cannot allocate buffer for command!\n");
|
|
return MLAN_STATUS_FAILURE;
|
|
}
|
|
|
|
prepare_buffer(buffer, argv[2], (argc - 3), &argv[3]);
|
|
|
|
cmd = (struct eth_priv_cmd *)malloc(sizeof(struct eth_priv_cmd));
|
|
if (!cmd) {
|
|
printf("ERR:Cannot allocate buffer for command!\n");
|
|
free(buffer);
|
|
return MLAN_STATUS_FAILURE;
|
|
}
|
|
|
|
/* Fill up buffer */
|
|
#ifdef USERSPACE_32BIT_OVER_KERNEL_64BIT
|
|
memset(cmd, 0, sizeof(struct eth_priv_cmd));
|
|
memcpy(&cmd->buf, &buffer, sizeof(buffer));
|
|
#else
|
|
cmd->buf = buffer;
|
|
#endif
|
|
cmd->used_len = 0;
|
|
cmd->total_len = BUFFER_LENGTH;
|
|
|
|
/* Perform IOCTL */
|
|
memset(&ifr, 0, sizeof(struct ifreq));
|
|
strncpy(ifr.ifr_ifrn.ifrn_name, dev_name, strlen(dev_name));
|
|
ifr.ifr_ifru.ifru_data = (void *)cmd;
|
|
|
|
if (ioctl(sockfd, MLAN_ETH_PRIV, &ifr)) {
|
|
perror("mlanutl");
|
|
fprintf(stderr, "mlanutl: dyn_bw fail\n");
|
|
if (cmd)
|
|
free(cmd);
|
|
if (buffer)
|
|
free(buffer);
|
|
return MLAN_STATUS_FAILURE;
|
|
}
|
|
|
|
/* Process result */
|
|
dyn_bw = *(int *)buffer;
|
|
printf("Dynamic bandwidth: 0x%02x\n", dyn_bw);
|
|
|
|
if (buffer)
|
|
free(buffer);
|
|
if (cmd)
|
|
free(cmd);
|
|
|
|
return MLAN_STATUS_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
* @brief Process HT Tx configuration
|
|
* @param argc Number of arguments
|
|
* @param argv A pointer to arguments array
|
|
* @return MLAN_STATUS_SUCCESS--success, otherwise--fail
|
|
*/
|
|
static int process_httxcfg(int argc, char *argv[])
|
|
{
|
|
t_u8 *buffer = NULL;
|
|
t_u32 *data = NULL;
|
|
struct eth_priv_cmd *cmd = NULL;
|
|
struct ifreq ifr;
|
|
|
|
/* Initialize buffer */
|
|
buffer = (t_u8 *)malloc(BUFFER_LENGTH);
|
|
if (!buffer) {
|
|
printf("ERR:Cannot allocate buffer for command!\n");
|
|
return MLAN_STATUS_FAILURE;
|
|
}
|
|
|
|
prepare_buffer(buffer, argv[2], (argc - 3), &argv[3]);
|
|
|
|
cmd = (struct eth_priv_cmd *)malloc(sizeof(struct eth_priv_cmd));
|
|
if (!cmd) {
|
|
printf("ERR:Cannot allocate buffer for command!\n");
|
|
free(buffer);
|
|
return MLAN_STATUS_FAILURE;
|
|
}
|
|
|
|
/* Fill up buffer */
|
|
#ifdef USERSPACE_32BIT_OVER_KERNEL_64BIT
|
|
memset(cmd, 0, sizeof(struct eth_priv_cmd));
|
|
memcpy(&cmd->buf, &buffer, sizeof(buffer));
|
|
#else
|
|
cmd->buf = buffer;
|
|
#endif
|
|
cmd->used_len = 0;
|
|
cmd->total_len = BUFFER_LENGTH;
|
|
|
|
/* Perform IOCTL */
|
|
memset(&ifr, 0, sizeof(struct ifreq));
|
|
strncpy(ifr.ifr_ifrn.ifrn_name, dev_name, strlen(dev_name));
|
|
ifr.ifr_ifru.ifru_data = (void *)cmd;
|
|
|
|
if (ioctl(sockfd, MLAN_ETH_PRIV, &ifr)) {
|
|
perror("mlanutl");
|
|
fprintf(stderr, "mlanutl: httxcfg fail\n");
|
|
if (cmd)
|
|
free(cmd);
|
|
if (buffer)
|
|
free(buffer);
|
|
return MLAN_STATUS_FAILURE;
|
|
}
|
|
|
|
if (argc == 3) {
|
|
/* Get result */
|
|
data = (t_u32 *)buffer;
|
|
printf("HT Tx cfg: \n");
|
|
printf(" BG band: 0x%08x\n", data[0]);
|
|
printf(" A band: 0x%08x\n", data[1]);
|
|
}
|
|
|
|
if (buffer)
|
|
free(buffer);
|
|
if (cmd)
|
|
free(cmd);
|
|
|
|
return MLAN_STATUS_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
* @brief Process HT capability configuration
|
|
* @param argc Number of arguments
|
|
* @param argv A pointer to arguments array
|
|
* @return MLAN_STATUS_SUCCESS--success, otherwise--fail
|
|
*/
|
|
static int process_htcapinfo(int argc, char *argv[])
|
|
{
|
|
t_u8 *buffer = NULL;
|
|
struct eth_priv_cmd *cmd = NULL;
|
|
struct eth_priv_htcapinfo *ht_cap = NULL;
|
|
struct ifreq ifr;
|
|
|
|
/* Initialize buffer */
|
|
buffer = (t_u8 *)malloc(BUFFER_LENGTH);
|
|
if (!buffer) {
|
|
printf("ERR:Cannot allocate buffer for command!\n");
|
|
return MLAN_STATUS_FAILURE;
|
|
}
|
|
|
|
prepare_buffer(buffer, argv[2], (argc - 3), &argv[3]);
|
|
|
|
cmd = (struct eth_priv_cmd *)malloc(sizeof(struct eth_priv_cmd));
|
|
if (!cmd) {
|
|
printf("ERR:Cannot allocate buffer for command!\n");
|
|
free(buffer);
|
|
return MLAN_STATUS_FAILURE;
|
|
}
|
|
|
|
/* Fill up buffer */
|
|
#ifdef USERSPACE_32BIT_OVER_KERNEL_64BIT
|
|
memset(cmd, 0, sizeof(struct eth_priv_cmd));
|
|
memcpy(&cmd->buf, &buffer, sizeof(buffer));
|
|
#else
|
|
cmd->buf = buffer;
|
|
#endif
|
|
cmd->used_len = 0;
|
|
cmd->total_len = BUFFER_LENGTH;
|
|
|
|
/* Perform IOCTL */
|
|
memset(&ifr, 0, sizeof(struct ifreq));
|
|
strncpy(ifr.ifr_ifrn.ifrn_name, dev_name, strlen(dev_name));
|
|
ifr.ifr_ifru.ifru_data = (void *)cmd;
|
|
|
|
if (ioctl(sockfd, MLAN_ETH_PRIV, &ifr)) {
|
|
perror("mlanutl");
|
|
fprintf(stderr, "mlanutl: htcapinfo fail\n");
|
|
if (cmd)
|
|
free(cmd);
|
|
if (buffer)
|
|
free(buffer);
|
|
return MLAN_STATUS_FAILURE;
|
|
}
|
|
|
|
/* Process result */
|
|
if (argc == 3) {
|
|
ht_cap = (struct eth_priv_htcapinfo *)buffer;
|
|
printf("HT cap info: \n");
|
|
printf(" BG band: 0x%08x\n", ht_cap->ht_cap_info_bg);
|
|
printf(" A band: 0x%08x\n", ht_cap->ht_cap_info_a);
|
|
}
|
|
|
|
if (buffer)
|
|
free(buffer);
|
|
if (cmd)
|
|
free(cmd);
|
|
|
|
return MLAN_STATUS_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
* @brief Process HT Add BA parameters
|
|
* @param argc Number of arguments
|
|
* @param argv A pointer to arguments array
|
|
* @return MLAN_STATUS_SUCCESS--success, otherwise--fail
|
|
*/
|
|
static int process_addbapara(int argc, char *argv[])
|
|
{
|
|
t_u8 *buffer = NULL;
|
|
struct eth_priv_cmd *cmd = NULL;
|
|
struct ifreq ifr;
|
|
struct eth_priv_addba *addba = NULL;
|
|
|
|
/* Initialize buffer */
|
|
buffer = (t_u8 *)malloc(BUFFER_LENGTH);
|
|
if (!buffer) {
|
|
printf("ERR:Cannot allocate buffer for command!\n");
|
|
return MLAN_STATUS_FAILURE;
|
|
}
|
|
|
|
prepare_buffer(buffer, argv[2], (argc - 3), &argv[3]);
|
|
|
|
cmd = (struct eth_priv_cmd *)malloc(sizeof(struct eth_priv_cmd));
|
|
if (!cmd) {
|
|
printf("ERR:Cannot allocate buffer for command!\n");
|
|
free(buffer);
|
|
return MLAN_STATUS_FAILURE;
|
|
}
|
|
|
|
/* Fill up buffer */
|
|
#ifdef USERSPACE_32BIT_OVER_KERNEL_64BIT
|
|
memset(cmd, 0, sizeof(struct eth_priv_cmd));
|
|
memcpy(&cmd->buf, &buffer, sizeof(buffer));
|
|
#else
|
|
cmd->buf = buffer;
|
|
#endif
|
|
cmd->used_len = 0;
|
|
cmd->total_len = BUFFER_LENGTH;
|
|
|
|
/* Perform IOCTL */
|
|
memset(&ifr, 0, sizeof(struct ifreq));
|
|
strncpy(ifr.ifr_ifrn.ifrn_name, dev_name, strlen(dev_name));
|
|
ifr.ifr_ifru.ifru_data = (void *)cmd;
|
|
|
|
if (ioctl(sockfd, MLAN_ETH_PRIV, &ifr)) {
|
|
perror("mlanutl");
|
|
fprintf(stderr, "mlanutl: addbapara fail\n");
|
|
if (cmd)
|
|
free(cmd);
|
|
if (buffer)
|
|
free(buffer);
|
|
return MLAN_STATUS_FAILURE;
|
|
}
|
|
|
|
if (argc == 3) {
|
|
/* Get */
|
|
addba = (struct eth_priv_addba *)buffer;
|
|
printf("Add BA configuration: \n");
|
|
printf(" Time out : %d\n", addba->time_out);
|
|
printf(" TX window: %d\n", addba->tx_win_size);
|
|
printf(" RX window: %d\n", addba->rx_win_size);
|
|
printf(" TX AMSDU : %d\n", addba->tx_amsdu);
|
|
printf(" RX AMSDU : %d\n", addba->rx_amsdu);
|
|
}
|
|
|
|
if (buffer)
|
|
free(buffer);
|
|
if (cmd)
|
|
free(cmd);
|
|
|
|
return MLAN_STATUS_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
* @brief Process Aggregation priority table parameters
|
|
* @param argc Number of arguments
|
|
* @param argv A pointer to arguments array
|
|
* @return MLAN_STATUS_SUCCESS--success, otherwise--fail
|
|
*/
|
|
static int process_aggrpriotbl(int argc, char *argv[])
|
|
{
|
|
t_u8 *buffer = NULL;
|
|
struct eth_priv_cmd *cmd = NULL;
|
|
struct ifreq ifr;
|
|
int i;
|
|
|
|
/* Initialize buffer */
|
|
buffer = (t_u8 *)malloc(BUFFER_LENGTH);
|
|
if (!buffer) {
|
|
printf("ERR:Cannot allocate buffer for command!\n");
|
|
return MLAN_STATUS_FAILURE;
|
|
}
|
|
|
|
prepare_buffer(buffer, argv[2], (argc - 3), &argv[3]);
|
|
|
|
cmd = (struct eth_priv_cmd *)malloc(sizeof(struct eth_priv_cmd));
|
|
if (!cmd) {
|
|
printf("ERR:Cannot allocate buffer for command!\n");
|
|
free(buffer);
|
|
return MLAN_STATUS_FAILURE;
|
|
}
|
|
|
|
/* Fill up buffer */
|
|
#ifdef USERSPACE_32BIT_OVER_KERNEL_64BIT
|
|
memset(cmd, 0, sizeof(struct eth_priv_cmd));
|
|
memcpy(&cmd->buf, &buffer, sizeof(buffer));
|
|
#else
|
|
cmd->buf = buffer;
|
|
#endif
|
|
cmd->used_len = 0;
|
|
cmd->total_len = BUFFER_LENGTH;
|
|
|
|
/* Perform IOCTL */
|
|
memset(&ifr, 0, sizeof(struct ifreq));
|
|
strncpy(ifr.ifr_ifrn.ifrn_name, dev_name, strlen(dev_name));
|
|
ifr.ifr_ifru.ifru_data = (void *)cmd;
|
|
|
|
if (ioctl(sockfd, MLAN_ETH_PRIV, &ifr)) {
|
|
perror("mlanutl");
|
|
fprintf(stderr, "mlanutl: aggrpriotbl fail\n");
|
|
if (cmd)
|
|
free(cmd);
|
|
if (buffer)
|
|
free(buffer);
|
|
return MLAN_STATUS_FAILURE;
|
|
}
|
|
|
|
if (argc == 3) {
|
|
/* Get */
|
|
printf("Aggregation priority table cfg: \n");
|
|
printf(" TID AMPDU AMSDU \n");
|
|
for (i = 0; i < MAX_NUM_TID; i++) {
|
|
printf(" %d %3d %3d \n", i,
|
|
buffer[2 * i], buffer[2 * i + 1]);
|
|
}
|
|
}
|
|
|
|
if (buffer)
|
|
free(buffer);
|
|
if (cmd)
|
|
free(cmd);
|
|
|
|
return MLAN_STATUS_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
* @brief Process HT Add BA reject configurations
|
|
* @param argc Number of arguments
|
|
* @param argv A pointer to arguments array
|
|
* @return MLAN_STATUS_SUCCESS--success, otherwise--fail
|
|
*/
|
|
static int process_addbareject(int argc, char *argv[])
|
|
{
|
|
t_u8 *buffer = NULL;
|
|
struct eth_priv_cmd *cmd = NULL;
|
|
struct ifreq ifr;
|
|
int i;
|
|
|
|
/* Initialize buffer */
|
|
buffer = (t_u8 *)malloc(BUFFER_LENGTH);
|
|
if (!buffer) {
|
|
printf("ERR:Cannot allocate buffer for command!\n");
|
|
return MLAN_STATUS_FAILURE;
|
|
}
|
|
|
|
prepare_buffer(buffer, argv[2], (argc - 3), &argv[3]);
|
|
|
|
cmd = (struct eth_priv_cmd *)malloc(sizeof(struct eth_priv_cmd));
|
|
if (!cmd) {
|
|
printf("ERR:Cannot allocate buffer for command!\n");
|
|
free(buffer);
|
|
return MLAN_STATUS_FAILURE;
|
|
}
|
|
|
|
/* Fill up buffer */
|
|
#ifdef USERSPACE_32BIT_OVER_KERNEL_64BIT
|
|
memset(cmd, 0, sizeof(struct eth_priv_cmd));
|
|
memcpy(&cmd->buf, &buffer, sizeof(buffer));
|
|
#else
|
|
cmd->buf = buffer;
|
|
#endif
|
|
cmd->used_len = 0;
|
|
cmd->total_len = BUFFER_LENGTH;
|
|
|
|
/* Perform IOCTL */
|
|
memset(&ifr, 0, sizeof(struct ifreq));
|
|
strncpy(ifr.ifr_ifrn.ifrn_name, dev_name, strlen(dev_name));
|
|
ifr.ifr_ifru.ifru_data = (void *)cmd;
|
|
|
|
if (ioctl(sockfd, MLAN_ETH_PRIV, &ifr)) {
|
|
perror("mlanutl");
|
|
fprintf(stderr, "mlanutl: addbareject fail\n");
|
|
if (cmd)
|
|
free(cmd);
|
|
if (buffer)
|
|
free(buffer);
|
|
return MLAN_STATUS_FAILURE;
|
|
}
|
|
|
|
if (argc == 3) {
|
|
/* Get */
|
|
printf("Add BA reject configuration: \n");
|
|
printf(" TID Reject \n");
|
|
for (i = 0; i < MAX_NUM_TID; i++) {
|
|
printf(" %d %d\n", i, buffer[i]);
|
|
}
|
|
}
|
|
|
|
if (buffer)
|
|
free(buffer);
|
|
if (cmd)
|
|
free(cmd);
|
|
|
|
return MLAN_STATUS_SUCCESS;
|
|
}
|
|
|
|
/********************************************************
|
|
Global Functions
|
|
********************************************************/
|
|
|
|
/**
|
|
* @brief Entry function for mlanutl
|
|
* @param argc Number of arguments
|
|
* @param argv A pointer to arguments array
|
|
* @return MLAN_STATUS_SUCCESS--success, otherwise--fail
|
|
*/
|
|
int main(int argc, char *argv[])
|
|
{
|
|
int ret = MLAN_STATUS_SUCCESS;
|
|
|
|
if ((argc == 2) && (strcmp(argv[1], "-v") == 0)) {
|
|
fprintf(stdout, "NXP mlanutl version %s\n", MLANUTL_VER);
|
|
exit(0);
|
|
}
|
|
if (argc < 3) {
|
|
fprintf(stderr, "Invalid number of parameters!\n");
|
|
display_usage();
|
|
exit(1);
|
|
}
|
|
|
|
strncpy(dev_name, argv[1], IFNAMSIZ - 1);
|
|
|
|
/*
|
|
* Create a socket
|
|
*/
|
|
sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
|
if (sockfd < 0) {
|
|
fprintf(stderr, "mlanutl: Cannot open socket.\n");
|
|
exit(1);
|
|
}
|
|
|
|
ret = process_command(argc, argv);
|
|
|
|
if (ret == MLAN_STATUS_NOTFOUND) {
|
|
if (ret) {
|
|
fprintf(stderr, "Invalid command specified!\n");
|
|
display_usage();
|
|
ret = 1;
|
|
}
|
|
}
|
|
|
|
close(sockfd);
|
|
return ret;
|
|
}
|