Both drivers forgot to configure some A-MPDU parameters into the firmware and announced the wrong A-MPDU max size in assoc responses.
Also announce that we don't support SMPS (signalled in htcaps by a value of 3 rather than zero...) ok? Index: if_iwm.c =================================================================== RCS file: /cvs/src/sys/dev/pci/if_iwm.c,v retrieving revision 1.76 diff -u -p -r1.76 if_iwm.c --- if_iwm.c 25 Jan 2016 11:27:11 -0000 1.76 +++ if_iwm.c 3 Feb 2016 18:23:17 -0000 @@ -4466,6 +4466,7 @@ iwm_mvm_sta_send_to_fw(struct iwm_softc struct iwm_mvm_add_sta_cmd_v6 add_sta_cmd; int ret; uint32_t status; + struct ieee80211com *ic = &sc->sc_ic; memset(&add_sta_cmd, 0, sizeof(add_sta_cmd)); @@ -4480,6 +4481,35 @@ iwm_mvm_sta_send_to_fw(struct iwm_softc add_sta_cmd.station_flags_msk |= htole32(IWM_STA_FLG_FAT_EN_MSK | IWM_STA_FLG_MIMO_EN_MSK); + if (in->in_ni.ni_flags & IEEE80211_NODE_HT) { + add_sta_cmd.station_flags_msk + |= htole32(IWM_STA_FLG_MAX_AGG_SIZE_MSK | + IWM_STA_FLG_AGG_MPDU_DENS_MSK); + + add_sta_cmd.station_flags + |= htole32(IWM_STA_FLG_MAX_AGG_SIZE_64K); + switch (ic->ic_ampdu_params & IEEE80211_AMPDU_PARAM_SS) { + case IEEE80211_AMPDU_PARAM_SS_2: + add_sta_cmd.station_flags + |= htole32(IWM_STA_FLG_AGG_MPDU_DENS_2US); + break; + case IEEE80211_AMPDU_PARAM_SS_4: + add_sta_cmd.station_flags + |= htole32(IWM_STA_FLG_AGG_MPDU_DENS_4US); + break; + case IEEE80211_AMPDU_PARAM_SS_8: + add_sta_cmd.station_flags + |= htole32(IWM_STA_FLG_AGG_MPDU_DENS_8US); + break; + case IEEE80211_AMPDU_PARAM_SS_16: + add_sta_cmd.station_flags + |= htole32(IWM_STA_FLG_AGG_MPDU_DENS_16US); + break; + default: + break; + } + } + status = IWM_ADD_STA_SUCCESS; ret = iwm_mvm_send_add_sta_cmd_status(sc, &add_sta_cmd, &status); if (ret) @@ -6810,11 +6840,11 @@ iwm_attach(struct device *parent, struct IEEE80211_C_SHPREAMBLE; /* short preamble supported */ /* No optional HT features supported for now, */ - ic->ic_htcaps = 0; + ic->ic_htcaps = IEEE80211_HTCAP_SMPS_DIS; ic->ic_htxcaps = 0; ic->ic_txbfcaps = 0; ic->ic_aselcaps = 0; - ic->ic_ampdu_params = IEEE80211_AMPDU_PARAM_SS_4; + ic->ic_ampdu_params = (IEEE80211_AMPDU_PARAM_SS_4 | 0x3 /* 64k */); ic->ic_sup_rates[IEEE80211_MODE_11A] = ieee80211_std_rateset_11a; ic->ic_sup_rates[IEEE80211_MODE_11B] = ieee80211_std_rateset_11b; Index: if_iwn.c =================================================================== RCS file: /cvs/src/sys/dev/pci/if_iwn.c,v retrieving revision 1.158 diff -u -p -r1.158 if_iwn.c --- if_iwn.c 25 Jan 2016 11:27:11 -0000 1.158 +++ if_iwn.c 3 Feb 2016 18:42:49 -0000 @@ -456,11 +456,11 @@ iwn_attach(struct device *parent, struct IEEE80211_C_PMGT; /* power saving supported */ /* No optional HT features supported for now, */ - ic->ic_htcaps = 0; + ic->ic_htcaps = IEEE80211_HTCAP_SMPS_DIS; ic->ic_htxcaps = 0; ic->ic_txbfcaps = 0; ic->ic_aselcaps = 0; - ic->ic_ampdu_params = IEEE80211_AMPDU_PARAM_SS_4; + ic->ic_ampdu_params = (IEEE80211_AMPDU_PARAM_SS_4 | 0x3 /* 64k */); #ifdef notyet if (sc->sc_flags & IWN_FLAG_HAS_11N) { @@ -4920,10 +4920,15 @@ iwn_run(struct iwn_softc *sc) memset(&node, 0, sizeof node); IEEE80211_ADDR_COPY(node.macaddr, ni->ni_macaddr); node.id = IWN_ID_BSS; -#ifdef notyet - node.htflags = htole32(IWN_AMDPU_SIZE_FACTOR(3) | - IWN_AMDPU_DENSITY(5)); /* 2us */ -#endif + if (ni->ni_flags & IEEE80211_NODE_HT) { + node.htmask = (IWN_AMDPU_SIZE_FACTOR_MASK | + IWN_AMDPU_DENSITY_MASK); + node.htflags = htole32( + IWN_AMDPU_SIZE_FACTOR( + (ic->ic_ampdu_params & IEEE80211_AMPDU_PARAM_LE)) | + IWN_AMDPU_DENSITY( + (ic->ic_ampdu_params & IEEE80211_AMPDU_PARAM_SS) >> 2)); + } DPRINTF(("adding BSS node\n")); error = ops->add_node(sc, &node, 1); if (error != 0) { @@ -5070,10 +5075,15 @@ iwn_update_htprot(struct ieee80211com *i memset(&node, 0, sizeof node); IEEE80211_ADDR_COPY(node.macaddr, ni->ni_macaddr); node.id = IWN_ID_BSS; -#ifdef notyet - node.htflags = htole32(IWN_AMDPU_SIZE_FACTOR(3) | - IWN_AMDPU_DENSITY(5)); /* 2us */ -#endif + if (ni->ni_flags & IEEE80211_NODE_HT) { + node.htmask = (IWN_AMDPU_SIZE_FACTOR_MASK | + IWN_AMDPU_DENSITY_MASK); + node.htflags = htole32( + IWN_AMDPU_SIZE_FACTOR( + (ic->ic_ampdu_params & IEEE80211_AMPDU_PARAM_LE)) | + IWN_AMDPU_DENSITY( + (ic->ic_ampdu_params & IEEE80211_AMPDU_PARAM_SS) >> 2)); + } error = ops->add_node(sc, &node, 1); if (error != 0) { printf("%s: could not add BSS node\n", sc->sc_dev.dv_xname); Index: if_iwnreg.h =================================================================== RCS file: /cvs/src/sys/dev/pci/if_iwnreg.h,v retrieving revision 1.51 diff -u -p -r1.51 if_iwnreg.h --- if_iwnreg.h 7 Jan 2016 23:08:38 -0000 1.51 +++ if_iwnreg.h 3 Feb 2016 17:45:09 -0000 @@ -605,9 +605,11 @@ struct iwn_node_info { uint32_t htflags; #define IWN_AMDPU_SIZE_FACTOR(x) ((x) << 19) +#define IWN_AMDPU_SIZE_FACTOR_MASK ((0x3) << 19) #define IWN_AMDPU_DENSITY(x) ((x) << 23) +#define IWN_AMDPU_DENSITY_MASK ((0x7) << 23) - uint32_t mask; + uint32_t htmask; uint16_t disable_tid; uint16_t reserved6; uint8_t addba_tid; @@ -632,7 +634,7 @@ struct iwn4965_node_info { uint8_t reserved5; uint8_t key[16]; uint32_t htflags; - uint32_t mask; + uint32_t htmask; uint16_t disable_tid; uint16_t reserved6; uint8_t addba_tid;