[iwm] Sync valid_tx_ant and valid_rx_ant mask handling with iwlwifi.
* This fixes the phy_cfg field sent in the iwm_send_phy_cfg_cmd() command, which wasn't taking into account the valid_rx_ant and valid_tx_ant masks from nvm_data before. Tested: * 7260, STA mode, 2G and 5G Obtained from: DragonflyBSD commit cbb82693c18fd71b4eb86855b82d03995f352d65
This commit is contained in:
parent
8c03b09087
commit
2a2476b30b
@ -771,8 +771,14 @@ iwm_read_firmware(struct iwm_softc *sc, enum iwm_ucode_type ucode_type)
|
||||
(int) tlv_len);
|
||||
goto parse_out;
|
||||
}
|
||||
sc->sc_fw_phy_config =
|
||||
sc->sc_fw.phy_config =
|
||||
le32toh(*(const uint32_t *)tlv_data);
|
||||
sc->sc_fw.valid_tx_ant = (sc->sc_fw.phy_config &
|
||||
IWM_FW_PHY_CFG_TX_CHAIN) >>
|
||||
IWM_FW_PHY_CFG_TX_CHAIN_POS;
|
||||
sc->sc_fw.valid_rx_ant = (sc->sc_fw.phy_config &
|
||||
IWM_FW_PHY_CFG_RX_CHAIN) >>
|
||||
IWM_FW_PHY_CFG_RX_CHAIN_POS;
|
||||
break;
|
||||
|
||||
case IWM_UCODE_TLV_API_CHANGES_SET: {
|
||||
@ -1401,12 +1407,13 @@ iwm_mvm_nic_config(struct iwm_softc *sc)
|
||||
{
|
||||
uint8_t radio_cfg_type, radio_cfg_step, radio_cfg_dash;
|
||||
uint32_t reg_val = 0;
|
||||
uint32_t phy_config = iwm_mvm_get_phy_config(sc);
|
||||
|
||||
radio_cfg_type = (sc->sc_fw_phy_config & IWM_FW_PHY_CFG_RADIO_TYPE) >>
|
||||
radio_cfg_type = (phy_config & IWM_FW_PHY_CFG_RADIO_TYPE) >>
|
||||
IWM_FW_PHY_CFG_RADIO_TYPE_POS;
|
||||
radio_cfg_step = (sc->sc_fw_phy_config & IWM_FW_PHY_CFG_RADIO_STEP) >>
|
||||
radio_cfg_step = (phy_config & IWM_FW_PHY_CFG_RADIO_STEP) >>
|
||||
IWM_FW_PHY_CFG_RADIO_STEP_POS;
|
||||
radio_cfg_dash = (sc->sc_fw_phy_config & IWM_FW_PHY_CFG_RADIO_DASH) >>
|
||||
radio_cfg_dash = (phy_config & IWM_FW_PHY_CFG_RADIO_DASH) >>
|
||||
IWM_FW_PHY_CFG_RADIO_DASH_POS;
|
||||
|
||||
/* SKU control */
|
||||
@ -2696,7 +2703,7 @@ iwm_send_phy_cfg_cmd(struct iwm_softc *sc)
|
||||
enum iwm_ucode_type ucode_type = sc->sc_uc_current;
|
||||
|
||||
/* Set parameters */
|
||||
phy_cfg_cmd.phy_cfg = htole32(sc->sc_fw_phy_config);
|
||||
phy_cfg_cmd.phy_cfg = htole32(iwm_mvm_get_phy_config(sc));
|
||||
phy_cfg_cmd.calib_control.event_trigger =
|
||||
sc->sc_default_calib[ucode_type].event_trigger;
|
||||
phy_cfg_cmd.calib_control.flow_trigger =
|
||||
@ -2783,6 +2790,7 @@ iwm_run_init_mvm_ucode(struct iwm_softc *sc, int justnvm)
|
||||
if (error != 0)
|
||||
return error;
|
||||
|
||||
#if 0
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_RESET,
|
||||
"%s: phy_txant=0x%08x, nvm_valid_tx_ant=0x%02x, valid=0x%02x\n",
|
||||
__func__,
|
||||
@ -2790,10 +2798,11 @@ iwm_run_init_mvm_ucode(struct iwm_softc *sc, int justnvm)
|
||||
>> IWM_FW_PHY_CFG_TX_CHAIN_POS),
|
||||
sc->nvm_data->valid_tx_ant,
|
||||
iwm_fw_valid_tx_ant(sc));
|
||||
|
||||
#endif
|
||||
|
||||
/* Send TX valid antennas before triggering calibrations */
|
||||
if ((error = iwm_send_tx_ant_cfg(sc, iwm_fw_valid_tx_ant(sc))) != 0) {
|
||||
error = iwm_send_tx_ant_cfg(sc, iwm_mvm_get_valid_tx_ant(sc));
|
||||
if (error != 0) {
|
||||
device_printf(sc->sc_dev,
|
||||
"failed to send antennas before calibration: %d\n", error);
|
||||
return error;
|
||||
@ -4238,11 +4247,11 @@ iwm_setrates(struct iwm_softc *sc, struct iwm_node *in)
|
||||
|
||||
#if 0
|
||||
if (txant == 0)
|
||||
txant = iwm_fw_valid_tx_ant(sc);
|
||||
txant = iwm_mvm_get_valid_tx_ant(sc);
|
||||
nextant = 1<<(ffs(txant)-1);
|
||||
txant &= ~nextant;
|
||||
#else
|
||||
nextant = iwm_fw_valid_tx_ant(sc);
|
||||
nextant = iwm_mvm_get_valid_tx_ant(sc);
|
||||
#endif
|
||||
/*
|
||||
* Map the rate id into a rate index into
|
||||
@ -4708,7 +4717,8 @@ iwm_init_hw(struct iwm_softc *sc)
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((error = iwm_send_tx_ant_cfg(sc, iwm_fw_valid_tx_ant(sc))) != 0) {
|
||||
error = iwm_send_tx_ant_cfg(sc, iwm_mvm_get_valid_tx_ant(sc));
|
||||
if (error != 0) {
|
||||
device_printf(sc->sc_dev, "antenna config failed\n");
|
||||
goto error;
|
||||
}
|
||||
|
@ -202,8 +202,8 @@ iwm_mvm_phy_ctxt_cmd_data(struct iwm_softc *sc,
|
||||
ieee80211_chan2ieee(ic, chan),
|
||||
chains_static,
|
||||
chains_dynamic,
|
||||
iwm_fw_valid_rx_ant(sc),
|
||||
iwm_fw_valid_tx_ant(sc));
|
||||
iwm_mvm_get_valid_rx_ant(sc),
|
||||
iwm_mvm_get_valid_tx_ant(sc));
|
||||
|
||||
|
||||
cmd->ci.band = IEEE80211_IS_CHAN_2GHZ(chan) ?
|
||||
@ -217,13 +217,13 @@ iwm_mvm_phy_ctxt_cmd_data(struct iwm_softc *sc,
|
||||
idle_cnt = chains_static;
|
||||
active_cnt = chains_dynamic;
|
||||
|
||||
cmd->rxchain_info = htole32(iwm_fw_valid_rx_ant(sc) <<
|
||||
cmd->rxchain_info = htole32(iwm_mvm_get_valid_rx_ant(sc) <<
|
||||
IWM_PHY_RX_CHAIN_VALID_POS);
|
||||
cmd->rxchain_info |= htole32(idle_cnt << IWM_PHY_RX_CHAIN_CNT_POS);
|
||||
cmd->rxchain_info |= htole32(active_cnt <<
|
||||
IWM_PHY_RX_CHAIN_MIMO_CNT_POS);
|
||||
|
||||
cmd->txchain_info = htole32(iwm_fw_valid_tx_ant(sc));
|
||||
cmd->txchain_info = htole32(iwm_mvm_get_valid_tx_ant(sc));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -172,7 +172,7 @@ iwm_mvm_scan_rx_chain(struct iwm_softc *sc)
|
||||
uint16_t rx_chain;
|
||||
uint8_t rx_ant;
|
||||
|
||||
rx_ant = iwm_fw_valid_rx_ant(sc);
|
||||
rx_ant = iwm_mvm_get_valid_rx_ant(sc);
|
||||
rx_chain = rx_ant << IWM_PHY_RX_CHAIN_VALID_POS;
|
||||
rx_chain |= rx_ant << IWM_PHY_RX_CHAIN_FORCE_MIMO_SEL_POS;
|
||||
rx_chain |= rx_ant << IWM_PHY_RX_CHAIN_FORCE_SEL_POS;
|
||||
@ -209,7 +209,7 @@ iwm_mvm_scan_rate_n_flags(struct iwm_softc *sc, int flags, int no_cck)
|
||||
for (i = 0, ind = sc->sc_scan_last_antenna;
|
||||
i < IWM_RATE_MCS_ANT_NUM; i++) {
|
||||
ind = (ind + 1) % IWM_RATE_MCS_ANT_NUM;
|
||||
if (iwm_fw_valid_tx_ant(sc) & (1 << ind)) {
|
||||
if (iwm_mvm_get_valid_tx_ant(sc) & (1 << ind)) {
|
||||
sc->sc_scan_last_antenna = ind;
|
||||
break;
|
||||
}
|
||||
@ -469,8 +469,8 @@ iwm_mvm_config_umac_scan(struct iwm_softc *sc)
|
||||
if (scan_config == NULL)
|
||||
return ENOMEM;
|
||||
|
||||
scan_config->tx_chains = htole32(iwm_fw_valid_tx_ant(sc));
|
||||
scan_config->rx_chains = htole32(iwm_fw_valid_rx_ant(sc));
|
||||
scan_config->tx_chains = htole32(iwm_mvm_get_valid_tx_ant(sc));
|
||||
scan_config->rx_chains = htole32(iwm_mvm_get_valid_rx_ant(sc));
|
||||
scan_config->legacy_rates = htole32(rates |
|
||||
IWM_SCAN_CONFIG_SUPPORTED_RATE(rates));
|
||||
|
||||
|
@ -428,31 +428,3 @@ iwm_free_resp(struct iwm_softc *sc, struct iwm_host_cmd *hcmd)
|
||||
sc->sc_wantresp = -1;
|
||||
wakeup(&sc->sc_wantresp);
|
||||
}
|
||||
|
||||
uint8_t
|
||||
iwm_fw_valid_tx_ant(struct iwm_softc *sc)
|
||||
{
|
||||
uint8_t tx_ant;
|
||||
|
||||
tx_ant = ((sc->sc_fw_phy_config & IWM_FW_PHY_CFG_TX_CHAIN)
|
||||
>> IWM_FW_PHY_CFG_TX_CHAIN_POS);
|
||||
|
||||
if (sc->nvm_data->valid_tx_ant)
|
||||
tx_ant &= sc->nvm_data->valid_tx_ant;
|
||||
|
||||
return tx_ant;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
iwm_fw_valid_rx_ant(struct iwm_softc *sc)
|
||||
{
|
||||
uint8_t rx_ant;
|
||||
|
||||
rx_ant = ((sc->sc_fw_phy_config & IWM_FW_PHY_CFG_RX_CHAIN)
|
||||
>> IWM_FW_PHY_CFG_RX_CHAIN_POS);
|
||||
|
||||
if (sc->nvm_data->valid_rx_ant)
|
||||
rx_ant &= sc->nvm_data->valid_rx_ant;
|
||||
|
||||
return rx_ant;
|
||||
}
|
||||
|
@ -116,7 +116,34 @@ extern int iwm_mvm_send_cmd_pdu_status(struct iwm_softc *sc, uint8_t id,
|
||||
uint16_t len, const void *data, uint32_t *status);
|
||||
extern void iwm_free_resp(struct iwm_softc *sc, struct iwm_host_cmd *hcmd);
|
||||
|
||||
extern uint8_t iwm_fw_valid_tx_ant(struct iwm_softc *sc);
|
||||
extern uint8_t iwm_fw_valid_rx_ant(struct iwm_softc *sc);
|
||||
static inline uint8_t
|
||||
iwm_mvm_get_valid_tx_ant(struct iwm_softc *sc)
|
||||
{
|
||||
return sc->nvm_data && sc->nvm_data->valid_tx_ant ?
|
||||
sc->sc_fw.valid_tx_ant & sc->nvm_data->valid_tx_ant :
|
||||
sc->sc_fw.valid_tx_ant;
|
||||
}
|
||||
|
||||
static inline uint8_t
|
||||
iwm_mvm_get_valid_rx_ant(struct iwm_softc *sc)
|
||||
{
|
||||
return sc->nvm_data && sc->nvm_data->valid_rx_ant ?
|
||||
sc->sc_fw.valid_rx_ant & sc->nvm_data->valid_rx_ant :
|
||||
sc->sc_fw.valid_rx_ant;
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
iwm_mvm_get_phy_config(struct iwm_softc *sc)
|
||||
{
|
||||
uint32_t phy_config = ~(IWM_FW_PHY_CFG_TX_CHAIN |
|
||||
IWM_FW_PHY_CFG_RX_CHAIN);
|
||||
uint32_t valid_rx_ant = iwm_mvm_get_valid_rx_ant(sc);
|
||||
uint32_t valid_tx_ant = iwm_mvm_get_valid_tx_ant(sc);
|
||||
|
||||
phy_config |= valid_tx_ant << IWM_FW_PHY_CFG_TX_CHAIN_POS |
|
||||
valid_rx_ant << IWM_FW_PHY_CFG_RX_CHAIN_POS;
|
||||
|
||||
return sc->sc_fw.phy_config & phy_config;
|
||||
}
|
||||
|
||||
#endif /* __IF_IWM_UTIL_H__ */
|
||||
|
@ -172,6 +172,10 @@ struct iwm_fw_info {
|
||||
} fw_sect[IWM_UCODE_SECT_MAX];
|
||||
int fw_count;
|
||||
} fw_sects[IWM_UCODE_TYPE_MAX];
|
||||
|
||||
uint32_t phy_config;
|
||||
uint8_t valid_tx_ant;
|
||||
uint8_t valid_rx_ant;
|
||||
};
|
||||
|
||||
struct iwm_nvm_data {
|
||||
@ -465,7 +469,6 @@ struct iwm_softc {
|
||||
|
||||
bus_size_t sc_fwdmasegsz;
|
||||
struct iwm_fw_info sc_fw;
|
||||
int sc_fw_phy_config;
|
||||
struct iwm_tlv_calib_ctrl sc_default_calib[IWM_UCODE_TYPE_MAX];
|
||||
|
||||
const struct iwm_cfg *cfg;
|
||||
|
Loading…
Reference in New Issue
Block a user