meta-digi/meta-digi-dey/recipes-connectivity/hostapd/hostapd/murata/0025-non-upstream-wl-cmd-cr...

470 lines
15 KiB
Diff

From 05b1387d4dc2e74a02cf524733d809acc4fd46fb Mon Sep 17 00:00:00 2001
From: Kurt Lee <kurt.lee@infineon.com>
Date: Wed, 27 Apr 2022 22:50:25 -0500
Subject: [PATCH 25/60] non-upstream: wl-cmd: create ops table to do wl
commands
Creeate wl_cmds to handle wl commands
Upstream-Status: Inappropriate [DEY specific]
Signed-off-by: Ian Lin <ian.lin@infineon.com>
Signed-off-by: Kurt Lee <kurt.lee@infineon.com>
---
src/drivers/driver_brcm_wlu.c | 247 ++++++++++++++++++++++++------
src/drivers/driver_brcm_wlu.h | 2 +-
src/drivers/driver_brcm_wlu_cmd.h | 23 +++
src/drivers/driver_nl80211.c | 27 ++--
4 files changed, 240 insertions(+), 59 deletions(-)
create mode 100644 src/drivers/driver_brcm_wlu_cmd.h
diff --git a/src/drivers/driver_brcm_wlu.c b/src/drivers/driver_brcm_wlu.c
index 4fc03e446..8e568f9f6 100644
--- a/src/drivers/driver_brcm_wlu.c
+++ b/src/drivers/driver_brcm_wlu.c
@@ -10,7 +10,110 @@
#include "common.h"
#include "common/brcm_vendor.h"
#include "common/brcm_wl_ioctl.h"
+#include "common/brcm_wl_ioctl_defs.h"
#include "common/wpa_common.h"
+#include "driver_brcm_wlu_cmd.h"
+
+static cmd_func_t wl_rate;
+static cmd_func_t wl_varint;
+
+#define RATE_2G_USAGE \
+"\tEither \"auto\", or a simple CCK/DSSS/OFDM rate value:\n" \
+"\t1 2 5.5 11 6 9 12 18 24 36 48 54\n\n" \
+"\tOr options to specify legacy, HT, or VHT rate:\n" \
+"\t-r R, --rate=R : legacy rate (CCK, DSSS, OFDM)\n" \
+"\t-h M, --ht=M : HT MCS index [0-23]\n" \
+"\t-v M[xS], --vht=M[xS] : VHT MCS index M [0-9],\n" \
+"\t : and optionally Nss S [1-8], eg. 5x2 is MCS=5, Nss=2\n" \
+"\t-c cM[sS] : VHT (c notation) MCS index M [0-9],\n" \
+"\t : and optionally Nss S [1-8], eg. c5s2 is MCS=5, Nss=2\n" \
+"\t-e M[xS], --he=M[xS] : HE rate M [0-11],\n" \
+"\t-s S, --ss=S : VHT Nss [1-8], number of spatial streams, default 1.\n" \
+"\t : Only used with -v/--vht when MxS format is not used\n" \
+"\t-x T, --exp=T : Tx Expansion, number of tx chains (NTx) beyond the minimum\n" \
+"\t : required for the space-time-streams, exp = NTx - Nsts\n" \
+"\t--stbc : Use STBC expansion, otherwise no STBC\n" \
+"\t-l, --ldpc : Use LDPC encoding, otherwise no LDPC\n" \
+"\t-g, --sgi : Guard interval. Different values for HT/VHT\n" \
+"\t : Use Short Guard Interval otherwise standard GI\n" \
+"\t-i, --hegi : Guard interval. Different values for HE\n" \
+"\t : For HE, cp_ltf combination allowed values (0,1,2,3)\n" \
+"\t-b, --bandwidth : transmit bandwidth in MHz [2.5, 5, 10, 20, 40, 80, 160] eg. -b 20\n" \
+"\t-d D, --dcm=D : Use -d to set DCM, otherwise no DCM\n" \
+"\t : (only when is MCS [0, 1], NSS 1, -b 20)\n" \
+"\t-n R, --er=R : R [106,242] HE Range extension\n" \
+"\t : otherwise no Rang extension and works only in 20 MHz"
+
+#define RATE_5G_6G_USAGE \
+"\tEither \"auto\", or a simple OFDM rate value:\n" \
+"\t6 9 12 18 24 36 48 54\n\n" \
+"\tOr options to specify legacy OFDM, HT, or VHT rate:\n" \
+"\t-r R, --rate=R : legacy OFDM rate\n" \
+"\t-h M, --ht=M : HT MCS index [0-23]\n" \
+"\t-v M[xS], --vht=M[xS] : VHT MCS index M [0-9],\n" \
+"\t : and optionally Nss S [1-8], eg. 5x2 is MCS=5, Nss=2\n" \
+"\t-c cM[sS] : VHT (c notation) MCS index M [0-9],\n" \
+"\t : and optionally Nss S [1-8], eg. c5s2 is MCS=5, Nss=2\n" \
+"\t-e M[xS], --he=M[xS] : HE rate M [0-11],\n" \
+"\t-s S, --ss=S : VHT Nss [1-8], number of spatial streams, default 1.\n" \
+"\t : Only used with -v/--vht when MxS format is not used\n" \
+"\t-x T, --exp=T : Tx Expansion, number of tx chains (NTx) beyond the minimum\n" \
+"\t : required for the space-time-streams, exp = NTx - Nsts\n" \
+"\t--stbc : Use STBC expansion, otherwise no STBC\n" \
+"\t-l, --ldpc : Use LDPC encoding, otherwise no LDPC\n" \
+"\t-g, --sgi : Guard interval. Different values for HT/VHT\n" \
+"\t : Use Short Guard Interval otherwise standard GI\n" \
+"\t-i, --hegi : Guard interval. Different values for HE\n" \
+"\t : For HE cp_ltf combination allowed values (0,1,2,3)\n" \
+"\t-b, --bandwidth : transmit bandwidth in MHz [2.5, 5, 10, 20, 40, 80, 160] eg. -b 20\n" \
+"\t-d D, --dcm=D : Use -d to set DCM, otherwise no DCM\n" \
+"\t : (only when is MCS [0, 1], NSS 1, -b 20)\n" \
+"\t-n R, --er=R : R [106,242] HE Range extension\n" \
+"\t : otherwise no Rang extension and works only in 20 MHz"
+
+/* If the new command needs to be part of 'wc.exe' tool used for WMM,
+ * be sure to modify wc_cmds[] array as well
+ *
+ * If you add a command, please update wlu_cmd.c cmd2cat to categorize the command.
+ */
+cmd_t wl_cmds[] = {
+ { "2g_rate", wl_rate, WLC_GET_VAR, WLC_SET_VAR,
+ "Force a fixed rate for data frames in the 2.4G band:\n\n"
+ RATE_2G_USAGE
+ },
+ { "2g_mrate", wl_rate, WLC_GET_VAR, WLC_SET_VAR,
+ "Force a fixed rate for mulitcast/broadcast data frames in the 2.4G band:\n\n"
+ RATE_2G_USAGE
+ },
+ { "5g_rate", wl_rate, WLC_GET_VAR, WLC_SET_VAR,
+ "Force a fixed rate for data frames in the 5G band:\n\n"
+ RATE_5G_6G_USAGE
+ },
+ { "5g_mrate", wl_rate, WLC_GET_VAR, WLC_SET_VAR,
+ "Force a fixed rate for mulitcast/broadcast data frames in the 5G band:\n\n"
+ RATE_5G_6G_USAGE
+ },
+ { NULL, NULL, 0, 0, NULL }
+};
+
+cmd_t wl_varcmd = {"var", wl_varint, -1, -1, "unrecognized name, type -h for help"};
+
+/* common function to find a command */
+cmd_t *
+wlu_find_cmd(char *name)
+{
+ cmd_t *cmd = wl_cmds;
+
+ /* search cmd in cmd table */
+ for (; cmd->name; cmd++) {
+ /* stop if we find a matching name */
+ if (!os_strncasecmp(cmd->name, name, os_strlen(cmd->name))) {
+ break;
+ }
+ }
+
+ return (cmd->name != NULL) ? cmd : NULL;
+}
/*
* Format a ratespec for output of any of the wl_rate() iovars
@@ -113,8 +216,7 @@ wl_rate_print(char *rate_buf, size_t buf_len, u32 rspec)
* return FALSE if the arg does not look like MxS or cMsS, where M and S are single digits
* return TRUE if the arg does look like MxS or cMsS, setting mcsp to M, and nssp to S
*/
-//static int
-int
+static int
wl_parse_he_vht_spec(const char* cp, int* mcsp, int* nssp)
{
char *startp, *endp;
@@ -171,12 +273,13 @@ wl_parse_he_vht_spec(const char* cp, int* mcsp, int* nssp)
}
-int wl_rate_set(char *cmd, char *set_buf, u32 *set_buf_len)
+static int
+wl_rate(char *cmd, char *buf, u32 *buf_len, bool *get, bool *is_get_int)
{
int ret = -1;
- char *pos;
- //bool legacy_set = false, ht_set = false, vht_set = false, he_set = false;
- bool he_set = false;
+ char *pos, *param = cmd;
+ bool auto_set = false;
+ bool legacy_set = false, ht_set = false, vht_set = false, he_set = false;
int rate, mcs, Nss, tx_exp, bw;
bool stbc, ldpc, sgi, dcm, er;
u8 hegi;
@@ -198,7 +301,48 @@ int wl_rate_set(char *cmd, char *set_buf, u32 *set_buf_len)
dcm = false;
er = false;
- pos = os_strstr(cmd, "-r ");
+ pos = os_strstr(cmd, "5g_rate");
+ if (pos) {
+ param = cmd + strlen("5g_rate");
+ os_memcpy(buf, cmd, strlen("5g_rate")); //Keep last byte as 0x00
+ *is_get_int = true;
+ *buf_len += strlen("5g_rate");
+
+ if (os_strncasecmp(cmd, "5g_rate ", 8) == 0) {
+ param += 1;
+ *get = false;
+ cmd += strlen("5g_rate ");
+ *buf_len += 1;
+ }
+ }
+
+ pos = os_strstr(cmd, "2g_rate");
+ if (pos) {
+ param = cmd + strlen("2g_rate");
+ os_memcpy(buf, cmd, strlen("2g_rate")); //Keep last byte as 0x00
+ *is_get_int = true;
+ *buf_len += strlen("2g_rate");
+
+ if (os_strncasecmp(cmd, "2g_rate ", 8) == 0) {
+ param += 1;
+ *get = false;
+ cmd += strlen("2g_rate ");
+ *buf_len += 1;
+ }
+ }
+
+ if (*get == true) {
+ ret = 0;
+ goto exit;
+ }
+
+ /* Option: -l or --ldpc */
+ pos = os_strstr(param, "auto");
+ if (pos) {
+ auto_set = true;
+ }
+
+ pos = os_strstr(param, "-r ");
if (pos) {
pos += 3;
rate = atoi(pos) * 2;
@@ -207,7 +351,7 @@ int wl_rate_set(char *cmd, char *set_buf, u32 *set_buf_len)
}
/* Option: -e or --he */
- pos = os_strstr(cmd, "-e ");
+ pos = os_strstr(param, "-e ");
if (pos) {
char var_str[10];
pos += 3;
@@ -240,7 +384,7 @@ int wl_rate_set(char *cmd, char *set_buf, u32 *set_buf_len)
}
- pos = os_strstr(cmd, "-i ");
+ pos = os_strstr(param, "-i ");
if (pos) {
if (!he_set) {
wpa_printf(MSG_DEBUG, ":use -i option only in he ");
@@ -264,11 +408,39 @@ int wl_rate_set(char *cmd, char *set_buf, u32 *set_buf_len)
}
/* Option: -l or --ldpc */
- pos = os_strstr(cmd, "-l");
+ pos = os_strstr(param, "-l");
if (pos) {
ldpc = true;
}
+ /* set the ratespec encoding type and basic rate value */
+ if (auto_set) {
+ rspec = 0;
+ } else if (legacy_set) {
+ rspec = WL_RSPEC_ENCODE_RATE; /* 11abg */
+ rspec |= rate;
+ } else if (ht_set) {
+ rspec = WL_RSPEC_ENCODE_HT; /* 11n HT */
+ rspec |= mcs;
+ } else if (vht_set) {
+ rspec = WL_RSPEC_ENCODE_VHT; /* 11ac VHT */
+ if (Nss == 0) {
+ Nss = 1; /* default Nss = 1 if --ss option not given */
+ }
+ rspec |= (Nss << WL_RSPEC_VHT_NSS_SHIFT) | mcs;
+ } else if (he_set) {
+ rspec = WL_RSPEC_ENCODE_HE; /* 11ax HE */
+ if (Nss == 0) {
+ Nss = WL_RSPEC_HE_NSS_UNSPECIFIED;
+ }
+ rspec |= (Nss << WL_RSPEC_HE_NSS_SHIFT) | mcs;
+ } else {
+ wpa_printf(MSG_ERROR,
+ "%s: Invalid rate set for %s option\n",
+ "wl", param);
+ goto exit;
+ }
+
/* set the other rspec fields */
rspec |= (tx_exp << WL_RSPEC_TXEXP_SHIFT);
rspec |= bw;
@@ -279,54 +451,39 @@ int wl_rate_set(char *cmd, char *set_buf, u32 *set_buf_len)
rspec |= (dcm << WL_RSPEC_DCM_SHIFT);
rspec |= (er << WL_RSPEC_ER_SHIFT);
- os_memcpy(set_buf + *set_buf_len, (char *)&rspec, sizeof(rspec));
- *set_buf_len += sizeof(rspec);
+ os_memcpy(buf + *buf_len, (char *)&rspec, sizeof(rspec));
+ *buf_len += sizeof(rspec);
ret = 0;
exit:
return ret;
}
+/* just issue a wl_var_setint() or a wl_var_getint() if there is a 2nd arg */
+static int
+wl_varint(char *cmd, char *buf, u32 *buf_len, bool *get, bool *is_get_int)
+{
+ return -1;
+}
-int wl_do_cmd(char *cmd, char *smbuf, u32 *msglen, bool *set, bool *is_get_int)
+int wl_do_cmd(char *cmd, char *smbuf, u32 *msglen, bool *get, bool *is_get_int)
{
+ cmd_t *wl_cmd = NULL;
int ret = -1;
- char *pos;
-
- pos = os_strstr(cmd, "5g_rate");
- if (pos) {
- os_memcpy(smbuf, cmd, strlen("5g_rate")); //Keep last byte as 0x00
- *is_get_int = true;
- *msglen += strlen("5g_rate");
-
- if (os_strncasecmp(cmd, "5g_rate ", 8) == 0) {
- *set = true;
- cmd += strlen("5g_rate ");
- *msglen += 1;
- ret = wl_rate_set(cmd, smbuf, msglen);
- if (ret != 0)
- goto exit;
- }
- }
+ /* search for command */
+ wl_cmd = wlu_find_cmd(cmd);
- pos = os_strstr(cmd, "2g_rate");
- if (pos) {
- os_memcpy(smbuf, cmd, strlen("2g_rate")); //Keep last byte as 0x00
- *is_get_int = true;
- *msglen += strlen("2g_rate");
-
- if (os_strncasecmp(cmd, "2g_rate ", 8) == 0) {
- *set = true;
- cmd += strlen("2g_rate ");
- *msglen += 1;
-
- ret = wl_rate_set(cmd, smbuf, msglen);
- if (ret != 0)
- goto exit;
- }
+ /* defaults to using the set_var and get_var commands */
+ if (!wl_cmd) {
+ wl_cmd = &wl_varcmd;
}
+ /* do command */
+ ret = (*wl_cmd->func)(cmd, smbuf, msglen, get, is_get_int);
+ if (ret != 0)
+ goto exit;
+ ret = 0;
exit:
return ret;
}
diff --git a/src/drivers/driver_brcm_wlu.h b/src/drivers/driver_brcm_wlu.h
index 7fc9118fc..a943a0832 100644
--- a/src/drivers/driver_brcm_wlu.h
+++ b/src/drivers/driver_brcm_wlu.h
@@ -9,4 +9,4 @@
/* Format a ratespec for output of any of the wl_rate() iovars */
char* wl_rate_print(char *rate_buf, size_t buf_len, u32 rspec);
-int wl_do_cmd(char *cmd, char *smbuf, u32 *msglen, bool *set, bool *is_get_int);
+int wl_do_cmd(char *cmd, char *smbuf, u32 *msglen, bool *get, bool *is_get_int);
diff --git a/src/drivers/driver_brcm_wlu_cmd.h b/src/drivers/driver_brcm_wlu_cmd.h
new file mode 100644
index 000000000..8443a625e
--- /dev/null
+++ b/src/drivers/driver_brcm_wlu_cmd.h
@@ -0,0 +1,23 @@
+/*
+ * Broadcom Corporation OUI and vendor specific assignments
+ * Copyright (c) 2020, Broadcom Corporation.
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+typedef struct cmd cmd_t;
+typedef int (cmd_func_t)(char *cmd, char *buf, u32 *buf_len, bool *set, bool *is_get_int);
+
+/* 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[];
+
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index a6b9c860d..de58b17e1 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -10141,7 +10141,7 @@ static int nl80211_wl_reply_handler(struct nl_msg *msg, void *arg)
genlmsg_attrlen(gnlh, 0), NULL);
if (tb_msg[NL80211_ATTR_VENDOR_DATA]) {
- wpa_printf(MSG_INFO, "nl80211: Vendor Data Found");
+ wpa_printf(MSG_INFO, "nl80211: wl data found");
ret = nla_parse_nested(bcmnl, BCM_NLATTR_MAX,
tb_msg[NL80211_ATTR_VENDOR_DATA], NULL);
if (ret != 0)
@@ -10163,7 +10163,7 @@ int nl80211_wl_command(void *priv, char *cmd, char *buf, size_t buf_len)
char smbuf[WLC_IOCTL_SMLEN * 2] = {0x00};
char outbuf[WLC_IOCTL_MEDLEN] = {0x00};
u32 msglen = 0;
- bool set = false;
+ bool get = true;
bool is_get_int = false;
u32 output_val = 0x00;
@@ -10172,7 +10172,7 @@ int nl80211_wl_command(void *priv, char *cmd, char *buf, size_t buf_len)
if (!msg)
return -ENOMEM;
- ret = wl_do_cmd(cmd, smbuf, &msglen, &set, &is_get_int);
+ ret = wl_do_cmd(cmd, smbuf, &msglen, &get, &is_get_int);
if (ret != 0)
goto exit;
@@ -10182,22 +10182,23 @@ int nl80211_wl_command(void *priv, char *cmd, char *buf, size_t buf_len)
*/
if (msglen > 0x600)
msglen = 0x600;
- if (set)
- msglen += sizeof(struct bcm_nlmsg_hdr);
- else
+ if (get)
msglen = WLC_IOCTL_SMLEN;
+ else
+ msglen += sizeof(struct bcm_nlmsg_hdr);
+
nlioc = malloc(msglen);
if (nlioc == NULL) {
nlmsg_free(msg);
return -ENOMEM;
}
- if (set)
- nlioc->cmd = WLC_SET_VAR;
- else
+ if (get)
nlioc->cmd = WLC_GET_VAR;
+ else
+ nlioc->cmd = WLC_SET_VAR;
nlioc->len = msglen - sizeof(struct bcm_nlmsg_hdr);
nlioc->offset = sizeof(struct bcm_nlmsg_hdr);
- nlioc->set = set;
+ nlioc->set = !get;
nlioc->magic = 0;
os_memcpy(((void *)nlioc) + nlioc->offset, smbuf, msglen - nlioc->offset);
@@ -10213,14 +10214,14 @@ int nl80211_wl_command(void *priv, char *cmd, char *buf, size_t buf_len)
ret = send_and_recv_msgs(drv, msg, nl80211_wl_reply_handler, outbuf, NULL, NULL);
msg = NULL;
if (ret) {
- wpa_printf(MSG_ERROR, "nl80211: vendor cmd failed: "
+ wpa_printf(MSG_ERROR, "nl80211: wl cmd failed: "
"ret=%d (%s)", ret, strerror(-ret));
ret = 0;
}
- wpa_printf(MSG_DEBUG, "nl80211: vendor cmd sent successfully ");
+ wpa_printf(MSG_DEBUG, "nl80211: wl cmd sent successfully ");
- if (set == false && is_get_int == true) {
+ if (get == true && is_get_int == true) {
os_memcpy(&output_val, outbuf, sizeof(output_val));
wl_rate_print(buf, buf_len, output_val);
ret = buf_len;
--
2.17.1