idualwifi7260: Merge patch from OpenBSD for some 9xxx devices.

This commit is contained in:
Augustin Cavalier 2022-06-22 14:34:17 -04:00
parent a928b16e36
commit c95c5ed821

View File

@ -1,4 +1,4 @@
/* $OpenBSD: if_iwm.c,v 1.400 2022/03/23 09:22:49 stsp Exp $ */ /* $OpenBSD: if_iwm.c,v 1.401 2022/06/04 11:32:11 stsp Exp $ */
/* /*
* Copyright (c) 2014, 2016 genua gmbh <info@genua.de> * Copyright (c) 2014, 2016 genua gmbh <info@genua.de>
@ -341,6 +341,9 @@ int iwm_nvm_read_chunk(struct iwm_softc *, uint16_t, uint16_t, uint16_t,
uint8_t *, uint16_t *); uint8_t *, uint16_t *);
int iwm_nvm_read_section(struct iwm_softc *, uint16_t, uint8_t *, int iwm_nvm_read_section(struct iwm_softc *, uint16_t, uint8_t *,
uint16_t *, size_t); uint16_t *, size_t);
uint8_t iwm_fw_valid_tx_ant(struct iwm_softc *);
uint8_t iwm_fw_valid_rx_ant(struct iwm_softc *);
int iwm_valid_siso_ant_rate_mask(struct iwm_softc *);
void iwm_init_channel_map(struct iwm_softc *, const uint16_t * const, void iwm_init_channel_map(struct iwm_softc *, const uint16_t * const,
const uint8_t *nvm_channels, int nchan); const uint8_t *nvm_channels, int nchan);
int iwm_mimo_enabled(struct iwm_softc *); int iwm_mimo_enabled(struct iwm_softc *);
@ -3065,6 +3068,23 @@ iwm_fw_valid_rx_ant(struct iwm_softc *sc)
return rx_ant; return rx_ant;
} }
int
iwm_valid_siso_ant_rate_mask(struct iwm_softc *sc)
{
uint8_t valid_tx_ant = iwm_fw_valid_tx_ant(sc);
/*
* According to the Linux driver, antenna B should be preferred
* on 9k devices since it is not shared with bluetooth. However,
* there are 9k devices which do not support antenna B at all.
*/
if (sc->sc_device_family == IWM_DEVICE_FAMILY_9000 &&
(valid_tx_ant & IWM_ANT_B))
return IWM_RATE_MCS_ANT_B_MSK;
return IWM_RATE_MCS_ANT_A_MSK;
}
void void
iwm_init_channel_map(struct iwm_softc *sc, const uint16_t * const nvm_ch_flags, iwm_init_channel_map(struct iwm_softc *sc, const uint16_t * const nvm_ch_flags,
const uint8_t *nvm_channels, int nchan) const uint8_t *nvm_channels, int nchan)
@ -6659,10 +6679,8 @@ iwm_tx_fill_cmd(struct iwm_softc *sc, struct iwm_node *in,
if ((ni->ni_flags & IEEE80211_NODE_VHT) == 0 && if ((ni->ni_flags & IEEE80211_NODE_VHT) == 0 &&
iwm_is_mimo_ht_plcp(rinfo->ht_plcp)) iwm_is_mimo_ht_plcp(rinfo->ht_plcp))
rate_flags = IWM_RATE_MCS_ANT_AB_MSK; rate_flags = IWM_RATE_MCS_ANT_AB_MSK;
else if (sc->sc_device_family == IWM_DEVICE_FAMILY_9000)
rate_flags = IWM_RATE_MCS_ANT_B_MSK;
else else
rate_flags = IWM_RATE_MCS_ANT_A_MSK; rate_flags = iwm_valid_siso_ant_rate_mask(sc);
if (IWM_RIDX_IS_CCK(ridx)) if (IWM_RIDX_IS_CCK(ridx))
rate_flags |= IWM_RATE_MCS_CCK_MSK; rate_flags |= IWM_RATE_MCS_CCK_MSK;
if ((ni->ni_flags & IEEE80211_NODE_HT) && if ((ni->ni_flags & IEEE80211_NODE_HT) &&
@ -9291,13 +9309,8 @@ iwm_set_rate_table_vht(struct iwm_node *in, struct iwm_lq_cmd *lqcmd)
IWM_RATE_VHT_MCS_NSS_MSK; IWM_RATE_VHT_MCS_NSS_MSK;
if (ni->ni_vht_ss > 1) if (ni->ni_vht_ss > 1)
tab |= IWM_RATE_MCS_ANT_AB_MSK; tab |= IWM_RATE_MCS_ANT_AB_MSK;
else { else
if (sc->sc_device_family == tab |= iwm_valid_siso_ant_rate_mask(sc);
IWM_DEVICE_FAMILY_9000)
tab |= IWM_RATE_MCS_ANT_B_MSK;
else
tab |= IWM_RATE_MCS_ANT_A_MSK;
}
/* /*
* First two Tx attempts may use 80MHz/40MHz/SGI. * First two Tx attempts may use 80MHz/40MHz/SGI.
@ -9337,10 +9350,7 @@ iwm_set_rate_table_vht(struct iwm_node *in, struct iwm_lq_cmd *lqcmd)
} else { } else {
/* Fill the rest with the lowest possible rate. */ /* Fill the rest with the lowest possible rate. */
tab = iwm_rates[ridx_min].plcp; tab = iwm_rates[ridx_min].plcp;
if (sc->sc_device_family == IWM_DEVICE_FAMILY_9000) tab |= iwm_valid_siso_ant_rate_mask(sc);
tab |= IWM_RATE_MCS_ANT_B_MSK;
else
tab |= IWM_RATE_MCS_ANT_A_MSK;
if (ni->ni_vht_ss > 1 && lqcmd->mimo_delim == 0) if (ni->ni_vht_ss > 1 && lqcmd->mimo_delim == 0)
lqcmd->mimo_delim = i; lqcmd->mimo_delim = i;
} }
@ -9421,10 +9431,8 @@ iwm_set_rate_table(struct iwm_node *in, struct iwm_lq_cmd *lqcmd)
if (iwm_is_mimo_ht_plcp(ht_plcp)) if (iwm_is_mimo_ht_plcp(ht_plcp))
tab |= IWM_RATE_MCS_ANT_AB_MSK; tab |= IWM_RATE_MCS_ANT_AB_MSK;
else if (sc->sc_device_family == IWM_DEVICE_FAMILY_9000)
tab |= IWM_RATE_MCS_ANT_B_MSK;
else else
tab |= IWM_RATE_MCS_ANT_A_MSK; tab |= iwm_valid_siso_ant_rate_mask(sc);
if (IWM_RIDX_IS_CCK(ridx)) if (IWM_RIDX_IS_CCK(ridx))
tab |= IWM_RATE_MCS_CCK_MSK; tab |= IWM_RATE_MCS_CCK_MSK;
@ -9438,10 +9446,7 @@ iwm_set_rate_table(struct iwm_node *in, struct iwm_lq_cmd *lqcmd)
tab = iwm_rates[ridx_min].plcp; tab = iwm_rates[ridx_min].plcp;
if (IWM_RIDX_IS_CCK(ridx_min)) if (IWM_RIDX_IS_CCK(ridx_min))
tab |= IWM_RATE_MCS_CCK_MSK; tab |= IWM_RATE_MCS_CCK_MSK;
if (sc->sc_device_family == IWM_DEVICE_FAMILY_9000) tab |= iwm_valid_siso_ant_rate_mask(sc);
tab |= IWM_RATE_MCS_ANT_B_MSK;
else
tab |= IWM_RATE_MCS_ANT_A_MSK;
lqcmd->rs_table[j++] = htole32(tab); lqcmd->rs_table[j++] = htole32(tab);
} }
} }
@ -9471,7 +9476,8 @@ iwm_setrates(struct iwm_node *in, int async)
else else
iwm_set_rate_table(in, &lqcmd); iwm_set_rate_table(in, &lqcmd);
if (sc->sc_device_family == IWM_DEVICE_FAMILY_9000) if (sc->sc_device_family == IWM_DEVICE_FAMILY_9000 &&
(iwm_fw_valid_tx_ant(sc) & IWM_ANT_B))
lqcmd.single_stream_ant_msk = IWM_ANT_B; lqcmd.single_stream_ant_msk = IWM_ANT_B;
else else
lqcmd.single_stream_ant_msk = IWM_ANT_A; lqcmd.single_stream_ant_msk = IWM_ANT_A;