Merge branch 'for-davem' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless
John W. Linville says: ==================== pull request: wireless 2014-04-17 Please pull this batch of fixes intended for the 3.15 stream... For the mac80211 bits, Johannes says: "We have a fix from Chun-Yeow to not look at management frame bitrates that are typically really low, two fixes from Felix for AP_VLAN interfaces, a fix from Ido to disable SMPS settings when a monitor interface is enabled, a radar detection fix from Michał and a fix from myself for a very old remain-on-channel bug." For the iwlwifi bits, Emmanuel says: "I have new device IDs and a new firmware API. These are the trivial ones. The less trivial ones are Johannes's fix that delays the enablement of an interrupt coalescing hardware until after association - this fixes a few connection problems seen in the field. Eyal has a bunch of rate control fixes. I decided to add these for 3.15 because they fix some disconnection and packet loss scenarios which were reported by the field. I also have a fix for a memory leak that happens only with a very new NIC." Along with those... Amitkumar Karwar fixes a couple of problems relating to driver/firmware interactions in mwifiex. Christian Engelmayer avoids a couple of potential memory leaks in the new rsi driver. Eliad Peller provides a wl18xx mailbox alignment fix for problems when using new firmware. Frederic Danis adds a couple of missing debugging strings to the cw1200 driver. Geert Uytterhoeven adds a variable initialization inside of the rsi driver. Luciano Coelho patches the wlcore code to ignore dummy packet events in PLT mode in order to work around a firmware bug. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
5a292f7bc6
@ -41,6 +41,8 @@ static const char * const cw1200_debug_link_id[] = {
|
||||
"REQ",
|
||||
"SOFT",
|
||||
"HARD",
|
||||
"RESET",
|
||||
"RESET_REMAP",
|
||||
};
|
||||
|
||||
static const char *cw1200_debug_mode(int mode)
|
||||
|
@ -67,8 +67,8 @@
|
||||
#include "iwl-agn-hw.h"
|
||||
|
||||
/* Highest firmware API version supported */
|
||||
#define IWL7260_UCODE_API_MAX 8
|
||||
#define IWL3160_UCODE_API_MAX 8
|
||||
#define IWL7260_UCODE_API_MAX 9
|
||||
#define IWL3160_UCODE_API_MAX 9
|
||||
|
||||
/* Oldest version we won't warn about */
|
||||
#define IWL7260_UCODE_API_OK 8
|
||||
@ -244,3 +244,4 @@ const struct iwl_cfg iwl7265_n_cfg = {
|
||||
|
||||
MODULE_FIRMWARE(IWL7260_MODULE_FIRMWARE(IWL7260_UCODE_API_OK));
|
||||
MODULE_FIRMWARE(IWL3160_MODULE_FIRMWARE(IWL3160_UCODE_API_OK));
|
||||
MODULE_FIRMWARE(IWL7265_MODULE_FIRMWARE(IWL7260_UCODE_API_OK));
|
||||
|
@ -190,7 +190,7 @@ static const __le32 iwl_combined_lookup[BT_COEX_MAX_LUT][BT_COEX_LUT_SIZE] = {
|
||||
cpu_to_le32(0xcc00aaaa),
|
||||
cpu_to_le32(0x0000aaaa),
|
||||
cpu_to_le32(0xc0004000),
|
||||
cpu_to_le32(0x00000000),
|
||||
cpu_to_le32(0x00004000),
|
||||
cpu_to_le32(0xf0005000),
|
||||
cpu_to_le32(0xf0005000),
|
||||
},
|
||||
@ -213,16 +213,16 @@ static const __le32 iwl_combined_lookup[BT_COEX_MAX_LUT][BT_COEX_LUT_SIZE] = {
|
||||
/* Tx Tx disabled */
|
||||
cpu_to_le32(0xaaaaaaaa),
|
||||
cpu_to_le32(0xaaaaaaaa),
|
||||
cpu_to_le32(0xaaaaaaaa),
|
||||
cpu_to_le32(0xeeaaaaaa),
|
||||
cpu_to_le32(0xaaaaaaaa),
|
||||
cpu_to_le32(0xcc00ff28),
|
||||
cpu_to_le32(0x0000aaaa),
|
||||
cpu_to_le32(0xcc00aaaa),
|
||||
cpu_to_le32(0x0000aaaa),
|
||||
cpu_to_le32(0xC0004000),
|
||||
cpu_to_le32(0xC0004000),
|
||||
cpu_to_le32(0xF0005000),
|
||||
cpu_to_le32(0xF0005000),
|
||||
cpu_to_le32(0xc0004000),
|
||||
cpu_to_le32(0xc0004000),
|
||||
cpu_to_le32(0xf0005000),
|
||||
cpu_to_le32(0xf0005000),
|
||||
},
|
||||
};
|
||||
|
||||
@ -1262,6 +1262,7 @@ int iwl_mvm_rx_ant_coupling_notif(struct iwl_mvm *mvm,
|
||||
struct iwl_rx_packet *pkt = rxb_addr(rxb);
|
||||
u32 ant_isolation = le32_to_cpup((void *)pkt->data);
|
||||
u8 __maybe_unused lower_bound, upper_bound;
|
||||
int ret;
|
||||
u8 lut;
|
||||
|
||||
struct iwl_bt_coex_cmd *bt_cmd;
|
||||
@ -1318,5 +1319,8 @@ int iwl_mvm_rx_ant_coupling_notif(struct iwl_mvm *mvm,
|
||||
memcpy(bt_cmd->bt4_corun_lut40, antenna_coupling_ranges[lut].lut20,
|
||||
sizeof(bt_cmd->bt4_corun_lut40));
|
||||
|
||||
return 0;
|
||||
ret = iwl_mvm_send_cmd(mvm, &cmd);
|
||||
|
||||
kfree(bt_cmd);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1332,6 +1332,7 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
|
||||
*/
|
||||
iwl_mvm_remove_time_event(mvm, mvmvif,
|
||||
&mvmvif->time_event_data);
|
||||
iwl_mvm_sf_update(mvm, vif, false);
|
||||
WARN_ON(iwl_mvm_enable_beacon_filter(mvm, vif, CMD_SYNC));
|
||||
} else if (changes & (BSS_CHANGED_PS | BSS_CHANGED_P2P_PS |
|
||||
BSS_CHANGED_QOS)) {
|
||||
|
@ -59,7 +59,7 @@
|
||||
/* max allowed rate miss before sync LQ cmd */
|
||||
#define IWL_MISSED_RATE_MAX 15
|
||||
#define RS_STAY_IN_COLUMN_TIMEOUT (5*HZ)
|
||||
|
||||
#define RS_IDLE_TIMEOUT (5*HZ)
|
||||
|
||||
static u8 rs_ht_to_legacy[] = {
|
||||
[IWL_RATE_MCS_0_INDEX] = IWL_RATE_6M_INDEX,
|
||||
@ -142,7 +142,7 @@ enum rs_column_mode {
|
||||
RS_MIMO2,
|
||||
};
|
||||
|
||||
#define MAX_NEXT_COLUMNS 5
|
||||
#define MAX_NEXT_COLUMNS 7
|
||||
#define MAX_COLUMN_CHECKS 3
|
||||
|
||||
typedef bool (*allow_column_func_t) (struct iwl_mvm *mvm,
|
||||
@ -212,8 +212,10 @@ static const struct rs_tx_column rs_tx_columns[] = {
|
||||
RS_COLUMN_LEGACY_ANT_B,
|
||||
RS_COLUMN_SISO_ANT_A,
|
||||
RS_COLUMN_SISO_ANT_B,
|
||||
RS_COLUMN_MIMO2,
|
||||
RS_COLUMN_MIMO2_SGI,
|
||||
RS_COLUMN_INVALID,
|
||||
RS_COLUMN_INVALID,
|
||||
RS_COLUMN_INVALID,
|
||||
RS_COLUMN_INVALID,
|
||||
},
|
||||
},
|
||||
[RS_COLUMN_LEGACY_ANT_B] = {
|
||||
@ -223,8 +225,10 @@ static const struct rs_tx_column rs_tx_columns[] = {
|
||||
RS_COLUMN_LEGACY_ANT_A,
|
||||
RS_COLUMN_SISO_ANT_A,
|
||||
RS_COLUMN_SISO_ANT_B,
|
||||
RS_COLUMN_MIMO2,
|
||||
RS_COLUMN_MIMO2_SGI,
|
||||
RS_COLUMN_INVALID,
|
||||
RS_COLUMN_INVALID,
|
||||
RS_COLUMN_INVALID,
|
||||
RS_COLUMN_INVALID,
|
||||
},
|
||||
},
|
||||
[RS_COLUMN_SISO_ANT_A] = {
|
||||
@ -235,7 +239,9 @@ static const struct rs_tx_column rs_tx_columns[] = {
|
||||
RS_COLUMN_MIMO2,
|
||||
RS_COLUMN_SISO_ANT_A_SGI,
|
||||
RS_COLUMN_SISO_ANT_B_SGI,
|
||||
RS_COLUMN_MIMO2_SGI,
|
||||
RS_COLUMN_LEGACY_ANT_A,
|
||||
RS_COLUMN_LEGACY_ANT_B,
|
||||
RS_COLUMN_INVALID,
|
||||
},
|
||||
.checks = {
|
||||
rs_siso_allow,
|
||||
@ -249,7 +255,9 @@ static const struct rs_tx_column rs_tx_columns[] = {
|
||||
RS_COLUMN_MIMO2,
|
||||
RS_COLUMN_SISO_ANT_B_SGI,
|
||||
RS_COLUMN_SISO_ANT_A_SGI,
|
||||
RS_COLUMN_MIMO2_SGI,
|
||||
RS_COLUMN_LEGACY_ANT_A,
|
||||
RS_COLUMN_LEGACY_ANT_B,
|
||||
RS_COLUMN_INVALID,
|
||||
},
|
||||
.checks = {
|
||||
rs_siso_allow,
|
||||
@ -265,6 +273,8 @@ static const struct rs_tx_column rs_tx_columns[] = {
|
||||
RS_COLUMN_SISO_ANT_A,
|
||||
RS_COLUMN_SISO_ANT_B,
|
||||
RS_COLUMN_MIMO2,
|
||||
RS_COLUMN_LEGACY_ANT_A,
|
||||
RS_COLUMN_LEGACY_ANT_B,
|
||||
},
|
||||
.checks = {
|
||||
rs_siso_allow,
|
||||
@ -281,6 +291,8 @@ static const struct rs_tx_column rs_tx_columns[] = {
|
||||
RS_COLUMN_SISO_ANT_B,
|
||||
RS_COLUMN_SISO_ANT_A,
|
||||
RS_COLUMN_MIMO2,
|
||||
RS_COLUMN_LEGACY_ANT_A,
|
||||
RS_COLUMN_LEGACY_ANT_B,
|
||||
},
|
||||
.checks = {
|
||||
rs_siso_allow,
|
||||
@ -296,6 +308,8 @@ static const struct rs_tx_column rs_tx_columns[] = {
|
||||
RS_COLUMN_SISO_ANT_A_SGI,
|
||||
RS_COLUMN_SISO_ANT_B_SGI,
|
||||
RS_COLUMN_MIMO2_SGI,
|
||||
RS_COLUMN_LEGACY_ANT_A,
|
||||
RS_COLUMN_LEGACY_ANT_B,
|
||||
},
|
||||
.checks = {
|
||||
rs_mimo_allow,
|
||||
@ -311,6 +325,8 @@ static const struct rs_tx_column rs_tx_columns[] = {
|
||||
RS_COLUMN_SISO_ANT_A,
|
||||
RS_COLUMN_SISO_ANT_B,
|
||||
RS_COLUMN_MIMO2,
|
||||
RS_COLUMN_LEGACY_ANT_A,
|
||||
RS_COLUMN_LEGACY_ANT_B,
|
||||
},
|
||||
.checks = {
|
||||
rs_mimo_allow,
|
||||
@ -503,10 +519,12 @@ static void rs_rate_scale_clear_window(struct iwl_rate_scale_data *window)
|
||||
window->average_tpt = IWL_INVALID_VALUE;
|
||||
}
|
||||
|
||||
static void rs_rate_scale_clear_tbl_windows(struct iwl_scale_tbl_info *tbl)
|
||||
static void rs_rate_scale_clear_tbl_windows(struct iwl_mvm *mvm,
|
||||
struct iwl_scale_tbl_info *tbl)
|
||||
{
|
||||
int i;
|
||||
|
||||
IWL_DEBUG_RATE(mvm, "Clearing up window stats\n");
|
||||
for (i = 0; i < IWL_RATE_COUNT; i++)
|
||||
rs_rate_scale_clear_window(&tbl->win[i]);
|
||||
}
|
||||
@ -992,6 +1010,13 @@ static void rs_tx_status(void *mvm_r, struct ieee80211_supported_band *sband,
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef CPTCFG_MAC80211_DEBUGFS
|
||||
/* Disable last tx check if we are debugging with fixed rate */
|
||||
if (lq_sta->dbg_fixed_rate) {
|
||||
IWL_DEBUG_RATE(mvm, "Fixed rate. avoid rate scaling\n");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if (!ieee80211_is_data(hdr->frame_control) ||
|
||||
info->flags & IEEE80211_TX_CTL_NO_ACK)
|
||||
return;
|
||||
@ -1034,6 +1059,18 @@ static void rs_tx_status(void *mvm_r, struct ieee80211_supported_band *sband,
|
||||
mac_index++;
|
||||
}
|
||||
|
||||
if (time_after(jiffies,
|
||||
(unsigned long)(lq_sta->last_tx + RS_IDLE_TIMEOUT))) {
|
||||
int tid;
|
||||
IWL_DEBUG_RATE(mvm, "Tx idle for too long. reinit rs\n");
|
||||
for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++)
|
||||
ieee80211_stop_tx_ba_session(sta, tid);
|
||||
|
||||
iwl_mvm_rs_rate_init(mvm, sta, sband->band, false);
|
||||
return;
|
||||
}
|
||||
lq_sta->last_tx = jiffies;
|
||||
|
||||
/* Here we actually compare this rate to the latest LQ command */
|
||||
if ((mac_index < 0) ||
|
||||
(rate.sgi != !!(mac_flags & IEEE80211_TX_RC_SHORT_GI)) ||
|
||||
@ -1186,9 +1223,26 @@ static void rs_set_stay_in_table(struct iwl_mvm *mvm, u8 is_legacy,
|
||||
lq_sta->visited_columns = 0;
|
||||
}
|
||||
|
||||
static int rs_get_max_allowed_rate(struct iwl_lq_sta *lq_sta,
|
||||
const struct rs_tx_column *column)
|
||||
{
|
||||
switch (column->mode) {
|
||||
case RS_LEGACY:
|
||||
return lq_sta->max_legacy_rate_idx;
|
||||
case RS_SISO:
|
||||
return lq_sta->max_siso_rate_idx;
|
||||
case RS_MIMO2:
|
||||
return lq_sta->max_mimo2_rate_idx;
|
||||
default:
|
||||
WARN_ON_ONCE(1);
|
||||
}
|
||||
|
||||
return lq_sta->max_legacy_rate_idx;
|
||||
}
|
||||
|
||||
static const u16 *rs_get_expected_tpt_table(struct iwl_lq_sta *lq_sta,
|
||||
const struct rs_tx_column *column,
|
||||
u32 bw)
|
||||
const struct rs_tx_column *column,
|
||||
u32 bw)
|
||||
{
|
||||
/* Used to choose among HT tables */
|
||||
const u16 (*ht_tbl_pointer)[IWL_RATE_COUNT];
|
||||
@ -1438,7 +1492,7 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search)
|
||||
|
||||
IWL_DEBUG_RATE(mvm,
|
||||
"LQ: stay in table clear win\n");
|
||||
rs_rate_scale_clear_tbl_windows(tbl);
|
||||
rs_rate_scale_clear_tbl_windows(mvm, tbl);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1446,8 +1500,7 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search)
|
||||
* bitmaps and stats in active table (this will become the new
|
||||
* "search" table). */
|
||||
if (lq_sta->rs_state == RS_STATE_SEARCH_CYCLE_STARTED) {
|
||||
IWL_DEBUG_RATE(mvm, "Clearing up window stats\n");
|
||||
rs_rate_scale_clear_tbl_windows(tbl);
|
||||
rs_rate_scale_clear_tbl_windows(mvm, tbl);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1485,14 +1538,14 @@ static enum rs_column rs_get_next_column(struct iwl_mvm *mvm,
|
||||
struct ieee80211_sta *sta,
|
||||
struct iwl_scale_tbl_info *tbl)
|
||||
{
|
||||
int i, j, n;
|
||||
int i, j, max_rate;
|
||||
enum rs_column next_col_id;
|
||||
const struct rs_tx_column *curr_col = &rs_tx_columns[tbl->column];
|
||||
const struct rs_tx_column *next_col;
|
||||
allow_column_func_t allow_func;
|
||||
u8 valid_ants = mvm->fw->valid_tx_ant;
|
||||
const u16 *expected_tpt_tbl;
|
||||
s32 tpt, max_expected_tpt;
|
||||
u16 tpt, max_expected_tpt;
|
||||
|
||||
for (i = 0; i < MAX_NEXT_COLUMNS; i++) {
|
||||
next_col_id = curr_col->next_columns[i];
|
||||
@ -1535,11 +1588,11 @@ static enum rs_column rs_get_next_column(struct iwl_mvm *mvm,
|
||||
if (WARN_ON_ONCE(!expected_tpt_tbl))
|
||||
continue;
|
||||
|
||||
max_expected_tpt = 0;
|
||||
for (n = 0; n < IWL_RATE_COUNT; n++)
|
||||
if (expected_tpt_tbl[n] > max_expected_tpt)
|
||||
max_expected_tpt = expected_tpt_tbl[n];
|
||||
max_rate = rs_get_max_allowed_rate(lq_sta, next_col);
|
||||
if (WARN_ON_ONCE(max_rate == IWL_RATE_INVALID))
|
||||
continue;
|
||||
|
||||
max_expected_tpt = expected_tpt_tbl[max_rate];
|
||||
if (tpt >= max_expected_tpt) {
|
||||
IWL_DEBUG_RATE(mvm,
|
||||
"Skip column %d: can't beat current TPT. Max expected %d current %d\n",
|
||||
@ -1547,14 +1600,15 @@ static enum rs_column rs_get_next_column(struct iwl_mvm *mvm,
|
||||
continue;
|
||||
}
|
||||
|
||||
IWL_DEBUG_RATE(mvm,
|
||||
"Found potential column %d. Max expected %d current %d\n",
|
||||
next_col_id, max_expected_tpt, tpt);
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == MAX_NEXT_COLUMNS)
|
||||
return RS_COLUMN_INVALID;
|
||||
|
||||
IWL_DEBUG_RATE(mvm, "Found potential column %d\n", next_col_id);
|
||||
|
||||
return next_col_id;
|
||||
}
|
||||
|
||||
@ -1640,87 +1694,78 @@ static enum rs_action rs_get_rate_action(struct iwl_mvm *mvm,
|
||||
{
|
||||
enum rs_action action = RS_ACTION_STAY;
|
||||
|
||||
/* Too many failures, decrease rate */
|
||||
if ((sr <= RS_SR_FORCE_DECREASE) || (current_tpt == 0)) {
|
||||
IWL_DEBUG_RATE(mvm,
|
||||
"decrease rate because of low SR\n");
|
||||
"Decrease rate because of low SR\n");
|
||||
return RS_ACTION_DOWNSCALE;
|
||||
}
|
||||
|
||||
if ((low_tpt == IWL_INVALID_VALUE) &&
|
||||
(high_tpt == IWL_INVALID_VALUE) &&
|
||||
(high != IWL_RATE_INVALID)) {
|
||||
IWL_DEBUG_RATE(mvm,
|
||||
"No data about high/low rates. Increase rate\n");
|
||||
return RS_ACTION_UPSCALE;
|
||||
}
|
||||
|
||||
if ((high_tpt == IWL_INVALID_VALUE) &&
|
||||
(high != IWL_RATE_INVALID) &&
|
||||
(low_tpt != IWL_INVALID_VALUE) &&
|
||||
(low_tpt < current_tpt)) {
|
||||
IWL_DEBUG_RATE(mvm,
|
||||
"No data about high rate and low rate is worse. Increase rate\n");
|
||||
return RS_ACTION_UPSCALE;
|
||||
}
|
||||
|
||||
if ((high_tpt != IWL_INVALID_VALUE) &&
|
||||
(high_tpt > current_tpt)) {
|
||||
IWL_DEBUG_RATE(mvm,
|
||||
"Higher rate is better. Increate rate\n");
|
||||
return RS_ACTION_UPSCALE;
|
||||
}
|
||||
|
||||
if ((low_tpt != IWL_INVALID_VALUE) &&
|
||||
(high_tpt != IWL_INVALID_VALUE) &&
|
||||
(low_tpt < current_tpt) &&
|
||||
(high_tpt < current_tpt)) {
|
||||
IWL_DEBUG_RATE(mvm,
|
||||
"Both high and low are worse. Maintain rate\n");
|
||||
return RS_ACTION_STAY;
|
||||
}
|
||||
|
||||
if ((low_tpt != IWL_INVALID_VALUE) &&
|
||||
(low_tpt > current_tpt)) {
|
||||
IWL_DEBUG_RATE(mvm,
|
||||
"Lower rate is better\n");
|
||||
action = RS_ACTION_DOWNSCALE;
|
||||
/* No throughput measured yet for adjacent rates; try increase. */
|
||||
} else if ((low_tpt == IWL_INVALID_VALUE) &&
|
||||
(high_tpt == IWL_INVALID_VALUE)) {
|
||||
if (high != IWL_RATE_INVALID && sr >= IWL_RATE_INCREASE_TH) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((low_tpt == IWL_INVALID_VALUE) &&
|
||||
(low != IWL_RATE_INVALID)) {
|
||||
IWL_DEBUG_RATE(mvm,
|
||||
"No data about lower rate\n");
|
||||
action = RS_ACTION_DOWNSCALE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
IWL_DEBUG_RATE(mvm, "Maintain rate\n");
|
||||
|
||||
out:
|
||||
if ((action == RS_ACTION_DOWNSCALE) && (low != IWL_RATE_INVALID)) {
|
||||
if (sr >= RS_SR_NO_DECREASE) {
|
||||
IWL_DEBUG_RATE(mvm,
|
||||
"Good SR and no high rate measurement. "
|
||||
"Increase rate\n");
|
||||
action = RS_ACTION_UPSCALE;
|
||||
} else if (low != IWL_RATE_INVALID) {
|
||||
IWL_DEBUG_RATE(mvm,
|
||||
"Remain in current rate\n");
|
||||
"SR is above NO DECREASE. Avoid downscale\n");
|
||||
action = RS_ACTION_STAY;
|
||||
} else if (current_tpt > (100 * tbl->expected_tpt[low])) {
|
||||
IWL_DEBUG_RATE(mvm,
|
||||
"Current TPT is higher than max expected in low rate. Avoid downscale\n");
|
||||
action = RS_ACTION_STAY;
|
||||
} else {
|
||||
IWL_DEBUG_RATE(mvm, "Decrease rate\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* Both adjacent throughputs are measured, but neither one has better
|
||||
* throughput; we're using the best rate, don't change it!
|
||||
*/
|
||||
else if ((low_tpt != IWL_INVALID_VALUE) &&
|
||||
(high_tpt != IWL_INVALID_VALUE) &&
|
||||
(low_tpt < current_tpt) &&
|
||||
(high_tpt < current_tpt)) {
|
||||
IWL_DEBUG_RATE(mvm,
|
||||
"Both high and low are worse. "
|
||||
"Maintain rate\n");
|
||||
action = RS_ACTION_STAY;
|
||||
}
|
||||
|
||||
/* At least one adjacent rate's throughput is measured,
|
||||
* and may have better performance.
|
||||
*/
|
||||
else {
|
||||
/* Higher adjacent rate's throughput is measured */
|
||||
if (high_tpt != IWL_INVALID_VALUE) {
|
||||
/* Higher rate has better throughput */
|
||||
if (high_tpt > current_tpt &&
|
||||
sr >= IWL_RATE_INCREASE_TH) {
|
||||
IWL_DEBUG_RATE(mvm,
|
||||
"Higher rate is better and good "
|
||||
"SR. Increate rate\n");
|
||||
action = RS_ACTION_UPSCALE;
|
||||
} else {
|
||||
IWL_DEBUG_RATE(mvm,
|
||||
"Higher rate isn't better OR "
|
||||
"no good SR. Maintain rate\n");
|
||||
action = RS_ACTION_STAY;
|
||||
}
|
||||
|
||||
/* Lower adjacent rate's throughput is measured */
|
||||
} else if (low_tpt != IWL_INVALID_VALUE) {
|
||||
/* Lower rate has better throughput */
|
||||
if (low_tpt > current_tpt) {
|
||||
IWL_DEBUG_RATE(mvm,
|
||||
"Lower rate is better. "
|
||||
"Decrease rate\n");
|
||||
action = RS_ACTION_DOWNSCALE;
|
||||
} else if (sr >= IWL_RATE_INCREASE_TH) {
|
||||
IWL_DEBUG_RATE(mvm,
|
||||
"Lower rate isn't better and "
|
||||
"good SR. Increase rate\n");
|
||||
action = RS_ACTION_UPSCALE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Sanity check; asked for decrease, but success rate or throughput
|
||||
* has been good at old rate. Don't change it.
|
||||
*/
|
||||
if ((action == RS_ACTION_DOWNSCALE) && (low != IWL_RATE_INVALID) &&
|
||||
((sr > IWL_RATE_HIGH_TH) ||
|
||||
(current_tpt > (100 * tbl->expected_tpt[low])))) {
|
||||
IWL_DEBUG_RATE(mvm,
|
||||
"Sanity check failed. Maintain rate\n");
|
||||
action = RS_ACTION_STAY;
|
||||
}
|
||||
|
||||
return action;
|
||||
}
|
||||
|
||||
@ -1792,6 +1837,7 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
|
||||
"Aggregation changed: prev %d current %d. Update expected TPT table\n",
|
||||
prev_agg, lq_sta->is_agg);
|
||||
rs_set_expected_tpt_table(lq_sta, tbl);
|
||||
rs_rate_scale_clear_tbl_windows(mvm, tbl);
|
||||
}
|
||||
|
||||
/* current tx rate */
|
||||
@ -2021,7 +2067,7 @@ lq_update:
|
||||
if (lq_sta->search_better_tbl) {
|
||||
/* Access the "search" table, clear its history. */
|
||||
tbl = &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
|
||||
rs_rate_scale_clear_tbl_windows(tbl);
|
||||
rs_rate_scale_clear_tbl_windows(mvm, tbl);
|
||||
|
||||
/* Use new "search" start rate */
|
||||
index = tbl->rate.index;
|
||||
@ -2042,8 +2088,18 @@ lq_update:
|
||||
* stay with best antenna legacy modulation for a while
|
||||
* before next round of mode comparisons. */
|
||||
tbl1 = &(lq_sta->lq_info[lq_sta->active_tbl]);
|
||||
if (is_legacy(&tbl1->rate) && !sta->ht_cap.ht_supported) {
|
||||
if (is_legacy(&tbl1->rate)) {
|
||||
IWL_DEBUG_RATE(mvm, "LQ: STAY in legacy table\n");
|
||||
|
||||
if (tid != IWL_MAX_TID_COUNT) {
|
||||
tid_data = &sta_priv->tid_data[tid];
|
||||
if (tid_data->state != IWL_AGG_OFF) {
|
||||
IWL_DEBUG_RATE(mvm,
|
||||
"Stop aggregation on tid %d\n",
|
||||
tid);
|
||||
ieee80211_stop_tx_ba_session(sta, tid);
|
||||
}
|
||||
}
|
||||
rs_set_stay_in_table(mvm, 1, lq_sta);
|
||||
} else {
|
||||
/* If we're in an HT mode, and all 3 mode switch actions
|
||||
@ -2342,9 +2398,10 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
||||
lq_sta->lq.sta_id = sta_priv->sta_id;
|
||||
|
||||
for (j = 0; j < LQ_SIZE; j++)
|
||||
rs_rate_scale_clear_tbl_windows(&lq_sta->lq_info[j]);
|
||||
rs_rate_scale_clear_tbl_windows(mvm, &lq_sta->lq_info[j]);
|
||||
|
||||
lq_sta->flush_timer = 0;
|
||||
lq_sta->last_tx = jiffies;
|
||||
|
||||
IWL_DEBUG_RATE(mvm,
|
||||
"LQ: *** rate scale station global init for station %d ***\n",
|
||||
@ -2388,11 +2445,22 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
||||
lq_sta->is_vht = true;
|
||||
}
|
||||
|
||||
IWL_DEBUG_RATE(mvm,
|
||||
"SISO-RATE=%X MIMO2-RATE=%X VHT=%d\n",
|
||||
lq_sta->max_legacy_rate_idx = find_last_bit(&lq_sta->active_legacy_rate,
|
||||
BITS_PER_LONG);
|
||||
lq_sta->max_siso_rate_idx = find_last_bit(&lq_sta->active_siso_rate,
|
||||
BITS_PER_LONG);
|
||||
lq_sta->max_mimo2_rate_idx = find_last_bit(&lq_sta->active_mimo2_rate,
|
||||
BITS_PER_LONG);
|
||||
|
||||
IWL_DEBUG_RATE(mvm, "RATE MASK: LEGACY=%lX SISO=%lX MIMO2=%lX VHT=%d\n",
|
||||
lq_sta->active_legacy_rate,
|
||||
lq_sta->active_siso_rate,
|
||||
lq_sta->active_mimo2_rate,
|
||||
lq_sta->is_vht);
|
||||
IWL_DEBUG_RATE(mvm, "MAX RATE: LEGACY=%d SISO=%d MIMO2=%d\n",
|
||||
lq_sta->max_legacy_rate_idx,
|
||||
lq_sta->max_siso_rate_idx,
|
||||
lq_sta->max_mimo2_rate_idx);
|
||||
|
||||
/* These values will be overridden later */
|
||||
lq_sta->lq.single_stream_ant_msk =
|
||||
@ -2547,6 +2615,7 @@ static void rs_build_rates_table(struct iwl_mvm *mvm,
|
||||
if (is_siso(&rate)) {
|
||||
num_rates = RS_SECONDARY_SISO_NUM_RATES;
|
||||
num_retries = RS_SECONDARY_SISO_RETRIES;
|
||||
lq_cmd->mimo_delim = index;
|
||||
} else if (is_legacy(&rate)) {
|
||||
num_rates = RS_SECONDARY_LEGACY_NUM_RATES;
|
||||
num_retries = RS_LEGACY_RETRIES_PER_RATE;
|
||||
@ -2749,7 +2818,7 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
|
||||
return -ENOMEM;
|
||||
|
||||
desc += sprintf(buff+desc, "sta_id %d\n", lq_sta->lq.sta_id);
|
||||
desc += sprintf(buff+desc, "failed=%d success=%d rate=0%X\n",
|
||||
desc += sprintf(buff+desc, "failed=%d success=%d rate=0%lX\n",
|
||||
lq_sta->total_failed, lq_sta->total_success,
|
||||
lq_sta->active_legacy_rate);
|
||||
desc += sprintf(buff+desc, "fixed rate 0x%X\n",
|
||||
|
@ -156,6 +156,7 @@ enum {
|
||||
#define IWL_RATE_HIGH_TH 10880 /* 85% */
|
||||
#define IWL_RATE_INCREASE_TH 6400 /* 50% */
|
||||
#define RS_SR_FORCE_DECREASE 1920 /* 15% */
|
||||
#define RS_SR_NO_DECREASE 10880 /* 85% */
|
||||
|
||||
#define LINK_QUAL_AGG_TIME_LIMIT_DEF (4000) /* 4 milliseconds */
|
||||
#define LINK_QUAL_AGG_TIME_LIMIT_MAX (8000)
|
||||
@ -310,13 +311,20 @@ struct iwl_lq_sta {
|
||||
u32 visited_columns; /* Bitmask marking which Tx columns were
|
||||
* explored during a search cycle
|
||||
*/
|
||||
u64 last_tx;
|
||||
bool is_vht;
|
||||
enum ieee80211_band band;
|
||||
|
||||
/* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */
|
||||
u16 active_legacy_rate;
|
||||
u16 active_siso_rate;
|
||||
u16 active_mimo2_rate;
|
||||
unsigned long active_legacy_rate;
|
||||
unsigned long active_siso_rate;
|
||||
unsigned long active_mimo2_rate;
|
||||
|
||||
/* Highest rate per Tx mode */
|
||||
u8 max_legacy_rate_idx;
|
||||
u8 max_siso_rate_idx;
|
||||
u8 max_mimo2_rate_idx;
|
||||
|
||||
s8 max_rate_idx; /* Max rate set by user */
|
||||
u8 missed_rate_counter;
|
||||
|
||||
|
@ -274,7 +274,8 @@ int iwl_mvm_sf_update(struct iwl_mvm *mvm, struct ieee80211_vif *changed_vif,
|
||||
return -EINVAL;
|
||||
if (changed_vif->type != NL80211_IFTYPE_STATION) {
|
||||
new_state = SF_UNINIT;
|
||||
} else if (changed_vif->bss_conf.assoc) {
|
||||
} else if (changed_vif->bss_conf.assoc &&
|
||||
changed_vif->bss_conf.dtim_period) {
|
||||
mvmvif = iwl_mvm_vif_from_mac80211(changed_vif);
|
||||
sta_id = mvmvif->ap_sta_id;
|
||||
new_state = SF_FULL_ON;
|
||||
|
@ -373,12 +373,14 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
|
||||
{IWL_PCI_DEVICE(0x095A, 0x500A, iwl7265_2n_cfg)},
|
||||
{IWL_PCI_DEVICE(0x095B, 0x5200, iwl7265_2n_cfg)},
|
||||
{IWL_PCI_DEVICE(0x095A, 0x5002, iwl7265_n_cfg)},
|
||||
{IWL_PCI_DEVICE(0x095A, 0x5102, iwl7265_n_cfg)},
|
||||
{IWL_PCI_DEVICE(0x095B, 0x5202, iwl7265_n_cfg)},
|
||||
{IWL_PCI_DEVICE(0x095A, 0x9010, iwl7265_2ac_cfg)},
|
||||
{IWL_PCI_DEVICE(0x095A, 0x9012, iwl7265_2ac_cfg)},
|
||||
{IWL_PCI_DEVICE(0x095A, 0x9110, iwl7265_2ac_cfg)},
|
||||
{IWL_PCI_DEVICE(0x095A, 0x9112, iwl7265_2ac_cfg)},
|
||||
{IWL_PCI_DEVICE(0x095A, 0x9210, iwl7265_2ac_cfg)},
|
||||
{IWL_PCI_DEVICE(0x095A, 0x9200, iwl7265_2ac_cfg)},
|
||||
{IWL_PCI_DEVICE(0x095A, 0x9510, iwl7265_2ac_cfg)},
|
||||
{IWL_PCI_DEVICE(0x095A, 0x9310, iwl7265_2ac_cfg)},
|
||||
{IWL_PCI_DEVICE(0x095A, 0x9410, iwl7265_2ac_cfg)},
|
||||
|
@ -292,6 +292,12 @@ process_start:
|
||||
while ((skb = skb_dequeue(&adapter->usb_rx_data_q)))
|
||||
mwifiex_handle_rx_packet(adapter, skb);
|
||||
|
||||
/* Check for event */
|
||||
if (adapter->event_received) {
|
||||
adapter->event_received = false;
|
||||
mwifiex_process_event(adapter);
|
||||
}
|
||||
|
||||
/* Check for Cmd Resp */
|
||||
if (adapter->cmd_resp_received) {
|
||||
adapter->cmd_resp_received = false;
|
||||
@ -304,12 +310,6 @@ process_start:
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for event */
|
||||
if (adapter->event_received) {
|
||||
adapter->event_received = false;
|
||||
mwifiex_process_event(adapter);
|
||||
}
|
||||
|
||||
/* Check if we need to confirm Sleep Request
|
||||
received previously */
|
||||
if (adapter->ps_state == PS_STATE_PRE_SLEEP) {
|
||||
|
@ -60,9 +60,10 @@ int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter,
|
||||
int status;
|
||||
|
||||
/* Wait for completion */
|
||||
status = wait_event_interruptible(adapter->cmd_wait_q.wait,
|
||||
*(cmd_queued->condition));
|
||||
if (status) {
|
||||
status = wait_event_interruptible_timeout(adapter->cmd_wait_q.wait,
|
||||
*(cmd_queued->condition),
|
||||
(12 * HZ));
|
||||
if (status <= 0) {
|
||||
dev_err(adapter->dev, "cmd_wait_q terminated: %d\n", status);
|
||||
mwifiex_cancel_all_pending_cmd(adapter);
|
||||
return status;
|
||||
|
@ -88,7 +88,7 @@ static u8 rsi_core_determine_hal_queue(struct rsi_common *common)
|
||||
bool recontend_queue = false;
|
||||
u32 q_len = 0;
|
||||
u8 q_num = INVALID_QUEUE;
|
||||
u8 ii, min = 0;
|
||||
u8 ii = 0, min = 0;
|
||||
|
||||
if (skb_queue_len(&common->tx_queue[MGMT_SOFT_Q])) {
|
||||
if (!common->mgmt_q_block)
|
||||
|
@ -841,16 +841,6 @@ int rsi_set_channel(struct rsi_common *common, u16 channel)
|
||||
rsi_dbg(MGMT_TX_ZONE,
|
||||
"%s: Sending scan req frame\n", __func__);
|
||||
|
||||
skb = dev_alloc_skb(FRAME_DESC_SZ);
|
||||
if (!skb) {
|
||||
rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
|
||||
__func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memset(skb->data, 0, FRAME_DESC_SZ);
|
||||
mgmt_frame = (struct rsi_mac_frame *)skb->data;
|
||||
|
||||
if (common->band == IEEE80211_BAND_5GHZ) {
|
||||
if ((channel >= 36) && (channel <= 64))
|
||||
channel = ((channel - 32) / 4);
|
||||
@ -868,6 +858,16 @@ int rsi_set_channel(struct rsi_common *common, u16 channel)
|
||||
}
|
||||
}
|
||||
|
||||
skb = dev_alloc_skb(FRAME_DESC_SZ);
|
||||
if (!skb) {
|
||||
rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
|
||||
__func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memset(skb->data, 0, FRAME_DESC_SZ);
|
||||
mgmt_frame = (struct rsi_mac_frame *)skb->data;
|
||||
|
||||
mgmt_frame->desc_word[0] = cpu_to_le16(RSI_WIFI_MGMT_Q << 12);
|
||||
mgmt_frame->desc_word[1] = cpu_to_le16(SCAN_REQUEST);
|
||||
mgmt_frame->desc_word[4] = cpu_to_le16(channel);
|
||||
@ -966,6 +966,7 @@ static int rsi_send_auto_rate_request(struct rsi_common *common)
|
||||
if (!selected_rates) {
|
||||
rsi_dbg(ERR_ZONE, "%s: Failed in allocation of mem\n",
|
||||
__func__);
|
||||
dev_kfree_skb(skb);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
|
@ -68,6 +68,26 @@ struct wl18xx_event_mailbox {
|
||||
|
||||
/* bitmap of inactive stations (by HLID) */
|
||||
__le32 inactive_sta_bitmap;
|
||||
|
||||
/* rx BA win size indicated by RX_BA_WIN_SIZE_CHANGE_EVENT_ID */
|
||||
u8 rx_ba_role_id;
|
||||
u8 rx_ba_link_id;
|
||||
u8 rx_ba_win_size;
|
||||
u8 padding;
|
||||
|
||||
/* smart config */
|
||||
u8 sc_ssid_len;
|
||||
u8 sc_pwd_len;
|
||||
u8 sc_token_len;
|
||||
u8 padding1;
|
||||
u8 sc_ssid[32];
|
||||
u8 sc_pwd[32];
|
||||
u8 sc_token[32];
|
||||
|
||||
/* smart config sync channel */
|
||||
u8 sc_sync_channel;
|
||||
u8 sc_sync_band;
|
||||
u8 padding2[2];
|
||||
} __packed;
|
||||
|
||||
int wl18xx_wait_for_event(struct wl1271 *wl, enum wlcore_wait_event event,
|
||||
|
@ -158,6 +158,11 @@ EXPORT_SYMBOL_GPL(wlcore_event_channel_switch);
|
||||
|
||||
void wlcore_event_dummy_packet(struct wl1271 *wl)
|
||||
{
|
||||
if (wl->plt) {
|
||||
wl1271_info("Got DUMMY_PACKET event in PLT mode. FW bug, ignoring.");
|
||||
return;
|
||||
}
|
||||
|
||||
wl1271_debug(DEBUG_EVENT, "DUMMY_PACKET_ID_EVENT_ID");
|
||||
wl1271_tx_dummy_packet(wl);
|
||||
}
|
||||
|
@ -249,7 +249,7 @@ ieee80211_new_chanctx(struct ieee80211_local *local,
|
||||
|
||||
if (!local->use_chanctx) {
|
||||
local->_oper_chandef = *chandef;
|
||||
ieee80211_hw_config(local, 0);
|
||||
ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
|
||||
} else {
|
||||
err = drv_add_chanctx(local, ctx);
|
||||
if (err) {
|
||||
@ -286,7 +286,7 @@ static void ieee80211_free_chanctx(struct ieee80211_local *local,
|
||||
check_single_channel = true;
|
||||
local->hw.conf.radar_enabled = false;
|
||||
|
||||
ieee80211_hw_config(local, 0);
|
||||
ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
|
||||
} else {
|
||||
drv_remove_chanctx(local, ctx);
|
||||
}
|
||||
@ -492,6 +492,13 @@ void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local,
|
||||
rx_chains_static = max(rx_chains_static, needed_static);
|
||||
rx_chains_dynamic = max(rx_chains_dynamic, needed_dynamic);
|
||||
}
|
||||
|
||||
/* Disable SMPS for the monitor interface */
|
||||
sdata = rcu_dereference(local->monitor_sdata);
|
||||
if (sdata &&
|
||||
rcu_access_pointer(sdata->vif.chanctx_conf) == &chanctx->conf)
|
||||
rx_chains_dynamic = rx_chains_static = local->rx_chains;
|
||||
|
||||
rcu_read_unlock();
|
||||
|
||||
if (!local->use_chanctx) {
|
||||
|
@ -148,6 +148,8 @@ static u32 ieee80211_hw_conf_chan(struct ieee80211_local *local)
|
||||
list_for_each_entry_rcu(sdata, &local->interfaces, list) {
|
||||
if (!rcu_access_pointer(sdata->vif.chanctx_conf))
|
||||
continue;
|
||||
if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
|
||||
continue;
|
||||
power = min(power, sdata->vif.bss_conf.txpower);
|
||||
}
|
||||
rcu_read_unlock();
|
||||
@ -199,7 +201,7 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
|
||||
{
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
|
||||
if (!changed)
|
||||
if (!changed || sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
|
||||
return;
|
||||
|
||||
drv_bss_info_changed(local, sdata, &sdata->vif.bss_conf, changed);
|
||||
|
@ -355,6 +355,7 @@ void ieee80211_sw_roc_work(struct work_struct *work)
|
||||
struct ieee80211_roc_work *dep;
|
||||
|
||||
/* start this ROC */
|
||||
ieee80211_offchannel_stop_vifs(local);
|
||||
|
||||
/* switch channel etc */
|
||||
ieee80211_recalc_idle(local);
|
||||
|
@ -618,6 +618,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
|
||||
sta, true, acked);
|
||||
|
||||
if ((local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL) &&
|
||||
(ieee80211_is_data(hdr->frame_control)) &&
|
||||
(rates_idx != -1))
|
||||
sta->last_tx_rate = info->status.rates[rates_idx];
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user