Stefan Sperling
2016-02-08 00:43:35 UTC
The AP HT parameters we provide to the firmware are still a bit messed up.
They are supposed to reflect the AP's capabilities, not our own.
So use params from "ni" instead of "ic".
In most case we just get lucky and things work regardless, it seems.
Add SMPS (MIMO powersave) parameters, too, so the firmware knows the
AP's settings in this regard. These probably don't really matter until
we add MIMO, but this matches what Linux is doing and doesn't seem
to cause harm in my testing, so why not.
Also adds some missing HT flag defines for iwn.
Index: if_iwm.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_iwm.c,v
retrieving revision 1.77
diff -u -p -r1.77 if_iwm.c
--- if_iwm.c 5 Feb 2016 16:08:44 -0000 1.77
+++ if_iwm.c 8 Feb 2016 00:25:02 -0000
@@ -4466,7 +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;
+ struct ieee80211_node *ni = &in->in_ni;
memset(&add_sta_cmd, 0, sizeof(add_sta_cmd));
@@ -4475,20 +4475,22 @@ iwm_mvm_sta_send_to_fw(struct iwm_softc
= htole32(IWM_FW_CMD_ID_AND_COLOR(in->in_id, in->in_color));
if (!update) {
add_sta_cmd.tfd_queue_msk = htole32(0xf);
- IEEE80211_ADDR_COPY(&add_sta_cmd.addr, in->in_ni.ni_bssid);
+ IEEE80211_ADDR_COPY(&add_sta_cmd.addr, ni->ni_bssid);
}
add_sta_cmd.add_modify = update ? 1 : 0;
- 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);
+ if (ni->ni_flags & IEEE80211_NODE_HT) {
+ add_sta_cmd.station_flags_msk |=
+ htole32(IWM_STA_FLG_RTS_MIMO_PROT |
+ IWM_STA_FLG_MIMO_EN_SISO |
+ IWM_STA_FLG_MAX_AGG_SIZE_MSK |
+ IWM_STA_FLG_MIMO_EN_MSK |
+ IWM_STA_FLG_AGG_MPDU_DENS_MSK |
+ IWM_STA_FLG_FAT_EN_MSK);
add_sta_cmd.station_flags
|= htole32(IWM_STA_FLG_MAX_AGG_SIZE_64K);
- switch (ic->ic_ampdu_params & IEEE80211_AMPDU_PARAM_SS) {
+ switch (ni->ni_ampdu_param & IEEE80211_AMPDU_PARAM_SS) {
case IEEE80211_AMPDU_PARAM_SS_2:
add_sta_cmd.station_flags
|= htole32(IWM_STA_FLG_AGG_MPDU_DENS_2US);
@@ -4508,6 +4510,18 @@ iwm_mvm_sta_send_to_fw(struct iwm_softc
default:
break;
}
+
+ switch ((ni->ni_htcaps & IEEE80211_HTCAP_SMPS_MASK) >>
+ IEEE80211_HTCAP_SMPS_SHIFT) {
+ case IEEE80211_HTCAP_SMPS_STA:
+ add_sta_cmd.station_flags |= IWM_STA_FLG_MIMO_EN_SISO;
+ break;
+ case IEEE80211_HTCAP_SMPS_DYN:
+ add_sta_cmd.station_flags |= IWM_STA_FLG_RTS_MIMO_PROT;
+ break;
+ default:
+ break;
+ }
}
status = IWM_ADD_STA_SUCCESS;
@@ -6840,7 +6854,7 @@ 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;
Index: if_iwn.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_iwn.c,v
retrieving revision 1.163
diff -u -p -r1.163 if_iwn.c
--- if_iwn.c 7 Feb 2016 23:56:19 -0000 1.163
+++ if_iwn.c 8 Feb 2016 00:33:48 -0000
@@ -456,7 +456,7 @@ 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;
@@ -4942,13 +4942,29 @@ iwn_run(struct iwn_softc *sc)
IEEE80211_ADDR_COPY(node.macaddr, ni->ni_macaddr);
node.id = IWN_ID_BSS;
if (ni->ni_flags & IEEE80211_NODE_HT) {
- node.htmask = (IWN_AMDPU_SIZE_FACTOR_MASK |
- IWN_AMDPU_DENSITY_MASK);
+ node.htmask = (IWN_HTF_RTS_MIMO_PROT |
+ IWN_HTF_AMDPU_SIZE_FACTOR_MASK |
+ IWN_HTF_AMDPU_DENSITY_MASK |
+ IWN_HTF_HT40_EN |
+ IWN_HTF_MIMO_DIS);
+
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));
+ IWN_HTF_AMDPU_SIZE_FACTOR(
+ (ni->ni_ampdu_param & IEEE80211_AMPDU_PARAM_LE)) |
+ IWN_HTF_AMDPU_DENSITY(
+ (ni->ni_ampdu_param & IEEE80211_AMPDU_PARAM_SS) >> 2));
+
+ switch ((ni->ni_htcaps & IEEE80211_HTCAP_SMPS_MASK) >>
+ IEEE80211_HTCAP_SMPS_SHIFT) {
+ case IEEE80211_HTCAP_SMPS_STA:
+ node.htflags |= IWN_HTF_MIMO_DIS;
+ break;
+ case IEEE80211_HTCAP_SMPS_DYN:
+ node.htflags |= IWN_HTF_RTS_MIMO_PROT;
+ break;
+ default:
+ break;
+ }
}
DPRINTF(("adding BSS node\n"));
error = ops->add_node(sc, &node, 1);
@@ -5097,13 +5113,29 @@ iwn_update_htprot(struct ieee80211com *i
IEEE80211_ADDR_COPY(node.macaddr, ni->ni_macaddr);
node.id = IWN_ID_BSS;
if (ni->ni_flags & IEEE80211_NODE_HT) {
- node.htmask = (IWN_AMDPU_SIZE_FACTOR_MASK |
- IWN_AMDPU_DENSITY_MASK);
+ node.htmask = (IWN_HTF_RTS_MIMO_PROT |
+ IWN_HTF_AMDPU_SIZE_FACTOR_MASK |
+ IWN_HTF_AMDPU_DENSITY_MASK |
+ IWN_HTF_HT40_EN |
+ IWN_HTF_MIMO_DIS);
+
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));
+ IWN_HTF_AMDPU_SIZE_FACTOR(
+ (ni->ni_ampdu_param & IEEE80211_AMPDU_PARAM_LE)) |
+ IWN_HTF_AMDPU_DENSITY(
+ (ni->ni_ampdu_param & IEEE80211_AMPDU_PARAM_SS) >> 2));
+
+ switch ((ni->ni_htcaps & IEEE80211_HTCAP_SMPS_MASK) >>
+ IEEE80211_HTCAP_SMPS_SHIFT) {
+ case IEEE80211_HTCAP_SMPS_STA:
+ node.htflags |= IWN_HTF_MIMO_DIS;
+ break;
+ case IEEE80211_HTCAP_SMPS_DYN:
+ node.htflags |= IWN_HTF_RTS_MIMO_PROT;
+ break;
+ default:
+ break;
+ }
}
error = ops->add_node(sc, &node, 1);
if (error != 0) {
Index: if_iwnreg.h
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_iwnreg.h,v
retrieving revision 1.52
diff -u -p -r1.52 if_iwnreg.h
--- if_iwnreg.h 5 Feb 2016 16:09:19 -0000 1.52
+++ if_iwnreg.h 7 Feb 2016 20:14:21 -0000
@@ -604,10 +604,17 @@ struct iwn_node_info {
uint8_t txmic[IEEE80211_TKIP_MICLEN];
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)
+#define IWN_HTF_TX_RATE (1 << 2)
+#define IWN_HTF_PWR_SAVE (1 << 8)
+#define IWN_HTF_PAN_STA (1 << 13)
+#define IWN_HTF_RTS_MIMO_PROT (1 << 17)
+#define IWN_HTF_AMPDU_8US (1 << 18)
+#define IWN_HTF_AMDPU_SIZE_FACTOR(x) ((x) << 19)
+#define IWN_HTF_AMDPU_SIZE_FACTOR_MASK ((0x3) << 19)
+#define IWN_HTF_HT40_EN (1 << 21)
+#define IWN_HTF_MIMO_DIS (1 << 22)
+#define IWN_HTF_AMDPU_DENSITY(x) ((x) << 23)
+#define IWN_HTF_AMDPU_DENSITY_MASK ((0x7) << 23)
uint32_t htmask;
uint16_t disable_tid;
They are supposed to reflect the AP's capabilities, not our own.
So use params from "ni" instead of "ic".
In most case we just get lucky and things work regardless, it seems.
Add SMPS (MIMO powersave) parameters, too, so the firmware knows the
AP's settings in this regard. These probably don't really matter until
we add MIMO, but this matches what Linux is doing and doesn't seem
to cause harm in my testing, so why not.
Also adds some missing HT flag defines for iwn.
Index: if_iwm.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_iwm.c,v
retrieving revision 1.77
diff -u -p -r1.77 if_iwm.c
--- if_iwm.c 5 Feb 2016 16:08:44 -0000 1.77
+++ if_iwm.c 8 Feb 2016 00:25:02 -0000
@@ -4466,7 +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;
+ struct ieee80211_node *ni = &in->in_ni;
memset(&add_sta_cmd, 0, sizeof(add_sta_cmd));
@@ -4475,20 +4475,22 @@ iwm_mvm_sta_send_to_fw(struct iwm_softc
= htole32(IWM_FW_CMD_ID_AND_COLOR(in->in_id, in->in_color));
if (!update) {
add_sta_cmd.tfd_queue_msk = htole32(0xf);
- IEEE80211_ADDR_COPY(&add_sta_cmd.addr, in->in_ni.ni_bssid);
+ IEEE80211_ADDR_COPY(&add_sta_cmd.addr, ni->ni_bssid);
}
add_sta_cmd.add_modify = update ? 1 : 0;
- 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);
+ if (ni->ni_flags & IEEE80211_NODE_HT) {
+ add_sta_cmd.station_flags_msk |=
+ htole32(IWM_STA_FLG_RTS_MIMO_PROT |
+ IWM_STA_FLG_MIMO_EN_SISO |
+ IWM_STA_FLG_MAX_AGG_SIZE_MSK |
+ IWM_STA_FLG_MIMO_EN_MSK |
+ IWM_STA_FLG_AGG_MPDU_DENS_MSK |
+ IWM_STA_FLG_FAT_EN_MSK);
add_sta_cmd.station_flags
|= htole32(IWM_STA_FLG_MAX_AGG_SIZE_64K);
- switch (ic->ic_ampdu_params & IEEE80211_AMPDU_PARAM_SS) {
+ switch (ni->ni_ampdu_param & IEEE80211_AMPDU_PARAM_SS) {
case IEEE80211_AMPDU_PARAM_SS_2:
add_sta_cmd.station_flags
|= htole32(IWM_STA_FLG_AGG_MPDU_DENS_2US);
@@ -4508,6 +4510,18 @@ iwm_mvm_sta_send_to_fw(struct iwm_softc
default:
break;
}
+
+ switch ((ni->ni_htcaps & IEEE80211_HTCAP_SMPS_MASK) >>
+ IEEE80211_HTCAP_SMPS_SHIFT) {
+ case IEEE80211_HTCAP_SMPS_STA:
+ add_sta_cmd.station_flags |= IWM_STA_FLG_MIMO_EN_SISO;
+ break;
+ case IEEE80211_HTCAP_SMPS_DYN:
+ add_sta_cmd.station_flags |= IWM_STA_FLG_RTS_MIMO_PROT;
+ break;
+ default:
+ break;
+ }
}
status = IWM_ADD_STA_SUCCESS;
@@ -6840,7 +6854,7 @@ 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;
Index: if_iwn.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_iwn.c,v
retrieving revision 1.163
diff -u -p -r1.163 if_iwn.c
--- if_iwn.c 7 Feb 2016 23:56:19 -0000 1.163
+++ if_iwn.c 8 Feb 2016 00:33:48 -0000
@@ -456,7 +456,7 @@ 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;
@@ -4942,13 +4942,29 @@ iwn_run(struct iwn_softc *sc)
IEEE80211_ADDR_COPY(node.macaddr, ni->ni_macaddr);
node.id = IWN_ID_BSS;
if (ni->ni_flags & IEEE80211_NODE_HT) {
- node.htmask = (IWN_AMDPU_SIZE_FACTOR_MASK |
- IWN_AMDPU_DENSITY_MASK);
+ node.htmask = (IWN_HTF_RTS_MIMO_PROT |
+ IWN_HTF_AMDPU_SIZE_FACTOR_MASK |
+ IWN_HTF_AMDPU_DENSITY_MASK |
+ IWN_HTF_HT40_EN |
+ IWN_HTF_MIMO_DIS);
+
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));
+ IWN_HTF_AMDPU_SIZE_FACTOR(
+ (ni->ni_ampdu_param & IEEE80211_AMPDU_PARAM_LE)) |
+ IWN_HTF_AMDPU_DENSITY(
+ (ni->ni_ampdu_param & IEEE80211_AMPDU_PARAM_SS) >> 2));
+
+ switch ((ni->ni_htcaps & IEEE80211_HTCAP_SMPS_MASK) >>
+ IEEE80211_HTCAP_SMPS_SHIFT) {
+ case IEEE80211_HTCAP_SMPS_STA:
+ node.htflags |= IWN_HTF_MIMO_DIS;
+ break;
+ case IEEE80211_HTCAP_SMPS_DYN:
+ node.htflags |= IWN_HTF_RTS_MIMO_PROT;
+ break;
+ default:
+ break;
+ }
}
DPRINTF(("adding BSS node\n"));
error = ops->add_node(sc, &node, 1);
@@ -5097,13 +5113,29 @@ iwn_update_htprot(struct ieee80211com *i
IEEE80211_ADDR_COPY(node.macaddr, ni->ni_macaddr);
node.id = IWN_ID_BSS;
if (ni->ni_flags & IEEE80211_NODE_HT) {
- node.htmask = (IWN_AMDPU_SIZE_FACTOR_MASK |
- IWN_AMDPU_DENSITY_MASK);
+ node.htmask = (IWN_HTF_RTS_MIMO_PROT |
+ IWN_HTF_AMDPU_SIZE_FACTOR_MASK |
+ IWN_HTF_AMDPU_DENSITY_MASK |
+ IWN_HTF_HT40_EN |
+ IWN_HTF_MIMO_DIS);
+
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));
+ IWN_HTF_AMDPU_SIZE_FACTOR(
+ (ni->ni_ampdu_param & IEEE80211_AMPDU_PARAM_LE)) |
+ IWN_HTF_AMDPU_DENSITY(
+ (ni->ni_ampdu_param & IEEE80211_AMPDU_PARAM_SS) >> 2));
+
+ switch ((ni->ni_htcaps & IEEE80211_HTCAP_SMPS_MASK) >>
+ IEEE80211_HTCAP_SMPS_SHIFT) {
+ case IEEE80211_HTCAP_SMPS_STA:
+ node.htflags |= IWN_HTF_MIMO_DIS;
+ break;
+ case IEEE80211_HTCAP_SMPS_DYN:
+ node.htflags |= IWN_HTF_RTS_MIMO_PROT;
+ break;
+ default:
+ break;
+ }
}
error = ops->add_node(sc, &node, 1);
if (error != 0) {
Index: if_iwnreg.h
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_iwnreg.h,v
retrieving revision 1.52
diff -u -p -r1.52 if_iwnreg.h
--- if_iwnreg.h 5 Feb 2016 16:09:19 -0000 1.52
+++ if_iwnreg.h 7 Feb 2016 20:14:21 -0000
@@ -604,10 +604,17 @@ struct iwn_node_info {
uint8_t txmic[IEEE80211_TKIP_MICLEN];
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)
+#define IWN_HTF_TX_RATE (1 << 2)
+#define IWN_HTF_PWR_SAVE (1 << 8)
+#define IWN_HTF_PAN_STA (1 << 13)
+#define IWN_HTF_RTS_MIMO_PROT (1 << 17)
+#define IWN_HTF_AMPDU_8US (1 << 18)
+#define IWN_HTF_AMDPU_SIZE_FACTOR(x) ((x) << 19)
+#define IWN_HTF_AMDPU_SIZE_FACTOR_MASK ((0x3) << 19)
+#define IWN_HTF_HT40_EN (1 << 21)
+#define IWN_HTF_MIMO_DIS (1 << 22)
+#define IWN_HTF_AMDPU_DENSITY(x) ((x) << 23)
+#define IWN_HTF_AMDPU_DENSITY_MASK ((0x7) << 23)
uint32_t htmask;
uint16_t disable_tid;