Currently, an athn(4) hostap in 11n mode sending data a fame
looks something like this:

  AP: RTS
  client: CTS
  AP: RTS
  client: CTS
  AP: RTS
  client: CTS
  AP: RTS
  client: CTS
  AP: RTS
  client: CTS
  AP: data
  client: ACK

The problem seems to be that while we're sending EDCA parameters in beacons
which clients will use, these parameters are not programmed into the athn
hardware. We never call the driver's ic_updateedca function in hostap mode.

With the diff below, frame traces are looking better:

  AP: RTS
  client: CTS
  AP: data
  client: ACK
  AP: RTS
  client: CTS
  AP: data
  client: ACK
 
Index: ieee80211_node.c
===================================================================
RCS file: /cvs/src/sys/net80211/ieee80211_node.c,v
retrieving revision 1.109
diff -u -p -r1.109 ieee80211_node.c
--- ieee80211_node.c    9 Jan 2017 12:40:00 -0000       1.109
+++ ieee80211_node.c    9 Jan 2017 14:36:25 -0000
@@ -354,6 +354,10 @@ ieee80211_create_ibss(struct ieee80211co
        if (ic->ic_flags & IEEE80211_F_WEPON)
                ni->ni_capinfo |= IEEE80211_CAPINFO_PRIVACY;
        if (ic->ic_flags & IEEE80211_F_HTON) {
+               const struct ieee80211_edca_ac_params *ac_qap;
+               struct ieee80211_edca_ac_params *ac;
+               int aci;
+
                /* 
                 * Default to non-member HT protection until we have a way
                 * of picking up information from the environment (such as
@@ -362,6 +366,19 @@ ieee80211_create_ibss(struct ieee80211co
                 */
                ni->ni_htop1 = IEEE80211_HTPROT_NONMEMBER;
                ic->ic_protmode = IEEE80211_PROT_RTSCTS;
+
+               /* Configure QoS EDCA parameters. */
+               for (aci = 0; aci < EDCA_NUM_AC; aci++) {
+                       ac = &ic->ic_edca_ac[aci];
+                       ac_qap = &ieee80211_qap_edca_table[ic->ic_curmode][aci];
+                       ac->ac_acm       = ac_qap->ac_acm;
+                       ac->ac_aifsn     = ac_qap->ac_aifsn;
+                       ac->ac_ecwmin    = ac_qap->ac_ecwmin;
+                       ac->ac_ecwmax    = ac_qap->ac_ecwmax;
+                       ac->ac_txoplimit = ac_qap->ac_txoplimit;
+               }
+               if (ic->ic_updateedca)
+                       (*ic->ic_updateedca)(ic);
        }
        if (ic->ic_flags & IEEE80211_F_RSNON) {
                struct ieee80211_key *k;
Index: ieee80211_output.c
===================================================================
RCS file: /cvs/src/sys/net80211/ieee80211_output.c,v
retrieving revision 1.113
diff -u -p -r1.113 ieee80211_output.c
--- ieee80211_output.c  9 Jan 2017 13:01:37 -0000       1.113
+++ ieee80211_output.c  9 Jan 2017 13:43:41 -0000
@@ -306,7 +306,7 @@ static const struct ieee80211_edca_ac_pa
 #endif
 
 #ifndef IEEE80211_STA_ONLY
-static const struct ieee80211_edca_ac_params
+const struct ieee80211_edca_ac_params
     ieee80211_qap_edca_table[IEEE80211_MODE_MAX][EDCA_NUM_AC] = {
        [IEEE80211_MODE_11B] = {
                [EDCA_AC_BK] = { 5, 10, 7,   0 },
Index: ieee80211_var.h
===================================================================
RCS file: /cvs/src/sys/net80211/ieee80211_var.h,v
retrieving revision 1.74
diff -u -p -r1.74 ieee80211_var.h
--- ieee80211_var.h     9 Jan 2017 12:40:00 -0000       1.74
+++ ieee80211_var.h     9 Jan 2017 13:54:07 -0000
@@ -160,6 +160,9 @@ struct ieee80211_edca_ac_params {
        u_int8_t        ac_acm;
 };
 
+extern const struct ieee80211_edca_ac_params
+           ieee80211_qap_edca_table[IEEE80211_MODE_MAX][EDCA_NUM_AC];
+
 #define IEEE80211_DEFRAG_SIZE  3       /* must be >= 3 according to spec */
 /*
  * Entry in the fragment cache.

Reply via email to