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.