This diff cannot be tested yet -- I'm looking for OKs only :-)

Manage the HT protection setting if acting as hostap with 11n enabled.

For now we flip-flop only between non-member protection and non-HT protection.
Running a HT network without protection would require monitoring environmental
conditions (e.g. foreign beacons) which make HT protection necessary.

The ic_update_htprot driver function becomes optional because it won't be
needed by all drivers. Only call it if the driver has set a function pointer.

Index: ieee80211_input.c
===================================================================
RCS file: /cvs/src/sys/net80211/ieee80211_input.c,v
retrieving revision 1.180
diff -u -p -r1.180 ieee80211_input.c
--- ieee80211_input.c   21 Sep 2016 12:21:27 -0000      1.180
+++ ieee80211_input.c   9 Jan 2017 10:07:34 -0000
@@ -1612,7 +1612,8 @@ ieee80211_recv_probe_resp(struct ieee802
                                    htprot_last, htprot));
                                ic->ic_stats.is_ht_prot_change++;
                                ic->ic_bss->ni_htop1 = ni->ni_htop1;
-                               ic->ic_update_htprot(ic, ic->ic_bss);
+                               if (ic->ic_update_htprot)
+                                       ic->ic_update_htprot(ic, ic->ic_bss);
                        }
                }
 
Index: ieee80211_node.c
===================================================================
RCS file: /cvs/src/sys/net80211/ieee80211_node.c,v
retrieving revision 1.108
diff -u -p -r1.108 ieee80211_node.c
--- ieee80211_node.c    9 Jan 2017 09:31:18 -0000       1.108
+++ ieee80211_node.c    9 Jan 2017 10:07:57 -0000
@@ -353,6 +353,16 @@ ieee80211_create_ibss(struct ieee80211co
        ni->ni_capinfo = IEEE80211_CAPINFO_IBSS;
        if (ic->ic_flags & IEEE80211_F_WEPON)
                ni->ni_capinfo |= IEEE80211_CAPINFO_PRIVACY;
+       if (ic->ic_flags & IEEE80211_F_HTON) {
+               /* 
+                * Default to non-member HT protection until we have a way
+                * of picking up information from the environment (such as
+                * beacons from other networks) which proves that only HT
+                * STAs are on the air.
+                */
+               ni->ni_htop1 = IEEE80211_HTPROT_NONMEMBER;
+               ic->ic_protmode = IEEE80211_PROT_RTSCTS;
+       }
        if (ic->ic_flags & IEEE80211_F_RSNON) {
                struct ieee80211_key *k;
 
@@ -1423,7 +1433,15 @@ ieee80211_needs_auth(struct ieee80211com
 void
 ieee80211_node_join_ht(struct ieee80211com *ic, struct ieee80211_node *ni)
 {
-       /* TBD */
+       enum ieee80211_htprot;
+
+       /* Update HT protection setting. */
+       if ((ni->ni_flags & IEEE80211_NODE_HT) == 0) {
+               ic->ic_nonhtsta++;
+               ic->ic_bss->ni_htop1 = IEEE80211_HTPROT_NONHT_MIXED;
+               if (ic->ic_update_htprot)
+                       ic->ic_update_htprot(ic, ic->ic_bss);
+       }
 }
 
 /*
@@ -1712,6 +1730,16 @@ ieee80211_node_leave(struct ieee80211com
 
        if (ni->ni_flags & IEEE80211_NODE_HT)
                ieee80211_node_leave_ht(ic, ni);
+       else if (ic->ic_flags & IEEE80211_F_HTON) {
+               if (ic->ic_nonhtsta == 0)
+                       panic("bogus non-HT station count %d", ic->ic_nonhtsta);
+               if (--ic->ic_nonhtsta == 0) {
+                       /* All associated stations now support HT. */
+                       ic->ic_bss->ni_htop1 = IEEE80211_HTPROT_NONMEMBER;
+                       if (ic->ic_update_htprot)
+                               ic->ic_update_htprot(ic, ic->ic_bss);
+               }
+       }
 
        if (ic->ic_node_leave != NULL)
                (*ic->ic_node_leave)(ic, ni);
Index: ieee80211_var.h
===================================================================
RCS file: /cvs/src/sys/net80211/ieee80211_var.h,v
retrieving revision 1.73
diff -u -p -r1.73 ieee80211_var.h
--- ieee80211_var.h     17 Dec 2016 18:35:54 -0000      1.73
+++ ieee80211_var.h     8 Jan 2017 21:11:30 -0000
@@ -310,6 +310,9 @@ struct ieee80211com {
        u_int                   ic_dtim_period;
        u_int                   ic_dtim_count;
 
+#ifndef IEEE80211_STA_ONLY
+       u_int16_t               ic_nonhtsta;    /* # non-HT stations */
+#endif
        u_int32_t               ic_txbfcaps;
        u_int16_t               ic_htcaps;
        u_int8_t                ic_ampdu_params;

Reply via email to