aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEyal Shapira <eyal@wizery.com>2014-09-14 08:23:23 -0400
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>2014-09-21 06:25:45 -0400
commit1ebc8f2ef83d182941e741af4b59dc904f12853c (patch)
tree0de970aeb5d14df952221aacffa2e26251b3edc6
parent361dbec8acffe0201486f1750353a26d21cfff32 (diff)
iwlwifi: mvm: rs: refactor to allow direct rs updating
Enable RS to get updated directly via iwl_mvm_rs_tx_status which will be called by the driver and not via mac80211 rate control. This is required for a following patch to report on BAs which do not cause the BA window to progress. Also this is a first step in decoupling rs from the mac80211 rate control. Signed-off-by: Eyal Shapira <eyalx.shapira@intel.com> Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.c98
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.h4
2 files changed, 52 insertions, 50 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c
index d179a8eb50df..1865ba68b6e5 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.c
@@ -377,9 +377,9 @@ static int iwl_hwrate_to_plcp_idx(u32 rate_n_flags)
377} 377}
378 378
379static void rs_rate_scale_perform(struct iwl_mvm *mvm, 379static void rs_rate_scale_perform(struct iwl_mvm *mvm,
380 struct sk_buff *skb, 380 struct ieee80211_sta *sta,
381 struct ieee80211_sta *sta, 381 struct iwl_lq_sta *lq_sta,
382 struct iwl_lq_sta *lq_sta); 382 int tid);
383static void rs_fill_lq_cmd(struct iwl_mvm *mvm, 383static void rs_fill_lq_cmd(struct iwl_mvm *mvm,
384 struct ieee80211_sta *sta, 384 struct ieee80211_sta *sta,
385 struct iwl_lq_sta *lq_sta, 385 struct iwl_lq_sta *lq_sta,
@@ -1007,27 +1007,35 @@ static u32 rs_ch_width_from_mac_flags(enum mac80211_rate_control_flags flags)
1007 return RATE_MCS_CHAN_WIDTH_20; 1007 return RATE_MCS_CHAN_WIDTH_20;
1008} 1008}
1009 1009
1010/* 1010static u8 rs_get_tid(struct ieee80211_hdr *hdr)
1011 * mac80211 sends us Tx status 1011{
1012 */ 1012 u8 tid = IWL_MAX_TID_COUNT;
1013static void rs_tx_status(void *mvm_r, struct ieee80211_supported_band *sband, 1013
1014 struct ieee80211_sta *sta, void *priv_sta, 1014 if (ieee80211_is_data_qos(hdr->frame_control)) {
1015 struct sk_buff *skb) 1015 u8 *qc = ieee80211_get_qos_ctl(hdr);
1016 tid = qc[0] & 0xf;
1017 }
1018
1019 if (unlikely(tid > IWL_MAX_TID_COUNT))
1020 tid = IWL_MAX_TID_COUNT;
1021
1022 return tid;
1023}
1024
1025void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
1026 int tid, struct ieee80211_tx_info *info)
1016{ 1027{
1017 int legacy_success; 1028 int legacy_success;
1018 int retries; 1029 int retries;
1019 int mac_index, i; 1030 int mac_index, i;
1020 struct iwl_lq_sta *lq_sta = priv_sta;
1021 struct iwl_lq_cmd *table; 1031 struct iwl_lq_cmd *table;
1022 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
1023 struct iwl_op_mode *op_mode = (struct iwl_op_mode *)mvm_r;
1024 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
1025 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1026 enum mac80211_rate_control_flags mac_flags; 1032 enum mac80211_rate_control_flags mac_flags;
1027 u32 ucode_rate; 1033 u32 ucode_rate;
1028 struct rs_rate rate; 1034 struct rs_rate rate;
1029 struct iwl_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl; 1035 struct iwl_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl;
1030 u8 reduced_txp = (uintptr_t)info->status.status_driver_data[0]; 1036 u8 reduced_txp = (uintptr_t)info->status.status_driver_data[0];
1037 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
1038 struct iwl_lq_sta *lq_sta = &mvmsta->lq_sta;
1031 1039
1032 /* Treat uninitialized rate scaling data same as non-existing. */ 1040 /* Treat uninitialized rate scaling data same as non-existing. */
1033 if (!lq_sta) { 1041 if (!lq_sta) {
@@ -1045,10 +1053,6 @@ static void rs_tx_status(void *mvm_r, struct ieee80211_supported_band *sband,
1045 return; 1053 return;
1046 } 1054 }
1047#endif 1055#endif
1048 if (!ieee80211_is_data(hdr->frame_control) ||
1049 info->flags & IEEE80211_TX_CTL_NO_ACK)
1050 return;
1051
1052 /* This packet was aggregated but doesn't carry status info */ 1056 /* This packet was aggregated but doesn't carry status info */
1053 if ((info->flags & IEEE80211_TX_CTL_AMPDU) && 1057 if ((info->flags & IEEE80211_TX_CTL_AMPDU) &&
1054 !(info->flags & IEEE80211_TX_STAT_AMPDU)) 1058 !(info->flags & IEEE80211_TX_STAT_AMPDU))
@@ -1094,7 +1098,7 @@ static void rs_tx_status(void *mvm_r, struct ieee80211_supported_band *sband,
1094 for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++) 1098 for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++)
1095 ieee80211_stop_tx_ba_session(sta, tid); 1099 ieee80211_stop_tx_ba_session(sta, tid);
1096 1100
1097 iwl_mvm_rs_rate_init(mvm, sta, sband->band, false); 1101 iwl_mvm_rs_rate_init(mvm, sta, info->band, false);
1098 return; 1102 return;
1099 } 1103 }
1100 lq_sta->last_tx = jiffies; 1104 lq_sta->last_tx = jiffies;
@@ -1221,8 +1225,28 @@ static void rs_tx_status(void *mvm_r, struct ieee80211_supported_band *sband,
1221 IWL_DEBUG_RATE(mvm, "reduced txpower: %d\n", reduced_txp); 1225 IWL_DEBUG_RATE(mvm, "reduced txpower: %d\n", reduced_txp);
1222done: 1226done:
1223 /* See if there's a better rate or modulation mode to try. */ 1227 /* See if there's a better rate or modulation mode to try. */
1224 if (sta && sta->supp_rates[sband->band]) 1228 if (sta && sta->supp_rates[info->band])
1225 rs_rate_scale_perform(mvm, skb, sta, lq_sta); 1229 rs_rate_scale_perform(mvm, sta, lq_sta, tid);
1230}
1231
1232/*
1233 * mac80211 sends us Tx status
1234 */
1235static void rs_mac80211_tx_status(void *mvm_r,
1236 struct ieee80211_supported_band *sband,
1237 struct ieee80211_sta *sta, void *priv_sta,
1238 struct sk_buff *skb)
1239{
1240 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
1241 struct iwl_op_mode *op_mode = (struct iwl_op_mode *)mvm_r;
1242 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
1243 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1244
1245 if (!ieee80211_is_data(hdr->frame_control) ||
1246 info->flags & IEEE80211_TX_CTL_NO_ACK)
1247 return;
1248
1249 iwl_mvm_rs_tx_status(mvm, sta, rs_get_tid(hdr), info);
1226} 1250}
1227 1251
1228/* 1252/*
@@ -1493,22 +1517,6 @@ static void rs_update_rate_tbl(struct iwl_mvm *mvm,
1493 iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, false); 1517 iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, false);
1494} 1518}
1495 1519
1496static u8 rs_get_tid(struct iwl_lq_sta *lq_data,
1497 struct ieee80211_hdr *hdr)
1498{
1499 u8 tid = IWL_MAX_TID_COUNT;
1500
1501 if (ieee80211_is_data_qos(hdr->frame_control)) {
1502 u8 *qc = ieee80211_get_qos_ctl(hdr);
1503 tid = qc[0] & 0xf;
1504 }
1505
1506 if (unlikely(tid > IWL_MAX_TID_COUNT))
1507 tid = IWL_MAX_TID_COUNT;
1508
1509 return tid;
1510}
1511
1512static enum rs_column rs_get_next_column(struct iwl_mvm *mvm, 1520static enum rs_column rs_get_next_column(struct iwl_mvm *mvm,
1513 struct iwl_lq_sta *lq_sta, 1521 struct iwl_lq_sta *lq_sta,
1514 struct ieee80211_sta *sta, 1522 struct ieee80211_sta *sta,
@@ -1947,12 +1955,10 @@ static bool rs_tpc_perform(struct iwl_mvm *mvm,
1947 * Do rate scaling and search for new modulation mode. 1955 * Do rate scaling and search for new modulation mode.
1948 */ 1956 */
1949static void rs_rate_scale_perform(struct iwl_mvm *mvm, 1957static void rs_rate_scale_perform(struct iwl_mvm *mvm,
1950 struct sk_buff *skb,
1951 struct ieee80211_sta *sta, 1958 struct ieee80211_sta *sta,
1952 struct iwl_lq_sta *lq_sta) 1959 struct iwl_lq_sta *lq_sta,
1960 int tid)
1953{ 1961{
1954 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1955 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
1956 int low = IWL_RATE_INVALID; 1962 int low = IWL_RATE_INVALID;
1957 int high = IWL_RATE_INVALID; 1963 int high = IWL_RATE_INVALID;
1958 int index; 1964 int index;
@@ -1969,19 +1975,11 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
1969 u8 done_search = 0; 1975 u8 done_search = 0;
1970 u16 high_low; 1976 u16 high_low;
1971 s32 sr; 1977 s32 sr;
1972 u8 tid = IWL_MAX_TID_COUNT;
1973 u8 prev_agg = lq_sta->is_agg; 1978 u8 prev_agg = lq_sta->is_agg;
1974 struct iwl_mvm_sta *sta_priv = (void *)sta->drv_priv; 1979 struct iwl_mvm_sta *sta_priv = (void *)sta->drv_priv;
1975 struct iwl_mvm_tid_data *tid_data; 1980 struct iwl_mvm_tid_data *tid_data;
1976 struct rs_rate *rate; 1981 struct rs_rate *rate;
1977 1982
1978 /* Send management frames and NO_ACK data using lowest rate. */
1979 /* TODO: this could probably be improved.. */
1980 if (!ieee80211_is_data(hdr->frame_control) ||
1981 info->flags & IEEE80211_TX_CTL_NO_ACK)
1982 return;
1983
1984 tid = rs_get_tid(lq_sta, hdr);
1985 if ((tid != IWL_MAX_TID_COUNT) && 1983 if ((tid != IWL_MAX_TID_COUNT) &&
1986 (lq_sta->tx_agg_tid_en & (1 << tid))) { 1984 (lq_sta->tx_agg_tid_en & (1 << tid))) {
1987 tid_data = &sta_priv->tid_data[tid]; 1985 tid_data = &sta_priv->tid_data[tid];
@@ -3323,7 +3321,7 @@ static void rs_rate_init_stub(void *mvm_r,
3323 3321
3324static const struct rate_control_ops rs_mvm_ops = { 3322static const struct rate_control_ops rs_mvm_ops = {
3325 .name = RS_NAME, 3323 .name = RS_NAME,
3326 .tx_status = rs_tx_status, 3324 .tx_status = rs_mac80211_tx_status,
3327 .get_rate = rs_get_rate, 3325 .get_rate = rs_get_rate,
3328 .rate_init = rs_rate_init_stub, 3326 .rate_init = rs_rate_init_stub,
3329 .alloc = rs_alloc, 3327 .alloc = rs_alloc,
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.h b/drivers/net/wireless/iwlwifi/mvm/rs.h
index 95c4b960fd71..eb34c1209acc 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rs.h
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.h
@@ -376,6 +376,10 @@ struct iwl_lq_sta {
376void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, 376void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
377 enum ieee80211_band band, bool init); 377 enum ieee80211_band band, bool init);
378 378
379/* Notify RS about Tx status */
380void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
381 int tid, struct ieee80211_tx_info *info);
382
379/** 383/**
380 * iwl_rate_control_register - Register the rate control algorithm callbacks 384 * iwl_rate_control_register - Register the rate control algorithm callbacks
381 * 385 *