Commit a13d276f authored by Wey-Yi Guy's avatar Wey-Yi Guy Committed by John W. Linville

iwlwifi: configure missed beacon threshold

Add support to configure missed beacon threshold, by default, if receive
"missed beacon" notification from uCode and has more than 5 consecutive
beacon missed, then perform sensitivity calibration; with this change,
allow user to adjust the missed beacon threshold from debugfs in case
more sensitivity calibration required for better performance in noisy
environment

The default value (=5) should be good enough for the normal condition,
but for very noisy environment, more sensitivity calibration could help
improve the throughput, so by setting the missed beacon threshold to
lower number, user might experience better performance result.
Signed-off-by: default avatarWey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: default avatarReinette Chatre <reinette.chatre@intel.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 3b43a187
...@@ -3372,6 +3372,7 @@ static int iwl_init_drv(struct iwl_priv *priv) ...@@ -3372,6 +3372,7 @@ static int iwl_init_drv(struct iwl_priv *priv)
priv->iw_mode = NL80211_IFTYPE_STATION; priv->iw_mode = NL80211_IFTYPE_STATION;
priv->current_ht_config.smps = IEEE80211_SMPS_STATIC; priv->current_ht_config.smps = IEEE80211_SMPS_STATIC;
priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF;
/* Choose which receivers/antennas to use */ /* Choose which receivers/antennas to use */
if (priv->cfg->ops->hcmd->set_rxon_chain) if (priv->cfg->ops->hcmd->set_rxon_chain)
......
...@@ -3165,13 +3165,30 @@ struct iwl_notif_statistics { ...@@ -3165,13 +3165,30 @@ struct iwl_notif_statistics {
/* /*
* MISSED_BEACONS_NOTIFICATION = 0xa2 (notification only, not a command) * MISSED_BEACONS_NOTIFICATION = 0xa2 (notification only, not a command)
*
* uCode send MISSED_BEACONS_NOTIFICATION to driver when detect beacon missed
* in regardless of how many missed beacons, which mean when driver receive the
* notification, inside the command, it can find all the beacons information
* which include number of total missed beacons, number of consecutive missed
* beacons, number of beacons received and number of beacons expected to
* receive.
*
* If uCode detected consecutive_missed_beacons > 5, it will reset the radio
* in order to bring the radio/PHY back to working state; which has no relation
* to when driver will perform sensitivity calibration.
*
* Driver should set it own missed_beacon_threshold to decide when to perform
* sensitivity calibration based on number of consecutive missed beacons in
* order to improve overall performance, especially in noisy environment.
*
*/ */
/* if ucode missed CONSECUTIVE_MISSED_BCONS_TH beacons in a row,
* then this notification will be sent. */ #define IWL_MISSED_BEACON_THRESHOLD_MIN (1)
#define CONSECUTIVE_MISSED_BCONS_TH 20 #define IWL_MISSED_BEACON_THRESHOLD_DEF (5)
#define IWL_MISSED_BEACON_THRESHOLD_MAX IWL_MISSED_BEACON_THRESHOLD_DEF
struct iwl_missed_beacon_notif { struct iwl_missed_beacon_notif {
__le32 consequtive_missed_beacons; __le32 consecutive_missed_beacons;
__le32 total_missed_becons; __le32 total_missed_becons;
__le32 num_expected_beacons; __le32 num_expected_beacons;
__le32 num_recvd_beacons; __le32 num_recvd_beacons;
......
...@@ -112,6 +112,7 @@ struct iwl_debugfs { ...@@ -112,6 +112,7 @@ struct iwl_debugfs {
struct dentry *file_csr; struct dentry *file_csr;
struct dentry *file_ucode_tracing; struct dentry *file_ucode_tracing;
struct dentry *file_fh_reg; struct dentry *file_fh_reg;
struct dentry *file_missed_beacon;
} dbgfs_debug_files; } dbgfs_debug_files;
u32 sram_offset; u32 sram_offset;
u32 sram_len; u32 sram_len;
......
...@@ -2131,6 +2131,49 @@ static ssize_t iwl_dbgfs_fh_reg_read(struct file *file, ...@@ -2131,6 +2131,49 @@ static ssize_t iwl_dbgfs_fh_reg_read(struct file *file,
return ret; return ret;
} }
static ssize_t iwl_dbgfs_missed_beacon_read(struct file *file,
char __user *user_buf,
size_t count, loff_t *ppos) {
struct iwl_priv *priv = file->private_data;
int pos = 0;
char buf[12];
const size_t bufsz = sizeof(buf);
ssize_t ret;
pos += scnprintf(buf + pos, bufsz - pos, "%d\n",
priv->missed_beacon_threshold);
ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
return ret;
}
static ssize_t iwl_dbgfs_missed_beacon_write(struct file *file,
const char __user *user_buf,
size_t count, loff_t *ppos)
{
struct iwl_priv *priv = file->private_data;
char buf[8];
int buf_size;
int missed;
memset(buf, 0, sizeof(buf));
buf_size = min(count, sizeof(buf) - 1);
if (copy_from_user(buf, user_buf, buf_size))
return -EFAULT;
if (sscanf(buf, "%d", &missed) != 1)
return -EINVAL;
if (missed < IWL_MISSED_BEACON_THRESHOLD_MIN ||
missed > IWL_MISSED_BEACON_THRESHOLD_MAX)
priv->missed_beacon_threshold =
IWL_MISSED_BEACON_THRESHOLD_DEF;
else
priv->missed_beacon_threshold = missed;
return count;
}
DEBUGFS_READ_FILE_OPS(rx_statistics); DEBUGFS_READ_FILE_OPS(rx_statistics);
DEBUGFS_READ_FILE_OPS(tx_statistics); DEBUGFS_READ_FILE_OPS(tx_statistics);
DEBUGFS_READ_WRITE_FILE_OPS(traffic_log); DEBUGFS_READ_WRITE_FILE_OPS(traffic_log);
...@@ -2148,6 +2191,7 @@ DEBUGFS_WRITE_FILE_OPS(clear_traffic_statistics); ...@@ -2148,6 +2191,7 @@ DEBUGFS_WRITE_FILE_OPS(clear_traffic_statistics);
DEBUGFS_WRITE_FILE_OPS(csr); DEBUGFS_WRITE_FILE_OPS(csr);
DEBUGFS_READ_WRITE_FILE_OPS(ucode_tracing); DEBUGFS_READ_WRITE_FILE_OPS(ucode_tracing);
DEBUGFS_READ_FILE_OPS(fh_reg); DEBUGFS_READ_FILE_OPS(fh_reg);
DEBUGFS_READ_WRITE_FILE_OPS(missed_beacon);
/* /*
* Create the debugfs files and directories * Create the debugfs files and directories
...@@ -2200,6 +2244,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) ...@@ -2200,6 +2244,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
DEBUGFS_ADD_FILE(clear_traffic_statistics, debug, S_IWUSR); DEBUGFS_ADD_FILE(clear_traffic_statistics, debug, S_IWUSR);
DEBUGFS_ADD_FILE(csr, debug, S_IWUSR); DEBUGFS_ADD_FILE(csr, debug, S_IWUSR);
DEBUGFS_ADD_FILE(fh_reg, debug, S_IRUSR); DEBUGFS_ADD_FILE(fh_reg, debug, S_IRUSR);
DEBUGFS_ADD_FILE(missed_beacon, debug, S_IWUSR);
if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) { if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) {
DEBUGFS_ADD_FILE(ucode_rx_stats, debug, S_IRUSR); DEBUGFS_ADD_FILE(ucode_rx_stats, debug, S_IRUSR);
DEBUGFS_ADD_FILE(ucode_tx_stats, debug, S_IRUSR); DEBUGFS_ADD_FILE(ucode_tx_stats, debug, S_IRUSR);
...@@ -2260,6 +2305,7 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv) ...@@ -2260,6 +2305,7 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv)
file_clear_traffic_statistics); file_clear_traffic_statistics);
DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_csr); DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_csr);
DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_fh_reg); DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_fh_reg);
DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_missed_beacon);
if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) { if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) {
DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files. DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
file_ucode_rx_stats); file_ucode_rx_stats);
......
...@@ -1053,6 +1053,7 @@ struct iwl_priv { ...@@ -1053,6 +1053,7 @@ struct iwl_priv {
#endif #endif
/* ucode beacon time */ /* ucode beacon time */
u32 ucode_beacon_time; u32 ucode_beacon_time;
int missed_beacon_threshold;
/* we allocate array of iwl4965_channel_info for NIC's valid channels. /* we allocate array of iwl4965_channel_info for NIC's valid channels.
* Access via channel # using indirect index array */ * Access via channel # using indirect index array */
......
...@@ -499,9 +499,10 @@ void iwl_rx_missed_beacon_notif(struct iwl_priv *priv, ...@@ -499,9 +499,10 @@ void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
struct iwl_missed_beacon_notif *missed_beacon; struct iwl_missed_beacon_notif *missed_beacon;
missed_beacon = &pkt->u.missed_beacon; missed_beacon = &pkt->u.missed_beacon;
if (le32_to_cpu(missed_beacon->consequtive_missed_beacons) > 5) { if (le32_to_cpu(missed_beacon->consecutive_missed_beacons) >
priv->missed_beacon_threshold) {
IWL_DEBUG_CALIB(priv, "missed bcn cnsq %d totl %d rcd %d expctd %d\n", IWL_DEBUG_CALIB(priv, "missed bcn cnsq %d totl %d rcd %d expctd %d\n",
le32_to_cpu(missed_beacon->consequtive_missed_beacons), le32_to_cpu(missed_beacon->consecutive_missed_beacons),
le32_to_cpu(missed_beacon->total_missed_becons), le32_to_cpu(missed_beacon->total_missed_becons),
le32_to_cpu(missed_beacon->num_recvd_beacons), le32_to_cpu(missed_beacon->num_recvd_beacons),
le32_to_cpu(missed_beacon->num_expected_beacons)); le32_to_cpu(missed_beacon->num_expected_beacons));
......
...@@ -3881,6 +3881,7 @@ static int iwl3945_init_drv(struct iwl_priv *priv) ...@@ -3881,6 +3881,7 @@ static int iwl3945_init_drv(struct iwl_priv *priv)
priv->band = IEEE80211_BAND_2GHZ; priv->band = IEEE80211_BAND_2GHZ;
priv->iw_mode = NL80211_IFTYPE_STATION; priv->iw_mode = NL80211_IFTYPE_STATION;
priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF;
iwl_reset_qos(priv); iwl_reset_qos(priv);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment