Discussion:
fix A-MPDU params for iwn/iwm (fixes apple airport AP)
Stefan Sperling
2016-02-03 19:00:04 UTC
Permalink
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;

Loading...