Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 21 Jan 2017 14:19:06 +0000 (UTC)
From:      Andriy Voskoboinyk <avos@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r312596 - in head: sbin/ifconfig sys/net80211
Message-ID:  <201701211419.v0LEJ67H063374@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: avos
Date: Sat Jan 21 14:19:06 2017
New Revision: 312596
URL: https://svnweb.freebsd.org/changeset/base/312596

Log:
  net80211: allow to configure LDPC support
  
  Tested with RTL8821AU, STA mode (Tx support only)
  
  Reviewed by:	adrian
  Differential Revision:	https://reviews.freebsd.org/D9268

Modified:
  head/sbin/ifconfig/ifieee80211.c
  head/sys/net80211/_ieee80211.h
  head/sys/net80211/ieee80211.h
  head/sys/net80211/ieee80211_ht.c
  head/sys/net80211/ieee80211_ioctl.c
  head/sys/net80211/ieee80211_node.h
  head/sys/net80211/ieee80211_var.h

Modified: head/sbin/ifconfig/ifieee80211.c
==============================================================================
--- head/sbin/ifconfig/ifieee80211.c	Sat Jan 21 13:25:57 2017	(r312595)
+++ head/sbin/ifconfig/ifieee80211.c	Sat Jan 21 14:19:06 2017	(r312596)
@@ -1787,6 +1787,21 @@ set80211stbc(const char *val, int d, int
 	set80211(s, IEEE80211_IOC_STBC, stbc, 0, NULL);
 }
 
+static void
+set80211ldpc(const char *val, int d, int s, const struct afswtch *rafp)
+{
+        int ldpc;
+ 
+        if (get80211val(s, IEEE80211_IOC_LDPC, &ldpc) < 0)
+                errx(-1, "cannot set LDPC setting");
+        if (d < 0) {
+                d = -d;
+                ldpc &= ~d;
+        } else
+                ldpc |= d;
+        set80211(s, IEEE80211_IOC_LDPC, ldpc, 0, NULL);
+}
+
 static
 DECL_CMD_FUNC(set80211ampdulimit, val, d)
 {
@@ -5030,6 +5045,23 @@ end:
 				break;
 			}
 		}
+		if (get80211val(s, IEEE80211_IOC_LDPC, &val) != -1) {
+			switch (val) {
+			case 0:
+				LINE_CHECK("-ldpc");
+				break;
+			case 1:
+				LINE_CHECK("ldpctx -ldpcrx");
+				break;
+			case 2:
+				LINE_CHECK("-ldpctx ldpcrx");
+				break;
+			case 3:
+				if (verbose)
+					LINE_CHECK("ldpc");
+				break;
+			}
+		}
 	}
 
 	if (IEEE80211_IS_CHAN_VHT(c) || verbose) {
@@ -5603,6 +5635,12 @@ static struct cmd ieee80211_cmds[] = {
 	DEF_CMD("-stbctx",	-1,	set80211stbc),
 	DEF_CMD("stbc",		3,	set80211stbc),		/* NB: tx+rx */
 	DEF_CMD("-stbc",	-3,	set80211stbc),
+	DEF_CMD("ldpcrx",	2,	set80211ldpc),
+	DEF_CMD("-ldpcrx",	-2,	set80211ldpc),
+	DEF_CMD("ldpctx",	1,	set80211ldpc),
+	DEF_CMD("-ldpctx",	-1,	set80211ldpc),
+	DEF_CMD("ldpc",		3,	set80211ldpc),		/* NB: tx+rx */
+	DEF_CMD("-ldpc",	-3,	set80211ldpc),
 	DEF_CMD("puren",	1,	set80211puren),
 	DEF_CMD("-puren",	0,	set80211puren),
 	DEF_CMD("doth",		1,	set80211doth),

Modified: head/sys/net80211/_ieee80211.h
==============================================================================
--- head/sys/net80211/_ieee80211.h	Sat Jan 21 13:25:57 2017	(r312595)
+++ head/sys/net80211/_ieee80211.h	Sat Jan 21 14:19:06 2017	(r312596)
@@ -517,9 +517,10 @@ struct ieee80211_mimo_info {
 #define	IEEE80211_HTC_RXMCS32	0x00400000	/* CAPABILITY: MCS32 support */
 #define	IEEE80211_HTC_TXUNEQUAL	0x00800000	/* CAPABILITY: TX unequal MCS */
 #define	IEEE80211_HTC_TXMCS32	0x01000000	/* CAPABILITY: MCS32 support */
+#define	IEEE80211_HTC_TXLDPC	0x02000000	/* CAPABILITY: TX using LDPC */
 
 #define	IEEE80211_C_HTCAP_BITS \
 	"\20\1LDPC\2CHWIDTH40\5GREENFIELD\6SHORTGI20\7SHORTGI40\10TXSTBC" \
-	"\21AMPDU\22AMSDU\23HT\24SMPS\25RIFS"
+	"\21AMPDU\22AMSDU\23HT\24SMPS\25RIFS\32TXLDPC"
 
 #endif /* _NET80211__IEEE80211_H_ */

Modified: head/sys/net80211/ieee80211.h
==============================================================================
--- head/sys/net80211/ieee80211.h	Sat Jan 21 13:25:57 2017	(r312595)
+++ head/sys/net80211/ieee80211.h	Sat Jan 21 14:19:06 2017	(r312596)
@@ -617,7 +617,7 @@ struct ieee80211_ie_htcap {
 } __packed;
 
 /* HT capability flags (ht_cap) */
-#define	IEEE80211_HTCAP_LDPC		0x0001	/* LDPC supported */
+#define	IEEE80211_HTCAP_LDPC		0x0001	/* LDPC rx supported */
 #define	IEEE80211_HTCAP_CHWIDTH40	0x0002	/* 20/40 supported */
 #define	IEEE80211_HTCAP_SMPS		0x000c	/* SM Power Save mode */
 #define	IEEE80211_HTCAP_SMPS_OFF	0x000c	/* disabled */

Modified: head/sys/net80211/ieee80211_ht.c
==============================================================================
--- head/sys/net80211/ieee80211_ht.c	Sat Jan 21 13:25:57 2017	(r312595)
+++ head/sys/net80211/ieee80211_ht.c	Sat Jan 21 14:19:06 2017	(r312596)
@@ -298,6 +298,11 @@ ieee80211_ht_vattach(struct ieee80211vap
 			vap->iv_flags_ht |= IEEE80211_FHT_STBC_TX;
 		if (vap->iv_htcaps & IEEE80211_HTCAP_RXSTBC)
 			vap->iv_flags_ht |= IEEE80211_FHT_STBC_RX;
+
+		if (vap->iv_htcaps & IEEE80211_HTCAP_LDPC)
+			vap->iv_flags_ht |= IEEE80211_FHT_LDPC_RX;
+		if (vap->iv_htcaps & IEEE80211_HTC_TXLDPC)
+			vap->iv_flags_ht |= IEEE80211_FHT_LDPC_TX;
 	}
 	/* NB: disable default legacy WDS, too many issues right now */
 	if (vap->iv_flags_ext & IEEE80211_FEXT_WDSLEGACY)
@@ -1650,6 +1655,20 @@ htcap_update_shortgi(struct ieee80211_no
 }
 
 /*
+ * Update LDPC state according to received htcap
+ * and local settings.
+ */
+static __inline void
+htcap_update_ldpc(struct ieee80211_node *ni)
+{
+	struct ieee80211vap *vap = ni->ni_vap;
+
+	if ((ni->ni_htcap & IEEE80211_HTCAP_LDPC) &&
+	    (vap->iv_flags_ht & IEEE80211_FHT_LDPC_TX))
+		ni->ni_flags |= IEEE80211_NODE_LDPC;
+}
+
+/*
  * Parse and update HT-related state extracted from
  * the HT cap and info ie's.
  *
@@ -1669,6 +1688,7 @@ ieee80211_ht_updateparams(struct ieee802
 	if (vap->iv_htcaps & IEEE80211_HTCAP_SMPS)
 		htcap_update_mimo_ps(ni);
 	htcap_update_shortgi(ni);
+	htcap_update_ldpc(ni);
 
 	if (htinfoie[0] == IEEE80211_ELEMID_VENDOR)
 		htinfoie += 4;
@@ -1821,6 +1841,7 @@ ieee80211_ht_updatehtcap(struct ieee8021
 	if (vap->iv_htcaps & IEEE80211_HTCAP_SMPS)
 		htcap_update_mimo_ps(ni);
 	htcap_update_shortgi(ni);
+	htcap_update_ldpc(ni);
 }
 
 /*
@@ -3027,7 +3048,9 @@ ieee80211_add_htcap_body(uint8_t *frm, s
 	if ((vap->iv_flags_ht & IEEE80211_FHT_STBC_RX) == 0)
 		caps &= ~IEEE80211_HTCAP_RXSTBC;
 
-	/* XXX TODO: adjust LDPC based on receive capabilities */
+	/* adjust LDPC based on receive capabilites */
+	if ((vap->iv_flags_ht & IEEE80211_FHT_LDPC_RX) == 0)
+		caps &= ~IEEE80211_HTCAP_LDPC;
 
 	ADDSHORT(frm, caps);
 

Modified: head/sys/net80211/ieee80211_ioctl.c
==============================================================================
--- head/sys/net80211/ieee80211_ioctl.c	Sat Jan 21 13:25:57 2017	(r312595)
+++ head/sys/net80211/ieee80211_ioctl.c	Sat Jan 21 14:19:06 2017	(r312596)
@@ -1136,6 +1136,13 @@ ieee80211_ioctl_get80211(struct ieee8021
 		if (vap->iv_flags_ht & IEEE80211_FHT_STBC_RX)
 			ireq->i_val |= 2;
 		break;
+	case IEEE80211_IOC_LDPC:
+		ireq->i_val = 0;
+		if (vap->iv_flags_ht & IEEE80211_FHT_LDPC_TX)
+			ireq->i_val |= 1;
+		if (vap->iv_flags_ht & IEEE80211_FHT_LDPC_RX)
+			ireq->i_val |= 2;
+		break;
 
 	/* VHT */
 	case IEEE80211_IOC_VHTCONF:
@@ -3372,6 +3379,31 @@ ieee80211_ioctl_set80211(struct ieee8021
 		if (isvapht(vap))
 			error = ERESTART;
 		break;
+	case IEEE80211_IOC_LDPC:
+		/* Check if we can do LDPC TX/RX before changing the setting */
+		if ((ireq->i_val & 1) &&
+		    (vap->iv_htcaps & IEEE80211_HTC_TXLDPC) == 0)
+			return EOPNOTSUPP;
+		if ((ireq->i_val & 2) &&
+		    (vap->iv_htcaps & IEEE80211_HTCAP_LDPC) == 0)
+			return EOPNOTSUPP;
+
+		/* TX */
+		if (ireq->i_val & 1)
+			vap->iv_flags_ht |= IEEE80211_FHT_LDPC_TX;
+		else
+			vap->iv_flags_ht &= ~IEEE80211_FHT_LDPC_TX;
+
+		/* RX */
+		if (ireq->i_val & 2)
+			vap->iv_flags_ht |= IEEE80211_FHT_LDPC_RX;
+		else
+			vap->iv_flags_ht &= ~IEEE80211_FHT_LDPC_RX;
+
+		/* NB: reset only if we're operating on an 11n channel */
+		if (isvapht(vap))
+			error = ERESTART;
+		break;
 
 	/* VHT */
 	case IEEE80211_IOC_VHTCONF:

Modified: head/sys/net80211/ieee80211_node.h
==============================================================================
--- head/sys/net80211/ieee80211_node.h	Sat Jan 21 13:25:57 2017	(r312595)
+++ head/sys/net80211/ieee80211_node.h	Sat Jan 21 14:19:06 2017	(r312596)
@@ -143,6 +143,7 @@ struct ieee80211_node {
 #define	IEEE80211_NODE_AMSDU_RX	0x040000	/* AMSDU rx enabled */
 #define	IEEE80211_NODE_AMSDU_TX	0x080000	/* AMSDU tx enabled */
 #define	IEEE80211_NODE_VHT	0x100000	/* VHT enabled */
+#define	IEEE80211_NODE_LDPC	0x200000	/* LDPC enabled */
 	uint16_t		ni_associd;	/* association ID */
 	uint16_t		ni_vlan;	/* vlan tag */
 	uint16_t		ni_txpower;	/* current transmit power */

Modified: head/sys/net80211/ieee80211_var.h
==============================================================================
--- head/sys/net80211/ieee80211_var.h	Sat Jan 21 13:25:57 2017	(r312595)
+++ head/sys/net80211/ieee80211_var.h	Sat Jan 21 14:19:06 2017	(r312596)
@@ -641,6 +641,8 @@ MALLOC_DECLARE(M_80211_VAP);
 
 /* ic_flags_ht/iv_flags_ht */
 #define	IEEE80211_FHT_NONHT_PR	 0x00000001	/* STATUS: non-HT sta present */
+#define	IEEE80211_FHT_LDPC_TX	 0x00010000	/* CONF: LDPC tx enabled */
+#define	IEEE80211_FHT_LDPC_RX	 0x00020000	/* CONF: LDPC rx enabled */
 #define	IEEE80211_FHT_GF  	 0x00040000	/* CONF: Greenfield enabled */
 #define	IEEE80211_FHT_HT	 0x00080000	/* CONF: HT supported */
 #define	IEEE80211_FHT_AMPDU_TX	 0x00100000	/* CONF: A-MPDU tx supported */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201701211419.v0LEJ67H063374>