Add wl source code

This commit is contained in:
leeboby
2020-11-18 10:07:26 +08:00
parent 2dbd89c6ae
commit 3ce7777768
147 changed files with 103999 additions and 0 deletions

28
external/cache/sources/wl/wl/Android.mk vendored Normal file
View File

@@ -0,0 +1,28 @@
LOCAL_PATH:= $(call my-dir)
OBJS_c := wlu.c \
wlu_common.c \
wlu_linux.c \
wlu_cmd.c \
wlu_iov.c \
wlu_pipe.c \
wlu_pipe_linux.c \
wlu_client_shared.c \
wlc_ppr.c \
wlu_rates_matrix.c
INCLUDES := $(LOCAL_PATH)/../include
INCLUDES += $(LOCAL_PATH)/../shared
L_CFLAGS := -DBCMWPA2 -DWLCNT -DWLBTAMP -Wextra -DWLPFN -DWLPFN_AUTO_CONNECT -DLINUX -DRWLASD -DRWL_SOCKET -DRWL_DONGLE -DRWL_WIFI
L_CFLAGS += -DSDTEST -DTARGETENV_android -Dlinux -DLINUX -DD11AC_IOTYPES
include $(CLEAR_VARS)
LOCAL_MODULE := wl
LOCAL_MODULE_TAGS := debug tests
LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
LOCAL_SHARED_LIBRARIES := libcutils
LOCAL_STATIC_LIBRARIES := libshared
LOCAL_CFLAGS = $(L_CFLAGS)
LOCAL_SRC_FILES := $(OBJS_c)
LOCAL_C_INCLUDES := $(INCLUDES)
include $(BUILD_EXECUTABLE)

52
external/cache/sources/wl/wl/Makefile vendored Normal file
View File

@@ -0,0 +1,52 @@
CC = $(CROSS_COMPILE)gcc
#IFLAGS := -I../include -I../shared -g -Wall -static
IFLAGS := -I../include -I../shared -g -Wall
DFLAGS := -DBCMWPA2 -DWLCNT -DWLBTAMP -Wextra -DWLPFN -DWLPFN_AUTO_CONNECT -DLINUX -DRWLASD -DRWL_SOCKET -DRWL_DONGLE -DRWL_WIFI
#IFLAGS += -DIL_BIGENDIAN
IFLAGS += -DSDTEST -DTARGETENV_android -Dlinux -DLINUX -DD11AC_IOTYPES
#IFLAGS += -DSDTEST -Dlinux -DLINUX -DD11AC_IOTYPES
obj-wl = wlu.o \
wlu_common.o \
wlu_linux.o \
wlu_cmd.o \
wlu_iov.o \
wlu_pipe.o \
wlu_pipe_linux.o \
wlu_client_shared.o \
wlc_ppr.o \
wlu_rates_matrix.o
WL = wl
ALL = all
LIBLINK := ../shared/libshared.a
LIBWL = libwl.a
CFLAGS += $(IFLAGS) $(DFLAGS)
ifeq ($(LIB),y)
CFLAGS += -DLIB
endif
all: $(ALL)
$(ALL):
make clean
make $(WL)
mv wl wl.back
make clean
make $(LIBWL) LIB=y
mv wl.back wl
$(WL): $(obj-wl)
$(CC) -o $@ $(obj-wl) $(LIBLINK)
$(LIBWL): $(obj-wl)
ar rscv $(LIBWL) $(obj-wl) $(LIBLINK)
# $(CC) $(obj-wl) -shared -o $(LIBWL) $(LIBLINK)
# for sequance
# $(CC) -Wl,-elf2flt -o $@ $(obj-wl)
clean:
-rm -f $(WL) *.o *.so *.a

View File

@@ -0,0 +1,708 @@
/*
* Remote shell command execution (common for all transports) for linux
*
* Copyright (C) 2013, Broadcom Corporation
* All Rights Reserved.
*
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation;
* the contents of this file may not be disclosed to third parties, copied
* or duplicated in any form, in whole or in part, without the prior
* written permission of Broadcom Corporation.
*
* $Id: shellproc_linux.c 281542 2011-09-02 17:31:19Z $
*/
/* Linux remote shell command execution
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/wait.h>
#include <signal.h>
#include <fcntl.h>
#include <typedefs.h>
#include <bcmutils.h>
#include <bcmcdc.h>
#include "wlu_remote.h"
#include <sys/poll.h>
#include <malloc.h>
#include <miniopt.h>
#include <sys/utsname.h>
#define ASYNC_RESP 0
#define MAX_SHELL_ASYNC_RESP 128 /* Support for maximum 5 async process */
#define MAX_ASYNC_FILE_LENGTH 50
#define MAX_PID_CMD_LENGTH 20
#define MAX_PID_RESP_LENTH 50
#define MAX_SHELL_CMD_LENTH 256
#define PID_TOKEN_SIZE 50
#define PID_SEARCH_CMD_SIZE 100
#define ASYNC_SHELL_CHAR "%" /* Async process identifier from the client */
#define FILE_PERMISSION 777
#define DEFAULT_SHELL_TIMEOUT 0 /* Default TimeOut Value for synchronous shell commands */
#define SHELL_RETURNVALUE_SIZE 2 /* Size of Return Value of the shell command */
#define SHELL_ASYNCCMD_ID 1 /* To identify if it is an async command */
#define REBOOT_MSG "Rebooting AP ...\n"
/* Function prototypes */
static int rwl_get_file_size(char *file_name);
static int remote_shell_async_exec(char *buf_ptr);
static int remote_shell_sync_exec(char *cmd_buf_ptr, void *wl);
/* Data structure to hold async shell information */
typedef struct remote_shell_async {
pid_t PID;
char file_name[MAX_ASYNC_FILE_LENGTH];
} remote_shell_async_t;
remote_shell_async_t g_async_resp[MAX_SHELL_ASYNC_RESP];
extern int g_shellsync_pid;
extern unsigned char g_return_stat;
extern void rwl_chld_handler(int num);
extern int set_ctrlc;
extern void handle_ctrlc(int unused);
/* Global variable to store the timeout value for the shell commands */
static int g_shellsync_timeout = DEFAULT_SHELL_TIMEOUT;
char globalbuffer[MAX_SHELL_CMD_LENTH];
/* Wait for process termination.
* This function returns immediately if the child has
* already exited (zombie process)
*/
static void
sigchld_handler(int s)
{
UNUSED_PARAMETER(s);
while (waitpid(-1, NULL, WNOHANG) > 0);
}
/* Create a main directory \tmp\RWL\ for the shell response files */
int
rwl_create_dir(void)
{
if (mkdir(SHELL_RESP_PATH, FILE_PERMISSION) < 0) {
if (errno != EEXIST)
return BCME_ERROR;
}
return SUCCESS;
}
/* Main function for shell command execution */
int
remote_shell_execute(char* buf_ptr, void *wl)
{
char *async_cmd_flag;
int msg_len;
/* Check for the "%" token in the buffer from client
* If "%" token is present, execute asynchronous process
* else, execute synchronous shell process
*/
async_cmd_flag = strstr((char*)buf_ptr, ASYNC_SHELL_CHAR);
if ((async_cmd_flag != NULL) && (!strcmp(async_cmd_flag, ASYNC_SHELL_CHAR))) {
g_shellsync_pid = SHELL_ASYNCCMD_ID;
msg_len = remote_shell_async_exec(buf_ptr);
}
else {
msg_len = remote_shell_sync_exec(buf_ptr, wl);
strcpy(buf_ptr, globalbuffer);
}
return msg_len;
}
/* Function to get the shell response from the file */
int
remote_shell_async_get_resp(char* shell_fname, char* buf_ptr, int msg_len)
{
int sts = 0;
FILE *shell_fpt;
shell_fpt = fopen(shell_fname, "rb");
if (shell_fpt == NULL) {
DPRINT_ERR(ERR, "\nShell Cmd:File open error\n");
return sts;
}
/* If there is any response from the shell, Read the file and
* update the buffer for the shell response
* else Just send the return value of the command executed
*/
if (g_shellsync_pid != SHELL_ASYNCCMD_ID) {
if (msg_len)
sts = fread(buf_ptr, sizeof(char), msg_len, shell_fpt);
fscanf(shell_fpt, "%2x", &sts);
}
else
sts = fread(buf_ptr, sizeof(char), MAX_SHELL_CMD_LENTH, shell_fpt);
fclose(shell_fpt);
remove(shell_fname);
DPRINT_DBG(OUTPUT, "\n Resp buff from shell cmdis %s\n", buf_ptr);
return sts;
}
/*
* Function to get the shell response length
* by opening the file containing the shell response
* and get the total file size.
* For a given input file name it returns File size.
*/
static int
rwl_get_file_size(char *file_name)
{
FILE *shell_fpt;
int filesize = 0;
shell_fpt = fopen(file_name, "rb");
if (shell_fpt == NULL) {
DPRINT_DBG(OUTPUT, "\nShell Cmd:File open error\n");
return filesize;
}
/* obtain file size */
if (fseek(shell_fpt, 0, SEEK_END) < 0)
return filesize;
filesize = ftell(shell_fpt);
fclose(shell_fpt);
return filesize;
}
/*
* Function for executing asynchronous shell comamnd
* Stores the results in async temp file and returns the PID
*/
static int
remote_shell_async_exec(char *buf_ptr)
{
int PID_val, val, msg_len, sts;
FILE *fpt;
int async_count = 0; /* counter needs to be initialized */
struct sigaction sa;
char pid_search_cmd[MAX_PID_CMD_LENGTH];
char pid_resp_buf[MAX_PID_RESP_LENTH];
char temp_async_file_name[MAX_ASYNC_FILE_LENGTH];
pid_t pid;
char *pid_token, next_pid[PID_TOKEN_SIZE][PID_TOKEN_SIZE];
struct utsname name;
/* Call the signal handler for reaping defunct or zombie process */
sa.sa_handler = sigchld_handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART;
if (sigaction(SIGCHLD, &sa, NULL) == -1) {
perror("sigaction:");
}
/* Store the async file name if that async process is not killed.
* Async file name: async_temp_0...5
*/
for (val = 0; val < MAX_SHELL_ASYNC_RESP; val++) {
if (g_async_resp[val].PID > 0) {
async_count++;
} else {
sprintf(g_async_resp[val].file_name, "%s%d", "async_temp_", val);
break;
}
}
sprintf(temp_async_file_name, "%s%s", SHELL_RESP_PATH,
g_async_resp[val].file_name);
DPRINT_DBG(OUTPUT, "\nasync_count:%d\n", async_count);
if (async_count >= MAX_SHELL_ASYNC_RESP) {
sprintf(buf_ptr, "\n%s\n", "Exceeded max async process forking");
return BCME_ERROR;
}
/* Open a child process. The fork will return the PID of the child process
* (i.e) defunct process PID in parent's thread of execution. Zero is returned
* for child's thread of execution.
*/
if ((pid = fork()) == 0) {
/* Redirect the async process output to the async file
* Then after the client executes the kill command for that
* async process, the file will give the status of async process
*/
strtok(buf_ptr, ASYNC_SHELL_CHAR); /* Remove % character from the command buf */
uname(&name);
/*
* Checking for mips architecture
* different command for mips and x86
*/
if (strncmp(name.machine, "mips", sizeof(name.machine)) != 0) {
strcat(buf_ptr, "&> "); /* buf_ptr is now "ping 127.0.0.1&> " */
strcat(buf_ptr, temp_async_file_name); /* Add path \tmp\RWL\async_temp_* */
}
else {
strcat(buf_ptr, " > "); /* buf_ptr is now "ping 127.0.0.1> " */
strcat(buf_ptr, temp_async_file_name); /* Add path \tmp\RWL\async_temp_* */
strcat(buf_ptr, " 2>&1 &");
}
if ((sts = execl(SH_PATH, "sh", "-c", buf_ptr, NULL)) == -1) {
sprintf(buf_ptr, "%s\n", "Not able to execute shell cmd");
return BCME_ERROR;
}
exit(0);
} /* end of fork */
if (pid < 0) {
perror("\nFork error:");
sprintf(buf_ptr, "%s\n", "Forking async process failed");
return BCME_ERROR;
}
/* Find the PID of the running process (for ex: ping)
* pidof -s options returns latest PID of the command.
*/
strtok(buf_ptr, " ");
uname(&name);
/* Checking for mips architecture */
if (strncmp(name.machine, "mips", sizeof(name.machine)) != 0)
sprintf(pid_search_cmd, "pidof -s %s", buf_ptr);
else
sprintf(pid_search_cmd, "pidof %s", buf_ptr);
sleep(1);
/* Execute the command e.g "pidof ping" */
if ((fpt = popen(pid_search_cmd, "r")) == NULL) {
sprintf(buf_ptr, "%s\n", "Can't return PID");
return BCME_ERROR;
}
/* Get the PID and copy the PID in buf_ptr to send to the client */
fgets(pid_resp_buf, sizeof(pid_resp_buf), fpt);
/* Checking for mips architecture */
if (strncmp(name.machine, "mips", sizeof(name.machine)) != 0) {
PID_val = atoi(pid_resp_buf);
}
else {
/* code to extract the correct PID */
pid_token = strtok_r(pid_resp_buf, " ", (char **)next_pid);
if (pid_token != NULL) {
while (pid_token != NULL) {
/* the pid buffer will terminate with a '\n'
* It will affect the string tokenizing logic
* To avoid this we're using the if case
*/
if (strncmp(pid_token, "\n", sizeof(pid_token)) == 0)
break;
PID_val = atoi(pid_token);
pid_token = strtok_r(NULL, " ", (char **)next_pid);
}
}
else
PID_val = atoi(pid_token);
}
if (PID_val == 0) {
msg_len = rwl_get_file_size(temp_async_file_name);
remote_shell_async_get_resp(temp_async_file_name, buf_ptr, msg_len);
} else {
g_async_resp[val].PID = PID_val;
/* Update PID value in buffer to send it to client */
sprintf(buf_ptr, "%d", PID_val);
msg_len = strlen(buf_ptr);
}
pclose(fpt);
/* In async case, the PID value will be copied to the input buffer only
* and there is no need of getting the response from the file. So return
* value can be -1.
*/
return msg_len;
}
/* Process for 'kill' command.
* Kill command can also be used from the client to get the
* result of asynchronous command and actually kill the mentioned process
*/
static int
remote_kill_cmd_exec(char *cmd_buf_ptr)
{
char file_name[MAX_ASYNC_FILE_LENGTH];
int PID_val, val, msg_len;
FILE *fpt;
char *pid_token, next_pid[PID_TOKEN_SIZE][PID_TOKEN_SIZE];
system(cmd_buf_ptr);
/* Parse the PID val from the kill command.
*/
pid_token = strtok_r(cmd_buf_ptr, " ", (char **)next_pid);
while (pid_token != NULL) {
/* to extract the PID from the kill command */
if (strncmp(pid_token, "\n", sizeof(pid_token)) == 0)
break;
PID_val = atoi(pid_token);
pid_token = strtok_r(NULL, " ", (char **)next_pid);
}
/* Check for the matching PID from the async structure and
* give the last 256 bytes statistics of the async process
* that was running
*/
for (val = 0; val < MAX_SHELL_ASYNC_RESP; ++val) {
if (g_async_resp[val].PID == PID_val) {
/* We found a match here. Hence get the response now from the
* corresponding async response file
*/
sprintf(file_name, "%s%s", SHELL_RESP_PATH, g_async_resp[val].file_name);
msg_len = rwl_get_file_size(file_name);
if (msg_len > 0) {
if ((fpt = fopen(file_name, "rb")) == NULL) {
DPRINT_DBG(OUTPUT, "\nShell Cmd:File open error\n");
return BCME_ERROR;
}
if (fseek(fpt, 0, SEEK_SET) < 0) {
fclose(fpt);
return BCME_ERROR;
}
if (fread(cmd_buf_ptr, sizeof(char), MAX_SHELL_CMD_LENTH,
fpt) <= 0) {
sprintf(cmd_buf_ptr, "%s\n", "Shell Resp:Reading error");
fclose(fpt);
return BCME_ERROR;
}
fclose(fpt);
}
else
sprintf(cmd_buf_ptr, "ed %d: No Response\n", PID_val);
remove(g_async_resp[val].file_name);
g_async_resp[val].PID = 0;
break;
}
}
return MAX_SHELL_CMD_LENTH;
}
/* Handle --timeout command line option for linux servers */
int
shell_timeout_cmd(char *cmd_buf_ptr, char *sync_file_name)
{
char *token1, *token2, *nexttoken;
FILE* fp;
int msg_len;
token1 = strtok_r(cmd_buf_ptr, "--timeout ", &nexttoken);
if (token1)
token2 = strtok_r(NULL, token1, &nexttoken);
if (token1 == NULL || atoi(token1) <= 0 || token2 == NULL) {
fp = fopen(sync_file_name, "w+");
fprintf(fp, "Usage: ./wl --<transport> <ip/mac> sh"
"--timeout <timeout value> <shell command>\n");
fprintf(fp, "Eg: ./wl --socket 172.22.65.226 sh --timeout 15 ls\n");
fflush(fp);
msg_len = rwl_get_file_size(sync_file_name);
strcpy(cmd_buf_ptr, sync_file_name);
fclose(fp);
strcpy(globalbuffer, sync_file_name);
printf("Fix timeout problem in socket!!!!!\n");
return msg_len;
}
else
g_shellsync_timeout = atoi(token1);
return BCME_OK;
}
/* Handle synchronous shell commands here */
static int
remote_shell_sync_exec(char *cmd_buf_ptr, void *wl)
{
char *kill_cmd_token;
char sync_file_name[] = TEMPLATE;
int fd, msg_len;
char cmd[(strlen(cmd_buf_ptr) + 1)];
int pid, status, pid_final;
char buf[SHELL_RESP_SIZE], cmd_find_lastpid[PID_SEARCH_CMD_SIZE];
int nbytes = 0;
int child_status;
static int sent_once = 0;
struct utsname name;
FILE *fpt;
/* Default Size of Return Value of the shell command is 2bytes */
kill_cmd_token = strstr(cmd_buf_ptr, "kill");
/* Synchronous Kill command processing is handled separately */
if (kill_cmd_token != NULL) {
msg_len = remote_kill_cmd_exec(cmd_buf_ptr);
remote_tx_response(wl, cmd_buf_ptr, msg_len);
return 0;
}
/* Process synchronous command other than kill command */
if ((fd = mkstemp(sync_file_name)) < 0) {
perror("mkstemp failed");
DPRINT_ERR(ERR, "\n errno:%d\n", errno);
sprintf(cmd_buf_ptr, "%s\n", "mkstemp failed");
return BCME_ERROR;
}
close(fd);
strcpy(cmd, cmd_buf_ptr);
/* Synchronous timeout command processing is handled separately */
if (strstr(cmd_buf_ptr, "--timeout") != NULL) {
if ((msg_len = shell_timeout_cmd (cmd, sync_file_name) > 0)) {
/* Signal end of command output */
g_rem_ptr->msg.len = 0;
g_rem_ptr->msg.cmd = g_return_stat;
remote_tx_response(wl, NULL, 0);
return msg_len;
} else {
/* Parse out --timeout <val> since command is successful
* point buffer to the shell command
*/
strcpy(cmd, cmd_buf_ptr);
strtok_r(cmd, " ", &cmd_buf_ptr);
strcpy(cmd, cmd_buf_ptr);
strtok_r(cmd, " ", &cmd_buf_ptr);
}
}
/* Schedule an ALARM in case of timeout value of SHELL_TIMEOUT seconds */
/* Defalut time out only in case of Non socket transport */
alarm(g_shellsync_timeout);
/* registering the relevant signals to handle end of child process,
* the ctrl+c event on the server side and the kill command on the
* server process
*/
signal(SIGCHLD, rwl_chld_handler);
signal(SIGINT, handle_ctrlc);
signal(SIGTERM, handle_ctrlc);
/* Set g_sig_chld before forking */
g_sig_chld = 1;
if (strcmp("reboot", cmd_buf_ptr) == 0) { /* reboot command */
memset(buf, 0, sizeof(buf));
strncpy(buf, REBOOT_MSG, sizeof(REBOOT_MSG));
remote_tx_response(wl, buf, 0);
/* Signal end of command output */
g_rem_ptr->msg.len = 0;
g_rem_ptr->msg.cmd = 0;
remote_tx_response(wl, NULL, 0);
sleep(1);
/* Clean up the temp file */
remove(sync_file_name);
}
if ((pid = fork()) == 0) {
close(STDOUT_FILENO);
fd = open(sync_file_name, O_WRONLY|O_SYNC);
/* Redirect stdin to dev/null. This handles un usual commands like
* sh cat from the client side
*/
close(STDIN_FILENO);
open("/dev/null", O_RDONLY);
close(STDERR_FILENO);
fcntl(fd, F_DUPFD, STDERR_FILENO);
if ((status = execl(SH_PATH, "sh", "-c", cmd_buf_ptr, NULL)) == -1) {
perror("Exec error");
}
} /* end of fork */
g_shellsync_pid = pid;
/* The g_return_stat is being set for short commands */
waitpid(g_shellsync_pid, &child_status, WNOHANG);
if (WIFEXITED(child_status))
g_return_stat = WEXITSTATUS(child_status);
else
g_return_stat = 1;
/* Read file in the interim from a temp file and send back the results */
fd = open(sync_file_name, O_RDONLY|O_SYNC);
while (1) {
/* read file in the interim and send back the results */
nbytes = read(fd, buf, SHELL_RESP_SIZE);
g_rem_ptr->msg.len = nbytes;
if (nbytes > 0) {
remote_tx_response(wl, buf, 0);
#ifdef RWL_SERIAL
/* usleep introduced for flooding of data over serial port */
usleep(1);
#endif
}
if (get_ctrlc_header(wl) >= 0) {
if (g_rem_ptr->msg.flags == (unsigned)CTRLC_FLAG) {
uname(&name);
/* Checking for mips architecture
* The mips machine responds differently to
* execl command. so the pid is incremented
* to kill the right command.
*/
if (strncmp(name.machine, "mips", sizeof(name.machine)) == 0)
pid++;
if (strncmp(name.machine, "armv5tel", sizeof(name.machine)) == 0) {
snprintf(cmd_find_lastpid, sizeof(cmd_find_lastpid),
"ps | awk \'PRINT $1\' | tail -n 1");
if ((fpt = popen(cmd_find_lastpid, "r")) == NULL) {
sprintf(buf, "%s\n", "Can't return PID");
return BCME_ERROR;
}
fgets(cmd_find_lastpid, sizeof(cmd_find_lastpid), fpt);
pid_final = atoi(cmd_find_lastpid);
while (pid <= pid_final) {
kill(pid, SIGKILL);
pid++;
}
pclose(fpt);
}
else {
kill(pid, SIGKILL);
}
break;
}
}
if (get_ctrlc_header(wl) >= 0) {
if (g_rem_ptr->msg.flags == (unsigned)CTRLC_FLAG) {
uname(&name);
/* Checking for mips architecture
* The mips machine responds differently to
* execl command. so the pid is incremented
* to kill the right command.
*/
if (strncmp(name.machine, "mips", sizeof(name.machine)) == 0) {
pid++;
kill(pid, SIGKILL);
}
/* Checking for arm architecture
* The multiple commands would not work
* for ctrl+C. So we kill the processes
* spawned after the parent. This method has
* its own limitations but the busybox in pxa
* doesnot have many options to implement it better
*/
else {
if (strncmp(name.machine, "armv5tel",
sizeof(name.machine)) == 0) {
/* The command below is used to get the
* PIDs and they are killed
*/
snprintf(cmd_find_lastpid,
sizeof(cmd_find_lastpid),
"ps | awk \'PRINT $1\' | tail -n 1");
if ((fpt = popen(cmd_find_lastpid, "r")) == NULL) {
sprintf(buf, "%s\n", "Can't return PID");
return BCME_ERROR;
}
fgets(cmd_find_lastpid, sizeof(cmd_find_lastpid),
fpt);
pid_final = atoi(cmd_find_lastpid);
while (pid <= pid_final) {
kill(pid, SIGKILL);
pid++;
}
pclose(fpt);
}
/* In the case of x86, on receiving ctrl+C
* the child PIDs are obtained by searching
* the parent PID to obtain the PIDs of the
* and kill them
*/
else {
while (pid != 0) {
/* The commad below is used to get the
* child PIDs by using their parent PID
*/
snprintf(cmd_find_lastpid,
sizeof(cmd_find_lastpid),
"ps al | awk \"{ if (\\$4 == %d)"
" {print \\$3}}\"| head -n 1",
g_shellsync_pid);
if ((fpt = popen(cmd_find_lastpid, "r"))
== NULL) {
sprintf(buf, "%s\n",
"Can't return PID");
return BCME_ERROR;
}
fgets(cmd_find_lastpid,
sizeof(cmd_find_lastpid),
fpt);
pid = atoi(cmd_find_lastpid);
if (pid == 0)
kill(g_shellsync_pid, SIGKILL);
else
kill(pid, SIGKILL);
pclose(fpt);
}
}
}
break;
}
}
if (set_ctrlc == 1) {
g_rem_ptr->msg.len = 0;
g_rem_ptr->msg.cmd = g_return_stat;
remote_tx_response(wl, NULL, g_return_stat);
unlink(sync_file_name);
kill(0, SIGKILL);
}
/* It is possible that the child would have exited
* However we did not get a chance to read the file
* In this case go once again and check the file
*/
if (!sent_once && !g_sig_chld) {
sent_once = 1;
continue;
}
if (!(g_sig_chld || nbytes))
break;
}
wait(NULL);
close(fd);
/* Signal end of command output */
g_rem_ptr->msg.len = 0;
g_rem_ptr->msg.cmd = g_return_stat;
remote_tx_response(wl, NULL, g_return_stat);
/* Cancel the time out alarm if any */
alarm(0);
sent_once = 0;
/* Clean up the temp file */
unlink(sync_file_name);
g_shellsync_timeout = DEFAULT_SHELL_TIMEOUT;
signal(SIGINT, SIG_DFL);
signal(SIGTERM, SIG_DFL);
return BCME_OK;
}

BIN
external/cache/sources/wl/wl/wl.tgz vendored Normal file

Binary file not shown.

2288
external/cache/sources/wl/wl/wlc_ppr.c vendored Normal file

File diff suppressed because it is too large Load Diff

340
external/cache/sources/wl/wl/wlc_ppr.h vendored Normal file
View File

@@ -0,0 +1,340 @@
/*
* PHY module Power-per-rate API. Provides interface functions and definitions for opaque
* ppr structure for use containing regulatory and board limits and tx power targets.
*
* $ Copyright Broadcom Corporation $
*
* $Id: $
*/
#ifndef _wlc_ppr_h_
#define _wlc_ppr_h_
#include <bcmwifi_rates.h>
#include <bcmutils.h>
#ifdef BCMDRIVER
#include <osl.h>
#else
#define osl_t void
#endif
/* Helper macro */
#define PPR_CHSPEC_BW(x) (CHSPEC_IS80(x) ? WL_TX_BW_80 : \
(CHSPEC_IS40(x) ? WL_TX_BW_40 : WL_TX_BW_20))
#ifndef BCMPHYCORENUM
#define PPR_MAX_TX_CHAINS 3
#else
#if (BCMPHYCORENUM < 1) || (BCMPHYCORENUM > 3)
#error Invalid number of PHY cores
#endif /* BCMPHYCORENUM < 1 || BCMPHYCORENUM > 3 */
#define PPR_MAX_TX_CHAINS (BCMPHYCORENUM)
#endif /* !defined(BCMPHYCORENUM) */
/* Opaque PPR data - it keeps its structure to itself */
typedef struct ppr ppr_t;
/* Power values for DSSS 1, 2, 5.5, 11 */
typedef struct ppr_dsss_rateset { int8 pwr[WL_RATESET_SZ_DSSS]; } ppr_dsss_rateset_t;
/* Power values for OFDM 6, 9, 12... 54 */
typedef struct ppr_ofdm_rateset { int8 pwr[WL_RATESET_SZ_OFDM]; } ppr_ofdm_rateset_t;
/* Power values one set of 8 HT MCS values (0-7, 8-15, etc) */
typedef struct ppr_ht_mcs_rateset { int8 pwr[WL_RATESET_SZ_HT_MCS]; } ppr_ht_mcs_rateset_t;
/* Power values one set of 10 VHT MCS values (0-9) */
typedef struct ppr_vht_mcs_rateset { int8 pwr[WL_RATESET_SZ_VHT_MCS]; } ppr_vht_mcs_rateset_t;
/* API Routines */
/* Initialization routine for opaque PPR struct */
void ppr_init(ppr_t* pprptr, wl_tx_bw_t bw);
/* Reinitialization routine for opaque PPR struct */
void ppr_clear(ppr_t* pprptr);
/* Size routine for user alloc/dealloc */
uint32 ppr_size(wl_tx_bw_t bw);
/* Size routine for user serialization alloc */
uint32 ppr_ser_size(const ppr_t* pprptr);
/* Size routine for user serialization alloc for a given bw */
uint32 ppr_ser_size_by_bw(wl_tx_bw_t bw);
/* Init allocated memory with a ppr serialization head
* This function must be called if serialization side has different
* compilation conditions (e.g PPR_MAX_TX_CHAINS, WL_BEAMFORMING etc.)
*/
int ppr_init_ser_mem_by_bw(uint8* pbuf, wl_tx_bw_t bw, uint32 len);
/* Init allocated memory with a ppr serialization head for the given ppr pointer
* This function must be called if serialization side has different
* compilation conditions (e.g PPR_MAX_TX_CHAINS, WL_BEAMFORMING etc.)
*/
int ppr_init_ser_mem(uint8* pbuf, ppr_t * ppr, uint32 len);
/* Constructor routine for opaque PPR struct */
ppr_t* ppr_create(osl_t *osh, wl_tx_bw_t bw);
/* Destructor routine for opaque PPR struct */
void ppr_delete(osl_t *osh, ppr_t* pprptr);
/* Type routine for inferring opaque structure size */
wl_tx_bw_t ppr_get_ch_bw(const ppr_t* pprptr);
/* Type routine to get ppr supported maximum bw */
wl_tx_bw_t ppr_get_max_bw(void);
/* Get the DSSS values for the given number of tx_chains and 20, 20in40, etc. */
int ppr_get_dsss(ppr_t* pprptr, wl_tx_bw_t bw, wl_tx_chains_t tx_chains,
ppr_dsss_rateset_t* dsss);
/* Get the OFDM values for the given number of tx_chains and 20, 20in40, etc. */
int ppr_get_ofdm(ppr_t* pprptr, wl_tx_bw_t bw, wl_tx_mode_t mode, wl_tx_chains_t tx_chains,
ppr_ofdm_rateset_t* ofdm);
/* Get the HT MCS values for the group specified by Nss, with the given bw and tx chains */
int ppr_get_ht_mcs(ppr_t* pprptr, wl_tx_bw_t bw, wl_tx_nss_t Nss, wl_tx_mode_t mode,
wl_tx_chains_t tx_chains, ppr_ht_mcs_rateset_t* mcs);
/* Get the VHT MCS values for the group specified by Nss, with the given bw and tx chains */
int ppr_get_vht_mcs(ppr_t* pprptr, wl_tx_bw_t bw, wl_tx_nss_t Nss, wl_tx_mode_t mode,
wl_tx_chains_t tx_chains, ppr_vht_mcs_rateset_t* mcs);
/* Routines to set target powers per rate for a whole rate set */
/* Set the DSSS values for the given number of tx_chains and 20, 20in40, etc. */
int ppr_set_dsss(ppr_t* pprptr, wl_tx_bw_t bw, wl_tx_chains_t tx_chains,
const ppr_dsss_rateset_t* dsss);
/* Set the OFDM values for the given number of tx_chains and 20, 20in40, etc. */
int ppr_set_ofdm(ppr_t* pprptr, wl_tx_bw_t bw, wl_tx_mode_t mode, wl_tx_chains_t tx_chains,
const ppr_ofdm_rateset_t* ofdm);
/* Set the HT MCS values for the group specified by Nss, with the given bw and tx chains */
int ppr_set_ht_mcs(ppr_t* pprptr, wl_tx_bw_t bw, wl_tx_nss_t Nss, wl_tx_mode_t mode,
wl_tx_chains_t tx_chains, const ppr_ht_mcs_rateset_t* mcs);
/* Set the VHT MCS values for the group specified by Nss, with the given bw and tx chains */
int ppr_set_vht_mcs(ppr_t* pprptr, wl_tx_bw_t bw, wl_tx_nss_t Nss, wl_tx_mode_t mode,
wl_tx_chains_t tx_chains, const ppr_vht_mcs_rateset_t* mcs);
/* Routines to set a whole rate set to a single target value */
/* Set the DSSS values for the given number of tx_chains and 20, 20in40, etc. */
int ppr_set_same_dsss(ppr_t* pprptr, wl_tx_bw_t bw, wl_tx_chains_t tx_chains, const int8 power);
/* Set the OFDM values for the given number of tx_chains and 20, 20in40, etc. */
int ppr_set_same_ofdm(ppr_t* pprptr, wl_tx_bw_t bw, wl_tx_mode_t mode, wl_tx_chains_t tx_chains,
const int8 power);
/* Set the HT MCS values for the group specified by Nss, with the given bw and tx chains */
int ppr_set_same_ht_mcs(ppr_t* pprptr, wl_tx_bw_t bw, wl_tx_nss_t Nss, wl_tx_mode_t mode,
wl_tx_chains_t tx_chains, const int8 power);
/* Set the HT MCS values for the group specified by Nss, with the given bw and tx chains */
int ppr_set_same_vht_mcs(ppr_t* pprptr, wl_tx_bw_t bw, wl_tx_nss_t Nss, wl_tx_mode_t mode,
wl_tx_chains_t tx_chains, const int8 power);
/* Helper routines to operate on the entire ppr set */
/* Ensure no rate limit is greater than the specified maximum */
uint ppr_apply_max(ppr_t* pprptr, int8 max);
/*
* Reduce total transmitted power to level of constraint.
* For two chain rates, the per-antenna power must be halved.
* For three chain rates, it must be a third of the constraint.
*/
uint ppr_apply_constraint_total_tx(ppr_t* pprptr, int8 constraint);
/* Ensure no rate limit is lower than the specified minimum */
uint ppr_apply_min(ppr_t* pprptr, int8 min);
/* Ensure no rate limit in this ppr set is greater than the corresponding limit in ppr_cap */
uint ppr_apply_vector_ceiling(ppr_t* pprptr, const ppr_t* ppr_cap);
/* Ensure no rate limit in this ppr set is lower than the corresponding limit in ppr_min */
uint ppr_apply_vector_floor(ppr_t* pprptr, const ppr_t* ppr_min);
/* Get the maximum power in the ppr set */
int8 ppr_get_max(ppr_t* pprptr);
/*
* Get the minimum power in the ppr set excluding disallowed
* rates and powers set to the minimum for the phy
*/
int8 ppr_get_min(ppr_t* pprptr, int8 floor);
/* Get the maximum power for a given bandwidth in the ppr set */
int8 ppr_get_max_for_bw(ppr_t* pprptr, wl_tx_bw_t bw);
/* Get the minimum power for a given bandwidth in the ppr set */
int8 ppr_get_min_for_bw(ppr_t* pprptr, wl_tx_bw_t bw);
typedef void (*ppr_mapfn_t)(void *context, uint8 *a, uint8 *b);
/* Map the given function with its context value over the two power vectors */
void ppr_map_vec_dsss(ppr_mapfn_t fn, void* context, ppr_t* pprptr1,
ppr_t* pprptr2, wl_tx_bw_t bw, wl_tx_chains_t tx_chains);
/* Map the given function with its context value over the two power vectors */
void ppr_map_vec_ofdm(ppr_mapfn_t fn, void* context, ppr_t* pprptr1,
ppr_t* pprptr2, wl_tx_bw_t bw, wl_tx_mode_t mode, wl_tx_chains_t tx_chains);
/* Map the given function with its context value over the two power vectors */
void ppr_map_vec_ht_mcs(ppr_mapfn_t fn, void* context, ppr_t* pprptr1,
ppr_t* pprptr2, wl_tx_bw_t bw, wl_tx_nss_t Nss, wl_tx_mode_t mode,
wl_tx_chains_t tx_chains);
/* Map the given function with its context value over the two power vectors */
void ppr_map_vec_vht_mcs(ppr_mapfn_t fn, void* context, ppr_t* pprptr1,
ppr_t* pprptr2, wl_tx_bw_t bw, wl_tx_nss_t Nss, wl_tx_mode_t mode,
wl_tx_chains_t tx_chains);
/* Map the given function with its context value over the two power vectors */
void ppr_map_vec_all(ppr_mapfn_t fn, void* context, ppr_t* pprptr1, ppr_t* pprptr2);
/* Get the first index that is larger than a given power level */
int16 ppr_get_idx(ppr_t* pprptr, int8 pwr);
/* Set PPR struct to a certain power level */
void ppr_set_cmn_val(ppr_t* pprptr, int8 val);
/* Make an identical copy of a ppr structure (for ppr_bw==all case) */
void ppr_copy_struct(ppr_t* pprptr_s, ppr_t* pprptr_d);
/* Subtract each power from a common value and re-store */
void ppr_cmn_val_minus(ppr_t* pprptr, int8 val);
/* Compare two ppr variables p1 and p2, save the min. value of each
* contents to variable p1
*/
void ppr_compare_min(ppr_t* p1, ppr_t* p2);
/* compare two ppr variables p1 and p2, save the max. value of each
* contents to variable p1
*/
void ppr_compare_max(ppr_t* p1, ppr_t* p2);
/* Serialize the contents of the opaque ppr struct.
* Writes number of bytes copied, zero on error.
* Returns error code, BCME_OK if successful.
*/
int ppr_serialize(const ppr_t* pprptr, uint8* buf, uint buflen, uint* bytes_copied);
/* Deserialize the contents of a buffer into an existing opaque ppr struct.
* The ppr struct *must* be of the same type as the one that was serialized.
* Returns error code, BCME_OK if successful.
*/
int ppr_deserialize(ppr_t* pprptr, const uint8* buf, uint buflen);
/* Deserialize the contents of a buffer into a new opaque ppr struct.
* Creates an opaque structure referenced by *pptrptr, NULL on error.
* Returns error code, BCME_OK if successful.
*/
int ppr_deserialize_create(osl_t *osh, const uint8* buf, uint buflen, ppr_t** pprptr);
/* Subtract a common value from each power and re-store */
void ppr_minus_cmn_val(ppr_t* pprptr, int8 val);
/* Add a common value to the given bw struct components */
void ppr_plus_cmn_val(ppr_t* pprptr, int8 val);
/* Multiply a percentage */
void ppr_multiply_percentage(ppr_t* pprptr, uint8 val);
#ifdef WLTXPWR_CACHE
/**
* Usage of the WLTXPWR_CACHE API:
* 1. Reserve one or more entries in the cache for a specific chanspec:
* wlc_phy_txpwr_setup_entry(chanspec1);
* wlc_phy_txpwr_setup_entry(chanspec2);
* 2. Use any of the getter/setter functions. Note that they may return an error on a chanspec
* that was not reserved. For setter functions, for pointer type arguments (e.g. ppr_t), the
* cache maintains a reference to the caller provided object rather than copying it.
* 3. Use wlc_phy_txpwr_cache_clear() or wlc_phy_txpwr_cache_invalidate() to get rid of cache
* entries. Note that this clears, amongst others, ppr_t structs.
*
* For non-BMAC builds, only the cache is allowed to delete the ppr_t object, and the driver code is
* not allowed to reuse it for another channel as it can when the cache is not being used.
*
* For BMAC builds, the cache has to be made to release the stf offsets object to avoid some nasty
* race conditions.
*
* Mike thinks when this is reimplemented for trunk he would consider having a reference count
* associated with each object to make this cleaner.
*
* Note that the functions start with wlc_phy_* despite not residing in the PHY code. This is
* probably for historical reasons.
*/
enum txpwr_cache_info_type {
TXPWR_CACHE_STF_OFFSETS, /* PPR offsets for stf */
TXPWR_CACHE_POWER_OFFSETS, /* PPR offsets for phy */
TXPWR_CACHE_NUM_TYPES, /* How many types of pwr info */
};
#define TXPWR_STF_PWR_MIN_INVALID 0x80
#define TXPWR_STF_TARGET_PWR_MIN_INVALID 0x40
#define TXPWR_STF_TARGET_PWR_NOT_CACHED 0x20
extern ppr_t* wlc_phy_get_cached_pwr(chanspec_t chanspec, uint pwr_type);
extern int wlc_phy_set_cached_pwr(osl_t *osh, chanspec_t chanspec, uint pwr_type, ppr_t* pwrptr);
extern uint8 wlc_phy_get_cached_pwr_max(chanspec_t chanspec, uint core);
extern int wlc_phy_set_cached_pwr_max(chanspec_t chanspec, uint core, uint8 max_pwr);
extern uint8 wlc_phy_get_cached_pwr_min(chanspec_t chanspec, uint core);
extern int wlc_phy_set_cached_pwr_min(chanspec_t chanspec, uint core, uint8 min_pwr);
extern int wlc_phy_get_cached_stf_target_pwr_min(chanspec_t chanspec);
extern int wlc_phy_set_cached_stf_target_pwr_min(chanspec_t chanspec, int min_pwr);
extern int8 wlc_phy_get_cached_txchain_offsets(chanspec_t chanspec, uint core);
extern int wlc_phy_set_cached_txchain_offsets(chanspec_t chanspec, uint core, int8 offset);
extern bool wlc_phy_txpwr_cache_is_cached(chanspec_t chanspec);
extern bool wlc_phy_is_pwr_cached(uint pwr_type, ppr_t* pwrptr);
extern void wlc_phy_uncache_pwr(uint pwr_type, ppr_t* pwrptr);
extern void wlc_phy_uncache_pwr(uint pwr_type, ppr_t* pwrptr);
extern chanspec_t wlc_phy_txpwr_cache_find_other_cached_chanspec(chanspec_t chanspec);
extern void wlc_phy_txpwr_cache_clear(osl_t *osh, chanspec_t chanspec);
extern void wlc_phy_txpwr_cache_invalidate(void);
extern void wlc_phy_txpwr_cache_close(osl_t *osh);
extern int wlc_phy_txpwr_setup_entry(chanspec_t chanspec);
extern bool wlc_phy_get_stf_ppr_cached(chanspec_t chanspec);
extern void wlc_phy_set_stf_ppr_cached(chanspec_t chanspec, bool bcached);
#endif /* WLTXPWR_CACHE */
#endif /* _wlc_ppr_h_ */

3357
external/cache/sources/wl/wl/wlm.c vendored Normal file

File diff suppressed because it is too large Load Diff

1241
external/cache/sources/wl/wl/wlm.h vendored Normal file

File diff suppressed because it is too large Load Diff

37927
external/cache/sources/wl/wl/wlu.c vendored Normal file

File diff suppressed because it is too large Load Diff

128
external/cache/sources/wl/wl/wlu.h vendored Normal file
View File

@@ -0,0 +1,128 @@
/*
* Common code for wl command line utility
*
* Copyright 2002, Broadcom Corporation
* All Rights Reserved.
*
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation;
* the contents of this file may not be disclosed to third parties, copied or
* duplicated in any form, in whole or in part, without the prior written
* permission of Broadcom Corporation.
*
* $Id: wlu.h 356283 2012-09-12 02:03:56Z jwang $
*/
#ifndef _wlu_h_
#define _wlu_h_
#include "wlu_cmd.h"
extern const char *wlu_av0;
/* parse common option */
extern int wl_option(char ***pargv, char **pifname, int *phelp);
extern void wl_cmd_init(void);
extern void wlu_init(void);
/* print usage */
extern void wl_cmd_usage(FILE *fid, cmd_t *cmd);
extern void wl_usage(FILE *fid, cmd_t *port_cmds);
extern void wl_cmds_usage(FILE *fid, cmd_t *port_cmds);
/* print helpers */
extern void wl_printlasterror(void *wl);
extern void wl_printint(int val);
/* pretty print an SSID */
extern int wl_format_ssid(char* buf, uint8* ssid, int ssid_len);
/* pretty hex print a contiguous buffer */
extern void wl_hexdump(uchar *buf, uint nbytes);
/* check driver version */
extern int wl_check(void *wl);
/* wl functions used by the ndis wl. */
extern void dump_rateset(uint8 *rates, uint count);
extern uint freq2channel(uint freq);
extern int wl_ether_atoe(const char *a, struct ether_addr *n);
extern char *wl_ether_etoa(const struct ether_addr *n);
struct ipv4_addr; /* forward declaration */
extern int wl_atoip(const char *a, struct ipv4_addr *n);
extern char *wl_iptoa(const struct ipv4_addr *n);
extern cmd_func_t wl_int;
extern cmd_func_t wl_varint;
extern void wl_dump_raw_ie(bcm_tlv_t *ie, uint len);
extern int wl_mk_ie_setbuf(const char *command, uint32 pktflag_ok, char **argv,
vndr_ie_setbuf_t **buf, int *buf_len);
extern cmd_func_t wl_list_ie;
extern void wl_printlasterror(void *wl);
extern bool wc_cmd_check(const char *cmd);
#ifdef BCMINTERNAL
extern int wl_iov_names(void *wl, cmd_t *cmd, char **argv);
extern int wl_cmd_help(void *wl, cmd_t *cmd_in, char **argv);
#endif
/* functions for downloading firmware to a device via serial or other transport */
#ifdef SERDOWNLOAD
extern int dhd_init(void *dhd, cmd_t *cmd, char **argv);
extern int dhd_download(void *dhd, cmd_t *cmd, char **argv);
extern int hsic_download(void *dhd, cmd_t *cmd, char **argv);
#endif /* SERDOWNLOAD */
#ifdef BCMDLL
#ifdef LOCAL
extern FILE *dll_fd;
#else
extern void * dll_fd_out;
extern void * dll_fd_in;
#endif
#undef printf
#undef fprintf
#define printf printf_to_fprintf /* printf to stdout */
#define fprintf fprintf_to_fprintf /* fprintf to stderr */
extern void fprintf_to_fprintf(FILE * stderror, const char *fmt, ...);
extern void printf_to_fprintf(const char *fmt, ...);
extern void raw_puts(const char *buf, void *dll_fd_out);
#define fputs(buf, stdout) raw_puts(buf, dll_fd_out)
#else
#undef fprintf
#define fprintf(x, ...) printf(__VA_ARGS__)
#endif /* BCMDLL */
#define RAM_SIZE_4325 0x60000
#define RAM_SIZE_4329 0x48000
#define RAM_SIZE_43291 0x60000
#define RAM_SIZE_4330_a1 0x3c000
#define RAM_SIZE_4330_b0 0x48000
/* useful macros */
#ifndef ARRAYSIZE
#define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0]))
#endif /* ARRAYSIZE */
/* buffer length needed for wl_format_ssid
* 32 SSID chars, max of 4 chars for each SSID char "\xFF", plus NULL
*/
#define SSID_FMT_BUF_LEN (4*32+1) /* Length for SSID format string */
#define USAGE_ERROR -1 /* Error code for Usage */
#define IOCTL_ERROR -2 /* Error code for Ioctl failure */
#define BAD_PARAM -3 /* Error code for bad params, but don't dump cmd_help */
#define CMD_DEPRECATED -4 /* Commands that are functionally deprecated or don't provide
* a useful value to a specific OS port of wl
*/
/* integer output format */
#define INT_FMT_DEC 0 /* signed integer */
#define INT_FMT_UINT 1 /* unsigned integer */
#define INT_FMT_HEX 2 /* hexdecimal */
/* command line argument usage */
#define CMD_ERR -1 /* Error for command */
#define CMD_OPT 0 /* a command line option */
#define CMD_WL 1 /* the start of a wl command */
#endif /* _wlu_h_ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,33 @@
/*
* OS independent client specific declarations
*
* $Copyright (C) 2008 Broadcom Corporation$
*
* $Id: wlu_client_shared.h 295438 2011-11-10 14:27:25Z alwin $
*/
#ifndef _wlu_client_shared_h
#define _wlu_client_shared_h
/* Newly added wrappers from wlu_client_shared.c */
extern int
rwl_shell_cmd_proc(void *wl, char **argv, int cmd);
extern int
rwl_queryinformation_fe(void *wl, int cmd, void* input_buf, unsigned long *input_len,
int debug, int rem_ioctl_select);
extern int
rwl_setinformation_fe(void *wl, int cmd, void* buf, unsigned long *len, int debug,
int rem_ioctl_select);
extern void
rwl_usage(int remote_type);
extern int
rwl_detect(void *wl, bool debug, int* os_type_ptr);
extern int rwl_shell_createproc(void *wl);
extern void rwl_shell_killproc(int pid);
#ifndef UNDER_CE
/* declaring these as extern to be used in wlu_ndis.c and wlu_linux.c */
extern volatile sig_atomic_t g_sig_ctrlc;
extern void ctrlc_handler(int num);
#endif /* Not UNDER_CE */
#endif /* _wlu_client_share_h */

975
external/cache/sources/wl/wl/wlu_cmd.c vendored Normal file
View File

@@ -0,0 +1,975 @@
/*
* $Id: wlu_cmd.c 399026 2013-04-27 00:44:07Z yongfang $
* $Copyright: (c) 2006, Broadcom Corp.
* All Rights Reserved.$
*
* File: wlu_cmd.c
* Purpose: Command and IO variable information commands
* Requires:
*/
#if defined(_CFE_)
#include <lib_types.h>
#include <lib_string.h>
#include <lib_printf.h>
#include <lib_malloc.h>
#include <cfe_error.h>
#elif defined(__IOPOS__)
#include <typedefs.h>
#include <bcmstdlib.h>
#include <bcmutils.h>
#else
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <assert.h>
#endif /* defined(_CFE_) */
#include <typedefs.h>
#include <bcmutils.h>
#include <wlioctl.h>
#include "wlu.h"
#if defined(__IOPOS__)
#define fprintf(file, fmt, arg...) jtag_printf(fmt , ## arg)
#endif /* __IOPOS__ */
#ifdef BCMINTERNAL
#ifndef NUM_ELS
#define NUM_ELS(_a) (sizeof(_a)/sizeof(_a[0]))
#endif /* num els */
typedef struct cmd2cat {
const char *name;
uint32 cat;
} cmd2cat_t;
/* Command categorization:
*
* Please keep these alphabetized (ascii ordering).
*/
cmd2cat_t cmd2cat[] = {
/* Please keep alphabetized */
{"PM", CMD_PHY + CMD_POWER},
{"a_mrate", CMD_PHY + CMD_RATE},
{"a_rate", CMD_PHY + CMD_RATE},
{"abminrate", CMD_MGMT + CMD_AP + CMD_STA},
{"aciargs", CMD_PHY},
{"add_ie", CMD_MGMT},
{"addkey", CMD_MGMT + CMD_SEC},
{"addwep", CMD_MGMT + CMD_SEC},
{"ampdu_clear_dump", CMD_MON + CMD_ADMIN},
{"ampdu_dump", CMD_DEP + CMD_UNCAT},
{"ampdu_retry_limit_tid", CMD_UNCAT},
{"ampdu_rr_retry_limit_tid", CMD_UNCAT},
{"ampdu_send_addba", CMD_MGMT},
{"ampdu_send_delba", CMD_MGMT},
{"ampdu_tid", CMD_MGMT},
{"amsdu_clear_counters", CMD_MON + CMD_ADMIN},
{"amsdu_dump", CMD_DEP + CMD_UNCAT},
{"antdiv", CMD_PHY},
{"ap", CMD_AP + CMD_STA},
{"ap_isolate", CMD_MGMT + CMD_AP},
{"apname", CMD_MGMT + CMD_MON + CMD_AP},
{"assoc", CMD_MON + CMD_STA + CMD_AP},
{"assoc_info", CMD_MGMT + CMD_STA},
{"assoc_pref", CMD_MGMT + CMD_AP + CMD_STA},
{"assoclist", CMD_MGMT + CMD_AP},
{"atten", CMD_PHY + CMD_CHAN + CMD_POWER},
{"auth", CMD_MGMT + CMD_SEC},
{"authe_sta_list", CMD_MGMT + CMD_SEC},
{"autho_sta_list", CMD_MGMT + CMD_SEC},
{"authorize", CMD_MGMT + CMD_SEC},
{"autochannel", CMD_PHY + CMD_CHAN},
{"ba_clear_counters", CMD_MON + CMD_ADMIN},
{"ba_dump", CMD_DEP + CMD_UNCAT},
{"band", CMD_PHY + CMD_CHAN},
{"bands", CMD_PHY + CMD_CHAN},
{"band_range", CMD_PHY + CMD_CHAN},
{"bcmerrorstr", CMD_ADMIN},
{"bg_mrate", CMD_PHY + CMD_RATE},
{"bg_rate", CMD_PHY + CMD_RATE},
{"bi", CMD_MGMT + CMD_AP},
{"bss", CMD_MGMT + CMD_AP + CMD_STA},
{"bssid", CMD_AP},
{"bssmax", CMD_AP + CMD_ADMIN},
{"btc_flags", CMD_DEV},
{"btc_params", CMD_DEV},
{"cac_addts", CMD_MGMT + CMD_WME + CMD_AP + CMD_STA},
{"cac_delts", CMD_MGMT + CMD_WME + CMD_AP + CMD_STA},
{"cac_delts_ea", CMD_MGMT + CMD_WME + CMD_AP + CMD_STA},
{"cac_tslist", CMD_MGMT + CMD_WME + CMD_AP + CMD_STA},
{"cac_tspec", CMD_MGMT + CMD_WME + CMD_AP + CMD_STA},
{"cap", CMD_ADMIN},
{"cck_txbw", CMD_PHY + CMD_CHAN + CMD_UNCAT},
{"chan_info", CMD_PHY + CMD_CHAN + CMD_MON},
{"chanlist", CMD_DEP + CMD_UNCAT},
{"channel", CMD_PHY + CMD_CHAN},
{"channel_qa", CMD_PHY + CMD_CHAN},
{"channel_qa_start", CMD_PHY + CMD_CHAN},
{"channels", CMD_PHY + CMD_CHAN},
{"channels_in_country", CMD_PHY + CMD_CHAN},
{"chanspec", CMD_PHY + CMD_CHAN},
{"chanspecs", CMD_PHY + CMD_CHAN},
{"clk", CMD_BOARD},
{"closed", CMD_SEC},
{"closednet", CMD_SEC},
{"cmds", CMD_ADMIN},
{"config", CMD_MGMT},
{"constraint", CMD_PHY + CMD_POWER},
{"counters", CMD_MON + CMD_ADMIN},
{"country", CMD_MGMT},
{"crsuprs", CMD_PHY + CMD_CHAN},
{"csa", CMD_PHY + CMD_CHAN + CMD_MGMT},
{"csscantimer", CMD_PHY + CMD_CHAN},
{"cur_etheraddr", CMD_MGMT},
{"curpower", CMD_PHY + CMD_POWER},
{"cwmax", CMD_MGMT},
{"cwmin", CMD_MGMT},
{"deauthenticate", CMD_MGMT + CMD_SEC},
{"deauthorize", CMD_MGMT + CMD_SEC},
{"decryptstatus", CMD_MGMT + CMD_SEC},
{"del_ie", CMD_MGMT},
{"delta_stats", CMD_MON + CMD_ADMIN},
{"delta_stats_interval", CMD_MON + CMD_ADMIN},
{"dfs_status", CMD_PHY + CMD_CHAN},
{"diag", CMD_ADMIN},
{"disassoc", CMD_MGMT + CMD_STA},
{"down", CMD_BOARD + CMD_ADMIN},
{"dtim", CMD_MGMT + CMD_AP},
{"dump", CMD_ADMIN},
{"eap", CMD_MGMT + CMD_SEC},
{"eap_restrict", CMD_SEC},
{"encryptstrength", CMD_MGMT + CMD_SEC},
{"event_msgs", CMD_MAC},
{"eventing", CMD_MAC},
{"evm", CMD_PHY + CMD_CHAN + CMD_RATE},
{"fasttimer", CMD_DEP + CMD_UNCAT},
{"fips", CMD_MGMT + CMD_STA},
{"force", CMD_PHY | CMD_BOARD},
{"fqacurcy", CMD_PHY + CMD_CHAN},
{"frag", CMD_DEP + CMD_UNCAT},
{"frameburst", CMD_MAC + CMD_MGMT},
{"freqtrack", CMD_PHY + CMD_CHAN},
{"glacialtimer", CMD_DEP + CMD_UNCAT},
{"gmode", CMD_PHY},
{"gmode_protection", CMD_PHY},
{"gmode_protection_control", CMD_PHY},
{"gmode_protection_override", CMD_PHY},
{"gpiodump", CMD_DEP + CMD_UNCAT},
{"gpioout", CMD_DEV},
{"help", CMD_ADMIN},
{"hwkeys", CMD_SEC + CMD_ADMIN + CMD_DEV},
{"ignore_bcns", CMD_MGMT},
{"infra", CMD_MGMT + CMD_AP + CMD_STA},
{"interference", CMD_PHY},
{"iov", CMD_ADMIN},
{"isup", CMD_MGMT + CMD_ADMIN},
{"join", CMD_MGMT + CMD_STA},
{"join_pref", CMD_MGMT + CMD_AP + CMD_STA},
{"keys", CMD_MGMT + CMD_SEC},
{"lazywds", CMD_MGMT + CMD_SEC},
{"leap", CMD_MGMT + CMD_SEC},
{"legacy_erp", CMD_UNCAT},
{"legacylink", CMD_PHY + CMD_BOARD},
{"lifetime", CMD_MGMT + CMD_AP + CMD_STA},
{"list", CMD_ADMIN},
{"list_ie", CMD_MGMT},
{"listen", CMD_MGMT},
{"longtrain", CMD_PHY + CMD_CHAN},
{"loop", CMD_MAC + CMD_ADMIN + CMD_DEV},
{"lrl", CMD_MGMT},
{"mac", CMD_MAC + CMD_MGMT},
{"macmode", CMD_MAC + CMD_MGMT},
{"macreg", CMD_MAC + CMD_DEV},
{"malloc_dump", CMD_DEP + CMD_UNCAT},
{"measure_req", CMD_PHY + CMD_MON},
{"mimo_ft", CMD_PHY + CMD_CHAN},
{"mimo_ofdm", CMD_PHY + CMD_CHAN},
{"mimo_ps", CMD_PHY + CMD_CHAN + CMD_POWER},
{"mimo_txbw", CMD_PHY + CMD_CHAN},
{"mode_reqd", CMD_MGMT},
{"monitor", CMD_PHY + CMD_MON},
{"mrate", CMD_DEP + CMD_UNCAT},
{"msglevel", CMD_ADMIN},
{"n_bw", CMD_PHY + CMD_CHAN},
{"ndis_frag", CMD_MGMT},
{"ndis_rts", CMD_MGMT},
{"ndisscan", CMD_MGMT + CMD_STA},
{"nettype", CMD_MGMT + CMD_PHY},
{"nettypes_supported", CMD_ADMIN + CMD_MON},
{"noise", CMD_PHY + CMD_MON},
{"nrate", CMD_PHY + CMD_RATE},
{"nvget", CMD_ADMIN},
{"nvotpw", CMD_ADMIN + CMD_DEV},
{"nvram_dump", CMD_ADMIN},
{"nvram_get", CMD_ADMIN},
{"nvset", CMD_ADMIN},
{"ofdm_txbw", CMD_PHY + CMD_CHAN + CMD_UNCAT},
{"otpdump", CMD_ADMIN + CMD_DEV},
{"otpw", CMD_ADMIN + CMD_DEV},
{"out", CMD_BOARD + CMD_ADMIN},
{"passive", CMD_PHY + CMD_MGMT + CMD_AP + CMD_STA},
{"pcicfgreg", CMD_BOARD + CMD_DEV},
{"pciereg", CMD_BOARD + CMD_DEV},
{"pcieregdump", CMD_DEP + CMD_UNCAT},
{"phylist", CMD_PHY},
{"phyreg", CMD_PHY + CMD_DEV},
{"phytype", CMD_PHY},
{"piomode", CMD_ADMIN + CMD_DEV},
{"pktcnt", CMD_MGMT + CMD_MON},
{"plcphdr", CMD_UNCAT},
{"pm2_rcv_dur", CMD_POWER},
{"pm2_sleep_ret", CMD_POWER},
{"pmkid_info", CMD_SEC},
{"powerindex", CMD_PHY + CMD_POWER},
{"prb_resp_timeout", CMD_PHY + CMD_CHAN + CMD_MGMT + CMD_AP + CMD_STA},
{"primary_key", CMD_MGMT + CMD_SEC},
{"promisc", CMD_PHY + CMD_MON},
{"protection_control", CMD_MGMT + CMD_AP + CMD_STA},
{"pwr_percent", CMD_PHY + CMD_POWER},
{"quiet", CMD_PHY},
{"radar", CMD_PHY},
{"radarargs", CMD_PHY},
{"radar_status", CMD_PHY},
{"clear_radar_status", CMD_PHY},
{"radio", CMD_PHY + CMD_DEV},
{"radioreg", CMD_PHY + CMD_DEV},
{"rand", CMD_ADMIN + CMD_DEV},
{"rate", CMD_PHY},
{"ratedump", CMD_PHY + CMD_RATE},
{"rateparam", CMD_PHY + CMD_RATE},
{"rateset", CMD_PHY + CMD_RATE},
{"rcvdropped", CMD_MON},
{"rcvok", CMD_MON},
{"reassoc", CMD_MGMT + CMD_STA},
{"reboot", CMD_BOARD + CMD_ADMIN},
{"regulatory", CMD_MGMT},
{"reinit", CMD_ADMIN + CMD_DEV},
{"reset_d11cnts", CMD_MON + CMD_ADMIN},
{"restart", CMD_BOARD + CMD_ADMIN},
{"revinfo", CMD_ADMIN + CMD_DEV},
{"rm_rep", CMD_PHY + CMD_MON},
{"rm_req", CMD_PHY + CMD_MON},
{"rmwep", CMD_MGMT + CMD_SEC},
{"rndismac", CMD_MGMT},
{"roam_delta", CMD_MGMT + CMD_STA},
{"roam_scan_period", CMD_MGMT + CMD_STA},
{"roam_trigger", CMD_MGMT + CMD_STA},
{"rssi", CMD_UNCAT},
{"rssi_event", CMD_UNCAT},
{"rts", CMD_DEP + CMD_UNCAT},
{"sample_collect", CMD_PHY},
{"scan", CMD_PHY + CMD_MGMT + CMD_AP + CMD_STA},
{"scan_channel_time", CMD_PHY + CMD_CHAN},
{"scan_home_time", CMD_PHY + CMD_CHAN},
{"scan_nprobes", CMD_UNCAT},
{"scan_passive_time", CMD_PHY + CMD_CHAN},
{"scan_unassoc_time", CMD_PHY + CMD_CHAN},
{"scanresults", CMD_MON + CMD_AP + CMD_STA},
{"scansuppress", CMD_PHY},
{"scb_timeout", CMD_MGMT + CMD_SEC + CMD_AP},
{"sd_blockmode", CMD_DEV},
{"sd_blocksize", CMD_DEV},
{"sd_cis", CMD_DEV},
{"sd_devreg", CMD_DEV},
{"sd_divisor", CMD_DEV},
{"sd_dma", CMD_DEV},
{"sd_drivestrength", CMD_DEV},
{"sd_hciregs", CMD_DEV},
{"sd_highspeed", CMD_DEV},
{"sd_hostreg", CMD_DEV},
{"sd_ints", CMD_DEV},
{"sd_mode", CMD_DEV},
{"sd_msglevel", CMD_ADMIN},
{"sd_numints", CMD_DEV},
{"sd_numlocalints", CMD_DEV},
{"send", CMD_ADMIN},
{"serdespllreg", CMD_BOARD + CMD_DEV},
{"serdesrxreg", CMD_BOARD + CMD_DEV},
{"serdestxreg", CMD_BOARD + CMD_DEV},
{"set_pmk", CMD_MGMT + CMD_SEC},
{"shmem", CMD_DEV},
{"shmem_dump", CMD_DEP + CMD_UNCAT},
{"shortslot", CMD_PHY},
{"shortslot_override", CMD_PHY},
{"shortslot_restrict", CMD_PHY},
{"shownetworks", CMD_MGMT + CMD_STA},
{"slowtimer", CMD_DEP + CMD_UNCAT},
{"spect", CMD_PHY + CMD_MGMT},
{"srdump", CMD_ADMIN + CMD_DEV},
{"srl", CMD_MGMT},
{"ssid", CMD_MGMT + CMD_AP + CMD_STA},
{"sta_info", CMD_MON + CMD_STA},
{"staname", CMD_MGMT + CMD_MON + CMD_STA},
{"stats", CMD_MON},
{"status", CMD_MON + CMD_STA + CMD_AP},
{"suprates", CMD_PHY + CMD_RATE},
{"tkip_countermeasures", CMD_MGMT + CMD_SEC},
#ifdef TRAFFIC_MGMT
{"trf_mgmt_config", CMD_ADMIN},
{"trf_mgmt_filters_add", CMD_ADMIN},
{"trf_mgmt_filters_remove", CMD_ADMIN},
{"trf_mgmt_filters_list", CMD_ADMIN},
{"trf_mgmt_filters_clear", CMD_ADMIN},
{"trf_mgmt_bandwidth", CMD_ADMIN},
{"trf_mgmt_flags", CMD_ADMIN},
{"trf_mgmt_stats", CMD_ADMIN},
{"trf_mgmt_stats_clear", CMD_ADMIN},
{"trf_mgmt_shaping_info", CMD_ADMIN},
#endif /* TRAFFIC_MGMT */
{"tsc", CMD_MGMT + CMD_SEC + CMD_MON},
{"tsf_dump", CMD_DEP + CMD_UNCAT},
{"tssi", CMD_PHY},
{"txant", CMD_PHY},
{"txinstpwr", CMD_PHY + CMD_POWER},
{"txpathpwr", CMD_PHY + CMD_POWER},
{"txpwr", CMD_DEP + CMD_UNCAT},
{"txpwr1", CMD_PHY + CMD_POWER},
{"txpwrlimit", CMD_PHY + CMD_POWER},
{"ucantdiv", CMD_PHY + CMD_DEV},
{"ucflags", CMD_DEV},
{"up", CMD_BOARD + CMD_ADMIN},
{"upgrade", CMD_ADMIN},
{"ver", CMD_ADMIN},
{"wake", CMD_PHY + CMD_POWER},
{"wds", CMD_MGMT + CMD_SEC},
{"wds_remote_mac", CMD_MGMT + CMD_SEC},
{"wds_wpa_role", CMD_MGMT + CMD_SEC},
{"wds_wpa_role_old", CMD_MGMT + CMD_SEC},
{"wepdefault", CMD_MGMT + CMD_SEC},
{"wepstatus", CMD_DEP + CMD_UNCAT},
{"wet", CMD_MGMT + CMD_SEC},
{"wme", CMD_WME},
{"wme_ac", CMD_WME},
{"wme_apsd", CMD_PHY + CMD_POWER + CMD_WME + CMD_AP},
{"wme_apsd_sta", CMD_WME},
{"wme_clear_counters", CMD_WME + CMD_MON + CMD_ADMIN},
{"wme_counters", CMD_WME + CMD_MON + CMD_ADMIN},
{"wme_dp", CMD_WME},
{"wme_tx_params", CMD_WME},
{"wme_maxbw_params", CMD_WME},
{"wpa_auth", CMD_MGMT + CMD_SEC},
{"wpa_cap", CMD_MGMT + CMD_SEC},
{"wsec", CMD_MGMT + CMD_SEC},
{"wsec_restrict", CMD_MGMT + CMD_SEC},
{"wsec_test", CMD_MGMT + CMD_SEC},
{"xlist", CMD_ADMIN},
{"xmitok", CMD_MON},
{"zzzzz", 0} /* Last for binary search */
};
/* Get the command category flags for command name; returns 0 if not found */
static uint32 cmd_cat_get(const char *name)
{
int low = 0, high = NUM_ELS(cmd2cat) - 1;
int mid;
int prev_mid;
int cmp_val;
mid = low + high / 2;
do {
prev_mid = mid;
cmp_val = strcmp(name, cmd2cat[mid].name);
if (cmp_val == 0) return cmd2cat[mid].cat;
else if (cmp_val > 0) low = mid + 1;
else high = mid - 1;
mid = (low + high) / 2;
} while (prev_mid != mid);
return 0;
}
/*
* IO variable information command
*/
/* Consolidation of parsing and state info for iov command */
struct iov_control_info {
char *substr; /* sub string to match if non-NULL */
int match_type; /* Display only the matched type if >= 0 */
bool show_type; /* Display type */
bool show_desc; /* Display var desc if avail */
bool show_mod; /* Display var modules if known */
bool show_dflt; /* Display var modules if known */
bool exact_match; /* Match at most one variable exactly to substring */
bool driver_not_ui; /* Show variables in driver but not in local info */
bool ui_not_driver; /* Show variables in local info but not driver */
int tot_count; /* How many variables from driver */
int out_count; /* How many displayed */
void *wl; /* Need for wl_get calls */
/* The following are dynmically allocated */
wlc_iov_trx_t *trx_block; /* Holding buffer for a block of variables */
int trx_block_bytes;
bool *var_found; /* Mark local vars to detect those not in driver */
char *mod_names; /* To be implemented */
};
/* Type string names for matching */
static const char *wl_iov_type_strings[] = BCM_IOV_TYPE_INIT;
static int wl_iov_type_count = ARRAYSIZE(wl_iov_type_strings);
static char wl_iov_mod_names[WLU_MOD_NAME_MAX][WLU_MOD_NAME_BYTES];
/* static bool wl_iov_mod_names_cached = FALSE; */ /* If needed, cache module names */
#define MOD_VALID(mod) (((unsigned int)(mod)) < WLU_MOD_NAME_MAX)
/* Returned when info not found if still printing */
static wlu_iov_info_t iov_unknown_info = {
NULL,
0,
0,
0,
"Variable not found in local info"
};
static void
wl_iov_usage(FILE *fid, char *cmd)
{
int i;
fprintf(fid, "Usage: %s [<options>] [-T <type>] [<substr>]\n", cmd);
fprintf(fid, " -h Display help message\t\t-i Show description (info)\n");
fprintf(fid, " -m Show module name\t\t\t-t Show variable types\n");
fprintf(fid, " -a Show all names\t\t\t-d Show default values\n");
fprintf(fid, " -e Exact match of substring\n");
fprintf(fid, " -v (verbose) Show module, type, default values\n");
fprintf(fid, " -V (verbose) Like -v plus descriptions\n");
fprintf(fid, " -u (undoc) Show only driver variables without UI info\n");
fprintf(fid, " -x Show only variable with UI info that are not in current driver\n");
fprintf(fid, " -T <type> Restrict to variables of the given type (see below)\n");
fprintf(fid, " <substr> Display all names containing the given substring\n");
fprintf(fid, "-u and -x are mutually exclusive\n");
fprintf(fid, "\nKnown variable types include:\n ");
for (i = 0; i < wl_iov_type_count; i++) {
fprintf(fid, "%s ", wl_iov_type_strings[i]);
}
fprintf(fid, "\n");
}
/* Parse args and initialize control structure */
static int
iov_parse_args_alloc(FILE *fid, void *wl, char **argv, struct iov_control_info *cinfo)
{
int idx;
int i;
int bytes;
memset(cinfo, 0, sizeof(*cinfo));
cinfo->match_type = -1;
cinfo->wl = wl;
for (idx = 1; argv[idx] != NULL; idx++) {
if (strcmp(argv[idx], "-T") == 0) { /* Search for type in list */
idx++;
if (argv[idx] == NULL) {
fprintf(fid, "Must specify type with -t.\n");
return -1;
}
for (i = 0; i < wl_iov_type_count; i++) {
if (strcmp(argv[idx], wl_iov_type_strings[i]) == 0) {
cinfo->match_type = i;
break;
}
}
if (cinfo->match_type < 0) {
fprintf(fid, "Unknown variable type: %s\n", argv[idx]);
return -1;
}
} else if (strcmp(argv[idx], "-v") == 0) {
cinfo->show_type = TRUE;
cinfo->show_mod = TRUE;
cinfo->show_dflt = TRUE;
} else if (strcmp(argv[idx], "-V") == 0) {
cinfo->show_type = TRUE;
cinfo->show_mod = TRUE;
cinfo->show_dflt = TRUE;
cinfo->show_desc = TRUE;
} else if (strcmp(argv[idx], "-m") == 0) {
cinfo->show_mod = TRUE;
} else if (strcmp(argv[idx], "-t") == 0) {
cinfo->show_type = TRUE;
} else if (strcmp(argv[idx], "-i") == 0) {
cinfo->show_desc = TRUE;
} else if (strcmp(argv[idx], "-d") == 0) {
cinfo->show_dflt = TRUE;
} else if (strcmp(argv[idx], "-e") == 0) {
cinfo->exact_match = TRUE;
} else if (strcmp(argv[idx], "-u") == 0) {
if (cinfo->ui_not_driver) {
return -1;
}
cinfo->driver_not_ui = TRUE;
} else if (strcmp(argv[idx], "-x") == 0) {
if (cinfo->driver_not_ui) {
return -1;
}
cinfo->ui_not_driver = TRUE;
} else if (strcmp(argv[idx], "-a") != 0) { /* matches all vars, so ignore */
/* Anything else is substring */
cinfo->substr = argv[idx];
}
}
/* Allocate transfer buffer */
bytes = sizeof(wlc_iov_trx_t) * WLU_IOV_BLOCK_LEN;
if ((cinfo->trx_block = malloc(bytes)) == NULL) {
fprintf(fid, "ERROR: Could not allocate transfer buffer of %d bytes\n", bytes);
return -1;
} else {
memset(cinfo->trx_block, 0, bytes);
cinfo->trx_block_bytes = bytes;
}
/* If "local vars not in driver" is set, allocate found buffer */
if (cinfo->ui_not_driver) { /* Allocate space to match vars */
bytes = sizeof(bool) * wlu_iov_info_count;
if ((cinfo->var_found = malloc(bytes)) != NULL) {
memset(cinfo->var_found, 0, bytes);
} else { /* do not show these vars */
fprintf(fid, "Unable to show variables missing from local info\n");
cinfo->ui_not_driver = FALSE;
}
}
if (cinfo->show_mod) {
/* Put parameters into ioctl buffer */
int *param_p;
/* XXX May implement "caching" of module names; add "force refresh" cmd if so */
param_p = (int *)(wl_iov_mod_names);
/* memcpy might be safer for alignment */
param_p[0] = WLU_MOD_NAME_BYTES;
param_p[1] = WLU_MOD_NAME_MAX;
if (wl_get(cinfo->wl, WLC_IOV_MODULES_GET, (void *)(wl_iov_mod_names),
sizeof(wl_iov_mod_names)) < 0) {
fprintf(fid, "Unable to show module names\n");
cinfo->show_mod = FALSE;
}
}
return 0;
}
/* Deallocation routine for dynamic mem */
static void
wl_iov_cleanup(struct iov_control_info *cinfo)
{
if (cinfo != NULL) {
if (cinfo->trx_block != NULL) {
free(cinfo->trx_block);
cinfo->trx_block = NULL;
}
if (cinfo->var_found != NULL) {
free(cinfo->var_found);
cinfo->var_found = NULL;
}
}
}
/* Look for a variable from driver in the local info; returns index in iov_info array */
static int
wl_iov_find(char *name)
{
int idx;
/* Could implement as bin search if iov_info kept sorted */
for (idx = 0; idx < wlu_iov_info_count; idx++) {
if (strcmp(wlu_iov_info[idx].name, name) == 0) {
return idx;
}
}
return -1;
}
/* First level of variable qualification check: type and substring */
static bool
wl_iov_var_match(wlc_iov_trx_t *var, struct iov_control_info *cinfo)
{
bool type_ok;
bool substr_ok;
type_ok = (cinfo->match_type < 0 || var->type == cinfo->match_type);
substr_ok = !cinfo->substr || !*cinfo->substr ||
(strstr(var->name, cinfo->substr) != NULL);
/* Look for exact match of string? */
if (cinfo->exact_match) {
substr_ok = (cinfo && cinfo->substr &&
strcmp(cinfo->substr, var->name) == 0);
}
return type_ok && substr_ok;
}
/* Does the var name match the given qualifications? Is it found in local info? */
static wlu_iov_info_t *
wl_iov_qualify(wlc_iov_trx_t *var, struct iov_control_info *cinfo)
{
int local_var_idx = -1;
wlu_iov_info_t *rv = NULL;
int var_qualifies;
cinfo->tot_count++; /* Count this driver variable */
var_qualifies = wl_iov_var_match(var, cinfo);
if (var_qualifies || cinfo->ui_not_driver) { /* Look up in local info */
local_var_idx = wl_iov_find(var->name);
}
/* Mark local variable if found */
if (local_var_idx >= 0 && cinfo->ui_not_driver && cinfo->var_found != NULL) {
cinfo->var_found[local_var_idx] = TRUE;
}
if (var_qualifies) { /* matched variable */
if (cinfo->driver_not_ui && local_var_idx < 0) { /* Not found case */
rv = &iov_unknown_info;
}
if (!cinfo->driver_not_ui && local_var_idx >= 0) { /* Found case */
rv = &wlu_iov_info[local_var_idx];
}
} /* else, not qualified, so return NULL */
return rv;
}
#define NAMES_ONLY(cinfo) (!cinfo->show_type && !cinfo->show_mod && \
!cinfo->show_desc && !cinfo->show_dflt)
/* Display headers if needed */
static void
show_header(FILE *fid, struct iov_control_info *cinfo)
{
char line_buf[80];
char *buf_p;
buf_p = line_buf;
buf_p += sprintf(buf_p, "Variables ");
if (BCM_IOVT_VALID(cinfo->match_type)) {
buf_p += sprintf(buf_p, "of type %s", wl_iov_type_strings[cinfo->match_type]);
}
if (cinfo->substr && *cinfo->substr) {
buf_p += sprintf(buf_p, "matching =%s=", cinfo->substr);
}
fprintf(fid, "%s\n", buf_p);
if (cinfo->driver_not_ui) {
fprintf(fid, "The following variables do NOT have UI information\n");
}
if (NAMES_ONLY(cinfo)) {
return;
}
buf_p = line_buf;
buf_p += sprintf(buf_p, "%-30s", "Variable name");
if (cinfo->show_type) {
buf_p += sprintf(buf_p, " %-8s", "Type");
}
if (cinfo->show_mod) {
buf_p += sprintf(buf_p, " %-20s", "Module");
}
if (cinfo->show_dflt) {
buf_p += sprintf(buf_p, " %-10s", "Default");
}
fprintf(fid, "%s\n", line_buf);
}
/* See if var should be displayed; if so do that and count */
static void
wl_iov_check_show(FILE *fid, wlc_iov_trx_t *var, struct iov_control_info *cinfo)
{
wlu_iov_info_t *local_var;
char line_buf[80];
char *buf_p;
if ((local_var = wl_iov_qualify(var, cinfo)) != NULL) {
if (cinfo->ui_not_driver) {
return; /* Don't print out driver matched vars */
}
if (NAMES_ONLY(cinfo)) {
fprintf(fid, "%-25s%s", var->name,
(cinfo->out_count + 1) % 3 ? " " : "\n");
} else {
buf_p = line_buf;
buf_p += sprintf(buf_p, "%-30s", var->name);
if (cinfo->show_type) {
buf_p += sprintf(buf_p, " %-8s", BCM_IOVT_VALID(var->type) ?
wl_iov_type_strings[var->type] : "no-type");
}
if (cinfo->show_mod) {
buf_p += sprintf(buf_p, " %-20s", MOD_VALID(var->module) ?
wl_iov_mod_names[var->module] : "no-mod");
}
if (cinfo->show_dflt) {
if (local_var->flags & WLU_IOVI_DEFAULT_VALID) {
buf_p += sprintf(buf_p, " %-10d", local_var->dflt);
} else {
buf_p += sprintf(buf_p, " %-10s", "?");
}
}
fprintf(fid, "%s\n", line_buf);
if (cinfo->show_desc) {
fprintf(fid, " %s\n", local_var->desc);
}
}
cinfo->out_count++;
}
}
/* After all vars gotten from driver, check if any missed from local info */
static void
wl_iov_check_ui_not_driver(FILE *fid, struct iov_control_info *cinfo)
{
int idx, out_idx;
bool first = TRUE;
if (cinfo->ui_not_driver && cinfo->var_found != NULL) {
for (out_idx = idx = 0; idx < wlu_iov_info_count; idx++) {
if (!cinfo->var_found[idx]) {
if (first) {
fprintf(fid, "UI variables not in driver:\n");
first = FALSE;
}
fprintf(fid, "%-25s%s", wlu_iov_info[idx].name,
(++out_idx % 3) ? " " : "\n");
cinfo->out_count++;
}
}
if (out_idx % 3) {
fprintf(fid, "\n");
}
}
}
/*
* IO variable information commands
*/
int
wl_iov_names(void *wl, cmd_t *cmd, char **argv)
{
wlc_iov_trx_t *iov_p;
int idx;
int rv = 0;
struct iov_control_info cinfo; /* XXX: Careful of internal dynamic allocation */
UNUSED_PARAMETER(cmd);
if (argv[1] == NULL || strcmp(argv[1], "-h") == 0) { /* Print usage */
wl_iov_usage(stderr, argv[0]);
return 0;
}
if (iov_parse_args_alloc(stderr, wl, argv, &cinfo) < 0) {
fprintf(stderr, "Error parsing arguments for command %s\n", argv[0]);
wl_iov_usage(stderr, argv[0]);
return -1;
}
/*
* NOTE: cinfo may contain dynamically allocate memory pointers that
* may require deallocation after this point
*/
show_header(stdout, &cinfo);
do {
/* Get a block of variables into trx_block starting at tot_vars */
/* Put input parameters into ioctl buffer */
int *param_p;
param_p = (int *)(cinfo.trx_block);
/* memcpy might be safer for alignment */
param_p[0] = WLC_IOV_NAME_LEN;
param_p[1] = cinfo.tot_count;
param_p[2] = WLU_IOV_BLOCK_LEN;
if (wl_get(wl, WLC_IOV_BLOCK_GET, (void *)(cinfo.trx_block),
cinfo.trx_block_bytes) < 0) {
fprintf(stderr, "Error on wl_get getting IOV block\n");
rv = -1;
break;
}
/* Search and display variables for matching criteria */
for (idx = 0, iov_p = cinfo.trx_block;
idx < WLU_IOV_BLOCK_LEN && iov_p->name[0] != '\0';
idx++, iov_p++) {
wl_iov_check_show(stdout, iov_p, &cinfo);
}
} while (idx == WLU_IOV_BLOCK_LEN);
wl_iov_check_ui_not_driver(stdout, &cinfo);
fprintf(stdout, "\n");
if (cinfo.out_count == 0) {
fprintf(stdout, "No matching variables found\n");
}
wl_iov_cleanup(&cinfo);
return rv;
}
/*
* Help command with category support
*/
const char *wl_cmd_category_strings[] = CMD_CATEGORY_STRINGS_INIT;
const int wl_cmd_category_count = ARRAYSIZE(wl_cmd_category_strings);
const char *wl_cmd_category_desc[] = CMD_CATEGORY_DESC_INIT;
/* ASSERT(ARRAYSIZE(wl_cmd_category_desc) == wl_cmd_category_count) */
/* If fewer than this many cmds are to be displayed, show full usage */
#define HELP_DESC_MAX 6
static void
wl_help_usage(FILE *fid, char *cmd)
{
int i;
fprintf(fid, "Usage: wl %s [-s <substr>] [<categories>]\n", cmd);
fprintf(fid, " Display commands matching substr in any of the given categories\n");
/* Note that -g (grep) is a synonym for -s */
fprintf(fid, "Command categories include (use lower case to specify):\n");
for (i = 0; i < wl_cmd_category_count; i++) {
fprintf(fid, " %-8s %s\n", wl_cmd_category_strings[i], wl_cmd_category_desc[i]);
}
}
static unsigned int
cat_str_to_flag(char *val)
{
int idx;
int len, match_len;
if (val == NULL || *val == '\0') {
return 0;
}
for (idx = 0; idx < wl_cmd_category_count; idx++) {
len = (int)strlen(val);
match_len = len < 3 ? 3 : len;
if (len > (int)strlen(wl_cmd_category_strings[idx])) {
continue;
}
if (strncmp(val, wl_cmd_category_strings[idx], match_len) == 0) {
return (1 << idx);
}
}
fprintf(stderr, "Unrecognized command category: %s\n", val);
return 0;
}
static int
wl_cmd_count(unsigned int cats, const char *substr)
{
int count = 0;
int i;
for (i = 0; i < (int)NUM_ELS(cmd2cat); i++) {
if ((cmd2cat[i].cat & cats) != 0) {
if (substr == NULL || strstr(cmd2cat[i].name, substr) != NULL) {
count++;
}
}
}
return count;
}
static void
print_cmds(unsigned int cats, const char *substr, int show_desc)
{
char buf[160], *bufp;
int count;
cmd_t *cmd_loop;
uint32 cmd_cat;
bufp = buf;
count = 0;
*bufp = '\0';
for (cmd_loop = wl_cmds; cmd_loop->name; cmd_loop++) {
cmd_cat = cmd_cat_get(cmd_loop->name);
if ((cmd_cat & cats) != 0) {
if (substr == NULL || strstr(cmd_loop->name, substr) != NULL) {
if (show_desc) {
wl_cmd_usage(stdout, cmd_loop);
} else {
bufp += sprintf(bufp, "%-18s ", cmd_loop->name);
count++;
if (count == 4) {
printf("%s\n", buf);
count = 0;
bufp = buf;
}
}
}
}
}
if (!show_desc && count > 0) {
printf("%s\n", buf);
}
}
int
wl_cmd_help(void *wl, cmd_t *cmd_in, char **argv)
{
char *substr = NULL;
int argv_idx = 1;
unsigned int cats = 0, flag;
int count;
UNUSED_PARAMETER(wl);
UNUSED_PARAMETER(cmd_in);
if (argv[1] == NULL || strcmp(argv[1], "-h") == 0) { /* Print usage */
wl_help_usage(stderr, argv[0]);
return 0;
}
if (strcmp(argv[1], "-s") == 0 || strcmp(argv[1], "-g") == 0) {
if (argv[2] == NULL) {
argv_idx = 2;
} else {
substr = argv[2];
argv_idx = 3;
}
}
while (argv[argv_idx] != NULL) {
if ((flag = cat_str_to_flag(argv[argv_idx++])) == 0) {
return -1;
}
cats |= flag;
}
if (cats == 0) {
cats = CMD_ALL;
}
count = wl_cmd_count(cats, substr);
if (count == 0) {
printf("No matching commands\n");
} else {
print_cmds(cats, substr, count <= HELP_DESC_MAX);
}
return 0;
}
#endif /* BCMINTERNAL */

141
external/cache/sources/wl/wl/wlu_cmd.h vendored Normal file
View File

@@ -0,0 +1,141 @@
/*
* Command structure for wl command line utility
*
* Copyright 2002, Broadcom Corporation
* All Rights Reserved.
*
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation;
* the contents of this file may not be disclosed to third parties, copied or
* duplicated in any form, in whole or in part, without the prior written
* permission of Broadcom Corporation.
*
* $Id: wlu_cmd.h 307762 2012-01-12 14:31:36Z srihemam $
*/
#ifndef _wlu_cmd_h_
#define _wlu_cmd_h_
typedef struct cmd cmd_t;
typedef int (cmd_func_t)(void *wl, cmd_t *cmd, char **argv);
/* generic command line argument handler */
struct cmd {
const char *name;
cmd_func_t *func;
int get;
int set;
const char *help;
};
/* list of command line arguments */
extern cmd_t wl_cmds[];
extern cmd_t wl_varcmd;
/* per-port ioctl handlers */
extern int wl_get(void *wl, int cmd, void *buf, int len);
extern int wl_set(void *wl, int cmd, void *buf, int len);
/*
* Flags for command categories. A command may belong to
* multiple categories. These are used in bitmaps, so be careful
* to keep the macro value (2 ^ n) and the array indexes (n)
* consistent.
*/
#define CMD_PHY 0x1
#define CMD_CHAN 0x2
#define CMD_RATE 0x4
#define CMD_POWER 0x8
#define CMD_MAC 0x10
#define CMD_MGMT 0x20
#define CMD_SEC 0x40
#define CMD_WME 0x80
#define CMD_MON 0x100
#define CMD_AP 0x200
#define CMD_STA 0x400
#define CMD_BOARD 0x800
#define CMD_ADMIN 0x1000
#define CMD_DEV 0x2000
#define CMD_DEP 0x4000
#define CMD_UNCAT 0x8000
#define CMD_ALL 0xffff
/* Initializer for category string array */
#define CMD_CATEGORY_STRINGS_INIT { \
"phy", \
"chan", \
"rate", \
"power", \
"mac", \
"mgmt", \
"sec", \
"wme", \
"mon", \
"ap", \
"sta", \
"board", \
"admin", \
"dev", \
"dep", \
"uncat", \
"" }
extern const char *wl_cmd_category_strings[];
extern const int wl_cmd_category_count;
/* Initializer for category description strings array */
#define CMD_CATEGORY_DESC_INIT { \
"PHY and radio; speed, band, etc", \
"Channel; subclass of phy", \
"Rate; subclass of phy, a/b/g", \
"Power; subclass of phy", \
"MAC; Media access", \
"Management, association, IE, etc", \
"Security; subclass of mgmt", \
"WME; media extensions", \
"Monitoring device (counters, etc)", \
"AP subclass of mgmt", \
"STA subclass of mgmt", \
"Board, hardware", \
"Administration; software, UI, diags", \
"Device; low level control", \
"Deprecated", \
"Uncategorized so far", \
"" }
extern const char *wl_cmd_category_desc[];
/*
*
* IO variable information
*
*/
/* Supplemental IO variable info structure */
typedef const struct wlu_iov_info_s {
const char *name;
uint32 cat; /* Category flags; same as command categories */
uint32 flags; /* See below */
int dflt; /* Only for integers; see flags */
const char *desc; /* Description */
} wlu_iov_info_t;
/* Flags for wlu_iov_info_t */
#define WLU_IOVI_READ_ONLY 0x1 /* Known to be read only */
#define WLU_IOVI_WRITE_ONLY 0x2 /* Known to be write only */
#define WLU_IOVI_BCM_INTERNAL 0x4 /* Known to be BCM internal */
#define WLU_IOVI_DEFAULT_VALID 0x8 /* Default value in structure is valid */
extern wlu_iov_info_t wlu_iov_info[];
extern int wlu_iov_info_count;
#define WLU_IOV_BLOCK_LEN 10
#define WLU_MOD_NAME_MAX 16
#define WLU_MOD_NAME_BYTES 16
extern int wl_get_scan(void *wl, int opc, char *scan_buf, uint buf_len);
#endif /* _wlu_cmd_h_ */

View File

@@ -0,0 +1,307 @@
/*
* Common code for wl routines
*
* $Copyright (C) 2002-2005 Broadcom Corporation$
*
* $Id: wlu_common.c 288685 2011-10-08 00:50:34Z pgarg $
*/
#ifdef WIN32
#include <windows.h>
#endif
#include "wlu_common.h"
#include "wlu.h"
#include <bcmendian.h>
extern int wl_get(void *wl, int cmd, void *buf, int len);
extern int wl_set(void *wl, int cmd, void *buf, int len);
wl_cmd_list_t cmd_list;
int cmd_pkt_list_num;
bool cmd_batching_mode;
const char *wlu_av0;
#ifdef SERDOWNLOAD
extern int debug;
#endif
#ifdef ATE_BUILD
int wlu_iovar_get(void *wl, const char *iovar, void *outbuf, int len);
int wlu_get(void *wl, int cmd, void *cmdbuf, int len);
int wlu_set(void *wl, int cmd, void *cmdbuf, int len);
int add_one_batched_cmd(int cmd, void *cmdbuf, int len);
int wlu_iovar_setint(void *wl, const char *iovar, int val);
int wlu_iovar_set(void *wl, const char *iovar, void *param, int paramlen);
#endif /* ATE_BUILD */
/*
* format an iovar buffer
* iovar name is converted to lower case
*/
static uint
wl_iovar_mkbuf(const char *name, char *data, uint datalen, char *iovar_buf, uint buflen, int *perr)
{
uint iovar_len;
char *p;
iovar_len = strlen(name) + 1;
/* check for overflow */
if ((iovar_len + datalen) > buflen) {
*perr = BCME_BUFTOOSHORT;
return 0;
}
/* copy data to the buffer past the end of the iovar name string */
if (datalen > 0)
memmove(&iovar_buf[iovar_len], data, datalen);
/* copy the name to the beginning of the buffer */
strcpy(iovar_buf, name);
/* wl command line automatically converts iovar names to lower case for
* ease of use
*/
p = iovar_buf;
while (*p != '\0') {
*p = tolower((int)*p);
p++;
}
*perr = 0;
return (iovar_len + datalen);
}
void
init_cmd_batchingmode(void)
{
cmd_pkt_list_num = 0;
cmd_batching_mode = FALSE;
}
void
clean_up_cmd_list(void)
{
wl_seq_cmd_pkt_t *this_cmd, *next_cmd;
this_cmd = cmd_list.head;
while (this_cmd != NULL) {
next_cmd = this_cmd->next;
if (this_cmd->data != NULL) {
free(this_cmd->data);
}
free(this_cmd);
this_cmd = next_cmd;
}
cmd_list.head = NULL;
cmd_list.tail = NULL;
cmd_pkt_list_num = 0;
}
int
add_one_batched_cmd(int cmd, void *cmdbuf, int len)
{
wl_seq_cmd_pkt_t *new_cmd;
new_cmd = malloc(sizeof(wl_seq_cmd_pkt_t));
if (new_cmd == NULL) {
printf("malloc(%d) failed, free %d batched commands and exit batching mode\n",
(int)sizeof(wl_seq_cmd_pkt_t), cmd_pkt_list_num);
goto free_and_exit;
} else {
#ifdef SERDOWNLOAD
if (debug)
#endif /* SERDOWNLOAD */
printf("batching %dth command %d\n", cmd_pkt_list_num+1, cmd);
}
new_cmd->cmd_header.cmd = cmd;
new_cmd->cmd_header.len = len;
new_cmd->next = NULL;
new_cmd->data = malloc(len);
if (new_cmd->data == NULL) {
printf("malloc(%d) failed, free %d batched commands and exit batching mode\n",
len, cmd_pkt_list_num);
free(new_cmd);
goto free_and_exit;
}
memcpy(new_cmd->data, cmdbuf, len);
if (cmd_list.tail != NULL)
cmd_list.tail->next = new_cmd;
else
cmd_list.head = new_cmd;
cmd_list.tail = new_cmd;
cmd_pkt_list_num ++;
return 0;
free_and_exit:
clean_up_cmd_list();
if (cmd_batching_mode) {
cmd_batching_mode = FALSE;
}
else {
printf("calling add_one_batched_cmd() at non-command-batching mode, weird\n");
}
return -1;
}
#ifndef ATE_BUILD
int
wlu_get_req_buflen(int cmd, void *cmdbuf, int len)
{
int modified_len = len;
char *cmdstr = (char *)cmdbuf;
if (len == WLC_IOCTL_MAXLEN) {
if ((strcmp(cmdstr, "dump") == 0) ||
(cmd == WLC_SCAN_RESULTS))
modified_len = WLC_IOCTL_MAXLEN;
else
modified_len = WLC_IOCTL_MEDLEN;
}
return modified_len;
}
#endif /* !ATE_BUILD */
/* now IOCTL GET commands shall call wlu_get() instead of wl_get() so that the commands
* can be batched when needed
*/
int
wlu_get(void *wl, int cmd, void *cmdbuf, int len)
{
if (cmd_batching_mode) {
if (!WL_SEQ_CMDS_GET_IOCTL_FILTER(cmd)) {
printf("IOCTL GET command %d is not supported in batching mode\n", cmd);
return IOCTL_ERROR;
}
}
return wl_get(wl, cmd, cmdbuf, len);
}
/* now IOCTL SET commands shall call wlu_set() instead of wl_set() so that the commands
* can be batched when needed
*/
int
wlu_set(void *wl, int cmd, void *cmdbuf, int len)
{
if (cmd_batching_mode) {
return add_one_batched_cmd(cmd, cmdbuf, len);
}
else {
return wl_set(wl, cmd, cmdbuf, len);
}
}
/*
* get named iovar providing both parameter and i/o buffers
* iovar name is converted to lower case
*/
int
wlu_iovar_getbuf(void* wl, const char *iovar,
void *param, int paramlen, void *bufptr, int buflen)
{
int err;
wl_iovar_mkbuf(iovar, param, paramlen, bufptr, buflen, &err);
if (err)
return err;
return wlu_get(wl, WLC_GET_VAR, bufptr, buflen);
}
/*
* set named iovar providing both parameter and i/o buffers
* iovar name is converted to lower case
*/
int
wlu_iovar_setbuf(void* wl, const char *iovar,
void *param, int paramlen, void *bufptr, int buflen)
{
int err;
int iolen;
iolen = wl_iovar_mkbuf(iovar, param, paramlen, bufptr, buflen, &err);
if (err)
return err;
return wlu_set(wl, WLC_SET_VAR, bufptr, iolen);
}
/*
* get named iovar without parameters into a given buffer
* iovar name is converted to lower case
*/
int
wlu_iovar_get(void *wl, const char *iovar, void *outbuf, int len)
{
char smbuf[WLC_IOCTL_SMLEN];
int err;
/* use the return buffer if it is bigger than what we have on the stack */
if (len > (int)sizeof(smbuf)) {
err = wlu_iovar_getbuf(wl, iovar, NULL, 0, outbuf, len);
} else {
memset(smbuf, 0, sizeof(smbuf));
err = wlu_iovar_getbuf(wl, iovar, NULL, 0, smbuf, sizeof(smbuf));
if (err == 0)
memcpy(outbuf, smbuf, len);
}
return err;
}
/*
* set named iovar given the parameter buffer
* iovar name is converted to lower case
*/
int
wlu_iovar_set(void *wl, const char *iovar, void *param, int paramlen)
{
char smbuf[WLC_IOCTL_SMLEN*2];
memset(smbuf, 0, sizeof(smbuf));
return wlu_iovar_setbuf(wl, iovar, param, paramlen, smbuf, sizeof(smbuf));
}
/*
* get named iovar as an integer value
* iovar name is converted to lower case
*/
int
wlu_iovar_getint(void *wl, const char *iovar, int *pval)
{
int ret;
ret = wlu_iovar_get(wl, iovar, pval, sizeof(int));
if (ret >= 0)
{
*pval = dtoh32(*pval);
}
return ret;
}
/*
* set named iovar given an integer parameter
* iovar name is converted to lower case
*/
int
wlu_iovar_setint(void *wl, const char *iovar, int val)
{
val = htod32(val);
return wlu_iovar_set(wl, iovar, &val, sizeof(int));
}

View File

@@ -0,0 +1,132 @@
/*
* Common code for wl routines
*
* $Copyright (C) 2002-2005 Broadcom Corporation$
*
* $Id: wlu_common.h 370210 2012-11-21 05:35:27Z nisar $
*/
#include <wlioctl.h>
#include <bcmutils.h>
#if defined(_CFE_)
#include <lib_types.h>
#include <lib_string.h>
#include <lib_printf.h>
#include <lib_malloc.h>
#include <cfe_error.h>
#elif defined(__IOPOS__)
#include <typedefs.h>
#include <bcmstdlib.h>
#include <bcmutils.h>
#else
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <assert.h>
#endif /* defined(_CFE_) */
#if defined (__NetBSD__) || defined(linux) || defined(MACOSX) || defined(EFI)
#define stricmp strcasecmp
#define strnicmp strncasecmp
#elif defined(vxworks) || defined(__ECOS)
extern int stricmp(const char *s1, const char *s2);
extern int strnicmp(const char *s1, const char *s2, size_t len);
#elif defined(UNDER_CE) || defined(_CRT_SECURE_NO_DEPRECATE)
#define stricmp _stricmp
#define strnicmp _strnicmp
#elif defined(_HNDRTE_)
#define stricmp strcmp
#define strnicmp strncmp
#elif defined(_CFE_)
#include <bcmutils.h>
#include <osl.h>
#define isalnum(c) bcm_isalnum(c)
#define isalpha(c) bcm_isalpha(c)
#define iscntrl(c) bcm_iscntrl(c)
#define isdigit(c) bcm_isdigit(c)
#define isgraph(c) bcm_isgraph(c)
#define islower(c) bcm_islower(c)
#define isprint(c) bcm_isprint(c)
#define ispunct(c) bcm_ispunct(c)
#define isspace(c) bcm_isspace(c)
#define isupper(c) bcm_isupper(c)
#define isxdigit(c) bcm_isxdigit(c)
#define stricmp(s1, s2) lib_strcmpi((s1), (s2))
#define strtoul(nptr, endptr, base) bcm_strtoul((nptr), (endptr), (base))
#define tolower(c) (bcm_isupper((c)) ? ((c) + 'a' - 'A') : (c))
#define fprintf(stream, fmt, args...) xprintf(fmt, ##args)
#define fputs(s, stream) puts(s)
#define malloc(size) KMALLOC((size), 0)
#define free(ptr) KFREE(ptr)
/* XXX Buggy implementations */
#define strnicmp(s1, s2, len) strncmp((s1), (s2), (len))
#define strspn(s, accept) (0)
#define strtol(nptr, endptr, base) bcm_strtoul((nptr), (endptr), (base))
#elif defined(__IOPOS__)
#define fprintf(file, fmt, arg...) jtag_printf(fmt, ##arg)
#define fputs(s, stream) jtag_puts(s)
#define printf jtag_printf
#define stricmp strcmp
#define strnicmp strncmp
#define strtol(nptr, endptr, base) ((long)strtoul((nptr), (endptr), (base)))
#define tolower(c) bcm_tolower(c)
#define toupper(c) bcm_toupper(c)
#define islower(c) bcm_islower(c)
#define isprint(c) bcm_isprint(c)
#define isspace(c) bcm_isspace(c)
#define isupper(c) bcm_isupper(c)
#define isxdigit(c) bcm_isxdigit(c)
#define isdigit(c) bcm_isdigit(c)
#elif defined(BWL_STRICMP)
#define stricmp bcmstricmp
#define strnicmp bcmstrnicmp
#endif /* __NetBSD__ */
/* IOCTL swapping mode for Big Endian host with Little Endian dongle. Default to off */
/* The below macros handle endian mis-matches between wl utility and wl driver. */
static bool g_swap = FALSE;
#define htod64(i) (g_swap?bcmswap64(i):(uint64)(i))
#define htod32(i) (g_swap?bcmswap32(i):(uint32)(i))
#define htod16(i) (g_swap?bcmswap16(i):(uint16)(i))
#define dtoh64(i) (g_swap?bcmswap64(i):(uint64)(i))
#define dtoh32(i) (g_swap?bcmswap32(i):(uint32)(i))
#define dtoh16(i) (g_swap?bcmswap16(i):(uint16)(i))
#define htodchanspec(i) (g_swap?htod16(i):i)
#define dtohchanspec(i) (g_swap?dtoh16(i):i)
#define htodenum(i) (g_swap?((sizeof(i) == 4) ? htod32(i) : ((sizeof(i) == 2) ? htod16(i) : i)):i)
#define dtohenum(i) (g_swap?((sizeof(i) == 4) ? dtoh32(i) : ((sizeof(i) == 2) ? htod16(i) : i)):i)
/* command batching data structure */
typedef struct wl_seq_cmd_pkt {
struct wl_seq_cmd_pkt *next;
wl_seq_cmd_ioctl_t cmd_header;
char * data; /* user buffer */
} wl_seq_cmd_pkt_t;
typedef struct wl_cmd_list {
wl_seq_cmd_pkt_t *head;
wl_seq_cmd_pkt_t *tail;
} wl_cmd_list_t;
extern wl_cmd_list_t cmd_list;
extern int cmd_pkt_list_num;
extern bool cmd_batching_mode;
extern int wlu_iovar_getbuf(void* wl, const char *iovar,
void *param, int paramlen, void *bufptr, int buflen);
extern int wlu_iovar_setbuf(void* wl, const char *iovar,
void *param, int paramlen, void *bufptr, int buflen);
extern int wlu_var_setbuf(void *wl, const char *iovar, void *param, int param_len);
extern int wlu_iovar_getint(void *wl, const char *iovar, int *pval);
extern void init_cmd_batchingmode(void);
extern void clean_up_cmd_list(void);
extern int wl_check(void *wl);
extern int add_one_batched_cmd(int cmd, void *cmdbuf, int len);
extern int wlu_get_req_buflen(int cmd, void *cmdbuf, int len);
extern int wlu_get(void *wl, int cmd, void *cmdbuf, int len);
extern int wlu_set(void *wl, int cmd, void *cmdbuf, int len);
extern int wlu_iovar_get(void *wl, const char *iovar, void *outbuf, int len);
extern int wlu_iovar_set(void *wl, const char *iovar, void *param, int paramlen);
extern int wlu_iovar_getint(void *wl, const char *iovar, int *pval);
extern int wlu_iovar_setint(void *wl, const char *iovar, int val);

1594
external/cache/sources/wl/wl/wlu_iov.c vendored Normal file

File diff suppressed because it is too large Load Diff

955
external/cache/sources/wl/wl/wlu_linux.c vendored Normal file
View File

@@ -0,0 +1,955 @@
/*
* Linux port of wl command line utility
*
* $Copyright (C) 2002-2003 Broadcom Corporation$
*
* $Id: wlu_linux.c 394871 2013-04-04 01:14:42Z chihap $
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <ctype.h>
#include <string.h>
#include <errno.h>
#ifndef TARGETENV_android
#include <error.h>
#endif /* TARGETENV_android */
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <proto/ethernet.h>
#include <proto/bcmip.h>
#ifndef TARGETENV_android
typedef u_int64_t u64;
typedef u_int32_t u32;
typedef u_int16_t u16;
typedef u_int8_t u8;
typedef u_int64_t __u64;
typedef u_int32_t __u32;
typedef u_int16_t __u16;
typedef u_int8_t __u8;
#endif /* TARGETENV_android */
#include <linux/sockios.h>
#include <linux/ethtool.h>
#include <signal.h>
#include <typedefs.h>
#include <wlioctl.h>
#include <bcmutils.h>
#include <sys/wait.h>
#include <netdb.h>
#include <netinet/in.h>
#include "wlu.h"
#include <bcmcdc.h>
#include "wlu_remote.h"
#include "wlu_client_shared.h"
#include "wlu_pipe.h"
#include <miniopt.h>
#define DEV_TYPE_LEN 3 /* length for devtype 'wl'/'et' */
#define INTERACTIVE_NUM_ARGS 15
#define INTERACTIVE_MAX_INPUT_LENGTH 512
#define NO_ERROR 0
#define RWL_WIFI_JOIN_DELAY 5
/* Function prototypes */
static cmd_t *wl_find_cmd(char* name);
static int do_interactive(struct ifreq *ifr);
static int wl_do_cmd(struct ifreq *ifr, char **argv);
int process_args(struct ifreq* ifr, char **argv);
extern int g_child_pid;
/* RemoteWL declarations */
int remote_type = NO_REMOTE;
int rwl_os_type = LINUX_OS;
static bool rwl_dut_autodetect = TRUE;
static bool debug = FALSE;
extern char *g_rwl_buf_mac;
extern char* g_rwl_device_name_serial;
unsigned short g_rwl_servport;
char *g_rwl_servIP = NULL;
unsigned short defined_debug = DEBUG_ERR | DEBUG_INFO;
static uint interactive_flag = 0;
extern char *remote_vista_cmds[];
extern char g_rem_ifname[IFNAMSIZ];
static void
syserr(char *s)
{
fprintf(stderr, "%s: ", wlu_av0);
perror(s);
exit(errno);
}
int
wl_ioctl(void *wl, int cmd, void *buf, int len, bool set)
{
struct ifreq *ifr = (struct ifreq *) wl;
wl_ioctl_t ioc;
int ret = 0;
int s;
/* open socket to kernel */
if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
syserr("socket");
/* do it */
ioc.cmd = cmd;
ioc.buf = buf;
ioc.len = len;
ioc.set = set;
ifr->ifr_data = (caddr_t) &ioc;
if ((ret = ioctl(s, SIOCDEVPRIVATE, ifr)) < 0) {
if (cmd != WLC_GET_MAGIC) {
ret = IOCTL_ERROR;
}
}
/* cleanup */
close(s);
return ret;
}
static int
wl_get_dev_type(char *name, void *buf, int len)
{
int s;
int ret;
struct ifreq ifr;
struct ethtool_drvinfo info;
/* open socket to kernel */
if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
syserr("socket");
/* get device type */
memset(&info, 0, sizeof(info));
info.cmd = ETHTOOL_GDRVINFO;
ifr.ifr_data = (caddr_t)&info;
strncpy(ifr.ifr_name, name, IFNAMSIZ);
if ((ret = ioctl(s, SIOCETHTOOL, &ifr)) < 0) {
/* print a good diagnostic if not superuser */
if (errno == EPERM)
syserr("wl_get_dev_type");
*(char *)buf = '\0';
} else {
strncpy(buf, info.driver, len);
}
close(s);
return ret;
}
static int
wl_find(struct ifreq *ifr)
{
char proc_net_dev[] = "/proc/net/dev";
FILE *fp;
char buf[1000], *c, *name;
char dev_type[DEV_TYPE_LEN];
int status;
ifr->ifr_name[0] = '\0';
if (!(fp = fopen(proc_net_dev, "r")))
return BCME_ERROR;
/* eat first two lines */
if (!fgets(buf, sizeof(buf), fp) ||
!fgets(buf, sizeof(buf), fp)) {
fclose(fp);
return BCME_ERROR;
}
while (fgets(buf, sizeof(buf), fp)) {
c = buf;
while (isspace(*c))
c++;
if (!(name = strsep(&c, ":")))
continue;
strncpy(ifr->ifr_name, name, IFNAMSIZ);
if (wl_get_dev_type(name, dev_type, DEV_TYPE_LEN) >= 0 &&
!strncmp(dev_type, "wl", 2))
if (wl_check((void *) ifr) == 0)
break;
ifr->ifr_name[0] = '\0';
}
if (ifr->ifr_name[0] == '\0')
status = BCME_ERROR;
else
status = BCME_OK;
fclose(fp);
return status;
}
static int
ioctl_queryinformation_fe(void *wl, int cmd, void* input_buf, unsigned long *input_len)
{
int error = NO_ERROR;
if (remote_type == NO_REMOTE) {
error = wl_ioctl(wl, cmd, input_buf, *input_len, FALSE);
} else {
error = rwl_queryinformation_fe(wl, cmd, input_buf,
input_len, 0, REMOTE_GET_IOCTL);
}
return error;
}
static int
ioctl_setinformation_fe(void *wl, int cmd, void* buf, unsigned long *input_len)
{
int error = 0;
if (remote_type == NO_REMOTE) {
error = wl_ioctl(wl, cmd, buf, *input_len, TRUE);
} else {
error = rwl_setinformation_fe(wl, cmd, buf,
input_len, 0, REMOTE_SET_IOCTL);
}
return error;
}
int
wl_get(void *wl, int cmd, void *buf, int len)
{
int error = 0;
unsigned long input_len = len;
if ((rwl_os_type == WIN32_OS || rwl_os_type == WINVISTA_OS) && remote_type != NO_REMOTE)
cmd += WL_OID_BASE;
error = (int)ioctl_queryinformation_fe(wl, cmd, buf, &input_len);
if (error == SERIAL_PORT_ERR)
return SERIAL_PORT_ERR;
else if (error == BCME_NODEVICE)
return BCME_NODEVICE;
else if (error != 0)
return IOCTL_ERROR;
return 0;
}
int
wl_set(void *wl, int cmd, void *buf, int len)
{
int error = 0;
unsigned long input_len = len;
if ((rwl_os_type == WIN32_OS || rwl_os_type == WINVISTA_OS) && remote_type != NO_REMOTE)
cmd += WL_OID_BASE;
error = (int)ioctl_setinformation_fe(wl, cmd, buf, &input_len);
if (error == SERIAL_PORT_ERR)
return SERIAL_PORT_ERR;
else if (error == BCME_NODEVICE)
return BCME_NODEVICE;
else if (error != 0)
return IOCTL_ERROR;
return 0;
}
#if defined(WLMSO)
int wl_os_type_get_rwl()
{
return rwl_os_type;
}
void wl_os_type_set_rwl(int os_type)
{
rwl_os_type = os_type;
}
int wl_ir_init_rwl(void **irh)
{
switch (rwl_get_remote_type()) {
case NO_REMOTE:
case REMOTE_WIFI: {
struct ifreq *ifr;
ifr = malloc(sizeof(struct ifreq));
if (ifr) {
memset(ifr, 0, sizeof(ifr));
wl_find(ifr);
}
*irh = ifr;
}
break;
default:
break;
}
return 0;
}
void wl_close_rwl(int remote_type, void *irh)
{
switch (remote_type) {
case NO_REMOTE:
case REMOTE_WIFI:
free(irh);
break;
default:
break;
}
}
#define LINUX_NUM_ARGS 16
static int
buf_to_args(char *tmp, char *new_args[])
{
char line[INTERACTIVE_MAX_INPUT_LENGTH];
char *token;
int argc = 0;
if (strlen(tmp) >= INTERACTIVE_MAX_INPUT_LENGTH) {
printf("wl:error: Input string too long; must be < %d bytes\n",
INTERACTIVE_MAX_INPUT_LENGTH);
return 0;
}
strcpy(line, tmp);
while (argc < (LINUX_NUM_ARGS - 1) &&
(token = strtok(argc ? NULL : line, " \t")) != NULL) {
new_args[argc] = malloc(strlen(token)+1);
strncpy(new_args[argc], token, strlen(token)+1);
argc++;
}
new_args[argc] = NULL;
if (argc == (LINUX_NUM_ARGS - 1) && (token = strtok(NULL, " \t")) != NULL) {
printf("wl:error: too many args; argc must be < %d\n",
(LINUX_NUM_ARGS - 1));
argc = LINUX_NUM_ARGS;
}
return argc;
}
int
wl_lib(char *input_str)
{
struct ifreq ifr;
char *ifname = NULL;
int err = 0;
int help = 0;
int status = CMD_WL;
void* serialHandle = NULL;
char *tmp_argv[LINUX_NUM_ARGS];
char **argv = tmp_argv;
int argc;
/* buf_to_args return 0 if no args or string too long
* or return NDIS_NUM_ARGS if too many args
*/
if (((argc = buf_to_args(input_str, argv)) == 0) || (argc == LINUX_NUM_ARGS)) {
printf("wl:error: can't convert input string\n");
return (-1);
}
#else
/* Main client function */
int
main(int argc, char **argv)
{
struct ifreq ifr;
char *ifname = NULL;
int err = 0;
int help = 0;
int status = CMD_WL;
#if defined (RWL_DONGLE) || (RWL_SERIAL)
void* serialHandle = NULL;
#endif
#endif /* WLMSO */
wlu_av0 = argv[0];
wlu_init();
memset(&ifr, 0, sizeof(ifr));
(void)*argv++;
if ((status = wl_option(&argv, &ifname, &help)) == CMD_OPT) {
if (ifname)
strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
/* Bug fix: If -h is used as an option, the above function call
* will notice it and raise the flag but it won't be processed
* in this function so we undo the argv increment so that the -h
* can be spotted by the next call of wl_option. This will ensure
* that wl -h [cmd] will function as desired.
*/
else if (help)
(void)*argv--;
}
/* Linux client looking for a indongle reflector */
if (*argv && strncmp (*argv, "--indongle", strlen(*argv)) == 0) {
rwl_dut_autodetect = FALSE;
(void)*argv++;
}
/* Linux client looking for a WinVista server */
if (*argv && strncmp (*argv, "--vista", strlen(*argv)) == 0) {
rwl_os_type = WINVISTA_OS;
rwl_dut_autodetect = FALSE;
(void)*argv++;
}
/* Provide option for disabling remote DUT autodetect */
if (*argv && strncmp(*argv, "--nodetect", strlen(*argv)) == 0) {
rwl_dut_autodetect = FALSE;
argv++;
}
if (*argv && strncmp (*argv, "--debug", strlen(*argv)) == 0) {
debug = TRUE;
argv++;
}
/* RWL socket transport Usage: --socket ipaddr/hostname [port num] */
if (*argv && strncmp (*argv, "--socket", strlen(*argv)) == 0) {
(void)*argv++;
remote_type = REMOTE_SOCKET;
if (!(*argv)) {
rwl_usage(remote_type);
return err;
}
/* IP address validation is done in client_shared file */
g_rwl_servIP = *argv;
(void)*argv++;
g_rwl_servport = DEFAULT_SERVER_PORT;
if ((*argv) && isdigit(**argv)) {
g_rwl_servport = atoi(*argv);
(void)*argv++;
}
}
/* RWL from system serial port on client to uart serial port on server */
/* Usage: --serial /dev/ttyS0 */
if (*argv && strncmp (*argv, "--serial", strlen(*argv)) == 0) {
(void)*argv++;
remote_type = REMOTE_SERIAL;
}
/* RWL from system serial port on client to uart dongle port on server */
/* Usage: --dongle /dev/ttyS0 */
if (*argv && strncmp (*argv, "--dongle", strlen(*argv)) == 0) {
(void)*argv++;
remote_type = REMOTE_DONGLE;
}
#if defined (RWL_SERIAL) || defined (RWL_DONGLE)
if (remote_type == REMOTE_SERIAL || remote_type == REMOTE_DONGLE) {
if (!(*argv)) {
rwl_usage(remote_type);
return err;
}
g_rwl_device_name_serial = *argv;
(void)*argv++;
if ((serialHandle = rwl_open_pipe(remote_type, g_rwl_device_name_serial, 0, 0))
== NULL) {
DPRINT_ERR(ERR, "serial device open error\r\n");
return -1;
}
ifr = (*(struct ifreq *)serialHandle);
}
#endif /* RWL_SERIAL */
/* RWL over wifi. Usage: --wifi mac_address */
if (*argv && strncmp (*argv, "--wifi", strlen(*argv)) == 0) {
(void)*argv++;
/* use default interface */
if (!*ifr.ifr_name)
wl_find(&ifr);
/* validate the interface */
if (!*ifr.ifr_name || (err = wl_check((void *)&ifr)) < 0) {
fprintf(stderr, "%s: wl driver adapter not found\n", wlu_av0);
exit(1);
}
remote_type = REMOTE_WIFI;
if (argc < 4) {
rwl_usage(remote_type);
return err;
}
/* copy server mac address to local buffer for later use by findserver cmd */
if (!wl_ether_atoe(*argv, (struct ether_addr *)g_rwl_buf_mac)) {
fprintf(stderr,
"could not parse as an ethternet MAC address\n");
return FAIL;
}
(void)*argv++;
}
if ((*argv) && (strlen(*argv) > 2) &&
(strncmp(*argv, "--interactive", strlen(*argv)) == 0)) {
interactive_flag = 1;
}
/* Process for local wl */
if (remote_type == NO_REMOTE) {
if (interactive_flag == 1)
(void)*argv--;
err = process_args(&ifr, argv);
return err;
} else {
#ifndef OLYMPIC_RWL
/* Autodetect remote DUT */
if (rwl_dut_autodetect == TRUE)
rwl_detect((void*)&ifr, debug, &rwl_os_type);
#endif /* OLYMPIC_RWL */
}
/* RWL client needs to initialize ioctl_version */
if (wl_check((void *)&ifr) != 0) {
fprintf(stderr, "%s: wl driver adapter not found\n", wlu_av0);
exit(1);
}
if (interactive_flag == 1) {
err = do_interactive(&ifr);
return err;
}
if ((*argv) && (interactive_flag == 0)) {
err = process_args(&ifr, argv);
if ((err == SERIAL_PORT_ERR) && (remote_type == REMOTE_DONGLE)) {
DPRINT_ERR(ERR, "\n Retry again\n");
err = process_args((struct ifreq*)&ifr, argv);
}
return err;
}
rwl_usage(remote_type);
#if defined (RWL_DONGLE) || (RWL_SERIAL)
if (remote_type == REMOTE_DONGLE || remote_type == REMOTE_SERIAL)
rwl_close_pipe(remote_type, (void*)&ifr);
#endif /* RWL_DONGLE || RWL_SERIAL */
return err;
}
/*
* Function called for 'local' execution and for 'remote' non-interactive session
* (shell cmd, wl cmd)
*/
int
process_args(struct ifreq* ifr, char **argv)
{
char *ifname = NULL;
int help = 0;
int status = 0;
int vista_cmd_index;
int err = 0;
cmd_t *cmd = NULL;
#ifdef RWL_WIFI
int retry;
#endif
while (*argv) {
if ((strcmp (*argv, "sh") == 0) && (remote_type != NO_REMOTE)) {
(void)*argv++; /* Get the shell command */
if (*argv) {
/* Register handler in case of shell command only */
err = rwl_shell_cmd_proc((void*)ifr, argv, SHELL_CMD);
} else {
DPRINT_ERR(ERR, "Enter the shell "
"command, e.g. ls(Linux) or dir(Win CE)\n");
err = -1;
}
return err;
}
#ifdef RWLASD
if ((strcmp (*argv, "asd") == 0) && (remote_type != NO_REMOTE)) {
(void)*argv++; /* Get the asd command */
if (*argv) {
err = rwl_shell_cmd_proc((void*)ifr, argv, ASD_CMD);
} else {
DPRINT_ERR(ERR, "Enter the ASD command, e.g. ca_get_version\n");
err = -1;
}
return err;
}
#endif
if (rwl_os_type == WINVISTA_OS) {
for (vista_cmd_index = 0; remote_vista_cmds[vista_cmd_index] &&
strcmp(remote_vista_cmds[vista_cmd_index], *argv);
vista_cmd_index++);
if (remote_vista_cmds[vista_cmd_index] != NULL) {
err = rwl_shell_cmd_proc((void *)ifr, argv, VISTA_CMD);
if ((remote_type == REMOTE_WIFI) && ((!strcmp(*argv, "join")))) {
#ifdef RWL_WIFI
DPRINT_INFO(OUTPUT,
"\nChannel will be synchronized by Findserver\n\n");
sleep(RWL_WIFI_JOIN_DELAY);
for (retry = 0; retry < RWL_WIFI_RETRY; retry++) {
if ((rwl_find_remote_wifi_server(ifr,
&g_rwl_buf_mac[0]) == 0)) {
break;
}
}
#endif /* RWL_WIFI */
}
return err;
}
}
if ((status = wl_option(&argv, &ifname, &help)) == CMD_OPT) {
if (help)
break;
if (ifname) {
if (remote_type == NO_REMOTE) {
strncpy((*ifr).ifr_name, ifname, IFNAMSIZ);
}
else {
strncpy(g_rem_ifname, ifname, IFNAMSIZ);
}
}
continue;
}
/* parse error */
else if (status == CMD_ERR)
break;
if (remote_type == NO_REMOTE) {
/* use default interface */
if (!*(*ifr).ifr_name)
wl_find(ifr);
/* validate the interface */
if (!*(*ifr).ifr_name || (err = wl_check((void *)ifr)) < 0) {
fprintf(stderr, "%s: wl driver adapter not found\n", wlu_av0);
exit(1);
}
if ((strcmp (*argv, "--interactive") == 0) || (interactive_flag == 1)) {
err = do_interactive(ifr);
return err;
}
}
/* search for command */
cmd = wl_find_cmd(*argv);
/* if not found, use default set_var and get_var commands */
if (!cmd) {
cmd = &wl_varcmd;
}
#ifdef RWL_WIFI
if (!strcmp(cmd->name, "findserver")) {
remote_wifi_ser_init_cmds((void *) ifr);
}
#endif /* RWL_WIFI */
/* RWL over Wifi supports 'lchannel' command which lets client
* (ie *this* machine) change channels since normal 'channel' command
* applies to the server (ie target machine)
*/
if (remote_type == REMOTE_WIFI) {
#ifdef RWL_WIFI
if (!strcmp(argv[0], "lchannel")) {
strcpy(argv[0], "channel");
rwl_wifi_swap_remote_type(remote_type);
err = (*cmd->func)((void *) ifr, cmd, argv);
rwl_wifi_swap_remote_type(remote_type);
} else {
err = (*cmd->func)((void *) ifr, cmd, argv);
}
/* After join cmd's gets exeuted on the server side , client needs to know
* the channel on which the server is associated with AP , after delay of
* few seconds client will intiate the scan on diffrent channels by calling
* rwl_find_remote_wifi_server fucntion
*/
if ((!strcmp(cmd->name, "join") || ((!strcmp(cmd->name, "ssid") &&
(*(++argv) != NULL))))) {
DPRINT_INFO(OUTPUT, "\n Findserver is called to synchronize the"
"channel\n\n");
sleep(RWL_WIFI_JOIN_DELAY);
for (retry = 0; retry < RWL_WIFI_RETRY; retry++) {
if ((rwl_find_remote_wifi_server(ifr,
&g_rwl_buf_mac[0]) == 0)) {
break;
}
}
}
#endif /* RWL_WIFI */
} else {
/* do command */
err = (*cmd->func)((void *) ifr, cmd, argv);
}
break;
} /* while loop end */
/* provide for help on a particular command */
if (help && *argv) {
cmd = wl_find_cmd(*argv);
if (cmd) {
wl_cmd_usage(stdout, cmd);
} else {
DPRINT_ERR(ERR, "%s: Unrecognized command \"%s\", type -h for help\n",
wlu_av0, *argv);
}
} else if (!cmd)
wl_usage(stdout, NULL);
else if (err == USAGE_ERROR)
wl_cmd_usage(stderr, cmd);
else if (err == IOCTL_ERROR)
wl_printlasterror((void *) ifr);
else if (err == BCME_NODEVICE)
DPRINT_ERR(ERR, "%s : wl driver adapter not found\n", g_rem_ifname);
return err;
}
/* Function called for 'local' interactive session and for 'remote' interactive session */
static int
do_interactive(struct ifreq *ifr)
{
int err = 0;
#ifdef RWL_WIFI
int retry;
#endif
while (1) {
char *fgsret;
char line[INTERACTIVE_MAX_INPUT_LENGTH];
fprintf(stdout, "> ");
fgsret = fgets(line, sizeof(line), stdin);
/* end of file */
if (fgsret == NULL)
break;
if (line[0] == '\n')
continue;
if (strlen (line) > 0) {
/* skip past first arg if it's "wl" and parse up arguments */
char *argv[INTERACTIVE_NUM_ARGS];
int argc;
char *token;
argc = 0;
while (argc < (INTERACTIVE_NUM_ARGS - 1) &&
(token = strtok(argc ? NULL : line, " \t\n")) != NULL) {
/* Specifically make sure empty arguments (like SSID) are empty */
if (token[0] == '"' && token[1] == '"') {
token[0] = '\0';
}
argv[argc++] = token;
}
argv[argc] = NULL;
if (argc == (INTERACTIVE_NUM_ARGS - 1) &&
(token = strtok(NULL, " \t")) != NULL) {
printf("wl:error: too many args; argc must be < %d\n",
(INTERACTIVE_NUM_ARGS - 1));
continue;
}
#ifdef RWL_WIFI
if (!strcmp(argv[0], "findserver")) {
remote_wifi_ser_init_cmds((void *) ifr);
}
#endif /* RWL_WIFI */
if (strcmp(argv[0], "q") == 0 || strcmp(argv[0], "exit") == 0) {
break;
}
if ((strcmp(argv[0], "sh") == 0) && (remote_type != NO_REMOTE)) {
if (argv[1]) {
process_args(ifr, argv);
} else {
DPRINT_ERR(ERR, "Give shell command");
continue;
}
} else { /* end shell */
/* check for lchannel support,applicable only for wifi transport.
* when lchannel is called remote type is swapped by calling swap_
* remote_type.This is done to change, the remote type to local,
* so that local machine's channel can be executed and
* returned to the user.
* To get back the original remote type, swap is recalled.
*/
if (remote_type == REMOTE_WIFI) {
#ifdef RWL_WIFI
if (!strcmp(argv[0], "lchannel")) {
strcpy(argv[0], "channel");
rwl_wifi_swap_remote_type(remote_type);
err = wl_do_cmd(ifr, argv);
rwl_wifi_swap_remote_type(remote_type);
} else {
err = wl_do_cmd(ifr, argv);
}
/* After join cmd's gets exeuted on the server side, client
* needs to know the channel on which the server is associated
* with AP , after delay of few seconds client will intiate the
* scan on diffrent channels by calling
* rwl_find_remote_wifi_server function
*/
if ((!strcmp(argv[0], "join")) ||
(!strcmp(argv[0], "ssid"))) {
DPRINT_INFO(OUTPUT, "\n Findserver is called"
"after the join issued to remote \n \n");
sleep(RWL_WIFI_JOIN_DELAY);
for (retry = 0; retry < RWL_WIFI_RETRY; retry++) {
if ((rwl_find_remote_wifi_server(ifr,
&g_rwl_buf_mac[0]) == 0)) {
break;
}
}
}
#endif /* RWL_WIFI */
} else {
err = wl_do_cmd(ifr, argv);
}
} /* end of wl */
} /* end of strlen (line) > 0 */
} /* while (1) */
return err;
}
/*
* find command in argv and execute it
* Won't handle changing ifname yet, expects that to happen with the --interactive
* Return an error if unable to find/execute command
*/
static int
wl_do_cmd(struct ifreq *ifr, char **argv)
{
cmd_t *cmd = NULL;
int err = 0;
int help = 0;
char *ifname = NULL;
int status = CMD_WL;
/* skip over 'wl' if it's there */
if (*argv && strcmp (*argv, "wl") == 0) {
argv++;
}
/* handle help or interface name changes */
if (*argv && (status = wl_option (&argv, &ifname, &help)) == CMD_OPT) {
if (ifname) {
fprintf(stderr,
"Interface name change not allowed within --interactive\n");
}
}
/* in case wl_option eats all the args */
if (!*argv) {
return err;
}
if (status != CMD_ERR) {
/* search for command */
cmd = wl_find_cmd(*argv);
/* defaults to using the set_var and get_var commands */
if (!cmd) {
cmd = &wl_varcmd;
}
/* do command */
err = (*cmd->func)((void *)ifr, cmd, argv);
}
/* provide for help on a particular command */
if (help && *argv) {
cmd = wl_find_cmd(*argv);
if (cmd) {
wl_cmd_usage(stdout, cmd);
} else {
DPRINT_ERR(ERR, "%s: Unrecognized command \"%s\", type -h for help\n",
wlu_av0, *argv);
}
} else if (!cmd)
wl_usage(stdout, NULL);
else if (err == USAGE_ERROR)
wl_cmd_usage(stderr, cmd);
else if (err == IOCTL_ERROR)
wl_printlasterror((void *)ifr);
else if (err == BCME_NODEVICE)
DPRINT_ERR(ERR, "%s : wl driver adapter not found\n", g_rem_ifname);
return err;
}
/* Search the wl_cmds table for a matching command name.
* Return the matching command or NULL if no match found.
*/
static cmd_t *
wl_find_cmd(char* name)
{
cmd_t *cmd = NULL;
/* search the wl_cmds for a matching name */
for (cmd = wl_cmds; cmd->name && strcmp(cmd->name, name); cmd++);
if (cmd->name == NULL)
cmd = NULL;
return cmd;
}
void def_handler(int signum)
{
UNUSED_PARAMETER(signum);
kill(g_child_pid, SIGINT);
kill(getpid(), SIGINT);
exit(0);
}
/* Create a child that waits for Ctrl-C at the client side
*/
int rwl_shell_createproc(void *wl)
{
UNUSED_PARAMETER(wl);
signal(SIGINT, ctrlc_handler);
signal(SIGTERM, def_handler);
signal(SIGABRT, def_handler);
return fork();
}
/* In case if the server shell command exits normally
* then kill the thread that was waiting for Ctr-C to happen
* at the client side
*/
void rwl_shell_killproc(int pid)
{
kill(pid, SIGKILL);
signal(SIGINT, SIG_DFL);
wait(NULL);
}
#ifdef RWL_SOCKET
/* to validate hostname/ip given by the client */
int validate_server_address()
{
struct hostent *he;
struct ipv4_addr temp;
if (!wl_atoip(g_rwl_servIP, &temp)) {
/* Wrong IP address format check for hostname */
if ((he = gethostbyname(g_rwl_servIP)) != NULL) {
if (!wl_atoip(*he->h_addr_list, &temp)) {
g_rwl_servIP =
inet_ntoa(*(struct in_addr *)*he->h_addr_list);
if (g_rwl_servIP == NULL) {
DPRINT_ERR(ERR, "Error at inet_ntoa \n");
return FAIL;
}
} else {
DPRINT_ERR(ERR, "Error in IP address \n");
return FAIL;
}
} else {
DPRINT_ERR(ERR, "Enter correct IP address/hostname format\n");
return FAIL;
}
}
return SUCCESS;
}
#endif /* RWL_SOCKET */

1104
external/cache/sources/wl/wl/wlu_pipe.c vendored Normal file

File diff suppressed because it is too large Load Diff

42
external/cache/sources/wl/wl/wlu_pipe.h vendored Normal file
View File

@@ -0,0 +1,42 @@
/*
* OS independent declarations
*
* $Copyright (C) 2008 Broadcom Corporation$
*
* $Id: wlu_pipe.h 287128 2011-09-30 04:27:53Z estucki $
*/
#ifndef _wlu_pipe_h
#define _wlu_pipe_h
/* Function prototypes defined in wlu_pipe.c */
/* Macros to access globals */
extern char *g_rwl_device_name_serial;
#define rwl_get_serial_port_name() (g_rwl_device_name_serial)
#define rwl_set_serial_port_name(name) (g_rwl_device_name_serial = name)
extern char *g_rwl_buf_mac;
#define rwl_get_wifi_mac() (g_rwl_buf_mac)
extern int remote_CDC_tx(void *wl, uint cmd, uchar *buf, uint buf_len,
uint data_len, uint flags, int debug);
extern rem_ioctl_t *remote_CDC_rx_hdr(void *remote, int debug);
extern int remote_CDC_rx(void *wl, rem_ioctl_t *rem_ptr, uchar *readbuf, uint buflen, int debug);
extern void* rwl_open_pipe(int remote_type, char *port, int ReadTotalTimeout, int debug);
extern int rwl_close_pipe(int remote_type, void* hndle);
#ifdef RWL_SOCKET
extern int rwl_sockconnect(int SockDes, struct sockaddr *servAddr, int size);
#endif /* RWL_SOCKET */
extern int remote_CDC_DATA_wifi_rx_frag(void *wl, rem_ioctl_t *rem_ptr, uint input_len,
void *input, bool shell);
extern int remote_CDC_DATA_wifi_rx(void *wl, struct dot11_action_wifi_vendor_specific *rec_frame);
extern int
remote_CDC_wifi_tx(void *wl, uint cmd, uchar *buf, uint buf_len, uint data_len, uint flags);
extern void rwl_wifi_server_response(void *wl, struct dot11_action_wifi_vendor_specific *rec_frame);
extern int rwl_find_remote_wifi_server(void *wl, char *id);
extern void rwl_wifi_purge_actionframes(void *wl);
extern void rwl_wifi_swap_remote_type(int flag);
extern void remote_wifi_ser_init_cmds(void *wl);
#endif /* _wlu_pipe_h */

View File

@@ -0,0 +1,572 @@
/*
* linux version of remote Wl transport mechanisms (pipes).
*
* $Copyright (C) 2008 Broadcom Corporation$
*
* $Id: wlu_pipe_linux.c 281542 2011-09-02 17:31:19Z hharte $
*/
/* Revision History: Linux version of remote Wl transport mechanisms (pipes).
*
* Date Author Description
*
* 27-Dec-2007 Suganthi Version 0.0
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netdb.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <termios.h>
#include <fcntl.h>
#include <proto/802.11.h>
#include <bcmendian.h>
#include <bcmcdc.h>
#include <proto/802.11.h>
#include <wlioctl.h>
#if defined(MACOSX)
#include <netinet/in.h>
#endif
#include <typedefs.h>
#include "wlu_remote.h"
#include <miniopt.h>
#if defined(RWL_DONGLE) || defined(RWL_SERIAL)
#define READ_DELAY 500000
#define BAUD_RATE_115200 115200
#define VMIN_VAL 16
#define VTIME_VAL 50
#define LINUX_SYNC_DELAY 200
extern char *g_rwl_device_name_serial;
#endif
#define MICRO_SEC_CONVERTER_VAL 1000
int g_irh;
int g_shellsync_pid;
#ifdef RWL_SOCKET
#define MAX_INTERFACE_NAME 32
static int
rwl_opensocket(int AddrFamily, int Type, int Protocol)
{
int SockDes;
if ((SockDes = socket(AddrFamily, Type, Protocol)) == -1) {
perror("rwl_opensocket Fails:");
DPRINT_ERR(ERR, "\nerrno:%d\n", errno);
return FAIL;
}
return SockDes;
}
static int
rwl_set_socket_option(int SocketDes, int Level, int OptName, int Val)
{
if (setsockopt(SocketDes, Level, OptName, &Val, sizeof(int)) == -1) {
perror("Error at SetTCPSocketOpt()");
DPRINT_ERR(ERR, "\n errno:%d\n", errno);
return FAIL;
}
return SUCCESS;
}
/* Function to connect with the server waiting in the same port */
int
rwl_connectsocket(int SocketDes, struct sockaddr* SerAddr, int SizeOfAddr)
{
if (connect(SocketDes, SerAddr, SizeOfAddr) == -1) {
perror("Failed to connect() to server");
DPRINT_ERR(ERR, "\n errno:%d\n", errno);
return FAIL;
}
return SUCCESS;
}
/*
* Function for associating a local address with a socket.
*/
int
rwl_bindsocket(int SocketDes, struct sockaddr * MyAddr, int SizeOfAddr)
{
if (bind(SocketDes, MyAddr, SizeOfAddr) == -1) {
perror("Error at rwl_bindSocket()");
DPRINT_ERR(ERR, "\n errno:%d\n", errno);
return FAIL;
}
return SUCCESS;
}
/*
* Function for making the socket to listen for incoming connection.
*/
int
rwl_listensocket(int SocketDes, int BackLog)
{
if (listen(SocketDes, BackLog) == -1) {
perror("Error at rwl_listensocket()");
DPRINT_ERR(ERR, "\n errno:%d\n", errno);
return FAIL;
}
return SUCCESS;
}
/*
* Function for permitting an incoming connection attempt on a socket
* Function called by server
*/
int
rwl_acceptconnection(int SocketDes, struct sockaddr* ClientAddr, int *SizeOfAddr)
{
int NewSockDes;
if ((NewSockDes = accept(SocketDes, ClientAddr, (socklen_t*)SizeOfAddr)) == -1) {
perror("Error at rwl_acceptConnection()");
DPRINT_ERR(ERR, "\n errno:%d\n", errno);
return FAIL;
}
return NewSockDes;
}
static int
rwl_closesocket(int SocketDes)
{
if (close(SocketDes) == -1) {
perror("Error at rwl_closeSocket()");
DPRINT_ERR(ERR, "\n errno:%d\n", errno);
return FAIL;
}
return SUCCESS;
}
/* Transmit the response in the opened TCP stream socket */
int
rwl_send_to_streamsocket(int SocketDes, const char* SendBuff, int data_size, int Flag)
{
int total_numwritten = 0, numwritten = 0;
while (total_numwritten < data_size) {
if ((numwritten = send(SocketDes, SendBuff,
data_size - total_numwritten, Flag)) == -1) {
perror("Failed to send()");
DPRINT_ERR(ERR, "\n errno:%d\n", errno);
return (FAIL);
}
/* Sent successfully at first attempt no more retries */
if (numwritten == data_size) {
total_numwritten = numwritten;
break;
}
/* If socket is busy we may hit this condition */
if (numwritten != data_size - total_numwritten) {
DPRINT_DBG(OUTPUT, "wanted to send %d bytes sent only %d bytes\n",
data_size - total_numwritten, numwritten);
}
/* Now send the remaining buffer */
total_numwritten += numwritten;
SendBuff += numwritten;
}
return total_numwritten;
}
/* Receive the response from the opened TCP stream socket */
int
rwl_receive_from_streamsocket(int SocketDes, char* RecvBuff, int data_size, int Flag)
{
int numread;
int total_numread = 0;
while (total_numread < data_size) {
if ((numread = recv(SocketDes, RecvBuff, data_size - total_numread, Flag)) == -1) {
perror("Failed to Receive()");
DPRINT_ERR(ERR, "\n errno:%d\n", errno);
return FAIL;
}
if (numread != data_size - total_numread) {
DPRINT_DBG(OUTPUT, "asked %d bytes got %d bytes\n",
data_size - total_numread, numread);
}
if (numread == 0)
break;
total_numread += numread;
RecvBuff += numread;
}
return numread;
}
int
rwl_init_server_socket_setup(int argc, char** argv, uint remote_type)
{
char netif[MAX_INTERFACE_NAME];
unsigned short servPort;
struct sockaddr_in ServerAddress;
int err, SockDes, val;
/* Default option */
servPort = DEFAULT_SERVER_PORT;
#ifdef MACOSX
strcpy(netif, "en0");
#else
strcpy(netif, "eth0");
#endif
/* User option can override default arguments */
if (argc == 3) {
argv++;
if (isalpha(**argv) == FALSE) {
DPRINT_ERR(ERR, "USAGE ERROR:Incorrect network interface\n");
return FAIL;
}
strcpy(netif, *argv);
argv++;
if (isdigit(**argv) == FALSE) {
DPRINT_ERR(ERR, "USAGE ERROR:Incorrect port\n");
return FAIL;
}
servPort = atoi(*argv);
}
if (argc == 2) {
argv++;
if (isalpha(**argv) == FALSE) {
if (isdigit(**argv) == FALSE) {
DPRINT_ERR(ERR, "USAGE ERROR\n");
return FAIL;
}
else
servPort = atoi(*argv);
}
else
strcpy(netif, *argv);
}
DPRINT_INFO(OUTPUT, "INFO: Network Interface:%s, Port:%d\n",
netif, servPort);
if ((SockDes = (*(int *)rwl_open_transport(remote_type, NULL, 0, 0))) == FAIL)
return FAIL;
val = 1;
if ((rwl_set_socket_option(SockDes, SOL_SOCKET, SO_REUSEADDR, val)) == FAIL)
return FAIL;
memset(&ServerAddress, 0, sizeof(ServerAddress));
rwl_GetifAddr(netif, &ServerAddress);
ServerAddress.sin_family = AF_INET; /* host byte order */
ServerAddress.sin_port = hton16(servPort); /* short, network byte order */
if (((err = rwl_bindsocket(SockDes, (struct sockaddr *)&ServerAddress,
sizeof(ServerAddress))) == FAIL))
return err;
if ((err = rwl_listensocket(SockDes, BACKLOG)) == FAIL)
return err;
DPRINT_DBG(OUTPUT, "Waiting for client to connect...\n");
return SockDes;
}
int rwl_GetifAddr(char *ifname, struct sockaddr_in *sa)
{
struct ifreq ifr;
int fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
if (fd < 0)
{
DPRINT_ERR(ERR, "socket open error\n");
return FAIL;
}
strcpy(ifr.ifr_name, ifname);
ifr.ifr_addr.sa_family = AF_INET;
if (ioctl(fd, SIOCGIFADDR, &ifr) == 0)
{
memcpy(sa, (struct sockaddr_in *)&ifr.ifr_addr, sizeof(struct sockaddr_in));
}
else
{
return FAIL;
}
close(fd);
return FAIL;
}
#endif /* RWL_SOCKET */
#if defined (RWL_SERIAL) || defined (RWL_DONGLE)
static int
rwl_open_serial(int remote_type, char *port)
{
struct termios tio;
int fCom;
int speed;
long BAUD, DATABITS, STOPBITS, PARITYON;
speed_t baud_rate;
DPRINT_DBG(OUTPUT, "\n rwl_open_serial:%s\n", port);
if (remote_type == REMOTE_DONGLE)
fCom = open(port, O_RDWR | O_NOCTTY | O_NDELAY);
else
fCom = open(port, O_RDWR | O_NOCTTY | O_NDELAY | O_SYNC);
if (fCom < 0) {
DPRINT_ERR(ERR, "open COM failed with error %d.\n", errno);
return fCom;
} else {
/* To make the read as a blocking operation */
fcntl(fCom, F_SETFL, 0);
}
bzero(&tio, sizeof(tio));
/* Get the current option for the port... */
tcgetattr(fCom, &tio);
/* Set the baud rate */
cfsetispeed(&tio, B115200);
cfsetospeed(&tio, B115200);
if (remote_type == REMOTE_DONGLE) {
if (tcsetattr(fCom, TCSANOW, &tio) < 0) {
perror("tcsetattr:setspeed");
return FAIL;
}
baud_rate = cfgetospeed(&tio);
if (baud_rate == B115200)
speed = BAUD_RATE_115200;
DPRINT_DBG(OUTPUT, "Baud_rate set is:%d\n", speed);
BAUD = B115200;
DATABITS = CS8;
STOPBITS = 1;
PARITYON = 0;
tio.c_cflag = BAUD | DATABITS | STOPBITS | PARITYON | CLOCAL | CREAD;
tio.c_iflag = IGNPAR;
tio.c_oflag = 0;
tio.c_lflag = 0;
tio.c_cc[VMIN] = VMIN_VAL;
tio.c_cc[VTIME] = VTIME_VAL;
tcflush(fCom, TCIOFLUSH);
if (tcsetattr(fCom, TCSANOW, &tio) < 0) {
perror("tcsetattr:");
return FAIL;
}
if (tcgetattr(fCom, &tio) < 0) {
perror("tcgetattr:");
return FAIL;
}
DPRINT_DBG(OUTPUT, "tcgetattr:VMIN is:%d\n", tio.c_cc[VMIN]);
DPRINT_DBG(OUTPUT, "tcgetattr:VTIME is:%d\n", tio.c_cc[VTIME]);
tcflush(fCom, TCIOFLUSH);
}
else {
UNUSED_PARAMETER(PARITYON);
UNUSED_PARAMETER(STOPBITS);
UNUSED_PARAMETER(DATABITS);
UNUSED_PARAMETER(BAUD);
UNUSED_PARAMETER(baud_rate);
UNUSED_PARAMETER(speed);
/* Enable the receiver and set local mode */
tio.c_cflag |= (CLOCAL | CREAD);
tio.c_cflag &= ~PARENB;
tio.c_cflag &= ~CSTOPB;
tio.c_cflag &= ~CSIZE;
tio.c_cflag |= CS8;
tio.c_cc[VTIME] = 255;
tio.c_cc[VMIN] = 1;
tio.c_iflag = 0;
tio.c_iflag |= IGNBRK;
tio.c_oflag &= ~OPOST;
tio.c_oflag &= ~OLCUC;
tio.c_oflag &= ~ONLCR;
tio.c_oflag &= ~OCRNL;
tio.c_oflag &= ~ONOCR;
tio.c_oflag &= ~ONLRET;
tio.c_oflag &= ~OFILL;
tio.c_lflag &= ~ICANON;
tio.c_lflag &= ~ISIG;
tio.c_lflag &= ~XCASE;
tio.c_lflag &= ~ECHO;
tio.c_lflag &= ~FLUSHO;
tio.c_lflag &= ~IEXTEN;
tio.c_lflag |= NOFLSH;
/* Set the new tio for the port... */
tcsetattr(fCom, TCSANOW, &tio);
tcflush(fCom, TCIOFLUSH);
}
return (fCom);
}
int
rwl_write_serial_port(void* hndle, char* write_buf, unsigned long size, unsigned long *numwritten)
{
int ret;
ret = write((*(int *)hndle), (const void*)write_buf, size);
*numwritten = ret;
if (ret == -1) {
perror("WriteToPort Failed");
DPRINT_ERR(ERR, "Errno:%d\n", errno);
return FAIL;
}
if (*numwritten != size) {
DPRINT_ERR(ERR, "rwl_write_serial_port failed numwritten %ld != len %ld\n",
*numwritten, size);
return FAIL;
}
return SUCCESS;
}
int
rwl_read_serial_port(void* hndle, char* read_buf, uint data_size, uint *numread)
{
int ret;
uint total_numread = 0;
while (total_numread < data_size) {
ret = read(*(int *)hndle, read_buf, data_size - total_numread);
*numread = ret;
if (ret == -1) {
perror("ReadFromPort Failed");
DPRINT_ERR(ERR, "Errno:%d\n", errno);
return FAIL;
}
if (*numread != data_size - total_numread) {
DPRINT_DBG(OUTPUT, "asked for %d bytes got %d bytes\n",
data_size - total_numread, *numread);
}
if (*numread == 0)
break;
total_numread += *numread;
read_buf += *numread;
}
return SUCCESS;
}
void
rwl_sync_delay(uint noframes)
{
if (noframes > 1) {
rwl_sleep(LINUX_SYNC_DELAY);
}
}
#endif /* RWL_DONGLE ||RWL_SERIAL */
#if defined (RWL_DONGLE) || defined (RWL_SOCKET) || defined(RWL_SERIAL)
void*
rwl_open_transport(int remote_type, char *port, int ReadTotalTimeout, int debug)
{
void* hndle;
UNUSED_PARAMETER(port);
UNUSED_PARAMETER(ReadTotalTimeout);
UNUSED_PARAMETER(debug);
switch (remote_type) {
#if defined(RWL_DONGLE) || defined(RWL_SERIAL)
case REMOTE_SERIAL:
#ifdef RWL_SERIAL
g_rwl_device_name_serial = port;
#endif
case REMOTE_DONGLE:
if ((g_irh = rwl_open_serial(remote_type, g_rwl_device_name_serial))
== FAIL) {
/* Initial port opening settings failed in reboot.
* So retry opening the serial port
*/
if ((g_irh = rwl_open_serial(remote_type, g_rwl_device_name_serial))
== FAIL) {
DPRINT_ERR(ERR, "Can't open serial port\n");
return NULL;
}
}
break;
#endif /* RWL_DONGLE || RWL_SERIAL */
#ifdef RWL_SOCKET
case REMOTE_SOCKET:
if ((g_irh = rwl_opensocket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == FAIL) {
DPRINT_ERR(ERR, "\nCan't open socket \n");
return NULL;
}
break;
#endif /* RWL_SOCKET */
default:
DPRINT_ERR(ERR, "rwl_open_transport: Unknown remote_type %d\n", remote_type);
return NULL;
break;
} /* end - switch case */
hndle = (void*) &g_irh;
return hndle;
}
int
rwl_close_transport(int remote_type, void* Des)
{
switch (remote_type) {
#ifdef RWL_SOCKET
case REMOTE_SOCKET:
if (rwl_closesocket(*(int *)Des) == FAIL)
return FAIL;
break;
#endif /* RWL_SOCKET */
#if defined(RWL_DONGLE) || defined(RWL_SERIAL)
case REMOTE_DONGLE:
case REMOTE_SERIAL:
if (close(*(int *)Des) == -1)
return FAIL;
break;
#endif /* RWL_DONGLE || RWL_SERIAL */
default:
DPRINT_ERR(ERR, "close_pipe: Unknown remote_type %d\n", remote_type);
break;
}
return SUCCESS;
}
#endif /* #if defined (RWL_DONGLE) || defined (RWL_SOCKET) */
void
rwl_sleep(int delay)
{
usleep(delay * MICRO_SEC_CONVERTER_VAL);
}
#if defined(WLMSO)
int
rwl_init_socket(void)
{
return 0;
}
#endif

View File

@@ -0,0 +1,741 @@
/*
* This module does provides various mappings to or from the CLM rate indexes.
*
* $Copyright (C) 2011 Broadcom Corporation$
*/
/*FILE-CSTYLED*/
#include <stdio.h>
#include <typedefs.h>
#include "wlu_rates_matrix.h"
#define CLM_NO_RATE_STRING "NO_RATE"
#define EXP_MODE_UNKNOWN "Unknown expansion mode"
#define AUTO_RATESPEC 0x0
#define MHZ_TO_HALF_MHZ 2
typedef enum exp_mode {
EXP_MODE_ID_DEF = 0,
EXP_MODE_ID_STBC,
EXP_MODE_ID_TXBF,
EXP_MODE_ID_MAX
} exp_mode_t;
#ifdef D11AC_IOTYPES
static reg_rate_index_t get_legacy_reg_rate_index(int rate_hmhz, int tx_expansion, exp_mode_t mode);
static reg_rate_index_t get_ht_reg_rate_index(int mcs, int tx_expansion, exp_mode_t mode);
static reg_rate_index_t get_vht_reg_rate_index(int mcs, int nss, int tx_expansion, exp_mode_t mode);
static int get_legacy_rate_identifier(int rate_hmhz);
static int get_legacy_mode_identifier(int tx_expansion, exp_mode_t mode);
static int get_vht_rate_identifier(int vht_mcs_index);
static int get_vht_ss1_mode_identifier(int tx_expansion, exp_mode_t mode);
static int get_vht_ss2_mode_identifier(int tx_expansion, exp_mode_t mode);
static int get_vht_ss3_mode_identifier(int tx_expansion, exp_mode_t mode);
static const char *get_mode_name(exp_mode_t mode);
#endif
enum {
LEGACY_RATE_ID_NO_RATE = -1,
LEGACY_RATE_ID_1MHZ = 0,
LEGACY_RATE_ID_2MHZ,
LEGACY_RATE_ID_5_5MHZ,
LEGACY_RATE_ID_11MHZ,
LEGACY_RATE_ID_6MHZ,
LEGACY_RATE_ID_9MHZ,
LEGACY_RATE_ID_12MHZ,
LEGACY_RATE_ID_18MHZ,
LEGACY_RATE_ID_24MHZ,
LEGACY_RATE_ID_36MHZ,
LEGACY_RATE_ID_48MHZ,
LEGACY_RATE_ID_54MHZ,
LEGACY_RATE_ID_MAX
};
enum {
LEGACY_MODE_ID_NONE = 0,
LEGACY_MODE_ID_TXEXP1,
LEGACY_MODE_ID_TXEXP2,
LEGACY_MODE_ID_TXBF1,
LEGACY_MODE_ID_TXBF2,
LEGACY_MODE_ID_MAX
};
enum {
VHT_RATE_INDEX_0 = 0,
VHT_RATE_INDEX_1,
VHT_RATE_INDEX_2,
VHT_RATE_INDEX_3,
VHT_RATE_INDEX_4,
VHT_RATE_INDEX_5,
VHT_RATE_INDEX_6,
VHT_RATE_INDEX_7,
VHT_RATE_INDEX_8,
VHT_RATE_INDEX_9,
VHT_RATE_INDEX_MAX
};
enum {
VHT_SS1_MODE_ID_NONE = 0,
VHT_SS1_MODE_ID_CDD1,
VHT_SS1_MODE_ID_STBC,
VHT_SS1_MODE_ID_CDD2,
VHT_SS1_MODE_ID_STBC_SPEXP1,
VHT_SS1_MODE_ID_TXBF1,
VHT_SS1_MODE_ID_TXBF2,
VHT_SS1_MODE_ID_MAX
};
enum {
VHT_SS2_MODE_ID_NONE = 0,
VHT_SS2_MODE_ID_SPEXP1,
VHT_SS2_MODE_ID_TXBF0,
VHT_SS2_MODE_ID_TXBF1,
VHT_SS2_MODE_ID_MAX
};
enum {
VHT_SS3_MODE_ID_NONE = 0,
VHT_SS3_MODE_ID_TXBF0,
VHT_SS3_MODE_ID_MAX
};
const char *clm_rate_group_labels[] = {
"DSSS",
"OFDM",
"MCS0_7",
"VHT8_9SS1",
"DSSS_MULTI1",
"OFDM_CDD1",
"MCS0_7_CDD1",
"VHT8_9SS1_CDD1",
"MCS0_7_STBC",
"VHT8_9SS1_STBC",
"MCS8_15",
"VHT8_9SS2",
"DSSS_MULTI2",
"OFDM_CDD2",
"MCS0_7_CDD2",
"VHT8_9SS1_CDD2",
"MCS0_7_STBC_SPEXP1",
"VHT8_9SS1_STBC_SPEXP1",
"MCS8_15_SPEXP1",
"VHT8_9SS2_SPEXP1",
"MCS16_23",
"VHT8_9SS3",
"OFDM_TXBF1",
"MCS0_7_TXBF1",
"VHT8_9SS1_TXBF1",
"MCS8_15_TXBF0",
"OFDM_TXBF2",
"MCS0_7_TXBF2",
"VHT8_9SS1_TXBF2",
"MCS8_15_TXBF1",
"VHT8_9SS2_TXBF1",
"MCS16_23_TXBF0",
};
const char *clm_rate_labels[] = {
"DSSS1",
"DSSS2",
"DSSS5",
"DSSS11",
"OFDM6",
"OFDM9",
"OFDM12",
"OFDM18",
"OFDM24",
"OFDM36",
"OFDM48",
"OFDM54",
"MCS0",
"MCS1",
"MCS2",
"MCS3",
"MCS4",
"MCS5",
"MCS6",
"MCS7",
"VHT8SS1",
"VHT9SS1",
"DSSS1_MULTI1",
"DSSS2_MULTI1",
"DSSS5_MULTI1",
"DSSS11_MULTI1",
"OFDM6_CDD1",
"OFDM9_CDD1",
"OFDM12_CDD1",
"OFDM18_CDD1",
"OFDM24_CDD1",
"OFDM36_CDD1",
"OFDM48_CDD1",
"OFDM54_CDD1",
"MCS0_CDD1",
"MCS1_CDD1",
"MCS2_CDD1",
"MCS3_CDD1",
"MCS4_CDD1",
"MCS5_CDD1",
"MCS6_CDD1",
"MCS7_CDD1",
"VHT8SS1_CDD1",
"VHT9SS1_CDD1",
"MCS0_STBC",
"MCS1_STBC",
"MCS2_STBC",
"MCS3_STBC",
"MCS4_STBC",
"MCS5_STBC",
"MCS6_STBC",
"MCS7_STBC",
"VHT8SS1_STBC",
"VHT9SS1_STBC",
"MCS8",
"MCS9",
"MCS10",
"MCS11",
"MCS12",
"MCS13",
"MCS14",
"MCS15",
"VHT8SS2",
"VHT9SS2",
"DSSS1_MULTI2",
"DSSS2_MULTI2",
"DSSS5_MULTI2",
"DSSS11_MULTI2",
"OFDM6_CDD2",
"OFDM9_CDD2",
"OFDM12_CDD2",
"OFDM18_CDD2",
"OFDM24_CDD2",
"OFDM36_CDD2",
"OFDM48_CDD2",
"OFDM54_CDD2",
"MCS0_CDD2",
"MCS1_CDD2",
"MCS2_CDD2",
"MCS3_CDD2",
"MCS4_CDD2",
"MCS5_CDD2",
"MCS6_CDD2",
"MCS7_CDD2",
"VHT8SS1_CDD2",
"VHT9SS1_CDD2",
"MCS0_STBC_SPEXP1",
"MCS1_STBC_SPEXP1",
"MCS2_STBC_SPEXP1",
"MCS3_STBC_SPEXP1",
"MCS4_STBC_SPEXP1",
"MCS5_STBC_SPEXP1",
"MCS6_STBC_SPEXP1",
"MCS7_STBC_SPEXP1",
"VHT8SS1_STBC_SPEXP1",
"VHT9SS1_STBC_SPEXP1",
"MCS8_SPEXP1",
"MCS9_SPEXP1",
"MCS10_SPEXP1",
"MCS11_SPEXP1",
"MCS12_SPEXP1",
"MCS13_SPEXP1",
"MCS14_SPEXP1",
"MCS15_SPEXP1",
"VHT8SS2_SPEXP1",
"VHT9SS2_SPEXP1",
"MCS16",
"MCS17",
"MCS18",
"MCS19",
"MCS20",
"MCS21",
"MCS22",
"MCS23",
"VHT8SS3",
"VHT9SS3",
"OFDM6_TXBF1",
"OFDM9_TXBF1",
"OFDM12_TXBF1",
"OFDM18_TXBF1",
"OFDM24_TXBF1",
"OFDM36_TXBF1",
"OFDM48_TXBF1",
"OFDM54_TXBF1",
"MCS0_TXBF1",
"MCS1_TXBF1",
"MCS2_TXBF1",
"MCS3_TXBF1",
"MCS4_TXBF1",
"MCS5_TXBF1",
"MCS6_TXBF1",
"MCS7_TXBF1",
"VHT8SS1_TXBF1",
"VHT9SS1_TXBF1",
"MCS8_TXBF0",
"MCS9_TXBF0",
"MCS10_TXBF0",
"MCS11_TXBF0",
"MCS12_TXBF0",
"MCS13_TXBF0",
"MCS14_TXBF0",
"MCS15_TXBF0",
"OFDM6_TXBF2",
"OFDM9_TXBF2",
"OFDM12_TXBF2",
"OFDM18_TXBF2",
"OFDM24_TXBF2",
"OFDM36_TXBF2",
"OFDM48_TXBF2",
"OFDM54_TXBF2",
"MCS0_TXBF2",
"MCS1_TXBF2",
"MCS2_TXBF2",
"MCS3_TXBF2",
"MCS4_TXBF2",
"MCS5_TXBF2",
"MCS6_TXBF2",
"MCS7_TXBF2",
"VHT8SS1_TXBF2",
"VHT9SS1_TXBF2",
"MCS8_TXBF1",
"MCS9_TXBF1",
"MCS10_TXBF1",
"MCS11_TXBF1",
"MCS12_TXBF1",
"MCS13_TXBF1",
"MCS14_TXBF1",
"MCS15_TXBF1",
"VHT8SS2_TXBF1",
"VHT9SS2_TXBF1",
"MCS16_TXBF0",
"MCS17_TXBF0",
"MCS18_TXBF0",
"MCS19_TXBF0",
"MCS20_TXBF0",
"MCS21_TXBF0",
"MCS22_TXBF0",
"MCS23_TXBF0",
};
int legacy_reg_rate_map[LEGACY_RATE_ID_MAX][LEGACY_MODE_ID_MAX] = {
{DSSS1, DSSS1_MULTI1, DSSS1_MULTI2, NO_RATE, NO_RATE},
{DSSS2, DSSS2_MULTI1, DSSS2_MULTI2, NO_RATE, NO_RATE},
{DSSS5, DSSS5_MULTI1, DSSS5_MULTI2, NO_RATE, NO_RATE},
{DSSS11, DSSS11_MULTI1, DSSS11_MULTI2,NO_RATE, NO_RATE},
{OFDM6, OFDM6_CDD1, OFDM6_CDD2, OFDM6_TXBF1, OFDM6_TXBF2},
{OFDM9, OFDM9_CDD1, OFDM9_CDD2, OFDM9_TXBF1, OFDM9_TXBF2},
{OFDM12, OFDM12_CDD1, OFDM12_CDD2, OFDM12_TXBF1, OFDM12_TXBF2},
{OFDM18, OFDM18_CDD1, OFDM18_CDD2, OFDM18_TXBF1, OFDM18_TXBF2},
{OFDM24, OFDM24_CDD1, OFDM24_CDD2, OFDM24_TXBF1, OFDM24_TXBF2},
{OFDM36, OFDM36_CDD1, OFDM36_CDD2, OFDM36_TXBF1, OFDM36_TXBF2},
{OFDM48, OFDM48_CDD1, OFDM48_CDD2, OFDM48_TXBF1, OFDM48_TXBF2},
{OFDM54, OFDM54_CDD1, OFDM54_CDD2, OFDM54_TXBF1, OFDM54_TXBF2}
};
int vht_ss1_reg_rate_map[VHT_RATE_INDEX_MAX][VHT_SS1_MODE_ID_MAX] = {
{MCS0, MCS0_CDD1, MCS0_STBC, MCS0_CDD2, MCS0_STBC_SPEXP1, MCS0_TXBF1, MCS0_TXBF2},
{MCS1, MCS1_CDD1, MCS1_STBC, MCS1_CDD2, MCS1_STBC_SPEXP1, MCS1_TXBF1, MCS1_TXBF2},
{MCS2, MCS2_CDD1, MCS2_STBC, MCS2_CDD2, MCS2_STBC_SPEXP1, MCS2_TXBF1, MCS2_TXBF2},
{MCS3, MCS3_CDD1, MCS3_STBC, MCS3_CDD2, MCS3_STBC_SPEXP1, MCS3_TXBF1, MCS3_TXBF2},
{MCS4, MCS4_CDD1, MCS4_STBC, MCS4_CDD2, MCS4_STBC_SPEXP1, MCS4_TXBF1, MCS4_TXBF2},
{MCS5, MCS5_CDD1, MCS5_STBC, MCS5_CDD2, MCS5_STBC_SPEXP1, MCS5_TXBF1, MCS5_TXBF2},
{MCS6, MCS6_CDD1, MCS6_STBC, MCS6_CDD2, MCS6_STBC_SPEXP1, MCS6_TXBF1, MCS6_TXBF2},
{MCS7, MCS7_CDD1, MCS7_STBC, MCS7_CDD2, MCS7_STBC_SPEXP1, MCS7_TXBF1, MCS7_TXBF2},
{VHT8SS1, VHT8SS1_CDD1, VHT8SS1_STBC, VHT8SS1_CDD2, VHT8SS1_STBC_SPEXP1,VHT8SS1_TXBF1, VHT8SS1_TXBF2},
{VHT9SS1, VHT9SS1_CDD1, VHT9SS1_STBC, VHT9SS1_CDD2, VHT9SS1_STBC_SPEXP1,VHT9SS1_TXBF1, VHT9SS1_TXBF2}
};
int vht_ss2_reg_rate_map[VHT_RATE_INDEX_MAX][VHT_SS2_MODE_ID_MAX] = {
{MCS8, MCS8_SPEXP1, MCS8_TXBF0, MCS8_TXBF1},
{MCS9, MCS9_SPEXP1, MCS9_TXBF0, MCS9_TXBF1},
{MCS10, MCS10_SPEXP1, MCS10_TXBF0, MCS10_TXBF1},
{MCS11, MCS11_SPEXP1, MCS11_TXBF0, MCS11_TXBF1},
{MCS12, MCS12_SPEXP1, MCS12_TXBF0, MCS12_TXBF1},
{MCS13, MCS13_SPEXP1, MCS13_TXBF0, MCS13_TXBF1},
{MCS14, MCS14_SPEXP1, MCS14_TXBF0, MCS14_TXBF1},
{MCS15, MCS15_SPEXP1, MCS15_TXBF0, MCS15_TXBF1},
{VHT8SS2, VHT8SS2_SPEXP1,NO_RATE, VHT8SS2_TXBF1},
{VHT9SS2, VHT9SS2_SPEXP1,NO_RATE, VHT8SS2_TXBF1}
};
int vht_ss3_reg_rate_map[VHT_RATE_INDEX_MAX][VHT_SS3_MODE_ID_MAX] = {
{MCS16, MCS16_TXBF0},
{MCS17, MCS17_TXBF0},
{MCS18, MCS18_TXBF0},
{MCS19, MCS19_TXBF0},
{MCS20, MCS20_TXBF0},
{MCS21, MCS21_TXBF0},
{MCS22, MCS22_TXBF0},
{MCS23, MCS23_TXBF0},
{VHT8SS3, NO_RATE},
{VHT9SS3, NO_RATE}
};
const char *exp_mode_name[EXP_MODE_ID_MAX] = {
"CDD",
"STBC",
"TXBF"
};
const char *
get_clm_rate_group_label(int rategroup)
{
return clm_rate_group_labels[rategroup];
}
#ifdef D11AC_IOTYPES
const char *
get_reg_rate_string_from_ratespec(int ratespec)
{
reg_rate_index_t index = get_reg_rate_index_from_ratespec(ratespec);
if (index >= 0)
{
return clm_rate_labels[index];
}
return CLM_NO_RATE_STRING;
}
reg_rate_index_t
get_reg_rate_index_from_ratespec(int ratespec)
{
uint encode, rate, txexp;
bool stbc,txbf;
int rate_index = NO_RATE;
exp_mode_t expmode = EXP_MODE_ID_DEF;
/* If auto is set, we don't get a ratespec that can be decoded */
if (ratespec == AUTO_RATESPEC)
return rate_index;
encode = (ratespec & WL_RSPEC_ENCODING_MASK);
rate = (ratespec & WL_RSPEC_RATE_MASK);
txexp = (ratespec & WL_RSPEC_TXEXP_MASK) >> WL_RSPEC_TXEXP_SHIFT;
stbc = (ratespec & WL_RSPEC_STBC) != 0;
txbf = (ratespec & WL_RSPEC_TXBF) != 0;
if (stbc && txbf) {
return rate_index;
} else if (txbf) {
expmode = EXP_MODE_ID_TXBF;
} else if (stbc) {
expmode = EXP_MODE_ID_STBC;
}
if (encode == WL_RSPEC_ENCODE_RATE) {
rate_index = get_legacy_reg_rate_index(rate, txexp, expmode);
} else if (encode == WL_RSPEC_ENCODE_HT) {
rate_index = get_ht_reg_rate_index(rate, txexp, expmode);
} else if (encode == WL_RSPEC_ENCODE_VHT) {
uint mcs = (ratespec & WL_RSPEC_VHT_MCS_MASK);
uint nss = (ratespec & WL_RSPEC_VHT_NSS_MASK) >> WL_RSPEC_VHT_NSS_SHIFT;
rate_index = get_vht_reg_rate_index(mcs, nss, txexp, expmode);
}
return rate_index;
}
reg_rate_index_t
get_legacy_reg_rate_index(int rate_hmhz, int tx_expansion, exp_mode_t expmode)
{
reg_rate_index_t index = NO_RATE;
int rate_id;
rate_id = get_legacy_rate_identifier(rate_hmhz);
if (rate_id == LEGACY_RATE_ID_NO_RATE || (expmode == EXP_MODE_ID_TXBF && rate_id < LEGACY_RATE_ID_6MHZ))
{
fprintf(stderr, "ERROR: Bad legacy rate spec: %d\n", rate_hmhz);
}
else
{
index = legacy_reg_rate_map[rate_id][get_legacy_mode_identifier(tx_expansion, expmode)];
}
return index;
}
static int get_legacy_rate_identifier(int rate_hmhz)
{
int rate_lut[LEGACY_RATE_ID_MAX];
int rate_index = LEGACY_RATE_ID_NO_RATE;
int i;
rate_lut[LEGACY_RATE_ID_1MHZ] = 1 * MHZ_TO_HALF_MHZ;
rate_lut[LEGACY_RATE_ID_2MHZ] = 2 * MHZ_TO_HALF_MHZ;
rate_lut[LEGACY_RATE_ID_5_5MHZ] = 11; /* 5.5 * MHZ_TO_HALF_MHZ */
rate_lut[LEGACY_RATE_ID_11MHZ] = 11 * MHZ_TO_HALF_MHZ;
rate_lut[LEGACY_RATE_ID_6MHZ] = 6 * MHZ_TO_HALF_MHZ;
rate_lut[LEGACY_RATE_ID_9MHZ] = 9 * MHZ_TO_HALF_MHZ;
rate_lut[LEGACY_RATE_ID_12MHZ] = 12 * MHZ_TO_HALF_MHZ;
rate_lut[LEGACY_RATE_ID_18MHZ] = 18 * MHZ_TO_HALF_MHZ;
rate_lut[LEGACY_RATE_ID_24MHZ] = 24 * MHZ_TO_HALF_MHZ;
rate_lut[LEGACY_RATE_ID_36MHZ] = 36 * MHZ_TO_HALF_MHZ;
rate_lut[LEGACY_RATE_ID_48MHZ] = 48 * MHZ_TO_HALF_MHZ;
rate_lut[LEGACY_RATE_ID_54MHZ] = 54 * MHZ_TO_HALF_MHZ;
for (i = 0; i < LEGACY_RATE_ID_MAX; i++)
{
if (rate_lut[i] == rate_hmhz)
{
rate_index = i;
break;
}
}
return rate_index;
}
static int get_legacy_mode_identifier(int tx_expansion, exp_mode_t expmode)
{
int mode_identifier = 0;
if (tx_expansion == 0)
{
mode_identifier = LEGACY_MODE_ID_NONE;
}
else if (tx_expansion == 1)
{
switch (expmode)
{
case EXP_MODE_ID_DEF:
mode_identifier = LEGACY_MODE_ID_TXEXP1;
break;
case EXP_MODE_ID_TXBF:
mode_identifier = LEGACY_MODE_ID_TXBF1;
break;
default:
fprintf(stderr, "ERROR: Bad legacy tx_expansion spec: %d expansion mode %s\n",
tx_expansion, get_mode_name(expmode));
break;
}
}
else if (tx_expansion == 2)
{
switch (expmode)
{
case EXP_MODE_ID_DEF:
mode_identifier = LEGACY_MODE_ID_TXEXP2;
break;
case EXP_MODE_ID_TXBF:
mode_identifier = LEGACY_MODE_ID_TXBF2;
break;
default:
fprintf(stderr, "ERROR: Bad legacy tx_expansion spec: %d expansion mode %s\n",
tx_expansion, get_mode_name(expmode));
break;
}
}
else
{
fprintf(stderr, "ERROR: Bad legacy tx_expansion spec: %d expansion mode %s\n", tx_expansion,
get_mode_name(expmode));
}
return mode_identifier;
}
reg_rate_index_t
get_ht_reg_rate_index(int mcs, int tx_expansion, exp_mode_t expmode)
{
reg_rate_index_t rate_index = NO_RATE;
int vht_mcs, nss;
if (mcs > 23)
{
fprintf(stderr, "ERROR: Bad ht mcs spec: %d\n", mcs);
}
else
{
vht_mcs = mcs % 8;
nss = (mcs / 8) + 1;
rate_index = get_vht_reg_rate_index(vht_mcs, nss, tx_expansion, expmode);
}
return rate_index;
}
reg_rate_index_t
get_vht_reg_rate_index(int mcs, int nss, int tx_expansion, exp_mode_t expmode)
{
reg_rate_index_t rate_index = NO_RATE;
int rate_id = get_vht_rate_identifier(mcs);
if (nss == 1)
{
rate_index = vht_ss1_reg_rate_map[rate_id][get_vht_ss1_mode_identifier(tx_expansion, expmode)];
}
else if (nss == 2)
{
rate_index = vht_ss2_reg_rate_map[rate_id][get_vht_ss2_mode_identifier(tx_expansion, expmode)];
}
else if (nss == 3)
{
rate_index = vht_ss3_reg_rate_map[rate_id][get_vht_ss3_mode_identifier(tx_expansion, expmode)];
}
return rate_index;
}
static int get_vht_rate_identifier(int vht_mcs_index)
{
int rate_index = 0;
if (vht_mcs_index >= VHT_RATE_INDEX_0 && vht_mcs_index < VHT_RATE_INDEX_MAX)
{
rate_index = vht_mcs_index;
}
else
{
fprintf(stderr, "ERROR: Bad vht mcs spec: %d\n", vht_mcs_index);
}
return rate_index;
}
static int get_vht_ss1_mode_identifier(int tx_expansion, exp_mode_t expmode)
{
int mode_identifier = 0;
if (tx_expansion == 0)
{
switch (expmode)
{
case EXP_MODE_ID_DEF:
mode_identifier = VHT_SS1_MODE_ID_NONE;
break;
case EXP_MODE_ID_STBC:
mode_identifier = VHT_SS1_MODE_ID_STBC;
break;
default:
fprintf(stderr, "ERROR: Bad vht ss1 mode: %d, expansion mode %s\n", tx_expansion,
get_mode_name(expmode));
break;
}
}
else if (tx_expansion == 1)
{
switch (expmode)
{
case EXP_MODE_ID_DEF:
mode_identifier = VHT_SS1_MODE_ID_CDD1;
break;
case EXP_MODE_ID_STBC:
mode_identifier = VHT_SS1_MODE_ID_STBC_SPEXP1;
break;
case EXP_MODE_ID_TXBF:
mode_identifier = VHT_SS1_MODE_ID_TXBF1;
break;
default:
fprintf(stderr, "ERROR: Bad vht ss1 mode: %d, expansion mode %s\n", tx_expansion,
get_mode_name(expmode));
break;
}
}
else if (tx_expansion == 2)
{
switch (expmode)
{
case EXP_MODE_ID_DEF:
mode_identifier = VHT_SS1_MODE_ID_CDD2;
break;
case EXP_MODE_ID_TXBF:
mode_identifier = VHT_SS1_MODE_ID_TXBF2;
break;
default:
fprintf(stderr, "ERROR: Bad vht ss1 mode: %d, expansion mode %s\n", tx_expansion,
get_mode_name(expmode));
break;
}
}
else
{
fprintf(stderr, "ERROR: Bad vht ss1 mode: %d, expansion mode: %s\n", tx_expansion,
get_mode_name(expmode));
}
return mode_identifier;
}
static int get_vht_ss2_mode_identifier(int tx_expansion, exp_mode_t expmode)
{
int mode_identifier = 0;
if (tx_expansion == 0)
{
switch (expmode)
{
case EXP_MODE_ID_DEF:
mode_identifier = VHT_SS2_MODE_ID_NONE;
break;
case EXP_MODE_ID_TXBF:
mode_identifier = VHT_SS2_MODE_ID_TXBF0;
break;
default:
fprintf(stderr, "ERROR: Bad vht ss2 mode: %d, expansion mode %s\n", tx_expansion,
get_mode_name(expmode));
break;
}
}
else if (tx_expansion == 1)
{
switch (expmode)
{
case EXP_MODE_ID_DEF:
mode_identifier = VHT_SS2_MODE_ID_SPEXP1;
break;
case EXP_MODE_ID_TXBF:
mode_identifier = VHT_SS2_MODE_ID_TXBF1;
break;
default:
fprintf(stderr, "ERROR: Bad vht ss2 mode: %d, expansion mode %s\n", tx_expansion,
get_mode_name(expmode));
break;
}
}
else
{
fprintf(stderr, "ERROR: Bad vht ss2 mode: %d expansion mode: %s\n", tx_expansion,
get_mode_name(expmode));
}
return mode_identifier;
}
static int get_vht_ss3_mode_identifier(int tx_expansion, exp_mode_t expmode)
{
int mode_identifier = 0;
if (tx_expansion == 0)
{
switch (expmode)
{
case EXP_MODE_ID_DEF:
mode_identifier = VHT_SS3_MODE_ID_NONE;
break;
case EXP_MODE_ID_TXBF:
mode_identifier = VHT_SS3_MODE_ID_TXBF0;
break;
default:
fprintf(stderr, "ERROR: Bad vht ss3 mode: %d, expansion mode: %s\n", tx_expansion
, get_mode_name(expmode));
break;
}
}
else
{
fprintf(stderr, "ERROR: Bad vht ss3 mode: %d, expansion: %s\n", tx_expansion,
get_mode_name(expmode));
}
return mode_identifier;
}
static const char *get_mode_name(exp_mode_t mode)
{
if (mode >= EXP_MODE_ID_MAX)
return EXP_MODE_UNKNOWN;
return exp_mode_name[mode];
}
#endif

View File

@@ -0,0 +1,397 @@
/*
* This module does provides various mappings to or from the CLM rate indexes.
*
* $Copyright (C) 2011 Broadcom Corporation$
*/
/*FILE-CSTYLED*/
#ifndef _WLU_RATES_MATRIX_H_
#define _WLU_RATES_MATRIX_H_
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#include <bcmwifi_rates.h>
#include <wlioctl.h>
#include <typedefs.h>
#include <epivers.h>
#include <bcmutils.h>
#include <bcmendian.h>
#include <bcmwifi_channels.h>
#include <wlc_ppr.h>
#ifdef LINUX
#include <inttypes.h>
#endif
#include <miniopt.h>
#define WL_UNSUPPORTED_IDX 0xFFF
typedef enum clm_rate_group_id {
RATE_GROUP_ID_DSSS = 0,
RATE_GROUP_ID_OFDM,
RATE_GROUP_ID_MCS0_7,
RATE_GROUP_ID_VHT8_9SS1,
RATE_GROUP_ID_DSSS_MULTI1,
RATE_GROUP_ID_OFDM_CDD1,
RATE_GROUP_ID_MCS0_7_CDD1,
RATE_GROUP_ID_VHT8_9SS1_CDD1,
RATE_GROUP_ID_MCS0_7_STBC,
RATE_GROUP_ID_VHT8_9SS1_STBC,
RATE_GROUP_ID_MCS8_15,
RATE_GROUP_ID_VHT8_9SS2,
RATE_GROUP_ID_DSSS_MULTI2,
RATE_GROUP_ID_OFDM_CDD2,
RATE_GROUP_ID_MCS0_7_CDD2,
RATE_GROUP_ID_VHT8_9SS1_CDD2,
RATE_GROUP_ID_MCS0_7_STBC_SPEXP1,
RATE_GROUP_ID_VHT8_9SS1_STBC_SPEXP1,
RATE_GROUP_ID_MCS8_15_SPEXP1,
RATE_GROUP_ID_VHT8_9SS2_SPEXP1,
RATE_GROUP_ID_MCS16_23,
RATE_GROUP_ID_VHT8_9SS3,
RATE_GROUP_ID_OFDM_TXBF1,
RATE_GROUP_ID_MCS0_7_TXBF1,
RATE_GROUP_ID_VHT8_9SS1_TXBF1,
RATE_GROUP_ID_MCS8_15_TXBF0,
RATE_GROUP_ID_OFDM_TXBF2,
RATE_GROUP_ID_MCS0_7_TXBF2,
RATE_GROUP_ID_VHT8_9SS1_TXBF2,
RATE_GROUP_ID_MCS8_15_TXBF1,
RATE_GROUP_ID_VHT8_9SS2_TXBF1,
RATE_GROUP_ID_MCS16_23_TXBF0,
RATE_GROUP_ID_COUNT
} clm_rate_group_id_t;
typedef struct {
char label[23];
uint8 chains;
clm_rate_group_id_t id;
clm_rates_t rate;
uint bw20ssl;
uint bw20n;
uint bw20ht;
uint bw40ssl;
uint bw40n;
uint bw40ht;
uint bw20in40ssl;
uint bw20in40n;
uint bw20in40ht;
uint bw80ssl;
uint bw80n;
uint bw80ht;
uint bw20in80ssl;
uint bw20in80n;
uint bw20in80ht;
uint bw40in80ssl;
uint bw40in80n;
uint bw40in80ht;
} clm_rate_matrix_t;
typedef enum reg_rate_index {
NO_RATE = -1,
DSSS1, DSSS2, DSSS5, DSSS11,
OFDM6, OFDM9, OFDM12, OFDM18,
OFDM24, OFDM36, OFDM48, OFDM54,
MCS0, MCS1, MCS2, MCS3,
MCS4, MCS5, MCS6, MCS7,
VHT8SS1, VHT9SS1,
DSSS1_MULTI1, DSSS2_MULTI1, DSSS5_MULTI1, DSSS11_MULTI1,
OFDM6_CDD1, OFDM9_CDD1, OFDM12_CDD1, OFDM18_CDD1,
OFDM24_CDD1, OFDM36_CDD1, OFDM48_CDD1, OFDM54_CDD1,
MCS0_CDD1, MCS1_CDD1, MCS2_CDD1, MCS3_CDD1,
MCS4_CDD1, MCS5_CDD1, MCS6_CDD1, MCS7_CDD1,
VHT8SS1_CDD1, VHT9SS1_CDD1,
MCS0_STBC, MCS1_STBC, MCS2_STBC, MCS3_STBC,
MCS4_STBC, MCS5_STBC, MCS6_STBC, MCS7_STBC,
VHT8SS1_STBC, VHT9SS1_STBC,
MCS8, MCS9, MCS10, MCS11,
MCS12, MCS13, MCS14, MCS15,
VHT8SS2, VHT9SS2,
DSSS1_MULTI2, DSSS2_MULTI2, DSSS5_MULTI2, DSSS11_MULTI2,
OFDM6_CDD2, OFDM9_CDD2, OFDM12_CDD2, OFDM18_CDD2,
OFDM24_CDD2, OFDM36_CDD2, OFDM48_CDD2, OFDM54_CDD2,
MCS0_CDD2, MCS1_CDD2, MCS2_CDD2, MCS3_CDD2,
MCS4_CDD2, MCS5_CDD2, MCS6_CDD2, MCS7_CDD2,
VHT8SS1_CDD2, VHT9SS1_CDD2,
MCS0_STBC_SPEXP1, MCS1_STBC_SPEXP1, MCS2_STBC_SPEXP1, MCS3_STBC_SPEXP1,
MCS4_STBC_SPEXP1, MCS5_STBC_SPEXP1, MCS6_STBC_SPEXP1, MCS7_STBC_SPEXP1,
VHT8SS1_STBC_SPEXP1, VHT9SS1_STBC_SPEXP1,
MCS8_SPEXP1, MCS9_SPEXP1, MCS10_SPEXP1, MCS11_SPEXP1,
MCS12_SPEXP1, MCS13_SPEXP1, MCS14_SPEXP1, MCS15_SPEXP1,
VHT8SS2_SPEXP1, VHT9SS2_SPEXP1,
MCS16, MCS17, MCS18, MCS19,
MCS20, MCS21, MCS22, MCS23,
VHT8SS3, VHT9SS3,
OFDM6_TXBF1, OFDM9_TXBF1, OFDM12_TXBF1, OFDM18_TXBF1,
OFDM24_TXBF1, OFDM36_TXBF1, OFDM48_TXBF1, OFDM54_TXBF1,
MCS0_TXBF1, MCS1_TXBF1, MCS2_TXBF1, MCS3_TXBF1,
MCS4_TXBF1, MCS5_TXBF1, MCS6_TXBF1, MCS7_TXBF1,
VHT8SS1_TXBF1, VHT9SS1_TXBF1,
MCS8_TXBF0, MCS9_TXBF0, MCS10_TXBF0, MCS11_TXBF0,
MCS12_TXBF0, MCS13_TXBF0, MCS14_TXBF0, MCS15_TXBF0,
OFDM6_TXBF2, OFDM9_TXBF2, OFDM12_TXBF2, OFDM18_TXBF2,
OFDM24_TXBF2, OFDM36_TXBF2, OFDM48_TXBF2, OFDM54_TXBF2,
MCS0_TXBF2, MCS1_TXBF2, MCS2_TXBF2, MCS3_TXBF2,
MCS4_TXBF2, MCS5_TXBF2, MCS6_TXBF2, MCS7_TXBF2,
VHT8SS1_TXBF2, VHT9SS1_TXBF2,
MCS8_TXBF1, MCS9_TXBF1, MCS10_TXBF1, MCS11_TXBF1,
MCS12_TXBF1, MCS13_TXBF1, MCS14_TXBF1, MCS15_TXBF1,
VHT8SS2_TXBF1, VHT9SS2_TXBF1,
MCS16_TXBF0, MCS17_TXBF0, MCS18_TXBF0, MCS19_TXBF0,
MCS20_TXBF0, MCS21_TXBF0, MCS22_TXBF0, MCS23_TXBF0,
} reg_rate_index_t;
typedef enum ppr_rate_type {
PPR_RATE_DSSS,
PPR_RATE_OFDM,
PPR_RATE_HT,
PPR_RATE_VHT,
} ppr_rate_type_t;
typedef struct ppr_tbl {
char label[23];
clm_rate_group_id_t id;
clm_rates_t rate;
} ppr_tbl_t;
typedef struct ppr_group {
clm_rate_group_id_t id;
wl_tx_chains_t chain;
wl_tx_mode_t mode;
wl_tx_nss_t nss;
ppr_rate_type_t rate_type;
reg_rate_index_t first_rate;
} ppr_group_t;
static const ppr_group_t ppr_group_table[] = {
/*group id chains mode nss rate type offset-first*/
{RATE_GROUP_ID_DSSS, WL_TX_CHAINS_1, WL_TX_MODE_NONE, WL_TX_NSS_1, PPR_RATE_DSSS, DSSS1},
{RATE_GROUP_ID_OFDM, WL_TX_CHAINS_1, WL_TX_MODE_NONE, WL_TX_NSS_1, PPR_RATE_OFDM, OFDM6},
{RATE_GROUP_ID_MCS0_7, WL_TX_CHAINS_1, WL_TX_MODE_NONE, WL_TX_NSS_1, PPR_RATE_VHT, MCS0},
{RATE_GROUP_ID_VHT8_9SS1, WL_TX_CHAINS_1, WL_TX_MODE_NONE, WL_TX_NSS_1, PPR_RATE_VHT, MCS0},
{RATE_GROUP_ID_DSSS_MULTI1, WL_TX_CHAINS_2, WL_TX_MODE_NONE, WL_TX_NSS_1, PPR_RATE_DSSS, DSSS1_MULTI1},
{RATE_GROUP_ID_OFDM_CDD1, WL_TX_CHAINS_2, WL_TX_MODE_CDD, WL_TX_NSS_1, PPR_RATE_OFDM, OFDM6_CDD1},
{RATE_GROUP_ID_MCS0_7_CDD1, WL_TX_CHAINS_2, WL_TX_MODE_CDD, WL_TX_NSS_1, PPR_RATE_VHT, MCS0_CDD1},
{RATE_GROUP_ID_VHT8_9SS1_CDD1, WL_TX_CHAINS_2, WL_TX_MODE_CDD, WL_TX_NSS_1, PPR_RATE_VHT, MCS0_CDD1},
{RATE_GROUP_ID_MCS0_7_STBC, WL_TX_CHAINS_2, WL_TX_MODE_STBC, WL_TX_NSS_2, PPR_RATE_VHT, MCS0_STBC},
{RATE_GROUP_ID_VHT8_9SS1_STBC, WL_TX_CHAINS_2, WL_TX_MODE_STBC, WL_TX_NSS_2, PPR_RATE_VHT, MCS0_STBC},
{RATE_GROUP_ID_MCS8_15, WL_TX_CHAINS_2, WL_TX_MODE_NONE, WL_TX_NSS_2, PPR_RATE_VHT, MCS8},
{RATE_GROUP_ID_VHT8_9SS2, WL_TX_CHAINS_2, WL_TX_MODE_NONE, WL_TX_NSS_2, PPR_RATE_VHT, MCS8},
{RATE_GROUP_ID_DSSS_MULTI2, WL_TX_CHAINS_3, WL_TX_MODE_NONE, WL_TX_NSS_1, PPR_RATE_DSSS, DSSS1_MULTI2},
{RATE_GROUP_ID_OFDM_CDD2, WL_TX_CHAINS_3, WL_TX_MODE_CDD, WL_TX_NSS_1, PPR_RATE_OFDM, OFDM6_CDD2},
{RATE_GROUP_ID_MCS0_7_CDD2, WL_TX_CHAINS_3, WL_TX_MODE_CDD, WL_TX_NSS_1, PPR_RATE_VHT, MCS0_CDD2},
{RATE_GROUP_ID_VHT8_9SS1_CDD2, WL_TX_CHAINS_3, WL_TX_MODE_CDD, WL_TX_NSS_1, PPR_RATE_VHT, MCS0_CDD2},
{RATE_GROUP_ID_MCS0_7_STBC_SPEXP1, WL_TX_CHAINS_3, WL_TX_MODE_STBC, WL_TX_NSS_2, PPR_RATE_VHT, MCS0_STBC_SPEXP1},
{RATE_GROUP_ID_VHT8_9SS1_STBC_SPEXP1, WL_TX_CHAINS_3, WL_TX_MODE_STBC, WL_TX_NSS_2, PPR_RATE_VHT, MCS0_STBC_SPEXP1},
{RATE_GROUP_ID_MCS8_15_SPEXP1, WL_TX_CHAINS_3, WL_TX_MODE_NONE, WL_TX_NSS_2, PPR_RATE_VHT, MCS8_SPEXP1},
{RATE_GROUP_ID_VHT8_9SS2_SPEXP1, WL_TX_CHAINS_3, WL_TX_MODE_NONE, WL_TX_NSS_2, PPR_RATE_VHT, MCS8_SPEXP1},
{RATE_GROUP_ID_MCS16_23, WL_TX_CHAINS_3, WL_TX_MODE_NONE, WL_TX_NSS_3, PPR_RATE_VHT, MCS16},
{RATE_GROUP_ID_VHT8_9SS3, WL_TX_CHAINS_3, WL_TX_MODE_NONE, WL_TX_NSS_3, PPR_RATE_VHT, MCS16},
{RATE_GROUP_ID_OFDM_TXBF1, WL_TX_CHAINS_2, WL_TX_MODE_TXBF, WL_TX_NSS_1, PPR_RATE_OFDM, OFDM6_TXBF1},
{RATE_GROUP_ID_MCS0_7_TXBF1, WL_TX_CHAINS_2, WL_TX_MODE_TXBF, WL_TX_NSS_1, PPR_RATE_VHT, MCS0_TXBF1},
{RATE_GROUP_ID_VHT8_9SS1_TXBF1, WL_TX_CHAINS_2, WL_TX_MODE_TXBF, WL_TX_NSS_1, PPR_RATE_VHT, MCS0_TXBF1},
{RATE_GROUP_ID_MCS8_15_TXBF0, WL_TX_CHAINS_2, WL_TX_MODE_TXBF, WL_TX_NSS_2, PPR_RATE_HT, MCS8_TXBF0},
{RATE_GROUP_ID_OFDM_TXBF2, WL_TX_CHAINS_3, WL_TX_MODE_TXBF, WL_TX_NSS_1, PPR_RATE_OFDM, OFDM6_TXBF2},
{RATE_GROUP_ID_MCS0_7_TXBF2, WL_TX_CHAINS_3, WL_TX_MODE_TXBF, WL_TX_NSS_1, PPR_RATE_VHT, MCS0_TXBF2},
{RATE_GROUP_ID_VHT8_9SS1_TXBF2, WL_TX_CHAINS_3, WL_TX_MODE_TXBF, WL_TX_NSS_1, PPR_RATE_VHT, MCS0_TXBF2},
{RATE_GROUP_ID_MCS8_15_TXBF1, WL_TX_CHAINS_3, WL_TX_MODE_TXBF, WL_TX_NSS_2, PPR_RATE_VHT, MCS8_TXBF1},
{RATE_GROUP_ID_VHT8_9SS2_TXBF1, WL_TX_CHAINS_3, WL_TX_MODE_TXBF, WL_TX_NSS_2, PPR_RATE_VHT, MCS8_TXBF1},
{RATE_GROUP_ID_MCS16_23_TXBF0, WL_TX_CHAINS_3, WL_TX_MODE_TXBF, WL_TX_NSS_3, PPR_RATE_HT, MCS16_TXBF0},
};
static const ppr_tbl_t ppr_table[] = {
/* Label Rate Group ID CLM index*/
{"DSSS1", RATE_GROUP_ID_DSSS, WL_RATE_1X1_DSSS_1},
{"DSSS2", RATE_GROUP_ID_DSSS, WL_RATE_1X1_DSSS_2},
{"DSSS5", RATE_GROUP_ID_DSSS, WL_RATE_1X1_DSSS_5_5},
{"DSSS11", RATE_GROUP_ID_DSSS, WL_RATE_1X1_DSSS_11},
{"OFDM6", RATE_GROUP_ID_OFDM, WL_RATE_1X1_OFDM_6},
{"OFDM9", RATE_GROUP_ID_OFDM, WL_RATE_1X1_OFDM_9},
{"OFDM12", RATE_GROUP_ID_OFDM, WL_RATE_1X1_OFDM_12},
{"OFDM18", RATE_GROUP_ID_OFDM, WL_RATE_1X1_OFDM_18},
{"OFDM24", RATE_GROUP_ID_OFDM, WL_RATE_1X1_OFDM_24},
{"OFDM36", RATE_GROUP_ID_OFDM, WL_RATE_1X1_OFDM_36},
{"OFDM48", RATE_GROUP_ID_OFDM, WL_RATE_1X1_OFDM_48},
{"OFDM54", RATE_GROUP_ID_OFDM, WL_RATE_1X1_OFDM_54},
{"MCS0", RATE_GROUP_ID_MCS0_7, WL_RATE_1X1_MCS0},
{"MCS1", RATE_GROUP_ID_MCS0_7, WL_RATE_1X1_MCS1},
{"MCS2", RATE_GROUP_ID_MCS0_7, WL_RATE_1X1_MCS2},
{"MCS3", RATE_GROUP_ID_MCS0_7, WL_RATE_1X1_MCS3},
{"MCS4", RATE_GROUP_ID_MCS0_7, WL_RATE_1X1_MCS4},
{"MCS5", RATE_GROUP_ID_MCS0_7, WL_RATE_1X1_MCS5},
{"MCS6", RATE_GROUP_ID_MCS0_7, WL_RATE_1X1_MCS6},
{"MCS7", RATE_GROUP_ID_MCS0_7, WL_RATE_1X1_MCS7},
{"VHT8SS1", RATE_GROUP_ID_VHT8_9SS1, WL_RATE_1X1_VHT8SS1},
{"VHT9SS1", RATE_GROUP_ID_VHT8_9SS1, WL_RATE_1X1_VHT9SS1},
{"DSSS1_MULTI1", RATE_GROUP_ID_DSSS_MULTI1, WL_RATE_1X2_DSSS_1},
{"DSSS2_MULTI1", RATE_GROUP_ID_DSSS_MULTI1, WL_RATE_1X2_DSSS_2},
{"DSSS5_MULTI1", RATE_GROUP_ID_DSSS_MULTI1, WL_RATE_1X2_DSSS_5_5},
{"DSSS11_MULTI1", RATE_GROUP_ID_DSSS_MULTI1, WL_RATE_1X2_DSSS_11},
{"OFDM6_CDD1", RATE_GROUP_ID_OFDM_CDD1, WL_RATE_1X2_CDD_OFDM_6},
{"OFDM9_CDD1", RATE_GROUP_ID_OFDM_CDD1, WL_RATE_1X2_CDD_OFDM_9},
{"OFDM12_CDD1", RATE_GROUP_ID_OFDM_CDD1, WL_RATE_1X2_CDD_OFDM_12,},
{"OFDM18_CDD1", RATE_GROUP_ID_OFDM_CDD1, WL_RATE_1X2_CDD_OFDM_18,},
{"OFDM24_CDD1", RATE_GROUP_ID_OFDM_CDD1, WL_RATE_1X2_CDD_OFDM_24,},
{"OFDM36_CDD1", RATE_GROUP_ID_OFDM_CDD1, WL_RATE_1X2_CDD_OFDM_36,},
{"OFDM48_CDD1", RATE_GROUP_ID_OFDM_CDD1, WL_RATE_1X2_CDD_OFDM_48,},
{"OFDM54_CDD1", RATE_GROUP_ID_OFDM_CDD1, WL_RATE_1X2_CDD_OFDM_54,},
{"MCS0_CDD1", RATE_GROUP_ID_MCS0_7_CDD1, WL_RATE_1X2_CDD_MCS0},
{"MCS1_CDD1", RATE_GROUP_ID_MCS0_7_CDD1, WL_RATE_1X2_CDD_MCS1},
{"MCS2_CDD1", RATE_GROUP_ID_MCS0_7_CDD1, WL_RATE_1X2_CDD_MCS2},
{"MCS3_CDD1", RATE_GROUP_ID_MCS0_7_CDD1, WL_RATE_1X2_CDD_MCS3},
{"MCS4_CDD1", RATE_GROUP_ID_MCS0_7_CDD1, WL_RATE_1X2_CDD_MCS4},
{"MCS5_CDD1", RATE_GROUP_ID_MCS0_7_CDD1, WL_RATE_1X2_CDD_MCS5},
{"MCS6_CDD1", RATE_GROUP_ID_MCS0_7_CDD1, WL_RATE_1X2_CDD_MCS6},
{"MCS7_CDD1", RATE_GROUP_ID_MCS0_7_CDD1, WL_RATE_1X2_CDD_MCS7},
{"VHT8SS1_CDD1", RATE_GROUP_ID_VHT8_9SS1_CDD1, WL_RATE_1X2_VHT8SS1},
{"VHT9SS1_CDD1", RATE_GROUP_ID_VHT8_9SS1_CDD1, WL_RATE_1X2_VHT9SS1},
{"MCS0_STBC", RATE_GROUP_ID_MCS0_7_STBC, WL_RATE_2X2_STBC_MCS0},
{"MCS1_STBC", RATE_GROUP_ID_MCS0_7_STBC, WL_RATE_2X2_STBC_MCS1},
{"MCS2_STBC", RATE_GROUP_ID_MCS0_7_STBC, WL_RATE_2X2_STBC_MCS2},
{"MCS3_STBC", RATE_GROUP_ID_MCS0_7_STBC, WL_RATE_2X2_STBC_MCS3},
{"MCS4_STBC", RATE_GROUP_ID_MCS0_7_STBC, WL_RATE_2X2_STBC_MCS4},
{"MCS5_STBC", RATE_GROUP_ID_MCS0_7_STBC, WL_RATE_2X2_STBC_MCS5},
{"MCS6_STBC", RATE_GROUP_ID_MCS0_7_STBC, WL_RATE_2X2_STBC_MCS6},
{"MCS7_STBC", RATE_GROUP_ID_MCS0_7_STBC, WL_RATE_2X2_STBC_MCS7},
{"VHT8SS1_STBC", RATE_GROUP_ID_VHT8_9SS1_STBC, WL_RATE_2X2_STBC_VHT8SS1},
{"VHT9SS1_STBC", RATE_GROUP_ID_VHT8_9SS1_STBC, WL_RATE_2X2_STBC_VHT9SS1},
{"MCS8", RATE_GROUP_ID_MCS8_15, WL_RATE_2X2_SDM_MCS8},
{"MCS9", RATE_GROUP_ID_MCS8_15, WL_RATE_2X2_SDM_MCS9},
{"MCS10", RATE_GROUP_ID_MCS8_15, WL_RATE_2X2_SDM_MCS10},
{"MCS11", RATE_GROUP_ID_MCS8_15, WL_RATE_2X2_SDM_MCS11},
{"MCS12", RATE_GROUP_ID_MCS8_15, WL_RATE_2X2_SDM_MCS12},
{"MCS13", RATE_GROUP_ID_MCS8_15, WL_RATE_2X2_SDM_MCS13},
{"MCS14", RATE_GROUP_ID_MCS8_15, WL_RATE_2X2_SDM_MCS14},
{"MCS15", RATE_GROUP_ID_MCS8_15, WL_RATE_2X2_SDM_MCS15},
{"VHT8SS2", RATE_GROUP_ID_VHT8_9SS2, WL_RATE_2X2_VHT8SS2},
{"VHT9SS2", RATE_GROUP_ID_VHT8_9SS2, WL_RATE_2X2_VHT9SS2},
{"DSSS1_MULTI2", RATE_GROUP_ID_DSSS_MULTI2, WL_RATE_1X3_DSSS_1},
{"DSSS2_MULTI2", RATE_GROUP_ID_DSSS_MULTI2, WL_RATE_1X3_DSSS_2},
{"DSSS5_MULTI2", RATE_GROUP_ID_DSSS_MULTI2, WL_RATE_1X3_DSSS_5_5},
{"DSSS11_MULTI2", RATE_GROUP_ID_DSSS_MULTI2, WL_RATE_1X3_DSSS_11},
{"OFDM6_CDD2", RATE_GROUP_ID_OFDM_CDD2, WL_RATE_1X3_CDD_OFDM_6},
{"OFDM9_CDD2", RATE_GROUP_ID_OFDM_CDD2, WL_RATE_1X3_CDD_OFDM_9},
{"OFDM12_CDD2", RATE_GROUP_ID_OFDM_CDD2, WL_RATE_1X3_CDD_OFDM_12},
{"OFDM18_CDD2", RATE_GROUP_ID_OFDM_CDD2, WL_RATE_1X3_CDD_OFDM_18},
{"OFDM24_CDD2", RATE_GROUP_ID_OFDM_CDD2, WL_RATE_1X3_CDD_OFDM_24},
{"OFDM36_CDD2", RATE_GROUP_ID_OFDM_CDD2, WL_RATE_1X3_CDD_OFDM_36},
{"OFDM48_CDD2", RATE_GROUP_ID_OFDM_CDD2, WL_RATE_1X3_CDD_OFDM_48},
{"OFDM54_CDD2", RATE_GROUP_ID_OFDM_CDD2, WL_RATE_1X3_CDD_OFDM_54},
{"MCS0_CDD2", RATE_GROUP_ID_MCS0_7_CDD2, WL_RATE_1X3_CDD_MCS0},
{"MCS1_CDD2", RATE_GROUP_ID_MCS0_7_CDD2, WL_RATE_1X3_CDD_MCS1},
{"MCS2_CDD2", RATE_GROUP_ID_MCS0_7_CDD2, WL_RATE_1X3_CDD_MCS2},
{"MCS3_CDD2", RATE_GROUP_ID_MCS0_7_CDD2, WL_RATE_1X3_CDD_MCS3},
{"MCS4_CDD2", RATE_GROUP_ID_MCS0_7_CDD2, WL_RATE_1X3_CDD_MCS4},
{"MCS5_CDD2", RATE_GROUP_ID_MCS0_7_CDD2, WL_RATE_1X3_CDD_MCS5},
{"MCS6_CDD2", RATE_GROUP_ID_MCS0_7_CDD2, WL_RATE_1X3_CDD_MCS6},
{"MCS7_CDD2", RATE_GROUP_ID_MCS0_7_CDD2, WL_RATE_1X3_CDD_MCS7},
{"VHT8SS1_CDD2", RATE_GROUP_ID_VHT8_9SS1_CDD2, WL_RATE_1X3_VHT8SS1},
{"VHT9SS1_CDD2", RATE_GROUP_ID_VHT8_9SS1_CDD2, WL_RATE_1X3_VHT9SS1},
{"MCS0_STBC_SPEXP1", RATE_GROUP_ID_MCS0_7_STBC_SPEXP1, WL_RATE_2X3_STBC_MCS0},
{"MCS1_STBC_SPEXP1", RATE_GROUP_ID_MCS0_7_STBC_SPEXP1, WL_RATE_2X3_STBC_MCS1},
{"MCS2_STBC_SPEXP1", RATE_GROUP_ID_MCS0_7_STBC_SPEXP1, WL_RATE_2X3_STBC_MCS2},
{"MCS3_STBC_SPEXP1", RATE_GROUP_ID_MCS0_7_STBC_SPEXP1, WL_RATE_2X3_STBC_MCS3},
{"MCS4_STBC_SPEXP1", RATE_GROUP_ID_MCS0_7_STBC_SPEXP1, WL_RATE_2X3_STBC_MCS4},
{"MCS5_STBC_SPEXP1", RATE_GROUP_ID_MCS0_7_STBC_SPEXP1, WL_RATE_2X3_STBC_MCS5},
{"MCS6_STBC_SPEXP1", RATE_GROUP_ID_MCS0_7_STBC_SPEXP1, WL_RATE_2X3_STBC_MCS6},
{"MCS7_STBC_SPEXP1", RATE_GROUP_ID_MCS0_7_STBC_SPEXP1, WL_RATE_2X3_STBC_MCS7},
{"VHT8SS1_STBC_SPEXP1", RATE_GROUP_ID_VHT8_9SS1_STBC_SPEXP1, WL_RATE_2X3_STBC_VHT8SS1},
{"VHT9SS1_STBC_SPEXP1", RATE_GROUP_ID_VHT8_9SS1_STBC_SPEXP1, WL_RATE_2X3_STBC_VHT9SS1},
{"MCS8_SPEXP1", RATE_GROUP_ID_MCS8_15_SPEXP1, WL_RATE_2X3_SDM_MCS8},
{"MCS9_SPEXP1", RATE_GROUP_ID_MCS8_15_SPEXP1, WL_RATE_2X3_SDM_MCS9},
{"MCS10_SPEXP1", RATE_GROUP_ID_MCS8_15_SPEXP1, WL_RATE_2X3_SDM_MCS10},
{"MCS11_SPEXP1", RATE_GROUP_ID_MCS8_15_SPEXP1, WL_RATE_2X3_SDM_MCS11},
{"MCS12_SPEXP1", RATE_GROUP_ID_MCS8_15_SPEXP1, WL_RATE_2X3_SDM_MCS12},
{"MCS13_SPEXP1", RATE_GROUP_ID_MCS8_15_SPEXP1, WL_RATE_2X3_SDM_MCS13},
{"MCS14_SPEXP1", RATE_GROUP_ID_MCS8_15_SPEXP1, WL_RATE_2X3_SDM_MCS14},
{"MCS15_SPEXP1", RATE_GROUP_ID_MCS8_15_SPEXP1, WL_RATE_2X3_SDM_MCS15},
{"VHT8SS2_SPEXP1", RATE_GROUP_ID_VHT8_9SS2_SPEXP1, WL_RATE_2X3_VHT8SS2},
{"VHT9SS2_SPEXP1", RATE_GROUP_ID_VHT8_9SS2_SPEXP1, WL_RATE_2X3_VHT9SS2},
{"MCS16", RATE_GROUP_ID_MCS16_23, WL_RATE_3X3_SDM_MCS16},
{"MCS17", RATE_GROUP_ID_MCS16_23, WL_RATE_3X3_SDM_MCS17},
{"MCS18", RATE_GROUP_ID_MCS16_23, WL_RATE_3X3_SDM_MCS18},
{"MCS19", RATE_GROUP_ID_MCS16_23, WL_RATE_3X3_SDM_MCS19},
{"MCS20", RATE_GROUP_ID_MCS16_23, WL_RATE_3X3_SDM_MCS20},
{"MCS21", RATE_GROUP_ID_MCS16_23, WL_RATE_3X3_SDM_MCS21},
{"MCS22", RATE_GROUP_ID_MCS16_23, WL_RATE_3X3_SDM_MCS22},
{"MCS23", RATE_GROUP_ID_MCS16_23, WL_RATE_3X3_SDM_MCS23},
{"VHT8SS3", RATE_GROUP_ID_VHT8_9SS3, WL_RATE_3X3_VHT8SS3},
{"VHT9SS3", RATE_GROUP_ID_VHT8_9SS3, WL_RATE_3X3_VHT9SS3},
{"OFDM6_TXBF1", RATE_GROUP_ID_OFDM_TXBF1, WL_RATE_1X2_TXBF_OFDM_6},
{"OFDM9_TXBF1", RATE_GROUP_ID_OFDM_TXBF1, WL_RATE_1X2_TXBF_OFDM_9},
{"OFDM12_TXBF1", RATE_GROUP_ID_OFDM_TXBF1, WL_RATE_1X2_TXBF_OFDM_12},
{"OFDM18_TXBF1", RATE_GROUP_ID_OFDM_TXBF1, WL_RATE_1X2_TXBF_OFDM_18},
{"OFDM24_TXBF1", RATE_GROUP_ID_OFDM_TXBF1, WL_RATE_1X2_TXBF_OFDM_24},
{"OFDM36_TXBF1", RATE_GROUP_ID_OFDM_TXBF1, WL_RATE_1X2_TXBF_OFDM_36},
{"OFDM48_TXBF1", RATE_GROUP_ID_OFDM_TXBF1, WL_RATE_1X2_TXBF_OFDM_48},
{"OFDM54_TXBF1", RATE_GROUP_ID_OFDM_TXBF1, WL_RATE_1X2_TXBF_OFDM_54},
{"MCS0_TXBF1", RATE_GROUP_ID_MCS0_7_TXBF1, WL_RATE_1X2_TXBF_MCS0},
{"MCS1_TXBF1", RATE_GROUP_ID_MCS0_7_TXBF1, WL_RATE_1X2_TXBF_MCS1},
{"MCS2_TXBF1", RATE_GROUP_ID_MCS0_7_TXBF1, WL_RATE_1X2_TXBF_MCS1},
{"MCS3_TXBF1", RATE_GROUP_ID_MCS0_7_TXBF1, WL_RATE_1X2_TXBF_MCS3},
{"MCS4_TXBF1", RATE_GROUP_ID_MCS0_7_TXBF1, WL_RATE_1X2_TXBF_MCS4},
{"MCS5_TXBF1", RATE_GROUP_ID_MCS0_7_TXBF1, WL_RATE_1X2_TXBF_MCS5},
{"MCS6_TXBF1", RATE_GROUP_ID_MCS0_7_TXBF1, WL_RATE_1X2_TXBF_MCS6},
{"MCS7_TXBF1", RATE_GROUP_ID_MCS0_7_TXBF1, WL_RATE_1X2_TXBF_MCS7},
{"VHT8SS1_TXBF1", RATE_GROUP_ID_VHT8_9SS1_TXBF1, WL_RATE_1X2_TXBF_VHT8SS1},
{"VHT9SS1_TXBF1", RATE_GROUP_ID_VHT8_9SS1_TXBF1, WL_RATE_1X2_TXBF_VHT9SS1},
{"MCS8_TXBF0", RATE_GROUP_ID_MCS8_15_TXBF0, WL_RATE_2X2_TXBF_SDM_MCS8},
{"MCS9_TXBF0", RATE_GROUP_ID_MCS8_15_TXBF0, WL_RATE_2X2_TXBF_SDM_MCS9},
{"MCS10_TXBF0", RATE_GROUP_ID_MCS8_15_TXBF0, WL_RATE_2X2_TXBF_SDM_MCS10},
{"MCS11_TXBF0", RATE_GROUP_ID_MCS8_15_TXBF0, WL_RATE_2X2_TXBF_SDM_MCS11},
{"MCS12_TXBF0", RATE_GROUP_ID_MCS8_15_TXBF0, WL_RATE_2X2_TXBF_SDM_MCS12},
{"MCS13_TXBF0", RATE_GROUP_ID_MCS8_15_TXBF0, WL_RATE_2X2_TXBF_SDM_MCS13},
{"MCS14_TXBF0", RATE_GROUP_ID_MCS8_15_TXBF0, WL_RATE_2X2_TXBF_SDM_MCS14},
{"MCS15_TXBF0", RATE_GROUP_ID_MCS8_15_TXBF0, WL_RATE_2X2_TXBF_SDM_MCS15},
{"OFDM6_TXBF2", RATE_GROUP_ID_OFDM_TXBF2, WL_RATE_1X3_TXBF_OFDM_6},
{"OFDM9_TXBF2", RATE_GROUP_ID_OFDM_TXBF2, WL_RATE_1X3_TXBF_OFDM_9},
{"OFDM12_TXBF2", RATE_GROUP_ID_OFDM_TXBF2, WL_RATE_1X3_TXBF_OFDM_12},
{"OFDM18_TXBF2", RATE_GROUP_ID_OFDM_TXBF2, WL_RATE_1X3_TXBF_OFDM_18},
{"OFDM24_TXBF2", RATE_GROUP_ID_OFDM_TXBF2, WL_RATE_1X3_TXBF_OFDM_24},
{"OFDM36_TXBF2", RATE_GROUP_ID_OFDM_TXBF2, WL_RATE_1X3_TXBF_OFDM_36},
{"OFDM48_TXBF2", RATE_GROUP_ID_OFDM_TXBF2, WL_RATE_1X3_TXBF_OFDM_48},
{"OFDM54_TXBF2", RATE_GROUP_ID_OFDM_TXBF2, WL_RATE_1X3_TXBF_OFDM_54},
{"MCS0_TXBF2", RATE_GROUP_ID_MCS0_7_TXBF2, WL_RATE_1X3_TXBF_MCS0},
{"MCS1_TXBF2", RATE_GROUP_ID_MCS0_7_TXBF2, WL_RATE_1X3_TXBF_MCS1},
{"MCS2_TXBF2", RATE_GROUP_ID_MCS0_7_TXBF2, WL_RATE_1X3_TXBF_MCS2},
{"MCS3_TXBF2", RATE_GROUP_ID_MCS0_7_TXBF2, WL_RATE_1X3_TXBF_MCS3},
{"MCS4_TXBF2", RATE_GROUP_ID_MCS0_7_TXBF2, WL_RATE_1X3_TXBF_MCS4},
{"MCS5_TXBF2", RATE_GROUP_ID_MCS0_7_TXBF2, WL_RATE_1X3_TXBF_MCS5},
{"MCS6_TXBF2", RATE_GROUP_ID_MCS0_7_TXBF2, WL_RATE_1X3_TXBF_MCS6},
{"MCS7_TXBF2", RATE_GROUP_ID_MCS0_7_TXBF2, WL_RATE_1X3_TXBF_MCS7},
{"VHT8SS1_TXBF2", RATE_GROUP_ID_VHT8_9SS1_TXBF2, WL_RATE_1X3_TXBF_VHT8SS1},
{"VHT9SS1_TXBF2", RATE_GROUP_ID_VHT8_9SS1_TXBF2, WL_RATE_1X3_TXBF_VHT9SS1},
{"MCS8_TXBF1", RATE_GROUP_ID_MCS8_15_TXBF1, WL_RATE_2X3_TXBF_SDM_MCS8},
{"MCS9_TXBF1", RATE_GROUP_ID_MCS8_15_TXBF1, WL_RATE_2X3_TXBF_SDM_MCS9},
{"MCS10_TXBF1", RATE_GROUP_ID_MCS8_15_TXBF1, WL_RATE_2X3_TXBF_SDM_MCS10},
{"MCS11_TXBF1", RATE_GROUP_ID_MCS8_15_TXBF1, WL_RATE_2X3_TXBF_SDM_MCS11},
{"MCS12_TXBF1", RATE_GROUP_ID_MCS8_15_TXBF1, WL_RATE_2X3_TXBF_SDM_MCS12},
{"MCS13_TXBF1", RATE_GROUP_ID_MCS8_15_TXBF1, WL_RATE_2X3_TXBF_SDM_MCS13},
{"MCS14_TXBF1", RATE_GROUP_ID_MCS8_15_TXBF1, WL_RATE_2X3_TXBF_SDM_MCS14},
{"MCS15_TXBF1", RATE_GROUP_ID_MCS8_15_TXBF1, WL_RATE_2X3_TXBF_SDM_MCS15},
{"VHT8SS2_TXBF1", RATE_GROUP_ID_VHT8_9SS2_TXBF1, WL_RATE_2X3_TXBF_VHT8SS2},
{"VHT9SS2_TXBF1", RATE_GROUP_ID_VHT8_9SS2_TXBF1, WL_RATE_2X3_TXBF_VHT9SS2},
{"MCS16_TXBF0", RATE_GROUP_ID_MCS16_23_TXBF0, WL_RATE_3X3_TXBF_SDM_MCS16},
{"MCS17_TXBF0", RATE_GROUP_ID_MCS16_23_TXBF0, WL_RATE_3X3_TXBF_SDM_MCS17},
{"MCS18_TXBF0", RATE_GROUP_ID_MCS16_23_TXBF0, WL_RATE_3X3_TXBF_SDM_MCS18},
{"MCS19_TXBF0", RATE_GROUP_ID_MCS16_23_TXBF0, WL_RATE_3X3_TXBF_SDM_MCS19},
{"MCS20_TXBF0", RATE_GROUP_ID_MCS16_23_TXBF0, WL_RATE_3X3_TXBF_SDM_MCS20},
{"MCS21_TXBF0", RATE_GROUP_ID_MCS16_23_TXBF0, WL_RATE_3X3_TXBF_SDM_MCS21},
{"MCS22_TXBF0", RATE_GROUP_ID_MCS16_23_TXBF0, WL_RATE_3X3_TXBF_SDM_MCS22},
{"MCS23_TXBF0", RATE_GROUP_ID_MCS16_23_TXBF0, WL_RATE_3X3_TXBF_SDM_MCS23},
};
#define MHZ_TO_HALF_MHZ 2
const char *get_clm_rate_group_label(int rategroup);
const char *get_reg_rate_string_from_ratespec(int ratespec);
reg_rate_index_t get_reg_rate_index_from_ratespec(int ratespec);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* _WLU_RATES_MATRIX_H_ */

View File

@@ -0,0 +1,255 @@
/*
* OS independent remote wl declarations
*
* $Copyright (C) 2008 Broadcom Corporation$
*
* $Id: wlu_remote.h 401759 2013-05-13 16:08:08Z sudhirbs $
*/
#ifndef _wlu_remote_h
#define _wlu_remote_h
#include <wlioctl.h>
/* Remote wl declararions */
#define NO_REMOTE 0
#define REMOTE_SERIAL 1
#define REMOTE_SOCKET 2
#define REMOTE_WIFI 3
#define REMOTE_DONGLE 4
#define SHELL_CMD -1 /* Invalid cmd id for shell */
#define ASD_CMD -2 /* Cmd id for ASD command */
#define SERVER_RESPONSE_MAX_BUF_LEN 8192
#define SHELL_RESP_SIZE 1024
#define CTRLC_PACKET 0xDEADBEAF
#define CTRLC_FLAG -4
#define VISTA_CMD -3 /* cmd id for remote vista */
/* For cross OS support */
/* For autonegotiation to work, these defines should be
* the same for client and server.
*/
#define UNKNOWN_OS 0
#define LINUX_OS 1
#define WIN32_OS 2
#define MAC_OSX 3
#define BACKLOG 4
#define WINVISTA_OS 5
#define INDONGLE 6
#define INVALID_OS 7 /* Should be last */
/* Used in cdc_ioctl_t.flags field */
#define REMOTE_SET_IOCTL 1
#define REMOTE_GET_IOCTL 2
#define REMOTE_REPLY 4
#define REMOTE_SHELL_CMD 8
#define REMOTE_FINDSERVER_IOCTL 16 /* Find remote server */
#define REMOTE_ASD_CMD 32 /* ASD integration */
#define RDHD_SET_IOCTL 64
#define RDHD_GET_IOCTL 128
#define REMOTE_VISTA_CMD 256 /* for remote vista specific commands */
#define REMOTE_NEGOTIATE_CMD 512 /* for RWL negotiation */
#define NEGOTIATE_GET_OS 0 /* detect remote OS */
#define RWL_WIFI_DEFAULT_TYPE 0x00
#define RWL_WIFI_DEFAULT_SUBTYPE 0x00
#define RWL_ACTION_FRAME_DATA_SIZE 1024 /* fixed size for the wifi frame data */
#define RWL_WIFI_CDC_HEADER_OFFSET 0
#define RWL_WIFI_FRAG_DATA_SIZE 960 /* max size of the frag data */
#define RWL_DEFAULT_WIFI_FRAG_COUNT 127 /* maximum fragment count */
#define RWL_WIFI_RETRY 5 /* CMD retry count for wifi */
#define RWL_WIFI_RX_RETRY 20 /* WIFI response rerty count */
#define RWL_WIFI_SEND 5 /* WIFI frame sent count */
#define RWL_WIFI_RETRY_DELAY 1000 /* wifi specific retry delay */
#define RWL_WIFI_SEND_DELAY 100 /* delay between two frames */
#define RWL_WIFI_RX_DELAY 250 /* wait between send and receive */
#define RWL_WIFI_RX_SHELL_DELAY 1000 /* delay added for shell cmd response read */
#define RWL_CHANNEL_RX_SCAN_DELAY 10 /* Delay between findserver rx calls */
#define RWL_CHANNEL_SCAN_WAIT 250 /* Sleep time in between the channel scans */
#define RWL_WIFI_BUF_LEN 64
#define RWL_WIFI_SHELL_CMD 1
#define RWL_WIFI_WL_CMD 0
#define RWL_WIFI_FIND_SER_CMD "findserver"
#define RWL_WIFI_ACTION_CMD "wifiaction"
#define RWL_WIFI_GET_ACTION_CMD "rwlwifivsaction"
#define RWL_DONGLE_SET_CMD "dongleset"
#define DATA_FRAME_LEN 960
/* wl & shell cmd work fine for 960 (512+256+128+64) */
/*
* Information about the action frame data fields in the
* dot11_action_wifi_vendor_specific
* cdc struct (1 to 16. This does not include status flag. Since this
* is not directly visible to the driver code we cant use sizeof struct
* cdc_ioctl_t. Hence Ref MAC address offset starts from byte 17.
* REF MAC ADDR (6 bytes (MAC Address len) from byte 17 to 22)
* DUT MAC ADDR (6 bytes after the REF MAC Address byte 23 to 28)
* unused (byte 29 to 49)
* REF/Client Channel offset (50)
* DUT/Server channel offset (51)
* ---------------------------------------------------------------------------------------
* cdc struct|REF MAC ADDR|DUT_MAC_ADDR|un used|REF Channel|DUT channel|Action frame Data|
* 1---------17-----------23-------------------50----------51----------52----------------1040
* REF MAC addr after CDC struct without status flag (status flag not used by wifi)
*/
#define RWL_ACTION_WIFI_CATEGORY 127 /* Vendor Specific category value for wifi */
#define RWL_REF_MAC_ADDRESS_OFFSET 17
#define RWL_DUT_MAC_ADDRESS_OFFSET 23
#define RWL_WIFI_CLIENT_CHANNEL_OFFSET 50
#define RWL_WIFI_SERVER_CHANNEL_OFFSET 51
#define SUCCESS 1
#define FAIL -1
#define NO_PACKET -2
#define SERIAL_PORT_ERR -3
#define DEFAULT_SERVER_PORT 8000
#define WL_MAX_BUF_LEN (127 * 1024)
#define MAX_VISTA_ARGC 10
#define HOST_TO_NETWORK TRUE
#define NETWORK_TO_HOST FALSE
#ifndef IFNAMSIZ
#define IFNAMSIZ 16
#endif
#if defined (WIN32) || defined (LINUX)
/* We don't want the server to allocate bigger buffers for some of the commands
* like scanresults. Server can still allocate 8K memory and send the response
* in fragments. This is used in case of Get commands only.
*/
#define SERVER_RESPONSE_MAX_BUF_LEN 8192
#endif
/* Used to set the cmds for wifi specific init */
typedef struct remote_wifi_cmds {
uint32 cmd; /* common ioctl definition */
char *data; /* max size of the data length */
int value;
} remote_wifi_cmds_t;
/* Added for debug utility support */
#define ERR stderr
#define OUTPUT stdout
#define DEBUG_DEFAULT 0x0001
#define DEBUG_ERR 0x0001
#define DEBUG_INFO 0x0002
#define DEBUG_DBG 0x0004
/* #ifdef TARGETOS_symbian */
#if 0
/* There is some side-defect when SymbianPrintf is used
* Error in Com Port Recv
*/
extern void SymbianPrintf(void *fd, char *format, ...);
#define DPRINT_ERR if (defined_debug & DEBUG_ERR) \
SymbianPrintf
#define DPRINT_INFO if (defined_debug & DEBUG_INFO) \
SymbianPrintf
#define DPRINT_DBG if (defined_debug & DEBUG_DBG) \
SymbianPrintf
#else
#define DPRINT_ERR if (defined_debug & DEBUG_ERR) \
fprintf
#define DPRINT_INFO if (defined_debug & DEBUG_INFO) \
fprintf
#define DPRINT_DBG if (defined_debug & DEBUG_DBG) \
fprintf
#endif /* TARGETOS_symbian */
extern unsigned short defined_debug;
#ifdef WIN32
#if 0
#define IPV4_ADDR_LEN 4
/* IPV4 packet formats */
struct ipv4_addr {
uint8 addr[IPV4_ADDR_LEN];
} PACKED;
#endif
/* Function defined in wlu.c for client and wlu_server_ce.c for server */
extern int wl_atoip(const char *a, struct ipv4_addr *n);
#endif /* WIN32 */
/* Function defined to do host to network and network to host conversions */
void rwl_swap_header(rem_ioctl_t *rem_ptr, bool host_to_network);
/* Macros to access remote type */
extern int remote_type;
#define rwl_get_remote_type() (remote_type)
#define rwl_set_remote_type(type) (remote_type = type)
/* Macros to access server IP and port globals */
extern char *g_rwl_servIP;
#define rwl_get_server_ip() (g_rwl_servIP)
#define rwl_set_server_ip(ip) (g_rwl_servIP = ip)
extern unsigned short g_rwl_servport;
#define rwl_get_server_port() (g_rwl_servport)
#define rwl_set_server_port(port) (g_rwl_servport = port)
/* Wrapper functions defined in wlu_pipe_xxx.c where xxx is OS specific */
extern int rwl_read_serial_port(void* hndle, char* read_buf, uint data_size, uint *numread);
extern int rwl_write_serial_port(void* hndle, char* write_buf, unsigned long size,
unsigned long *numwritten);
extern void rwl_sleep(int delay);
extern void* rwl_open_transport(int remote_type, char *port, int ReadTotalTimeout, int debug);
extern int rwl_close_transport(int remote_type, void * handle);
extern int rwl_poll_serial_buffer(void *hndle);
extern int rwl_serial_handle_timeout(void);
extern void rwl_sync_delay(uint noframes);
#ifdef RWL_SOCKET
extern int rwl_connectsocket(int SocketDes, struct sockaddr* SerAddr, int SizeOfAddr);
extern int rwl_acceptconnection(int SocketDes, struct sockaddr *ClientAddr, int *SizeOfAddr);
extern int rwl_send_to_streamsocket(int SocketDes, const char* SendBuff, int data_size, int Flag);
extern int rwl_receive_from_streamsocket(int SocketDes, char* RecvBuff, int data_size, int Flag);
extern int rwl_init_server_socket_setup(int argc, char** argv, uint remote_type);
#ifdef vxworks
extern int rwl_GetifAddr(char *ifname, char *ifaddr);
#else
extern int rwl_GetifAddr(char *ifname, struct sockaddr_in* sa);
#endif /* vxworks */
#endif /* RWL_SOCKET */
#if defined(vxworks) || defined(LINUX)
extern int set_interface(void *wl, char *intf_name);
#endif /* defined(vxworks) || defined(LINUX) */
/* Win32 specific function wlu_pipe_win32.c */
extern int rwl_init_ws2_32dll(void);
extern int rwl_terminate_ws2_32dll(void);
/* Function definitions for wlu_client_shared.c and wlu_server_shared.c */
extern int rwl_var_getbuf(void *wl, const char *iovar, void *param, int param_len, void **bufptr);
extern int rwl_var_setbuf(void *wl, const char *iovar, void *param, int param_len);
extern int rwl_var_send_vs_actionframe(void* wl, const char* iovar, void* param, int param_len);
/* Function definitions for wlu_ndis.c/wlu_linux.c and wlu_server_ce.c/wlu_server_linux.c */
extern int wl_get(void *wl, int cmd, void *buf, int len);
extern int wl_set(void *wl, int cmd, void *buf, int len);
#ifdef RWLASD
typedef unsigned char BYTE;
extern void wfa_dut_init(BYTE **tBuf, BYTE **rBuf, BYTE **paBuf, BYTE **cBuf, struct timeval **);
extern int remote_asd_exec(unsigned char* command, int* cmd_len);
void wfa_dut_deinit(void);
#endif
extern int get_ctrlc_header(void *wl);
extern int remote_tx_response(void *wl, void *buf_ptr, int cmd);
extern rem_ioctl_t *g_rem_ptr;
extern int g_rwl_hndle;
#if defined (LINUX) || defined (MACOSX)
/* Variable to indiate if the server child has completed execution */
extern volatile sig_atomic_t g_sig_chld;
#endif
/*
* Separate paths are defined for android and linux machines
* / filesystem on android is read only memory
*/
#ifndef WIN32
#ifdef TARGETENV_android
#define SH_PATH "/data/busybox/sh"
#define SHELL_RESP_PATH "/data/local/RWL/" /* Default path for storing files for shell response */
#define TEMPLATE "/data/local/RWL/SyncXXXXXX"
#else
#define SHELL_RESP_PATH "/tmp/RWL/" /* Default path for storing files for shell response */
#define TEMPLATE "/tmp/RWL/SyncXXXXXX"
#define SH_PATH "/bin/sh"
#endif
#endif /* !WIN32 */
#endif /* _wlu_remote_h */

View File

@@ -0,0 +1,379 @@
/*
* Wl server for linux
*
* Copyright (C) 2013, Broadcom Corporation
* All Rights Reserved.
*
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation;
* the contents of this file may not be disclosed to third parties, copied
* or duplicated in any form, in whole or in part, without the prior
* written permission of Broadcom Corporation.
*
* $Id: wlu_server_linux.c 363687 2012-10-19 00:09:59Z $
*/
/* Revision History:Linux port of Remote wl server
*
* Date Author Description
*
* 27-Dec-2007 Suganthi Version 0.1
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <malloc.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <net/if.h>
#ifndef TARGETENV_android
typedef u_int64_t u64;
typedef u_int32_t u32;
typedef u_int16_t u16;
typedef u_int8_t u8;
typedef u_int64_t __u64;
typedef u_int32_t __u32;
typedef u_int16_t __u16;
typedef u_int8_t __u8;
#endif
#include <linux/sockios.h>
#include <linux/ethtool.h>
#include <typedefs.h>
#include <wlioctl.h>
#include <dhdioctl.h>
#include <proto/ethernet.h>
#include <bcmendian.h>
#include <bcmutils.h>
#include <bcmcdc.h>
#include <proto/802.11.h>
#include "wlu_remote.h"
#define DEV_TYPE_LEN 3 /* length for devtype 'wl'/'et' */
#define IOCTL_ERROR -2
#define BUF_LENGTH 1000
#define dtoh32(i) i
const char *rwl_server_name;
void *g_wl_handle;
unsigned short defined_debug = DEBUG_ERR | DEBUG_INFO;
extern int remote_server_exec(int argc, char **argv, void *ifr);
/* Global to have the PID of the current sync command
* This is required in case the sync command fails to respond,
* the alarm handler shall kill the PID upon a timeout
*/
int g_shellsync_pid;
unsigned char g_return_stat = 0;
static void
syserr(char *s)
{
fprintf(stderr, "%s: ", rwl_server_name);
perror(s);
exit(errno);
}
/* The handler for DHD commands */
int
dhd_ioctl(void *dhd, int cmd, void *buf, int len, bool set)
{
struct ifreq *ifr = (struct ifreq *) dhd;
dhd_ioctl_t ioc;
int ret = 0;
int s;
/* open socket to kernel */
if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
syserr("socket");
/* do it */
ioc.cmd = cmd;
ioc.buf = buf;
ioc.len = len;
ioc.set = set;
ioc.driver = DHD_IOCTL_MAGIC;
ifr->ifr_data = (caddr_t) &ioc;
if ((ret = ioctl(s, SIOCDEVPRIVATE, ifr)) < 0) {
if (cmd != DHD_GET_MAGIC) {
ret = IOCTL_ERROR;
}
}
/* cleanup */
close(s);
return ret;
}
int
wl_ioctl(void *wl, int cmd, void *buf, int len, bool set)
{
struct ifreq *ifr = (struct ifreq *) wl;
wl_ioctl_t ioc;
int ret = 0;
int s;
/* open socket to kernel */
if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
syserr("socket");
/* do it */
ioc.cmd = cmd;
ioc.buf = buf;
ioc.len = len;
ioc.set = set;
ifr->ifr_data = (caddr_t) &ioc;
if ((ret = ioctl(s, SIOCDEVPRIVATE, ifr)) < 0) {
if (cmd != WLC_GET_MAGIC) {
ret = IOCTL_ERROR;
}
}
/* cleanup */
close(s);
return ret;
}
/* Functions copied from wlu.c to check for the driver adapter in the server machine */
int
wl_check(void *wl)
{
int ret;
int val;
if ((ret = wl_ioctl(wl, WLC_GET_MAGIC, &val, sizeof(int), FALSE)) < 0)
return ret;
if (val != WLC_IOCTL_MAGIC)
return -1;
if ((ret = wl_ioctl(wl, WLC_GET_VERSION, &val, sizeof(int), FALSE)) < 0)
return ret;
val = dtoh32(val);
if (val > WLC_IOCTL_VERSION) {
fprintf(stderr, "Version mismatch, please upgrade\n");
return -1;
}
return 0;
}
static int
wl_get_dev_type(char *name, void *buf, int len)
{
int s;
int ret;
struct ifreq ifr;
struct ethtool_drvinfo info;
/* open socket to kernel */
if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
syserr("socket");
/* get device type */
memset(&info, 0, sizeof(info));
info.cmd = ETHTOOL_GDRVINFO;
ifr.ifr_data = (caddr_t)&info;
strncpy(ifr.ifr_name, name, IFNAMSIZ);
if ((ret = ioctl(s, SIOCETHTOOL, &ifr)) < 0) {
/* print a good diagnostic if not superuser */
if (errno == EPERM)
syserr("wl_get_dev_type");
*(char *)buf = '\0';
} else {
strncpy(buf, info.driver, len);
}
close(s);
return ret;
}
static void
wl_find_adapter(struct ifreq *ifr)
{
char proc_net_dev[] = "/proc/net/dev";
FILE *fp;
char buf[BUF_LENGTH], *c, *name;
char dev_type[DEV_TYPE_LEN];
ifr->ifr_name[0] = '\0';
if (!(fp = fopen(proc_net_dev, "r")))
return;
/* eat first two lines */
if (!fgets(buf, sizeof(buf), fp) ||
!fgets(buf, sizeof(buf), fp)) {
fclose(fp);
return;
}
while (fgets(buf, sizeof(buf), fp)) {
c = buf;
while (isspace(*c))
c++;
if (!(name = strsep(&c, ":")))
continue;
strncpy(ifr->ifr_name, name, IFNAMSIZ);
if (wl_get_dev_type(name, dev_type, DEV_TYPE_LEN) >= 0 &&
!strncmp(dev_type, "wl", 2))
if (wl_check((void *) ifr) == 0)
break;
ifr->ifr_name[0] = '\0';
}
fclose(fp);
}
int
wl_get(void *wl, int cmd, void *buf, int len)
{
int error;
error = wl_ioctl(wl, cmd, buf, len, FALSE);
return error;
}
int
wl_set(void *wl, int cmd, void *buf, int len)
{
int error;
error = wl_ioctl(wl, cmd, buf, len, TRUE);
return error;
}
extern int set_ctrlc;
void handle_ctrlc(int unused)
{
UNUSED_PARAMETER(unused);
set_ctrlc = 1;
return;
}
volatile sig_atomic_t g_sig_chld = 1;
void rwl_chld_handler(int num)
{
int child_status;
UNUSED_PARAMETER(num);
/* g_return_stat is being set with the return status of sh commands */
waitpid(g_shellsync_pid, &child_status, WNOHANG);
if (WIFEXITED(child_status))
g_return_stat = WEXITSTATUS(child_status);
else if (g_rem_ptr->msg.flags == (unsigned)CTRLC_FLAG)
g_return_stat = 0;
else
g_return_stat = 1;
g_sig_chld = 0;
}
/* Alarm handler called after SHELL_TIMEOUT value
* This handler kills the non-responsive shell process
* with the PID value g_shellsync_pid
*/
static void
sigalrm_handler(int s)
{
UNUSED_PARAMETER(s);
if (g_shellsync_pid) {
kill(g_shellsync_pid, SIGINT);
}
#ifdef RWL_SOCKET
g_sig_chld = 0;
#endif
}
static void
def_handler(int s)
{
UNUSED_PARAMETER(s);
kill(g_shellsync_pid, SIGKILL);
exit(0);
}
static void
pipe_handler(int s)
{
UNUSED_PARAMETER(s);
kill(g_shellsync_pid, SIGKILL);
}
int
main(int argc, char **argv)
{
int err = 0;
struct ifreq *ifr;
rwl_server_name = argv[0];
if ((ifr = malloc(sizeof(struct ifreq))) == NULL)
{
DPRINT_ERR(ERR, "wl_server: Unable to allocate memory for handle\n");
exit(1);
}
memset(ifr, 0, sizeof(ifr));
/* use default interface */
if (!ifr->ifr_name[0])
wl_find_adapter(ifr);
/* validate the interface */
if (!ifr->ifr_name[0] || wl_check((void *)ifr)) {
DPRINT_INFO(OUTPUT, "wl_server: wl driver adapter not found\n");
}
g_wl_handle = ifr;
/* Register signal handlers */
signal(SIGCHLD, rwl_chld_handler);
signal(SIGALRM, sigalrm_handler);
signal(SIGTERM, def_handler);
signal(SIGPIPE, pipe_handler);
signal(SIGABRT, def_handler);
#ifdef RWL_DONGLE
signal(SIGINT, handle_ctrlc);
#endif
/* Main server process for all transport types */
err = remote_server_exec(argc, argv, ifr);
return err;
}
/*
* Funtion to store old interface.
*/
void
store_old_interface(void *wl, char *old_intf_name)
{
strcpy(old_intf_name, ((struct ifreq *)wl)->ifr_name);
}
/*
* Function to set interface.
*/
int
set_interface(void *wl, char *intf_name)
{
struct ifreq *ifr = (struct ifreq *)wl;
if (strlen(intf_name) != 0) {
strncpy(ifr->ifr_name, intf_name, strlen(intf_name) + 1);
return BCME_OK;
}
else {
DPRINT_DBG(OUTPUT, "Default Interface will be used ... \n");
return BCME_ERROR;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,67 @@
/*
* wl server declarations
*
* Copyright (C) 2013, Broadcom Corporation
* All Rights Reserved.
*
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation;
* the contents of this file may not be disclosed to third parties, copied
* or duplicated in any form, in whole or in part, without the prior
* written permission of Broadcom Corporation.
*
* $Id: wlu_server_shared.h 287128 2011-09-30 04:27:53Z $
*/
#ifndef _wlu_server_shared_h
#define _wlu_server_shared_h
extern int wl_ioctl(void *wl, int cmd, void *buf, int len, bool set);
extern int dhd_ioctl(void *dhd, int cmd, void *buf, int len, bool set);
#ifdef RWLASD
/* streams' buffers */
BYTE *xcCmdBuf = NULL, *parmsVal = NULL;
BYTE *trafficBuf = NULL, *respBuf = NULL;
struct timeval *toutvalp = NULL;
#endif
#define POLLING_TIME 200
#define DONGLE_TX_FRAME_SIZE 1024
#define MESSAGE_LENGTH 1024
#define MAX_SHELL_FILE_LENGTH 50
#define MAX_IOVAR 10000
int remote_type = NO_REMOTE;
rem_ioctl_t *g_rem_ptr;
extern int wl_ioctl(void *wl, int cmd, void *buf, int len, bool set);
/* Function prototypes from shellpoc_linux.c/shell_ce.c */
extern int rwl_create_dir(void);
extern int remote_shell_execute(char *buf_ptr, void *wl);
extern int remote_shell_get_resp(char* shell_fname, void *wl);
extern void rwl_wifi_find_server_response(void *wl, dot11_action_wifi_vendor_specific_t *rec_frame);
extern dot11_action_wifi_vendor_specific_t *rwl_wifi_allocate_actionframe(void);
/* Common code for serial and wifi */
#if defined(RWL_DONGLE) || defined(RWL_WIFI) || defined(RWL_SERIAL)
typedef struct rem_packet {
rem_ioctl_t rem_cdc;
uchar message[MESSAGE_LENGTH];
} rem_packet_t;
#define REMOTE_PACKET_SIZE sizeof(rem_packet_t)
rem_packet_t *g_rem_pkt_ptr;
rem_packet_t g_rem_pkt;
#endif
static struct ether_addr rwlea;
static union {
uchar bufdata[WLC_IOCTL_MAXLEN];
uint32 alignme;
} bufstruct_wlu;
static uchar* rwl_buf = (uchar*) &bufstruct_wlu.bufdata;
extern int need_speedy_response;
#endif /* _wlu_server_shared_h_ */