static struct iwl_link_quality_cmd * iwl_sta_alloc_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx, u8 sta_id) { int i, r; struct iwl_link_quality_cmd *link_cmd; u32 rate_flags = 0; __le32 rate_n_flags; link_cmd = kzalloc(sizeof(struct iwl_link_quality_cmd), GFP_KERNEL); if (!link_cmd) { IWL_ERR(priv, "Unable to allocate memory for LQ cmd.\n"); return NULL; } lockdep_assert_held(&priv->shrd->mutex); /* Set up the rate scaling to start at selected rate, fall back * all the way down to 1M in IEEE order, and then spin on 1M */ if (priv->band == IEEE80211_BAND_5GHZ) r = IWL_RATE_6M_INDEX; else if (ctx && ctx->vif && ctx->vif->p2p) r = IWL_RATE_6M_INDEX; else r = IWL_RATE_1M_INDEX; if (r >= IWL_FIRST_CCK_RATE && r <= IWL_LAST_CCK_RATE) rate_flags |= RATE_MCS_CCK_MSK; rate_flags |= first_antenna(hw_params(priv).valid_tx_ant) << RATE_MCS_ANT_POS; rate_n_flags = iwl_hw_set_rate_n_flags(iwl_rates[r].plcp, rate_flags); for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) link_cmd->rs_table[i].rate_n_flags = rate_n_flags; link_cmd->general_params.single_stream_ant_msk = first_antenna(hw_params(priv).valid_tx_ant); link_cmd->general_params.dual_stream_ant_msk = hw_params(priv).valid_tx_ant & ~first_antenna(hw_params(priv).valid_tx_ant); if (!link_cmd->general_params.dual_stream_ant_msk) { link_cmd->general_params.dual_stream_ant_msk = ANT_AB; } else if (num_of_ant(hw_params(priv).valid_tx_ant) == 2) { link_cmd->general_params.dual_stream_ant_msk = hw_params(priv).valid_tx_ant; } link_cmd->agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF; link_cmd->agg_params.agg_time_limit = cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF); link_cmd->sta_id = sta_id; return link_cmd; }
static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv, struct iwl_tx_cmd *tx_cmd, struct ieee80211_tx_info *info, __le16 fc) { u32 rate_flags; int rate_idx; u8 rts_retry_limit; u8 data_retry_limit; u8 rate_plcp; if (priv->shrd->wowlan) { rts_retry_limit = IWLAGN_LOW_RETRY_LIMIT; data_retry_limit = IWLAGN_LOW_RETRY_LIMIT; } else { /* Set retry limit on RTS packets */ rts_retry_limit = IWLAGN_RTS_DFAULT_RETRY_LIMIT; /* Set retry limit on DATA packets and Probe Responses*/ if (ieee80211_is_probe_resp(fc)) { data_retry_limit = IWLAGN_MGMT_DFAULT_RETRY_LIMIT; rts_retry_limit = min(data_retry_limit, rts_retry_limit); } else if (ieee80211_is_back_req(fc)) data_retry_limit = IWLAGN_BAR_DFAULT_RETRY_LIMIT; else data_retry_limit = IWLAGN_DEFAULT_TX_RETRY; } tx_cmd->data_retry_limit = data_retry_limit; tx_cmd->rts_retry_limit = rts_retry_limit; /* DATA packets will use the uCode station table for rate/antenna * selection */ if (ieee80211_is_data(fc)) { tx_cmd->initial_rate_index = 0; tx_cmd->tx_flags |= TX_CMD_FLG_STA_RATE_MSK; #ifdef CONFIG_IWLWIFI_DEVICE_SVTOOL if (priv->tm_fixed_rate) { /* * rate overwrite by testmode * we not only send lq command to change rate * we also re-enforce per data pkt base. */ tx_cmd->tx_flags &= ~TX_CMD_FLG_STA_RATE_MSK; memcpy(&tx_cmd->rate_n_flags, &priv->tm_fixed_rate, sizeof(tx_cmd->rate_n_flags)); } #endif return; } /** * If the current TX rate stored in mac80211 has the MCS bit set, it's * not really a TX rate. Thus, we use the lowest supported rate for * this band. Also use the lowest supported rate if the stored rate * index is invalid. */ rate_idx = info->control.rates[0].idx; if (info->control.rates[0].flags & IEEE80211_TX_RC_MCS || (rate_idx < 0) || (rate_idx > IWL_RATE_COUNT_LEGACY)) rate_idx = rate_lowest_index(&priv->bands[info->band], info->control.sta); /* For 5 GHZ band, remap mac80211 rate indices into driver indices */ if (info->band == IEEE80211_BAND_5GHZ) rate_idx += IWL_FIRST_OFDM_RATE; /* Get PLCP rate for tx_cmd->rate_n_flags */ rate_plcp = iwl_rates[rate_idx].plcp; /* Zero out flags for this packet */ rate_flags = 0; /* Set CCK flag as needed */ if ((rate_idx >= IWL_FIRST_CCK_RATE) && (rate_idx <= IWL_LAST_CCK_RATE)) rate_flags |= RATE_MCS_CCK_MSK; /* Set up antennas */ if (priv->cfg->bt_params && priv->cfg->bt_params->advanced_bt_coexist && priv->bt_full_concurrent) { /* operated as 1x1 in full concurrency mode */ priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant, first_antenna(hw_params(priv).valid_tx_ant)); } else priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant, hw_params(priv).valid_tx_ant); rate_flags |= iwl_ant_idx_to_flags(priv->mgmt_tx_ant); /* Set the rate in the TX cmd */ tx_cmd->rate_n_flags = iwl_hw_set_rate_n_flags(rate_plcp, rate_flags); }
void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, enum ieee80211_band band) { int i, j; struct ieee80211_hw *hw = mvm->hw; struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; struct iwl_mvm_sta *sta_priv; struct iwl_lq_sta *lq_sta; struct ieee80211_supported_band *sband; unsigned long supp; /* must be unsigned long for for_each_set_bit */ sta_priv = (struct iwl_mvm_sta *)sta->drv_priv; lq_sta = &sta_priv->lq_sta; sband = hw->wiphy->bands[band]; lq_sta->lq.sta_id = sta_priv->sta_id; for (j = 0; j < LQ_SIZE; j++) for (i = 0; i < IWL_RATE_COUNT; i++) rs_rate_scale_clear_window(&lq_sta->lq_info[j].win[i]); lq_sta->flush_timer = 0; lq_sta->supp_rates = sta->supp_rates[sband->band]; for (j = 0; j < LQ_SIZE; j++) for (i = 0; i < IWL_RATE_COUNT; i++) rs_rate_scale_clear_window(&lq_sta->lq_info[j].win[i]); IWL_DEBUG_RATE(mvm, "LQ: *** rate scale station global init for station %d ***\n", sta_priv->sta_id); /* TODO: what is a good starting rate for STA? About middle? Maybe not * the lowest or the highest rate.. Could consider using RSSI from * previous packets? Need to have IEEE 802.1X auth succeed immediately * after assoc.. */ lq_sta->max_rate_idx = -1; lq_sta->missed_rate_counter = IWL_MISSED_RATE_MAX; lq_sta->is_green = rs_use_green(sta); lq_sta->band = sband->band; /* * active legacy rates as per supported rates bitmap */ supp = sta->supp_rates[sband->band]; lq_sta->active_legacy_rate = 0; for_each_set_bit(i, &supp, BITS_PER_LONG) lq_sta->active_legacy_rate |= BIT(sband->bitrates[i].hw_value); /* * active_siso_rate mask includes 9 MBits (bit 5), and CCK (bits 0-3), * supp_rates[] does not; shift to convert format, force 9 MBits off. */ lq_sta->active_siso_rate = ht_cap->mcs.rx_mask[0] << 1; lq_sta->active_siso_rate |= ht_cap->mcs.rx_mask[0] & 0x1; lq_sta->active_siso_rate &= ~((u16)0x2); lq_sta->active_siso_rate <<= IWL_FIRST_OFDM_RATE; /* Same here */ lq_sta->active_mimo2_rate = ht_cap->mcs.rx_mask[1] << 1; lq_sta->active_mimo2_rate |= ht_cap->mcs.rx_mask[1] & 0x1; lq_sta->active_mimo2_rate &= ~((u16)0x2); lq_sta->active_mimo2_rate <<= IWL_FIRST_OFDM_RATE; lq_sta->active_mimo3_rate = ht_cap->mcs.rx_mask[2] << 1; lq_sta->active_mimo3_rate |= ht_cap->mcs.rx_mask[2] & 0x1; lq_sta->active_mimo3_rate &= ~((u16)0x2); lq_sta->active_mimo3_rate <<= IWL_FIRST_OFDM_RATE; IWL_DEBUG_RATE(mvm, "SISO-RATE=%X MIMO2-RATE=%X MIMO3-RATE=%X\n", lq_sta->active_siso_rate, lq_sta->active_mimo2_rate, lq_sta->active_mimo3_rate); /* These values will be overridden later */ lq_sta->lq.single_stream_ant_msk = first_antenna(iwl_fw_valid_tx_ant(mvm->fw)); lq_sta->lq.dual_stream_ant_msk = iwl_fw_valid_tx_ant(mvm->fw) & ~first_antenna(iwl_fw_valid_tx_ant(mvm->fw)); if (!lq_sta->lq.dual_stream_ant_msk) { lq_sta->lq.dual_stream_ant_msk = ANT_AB; } else if (num_of_ant(iwl_fw_valid_tx_ant(mvm->fw)) == 2) { lq_sta->lq.dual_stream_ant_msk = iwl_fw_valid_tx_ant(mvm->fw); } /* as default allow aggregation for all tids */ lq_sta->tx_agg_tid_en = IWL_AGG_ALL_TID; lq_sta->drv = mvm; /* Set last_txrate_idx to lowest rate */ lq_sta->last_txrate_idx = rate_lowest_index(sband, sta); if (sband->band == IEEE80211_BAND_5GHZ) lq_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE; lq_sta->is_agg = 0; #ifdef CONFIG_MAC80211_DEBUGFS lq_sta->dbg_fixed_rate = 0; #endif rs_initialize_lq(mvm, sta, lq_sta, band); }