On Wed, Jun 01, 2022 at 12:32:45AM +0100, Chris Narkiewicz wrote: > > Can you please apply this patch, boot the resulting kernel, and > > show me the new line that now appears in dmesg? It will show us > > the antenna configuration of your device. > > So I applied the patch and this is the result: > > iwm0: hw rev 0x310, fw ver 46.4e1ceb39.0, address 20:1e:88:77:66:72 > iwm0: valid Tx antenna masks: phycfg: 0x3 nvm: 0x1 > > I hope it leads somewhere. Thank you.
Let's try this patch. Does it help? diff 98c04410ecc965030a8aa6f07102b14a69145a48 54780b8cb6da1f75e7566af8b6117d93126a96b1 blob - 6de80bd303e3c03a8f4eb2533f54f65d4deebdd3 blob + 8b411c541a334905e8c6ba883bd8cabff15e999d --- sys/dev/pci/if_iwm.c +++ sys/dev/pci/if_iwm.c @@ -331,6 +331,9 @@ int iwm_nvm_read_chunk(struct iwm_softc *, uint16_t, u uint8_t *, uint16_t *); int iwm_nvm_read_section(struct iwm_softc *, uint16_t, uint8_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, const uint8_t *nvm_channels, int nchan); int iwm_mimo_enabled(struct iwm_softc *); @@ -3038,6 +3041,23 @@ iwm_fw_valid_rx_ant(struct iwm_softc *sc) 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 iwm_init_channel_map(struct iwm_softc *sc, const uint16_t * const nvm_ch_flags, const uint8_t *nvm_channels, int nchan) @@ -6628,10 +6648,8 @@ iwm_tx_fill_cmd(struct iwm_softc *sc, struct iwm_node if ((ni->ni_flags & IEEE80211_NODE_VHT) == 0 && iwm_is_mimo_ht_plcp(rinfo->ht_plcp)) 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 - rate_flags = IWM_RATE_MCS_ANT_A_MSK; + rate_flags = iwm_valid_siso_ant_rate_mask(sc); if (IWM_RIDX_IS_CCK(ridx)) rate_flags |= IWM_RATE_MCS_CCK_MSK; if ((ni->ni_flags & IEEE80211_NODE_HT) && @@ -9248,13 +9266,8 @@ iwm_set_rate_table_vht(struct iwm_node *in, struct iwm IWM_RATE_VHT_MCS_NSS_MSK; if (ni->ni_vht_ss > 1) 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 - tab |= IWM_RATE_MCS_ANT_A_MSK; - } + else + tab |= iwm_valid_siso_ant_rate_mask(sc); /* * First two Tx attempts may use 80MHz/40MHz/SGI. @@ -9294,10 +9307,7 @@ iwm_set_rate_table_vht(struct iwm_node *in, struct iwm } else { /* Fill the rest with the lowest possible rate. */ tab = iwm_rates[ridx_min].plcp; - if (sc->sc_device_family == IWM_DEVICE_FAMILY_9000) - tab |= IWM_RATE_MCS_ANT_B_MSK; - else - tab |= IWM_RATE_MCS_ANT_A_MSK; + tab |= iwm_valid_siso_ant_rate_mask(sc); if (ni->ni_vht_ss > 1 && lqcmd->mimo_delim == 0) lqcmd->mimo_delim = i; } @@ -9378,10 +9388,8 @@ iwm_set_rate_table(struct iwm_node *in, struct iwm_lq_ if (iwm_is_mimo_ht_plcp(ht_plcp)) 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 - tab |= IWM_RATE_MCS_ANT_A_MSK; + tab |= iwm_valid_siso_ant_rate_mask(sc); if (IWM_RIDX_IS_CCK(ridx)) tab |= IWM_RATE_MCS_CCK_MSK; @@ -9395,10 +9403,7 @@ iwm_set_rate_table(struct iwm_node *in, struct iwm_lq_ tab = iwm_rates[ridx_min].plcp; if (IWM_RIDX_IS_CCK(ridx_min)) tab |= IWM_RATE_MCS_CCK_MSK; - if (sc->sc_device_family == IWM_DEVICE_FAMILY_9000) - tab |= IWM_RATE_MCS_ANT_B_MSK; - else - tab |= IWM_RATE_MCS_ANT_A_MSK; + tab |= iwm_valid_siso_ant_rate_mask(sc); lqcmd->rs_table[j++] = htole32(tab); } } @@ -9428,7 +9433,8 @@ iwm_setrates(struct iwm_node *in, int async) else 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; else lqcmd.single_stream_ant_msk = IWM_ANT_A;