Download raw body.
fix fatal firmware error when forcing iwx to 11a/b/g mode
Forcing iwx(4) into 11a/b/g mode produces a fatal firmware error with
BZ firmware, and possibly other firmware, too. This also happens when
I try to disable mimo with "ifconfig iwx0 nwflag nomimo".
The driver does not take limitations of 11a/b/g modes into account while
initializing Tx rate selection, which triggers some sanity checks in the
firmware. The patch below fixes this.
ok?
M sys/dev/pci/if_iwx.c | 24+ 10-
1 file changed, 24 insertions(+), 10 deletions(-)
path + /usr/src
commit - bf3713f7dfbf19ede85da952a0d01b849aa8a252
blob - e731cf032ef66ed7a7eab46a3669fc5d80d9e8d3
file + sys/dev/pci/if_iwx.c
--- sys/dev/pci/if_iwx.c
+++ sys/dev/pci/if_iwx.c
@@ -8483,18 +8483,25 @@ iwx_rs_init_v3(struct iwx_softc *sc, struct iwx_node *
cfg_cmd.mode = IWX_TLC_MNG_MODE_NON_HT;
cfg_cmd.sta_id = IWX_STATION_ID;
- if (in->in_phyctxt->vht_chan_width == IEEE80211_VHTOP0_CHAN_WIDTH_80)
+ if ((ni->ni_flags & IEEE80211_NODE_VHT) &&
+ in->in_phyctxt->vht_chan_width == IEEE80211_VHTOP0_CHAN_WIDTH_80)
cfg_cmd.max_ch_width = IWX_TLC_MNG_CH_WIDTH_80MHZ;
- else if (in->in_phyctxt->sco == IEEE80211_HTOP0_SCO_SCA ||
- in->in_phyctxt->sco == IEEE80211_HTOP0_SCO_SCB)
+ else if ((ni->ni_flags & IEEE80211_NODE_HT) &&
+ (in->in_phyctxt->sco == IEEE80211_HTOP0_SCO_SCA ||
+ in->in_phyctxt->sco == IEEE80211_HTOP0_SCO_SCB))
cfg_cmd.max_ch_width = IWX_TLC_MNG_CH_WIDTH_40MHZ;
else
cfg_cmd.max_ch_width = IWX_TLC_MNG_CH_WIDTH_20MHZ;
- cfg_cmd.chains = IWX_TLC_MNG_CHAIN_A_MSK | IWX_TLC_MNG_CHAIN_B_MSK;
+ if ((ni->ni_flags & IEEE80211_NODE_HT) && iwx_mimo_enabled(sc))
+ cfg_cmd.chains = IWX_TLC_MNG_CHAIN_A_MSK | IWX_TLC_MNG_CHAIN_B_MSK;
+ else
+ cfg_cmd.chains = IWX_TLC_MNG_CHAIN_A_MSK;
if (ni->ni_flags & IEEE80211_NODE_VHT)
cfg_cmd.max_mpdu_len = htole16(3895);
- else
+ else if (ni->ni_flags & IEEE80211_NODE_HT)
cfg_cmd.max_mpdu_len = htole16(3839);
+ else
+ cfg_cmd.max_mpdu_len = IEEE80211_MAX_LEN;
if (ni->ni_flags & IEEE80211_NODE_HT) {
if (ieee80211_node_supports_ht_sgi20(ni)) {
cfg_cmd.sgi_ch_width_supp |= (1 <<
@@ -8551,18 +8558,25 @@ iwx_rs_init_v4(struct iwx_softc *sc, struct iwx_node *
cfg_cmd.mode = IWX_TLC_MNG_MODE_NON_HT;
cfg_cmd.sta_id = IWX_STATION_ID;
- if (in->in_phyctxt->vht_chan_width == IEEE80211_VHTOP0_CHAN_WIDTH_80)
+ if ((ni->ni_flags & IEEE80211_NODE_VHT) &&
+ in->in_phyctxt->vht_chan_width == IEEE80211_VHTOP0_CHAN_WIDTH_80)
cfg_cmd.max_ch_width = IWX_TLC_MNG_CH_WIDTH_80MHZ;
- else if (in->in_phyctxt->sco == IEEE80211_HTOP0_SCO_SCA ||
- in->in_phyctxt->sco == IEEE80211_HTOP0_SCO_SCB)
+ else if ((ni->ni_flags & IEEE80211_NODE_HT) &&
+ (in->in_phyctxt->sco == IEEE80211_HTOP0_SCO_SCA ||
+ in->in_phyctxt->sco == IEEE80211_HTOP0_SCO_SCB))
cfg_cmd.max_ch_width = IWX_TLC_MNG_CH_WIDTH_40MHZ;
else
cfg_cmd.max_ch_width = IWX_TLC_MNG_CH_WIDTH_20MHZ;
- cfg_cmd.chains = IWX_TLC_MNG_CHAIN_A_MSK | IWX_TLC_MNG_CHAIN_B_MSK;
+ if ((ni->ni_flags & IEEE80211_NODE_HT) && iwx_mimo_enabled(sc))
+ cfg_cmd.chains = IWX_TLC_MNG_CHAIN_A_MSK | IWX_TLC_MNG_CHAIN_B_MSK;
+ else
+ cfg_cmd.chains = IWX_TLC_MNG_CHAIN_A_MSK;
if (ni->ni_flags & IEEE80211_NODE_VHT)
cfg_cmd.max_mpdu_len = htole16(3895);
- else
+ else if (ni->ni_flags & IEEE80211_NODE_HT)
cfg_cmd.max_mpdu_len = htole16(3839);
+ else
+ cfg_cmd.max_mpdu_len = IEEE80211_MAX_LEN;
if (ni->ni_flags & IEEE80211_NODE_HT) {
if (ieee80211_node_supports_ht_sgi20(ni)) {
cfg_cmd.sgi_ch_width_supp |= (1 <<
fix fatal firmware error when forcing iwx to 11a/b/g mode