diff mbox series

[OpenWrt-Devel,1/2] nl80211: add htmode to iwinfo_ops

Message ID 20191127172952.2143-3-daniel@dd-wrt.com
State Superseded
Headers show
Series iwinfo/rpcd: add current hw and ht mode to info call | expand

Commit Message

Daniel Danzberger Nov. 27, 2019, 5:29 p.m. UTC
This callback shows the currently active HTMODE of the device.

Signed-off-by: Daniel Danzberger <daniel@dd-wrt.com>
---
 include/iwinfo.h |  4 ++-
 iwinfo_nl80211.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 73 insertions(+), 1 deletion(-)

Comments

Hauke Mehrtens Dec. 19, 2019, 10:33 a.m. UTC | #1
On 11/27/19 6:29 PM, Daniel Danzberger wrote:
> This callback shows the currently active HTMODE of the device.
> 
> Signed-off-by: Daniel Danzberger <daniel@dd-wrt.com>
> ---
>  include/iwinfo.h |  4 ++-
>  iwinfo_nl80211.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 73 insertions(+), 1 deletion(-)
> 
> diff --git a/include/iwinfo.h b/include/iwinfo.h
> index d035c9c..5e64294 100644
> --- a/include/iwinfo.h
> +++ b/include/iwinfo.h
> @@ -88,8 +88,9 @@ enum iwinfo_htmode {
>  	IWINFO_HTMODE_VHT80      = (1 << 4),
>  	IWINFO_HTMODE_VHT80_80   = (1 << 5),
>  	IWINFO_HTMODE_VHT160     = (1 << 6),
> +	IWINFO_HTMODE_NOHT       = (1 << 7),
>  
> -	IWINFO_HTMODE_COUNT      = 7
> +	IWINFO_HTMODE_COUNT      = 8
>  };
>  
>  extern const char *IWINFO_HTMODE_NAMES[IWINFO_HTMODE_COUNT];
> @@ -231,6 +232,7 @@ struct iwinfo_ops {
>  	int (*mbssid_support)(const char *, int *);
>  	int (*hwmodelist)(const char *, int *);
>  	int (*htmodelist)(const char *, int *);
> +	int (*htmode)(const char *, int *);
>  	int (*ssid)(const char *, char *);
>  	int (*bssid)(const char *, char *);
>  	int (*country)(const char *, char *);
> diff --git a/iwinfo_nl80211.c b/iwinfo_nl80211.c
> index 4b6ef91..36f1da2 100644
> --- a/iwinfo_nl80211.c
> +++ b/iwinfo_nl80211.c
> @@ -2958,6 +2958,75 @@ out:
>  	return -1;
>  }
>  
> +struct chan_info {
> +	int width;
> +	int mode;
> +};
> +
> +static int nl80211_get_htmode_cb(struct nl_msg *msg, void *arg)
> +{
> +	struct nlattr **tb = nl80211_parse(msg);
> +	struct nlattr *cur;
> +	struct chan_info *chn = arg;
> +
> +	if ((cur = tb[NL80211_ATTR_CHANNEL_WIDTH]))
> +		chn->width = nla_get_u32(cur);
> +
> +	if ((cur = tb[NL80211_ATTR_BSS_HT_OPMODE]))
> +		chn->mode = nla_get_u32(cur);
> +
> +	return NL_SKIP;
> +}
> +
> +static int nl80211_get_htmode(const char *ifname, int *buf)
> +{
> +	struct chan_info chn = { .width = 0, .mode = 0 };
> +	char *res;
> +	int err;
> +
> +	res = nl80211_phy2ifname(ifname);
> +	*buf = 0;
> +
> +	err =  nl80211_request(res ? res : ifname,
> +				NL80211_CMD_GET_INTERFACE, 0,
> +				nl80211_get_htmode_cb, &chn);
> +	if (err)
> +		return -1;
> +
> +	switch (chn.width) {
> +	case NL80211_CHAN_WIDTH_20_NOHT:
> +		*buf = IWINFO_HTMODE_NOHT;
> +		break;
> +	case NL80211_CHAN_WIDTH_20:
> +		if (chn.mode == -1)
> +			*buf = IWINFO_HTMODE_VHT20;
> +		else
> +			*buf = IWINFO_HTMODE_HT20;
> +		break;
> +	case NL80211_CHAN_WIDTH_40:
> +		if (chn.mode == -1)
> +			*buf = IWINFO_HTMODE_VHT40;
> +		else
> +			*buf = IWINFO_HTMODE_HT40;
> +		break;
> +	case NL80211_CHAN_WIDTH_80:
> +		*buf = IWINFO_HTMODE_VHT80;
> +		break;
> +	case NL80211_CHAN_WIDTH_80P80:
> +		*buf = IWINFO_HTMODE_VHT80_80;
> +		break;
> +	case NL80211_CHAN_WIDTH_160:
> +		*buf = IWINFO_HTMODE_VHT160;
> +		break;
> +	case NL80211_CHAN_WIDTH_5:
> +	case NL80211_CHAN_WIDTH_10:

Should this also return IWINFO_HTMODE_NOHT ?

> +	default:
> +		break;

Why not return an error if nothing matches?

> +	}
> +
> +	return 0;
> +}
> +
>  static int nl80211_get_htmodelist(const char *ifname, int *buf)
>  {
>  	struct nl80211_modes m = { 0 };
> @@ -3147,6 +3216,7 @@ const struct iwinfo_ops nl80211_ops = {
>  	.mbssid_support   = nl80211_get_mbssid_support,
>  	.hwmodelist       = nl80211_get_hwmodelist,
>  	.htmodelist       = nl80211_get_htmodelist,
> +	.htmode		  = nl80211_get_htmode,
>  	.mode             = nl80211_get_mode,
>  	.ssid             = nl80211_get_ssid,
>  	.bssid            = nl80211_get_bssid,
>
diff mbox series

Patch

diff --git a/include/iwinfo.h b/include/iwinfo.h
index d035c9c..5e64294 100644
--- a/include/iwinfo.h
+++ b/include/iwinfo.h
@@ -88,8 +88,9 @@  enum iwinfo_htmode {
 	IWINFO_HTMODE_VHT80      = (1 << 4),
 	IWINFO_HTMODE_VHT80_80   = (1 << 5),
 	IWINFO_HTMODE_VHT160     = (1 << 6),
+	IWINFO_HTMODE_NOHT       = (1 << 7),
 
-	IWINFO_HTMODE_COUNT      = 7
+	IWINFO_HTMODE_COUNT      = 8
 };
 
 extern const char *IWINFO_HTMODE_NAMES[IWINFO_HTMODE_COUNT];
@@ -231,6 +232,7 @@  struct iwinfo_ops {
 	int (*mbssid_support)(const char *, int *);
 	int (*hwmodelist)(const char *, int *);
 	int (*htmodelist)(const char *, int *);
+	int (*htmode)(const char *, int *);
 	int (*ssid)(const char *, char *);
 	int (*bssid)(const char *, char *);
 	int (*country)(const char *, char *);
diff --git a/iwinfo_nl80211.c b/iwinfo_nl80211.c
index 4b6ef91..36f1da2 100644
--- a/iwinfo_nl80211.c
+++ b/iwinfo_nl80211.c
@@ -2958,6 +2958,75 @@  out:
 	return -1;
 }
 
+struct chan_info {
+	int width;
+	int mode;
+};
+
+static int nl80211_get_htmode_cb(struct nl_msg *msg, void *arg)
+{
+	struct nlattr **tb = nl80211_parse(msg);
+	struct nlattr *cur;
+	struct chan_info *chn = arg;
+
+	if ((cur = tb[NL80211_ATTR_CHANNEL_WIDTH]))
+		chn->width = nla_get_u32(cur);
+
+	if ((cur = tb[NL80211_ATTR_BSS_HT_OPMODE]))
+		chn->mode = nla_get_u32(cur);
+
+	return NL_SKIP;
+}
+
+static int nl80211_get_htmode(const char *ifname, int *buf)
+{
+	struct chan_info chn = { .width = 0, .mode = 0 };
+	char *res;
+	int err;
+
+	res = nl80211_phy2ifname(ifname);
+	*buf = 0;
+
+	err =  nl80211_request(res ? res : ifname,
+				NL80211_CMD_GET_INTERFACE, 0,
+				nl80211_get_htmode_cb, &chn);
+	if (err)
+		return -1;
+
+	switch (chn.width) {
+	case NL80211_CHAN_WIDTH_20_NOHT:
+		*buf = IWINFO_HTMODE_NOHT;
+		break;
+	case NL80211_CHAN_WIDTH_20:
+		if (chn.mode == -1)
+			*buf = IWINFO_HTMODE_VHT20;
+		else
+			*buf = IWINFO_HTMODE_HT20;
+		break;
+	case NL80211_CHAN_WIDTH_40:
+		if (chn.mode == -1)
+			*buf = IWINFO_HTMODE_VHT40;
+		else
+			*buf = IWINFO_HTMODE_HT40;
+		break;
+	case NL80211_CHAN_WIDTH_80:
+		*buf = IWINFO_HTMODE_VHT80;
+		break;
+	case NL80211_CHAN_WIDTH_80P80:
+		*buf = IWINFO_HTMODE_VHT80_80;
+		break;
+	case NL80211_CHAN_WIDTH_160:
+		*buf = IWINFO_HTMODE_VHT160;
+		break;
+	case NL80211_CHAN_WIDTH_5:
+	case NL80211_CHAN_WIDTH_10:
+	default:
+		break;
+	}
+
+	return 0;
+}
+
 static int nl80211_get_htmodelist(const char *ifname, int *buf)
 {
 	struct nl80211_modes m = { 0 };
@@ -3147,6 +3216,7 @@  const struct iwinfo_ops nl80211_ops = {
 	.mbssid_support   = nl80211_get_mbssid_support,
 	.hwmodelist       = nl80211_get_hwmodelist,
 	.htmodelist       = nl80211_get_htmodelist,
+	.htmode		  = nl80211_get_htmode,
 	.mode             = nl80211_get_mode,
 	.ssid             = nl80211_get_ssid,
 	.bssid            = nl80211_get_bssid,