This fixes issues with iwm(4) firmware's retry rate table.
For a HT node ni_txrate is always zero and we should be using
ni_txmcs instead. Simplify the if-else logic to make sure of that.
The mimo delimiter in the link quality command was never set.
I don't know how important this is. But Linux sets it, so why not.
Hardcode the lowest rate at the tail of the retry table.
While debugging the old code I have encountered retry tables filled
with only 'MCS 8' which is obviously not ideal.
Index: if_iwm.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_iwm.c,v
retrieving revision 1.178
diff -u -p -r1.178 if_iwm.c
--- if_iwm.c 4 May 2017 09:03:42 -0000 1.178
+++ if_iwm.c 5 May 2017 13:18:44 -0000
@@ -241,7 +241,7 @@ struct iwm_nvm_section {
uint8_t *data;
};
-int iwm_is_mimo_plcp(uint8_t);
+int iwm_is_mimo_ht_plcp(uint8_t);
int iwm_is_mimo_mcs(int);
int iwm_store_cscheme(struct iwm_softc *, uint8_t *, size_t);
int iwm_firmware_store_section(struct iwm_softc *, enum iwm_ucode_type,
@@ -5375,8 +5375,9 @@ iwm_setrates(struct iwm_node *in)
if (j >= nitems(lq->rs_table))
break;
tab = 0;
- if ((ni->ni_flags & IEEE80211_NODE_HT) &&
- ht_plcp != IWM_RATE_HT_SISO_MCS_INV_PLCP) {
+ if (ni->ni_flags & IEEE80211_NODE_HT) {
+ if (ht_plcp == IWM_RATE_HT_SISO_MCS_INV_PLCP)
+ continue;
/* Do not mix SISO and MIMO HT rates. */
if ((mimo && !iwm_is_mimo_ht_plcp(ht_plcp)) ||
(!mimo && iwm_is_mimo_ht_plcp(ht_plcp)))
@@ -5392,8 +5393,7 @@ iwm_setrates(struct iwm_node *in)
break;
}
}
- }
- if (tab == 0 && plcp != IWM_RATE_INVM_PLCP) {
+ } else if (plcp != IWM_RATE_INVM_PLCP) {
for (i = ni->ni_txrate; i >= 0; i--) {
if (iwm_rates[ridx].rate == (rs->rs_rates[i] &
IEEE80211_RATE_VAL)) {
@@ -5416,10 +5416,16 @@ iwm_setrates(struct iwm_node *in)
lq->rs_table[j++] = htole32(tab);
}
+ lq->mimo_delim = (mimo ? j : 0);
+
/* Fill the rest with the lowest possible rate */
- i = j > 0 ? j - 1 : 0;
- while (j < nitems(lq->rs_table))
- lq->rs_table[j++] = lq->rs_table[i];
+ while (j < nitems(lq->rs_table)) {
+ tab = iwm_rates[ridx_min].plcp;
+ if (IWM_RIDX_IS_CCK(ridx_min))
+ tab |= IWM_RATE_MCS_CCK_MSK;
+ tab |= IWM_RATE_MCS_ANT_A_MSK;
+ lq->rs_table[j++] = htole32(tab);
+ }
lq->single_stream_ant_msk = IWM_ANT_A;
lq->dual_stream_ant_msk = IWM_ANT_AB;