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 */
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to