aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-1000.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debug.h1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debugfs.c44
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h12
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rx.c54
10 files changed, 132 insertions, 0 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index d5c6edbbc95a..85162e2c35d9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -175,6 +175,7 @@ struct iwl_cfg iwl1000_bgn_cfg = {
175 .use_rts_for_ht = true, /* use rts/cts protection */ 175 .use_rts_for_ht = true, /* use rts/cts protection */
176 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 176 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
177 .support_ct_kill_exit = true, 177 .support_ct_kill_exit = true,
178 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
178}; 179};
179 180
180struct iwl_cfg iwl1000_bg_cfg = { 181struct iwl_cfg iwl1000_bg_cfg = {
@@ -201,6 +202,7 @@ struct iwl_cfg iwl1000_bg_cfg = {
201 .led_compensation = 51, 202 .led_compensation = 51,
202 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 203 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
203 .support_ct_kill_exit = true, 204 .support_ct_kill_exit = true,
205 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
204}; 206};
205 207
206MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_MAX)); 208MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 6472910b72d4..764479f74c8b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -2830,6 +2830,7 @@ static struct iwl_cfg iwl3945_bg_cfg = {
2830 .ht_greenfield_support = false, 2830 .ht_greenfield_support = false,
2831 .led_compensation = 64, 2831 .led_compensation = 64,
2832 .broken_powersave = true, 2832 .broken_powersave = true,
2833 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
2833}; 2834};
2834 2835
2835static struct iwl_cfg iwl3945_abg_cfg = { 2836static struct iwl_cfg iwl3945_abg_cfg = {
@@ -2847,6 +2848,7 @@ static struct iwl_cfg iwl3945_abg_cfg = {
2847 .ht_greenfield_support = false, 2848 .ht_greenfield_support = false,
2848 .led_compensation = 64, 2849 .led_compensation = 64,
2849 .broken_powersave = true, 2850 .broken_powersave = true,
2851 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
2850}; 2852};
2851 2853
2852struct pci_device_id iwl3945_hw_card_ids[] = { 2854struct pci_device_id iwl3945_hw_card_ids[] = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 8159a0fcf5a8..c36fef99b4b0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -2239,6 +2239,7 @@ struct iwl_cfg iwl4965_agn_cfg = {
2239 .broken_powersave = true, 2239 .broken_powersave = true,
2240 .led_compensation = 61, 2240 .led_compensation = 61,
2241 .chain_noise_num_beacons = IWL4965_CAL_NUM_BEACONS, 2241 .chain_noise_num_beacons = IWL4965_CAL_NUM_BEACONS,
2242 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
2242}; 2243};
2243 2244
2244/* Module firmware */ 2245/* Module firmware */
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index aab6cf23c2bd..cbbc0e4f2c76 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -1603,6 +1603,7 @@ struct iwl_cfg iwl5300_agn_cfg = {
1603 .led_compensation = 51, 1603 .led_compensation = 51,
1604 .use_rts_for_ht = true, /* use rts/cts protection */ 1604 .use_rts_for_ht = true, /* use rts/cts protection */
1605 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 1605 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1606 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1606}; 1607};
1607 1608
1608struct iwl_cfg iwl5100_bgn_cfg = { 1609struct iwl_cfg iwl5100_bgn_cfg = {
@@ -1627,6 +1628,7 @@ struct iwl_cfg iwl5100_bgn_cfg = {
1627 .led_compensation = 51, 1628 .led_compensation = 51,
1628 .use_rts_for_ht = true, /* use rts/cts protection */ 1629 .use_rts_for_ht = true, /* use rts/cts protection */
1629 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 1630 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1631 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1630}; 1632};
1631 1633
1632struct iwl_cfg iwl5100_abg_cfg = { 1634struct iwl_cfg iwl5100_abg_cfg = {
@@ -1649,6 +1651,7 @@ struct iwl_cfg iwl5100_abg_cfg = {
1649 .use_bsm = false, 1651 .use_bsm = false,
1650 .led_compensation = 51, 1652 .led_compensation = 51,
1651 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 1653 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1654 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1652}; 1655};
1653 1656
1654struct iwl_cfg iwl5100_agn_cfg = { 1657struct iwl_cfg iwl5100_agn_cfg = {
@@ -1673,6 +1676,7 @@ struct iwl_cfg iwl5100_agn_cfg = {
1673 .led_compensation = 51, 1676 .led_compensation = 51,
1674 .use_rts_for_ht = true, /* use rts/cts protection */ 1677 .use_rts_for_ht = true, /* use rts/cts protection */
1675 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 1678 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1679 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1676}; 1680};
1677 1681
1678struct iwl_cfg iwl5350_agn_cfg = { 1682struct iwl_cfg iwl5350_agn_cfg = {
@@ -1697,6 +1701,7 @@ struct iwl_cfg iwl5350_agn_cfg = {
1697 .led_compensation = 51, 1701 .led_compensation = 51,
1698 .use_rts_for_ht = true, /* use rts/cts protection */ 1702 .use_rts_for_ht = true, /* use rts/cts protection */
1699 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 1703 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1704 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1700}; 1705};
1701 1706
1702struct iwl_cfg iwl5150_agn_cfg = { 1707struct iwl_cfg iwl5150_agn_cfg = {
@@ -1721,6 +1726,7 @@ struct iwl_cfg iwl5150_agn_cfg = {
1721 .led_compensation = 51, 1726 .led_compensation = 51,
1722 .use_rts_for_ht = true, /* use rts/cts protection */ 1727 .use_rts_for_ht = true, /* use rts/cts protection */
1723 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 1728 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1729 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1724}; 1730};
1725 1731
1726struct iwl_cfg iwl5150_abg_cfg = { 1732struct iwl_cfg iwl5150_abg_cfg = {
@@ -1743,6 +1749,7 @@ struct iwl_cfg iwl5150_abg_cfg = {
1743 .use_bsm = false, 1749 .use_bsm = false,
1744 .led_compensation = 51, 1750 .led_compensation = 51,
1745 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 1751 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1752 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1746}; 1753};
1747 1754
1748MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX)); 1755MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index 4dab7f12e725..b191c634ad92 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -308,6 +308,7 @@ struct iwl_cfg iwl6000i_2agn_cfg = {
308 .supports_idle = true, 308 .supports_idle = true,
309 .adv_thermal_throttle = true, 309 .adv_thermal_throttle = true,
310 .support_ct_kill_exit = true, 310 .support_ct_kill_exit = true,
311 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
311}; 312};
312 313
313struct iwl_cfg iwl6000i_2abg_cfg = { 314struct iwl_cfg iwl6000i_2abg_cfg = {
@@ -337,6 +338,7 @@ struct iwl_cfg iwl6000i_2abg_cfg = {
337 .supports_idle = true, 338 .supports_idle = true,
338 .adv_thermal_throttle = true, 339 .adv_thermal_throttle = true,
339 .support_ct_kill_exit = true, 340 .support_ct_kill_exit = true,
341 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
340}; 342};
341 343
342struct iwl_cfg iwl6000i_2bg_cfg = { 344struct iwl_cfg iwl6000i_2bg_cfg = {
@@ -366,6 +368,7 @@ struct iwl_cfg iwl6000i_2bg_cfg = {
366 .supports_idle = true, 368 .supports_idle = true,
367 .adv_thermal_throttle = true, 369 .adv_thermal_throttle = true,
368 .support_ct_kill_exit = true, 370 .support_ct_kill_exit = true,
371 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
369}; 372};
370 373
371struct iwl_cfg iwl6050_2agn_cfg = { 374struct iwl_cfg iwl6050_2agn_cfg = {
@@ -396,6 +399,7 @@ struct iwl_cfg iwl6050_2agn_cfg = {
396 .supports_idle = true, 399 .supports_idle = true,
397 .adv_thermal_throttle = true, 400 .adv_thermal_throttle = true,
398 .support_ct_kill_exit = true, 401 .support_ct_kill_exit = true,
402 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
399}; 403};
400 404
401struct iwl_cfg iwl6050_2abg_cfg = { 405struct iwl_cfg iwl6050_2abg_cfg = {
@@ -425,6 +429,7 @@ struct iwl_cfg iwl6050_2abg_cfg = {
425 .supports_idle = true, 429 .supports_idle = true,
426 .adv_thermal_throttle = true, 430 .adv_thermal_throttle = true,
427 .support_ct_kill_exit = true, 431 .support_ct_kill_exit = true,
432 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
428}; 433};
429 434
430struct iwl_cfg iwl6000_3agn_cfg = { 435struct iwl_cfg iwl6000_3agn_cfg = {
@@ -455,6 +460,7 @@ struct iwl_cfg iwl6000_3agn_cfg = {
455 .supports_idle = true, 460 .supports_idle = true,
456 .adv_thermal_throttle = true, 461 .adv_thermal_throttle = true,
457 .support_ct_kill_exit = true, 462 .support_ct_kill_exit = true,
463 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
458}; 464};
459 465
460MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX)); 466MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 6de83d1e1eb8..661918347d48 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -232,6 +232,8 @@ struct iwl_mod_params {
232 * @adv_thermal_throttle: support advance thermal throttle 232 * @adv_thermal_throttle: support advance thermal throttle
233 * @support_ct_kill_exit: support ct kill exit condition 233 * @support_ct_kill_exit: support ct kill exit condition
234 * @support_wimax_coexist: support wimax/wifi co-exist 234 * @support_wimax_coexist: support wimax/wifi co-exist
235 * @plcp_delta_threshold: plcp error rate threshold used to trigger
236 * radio tuning when there is a high receiving plcp error rate
235 * 237 *
236 * We enable the driver to be backward compatible wrt API version. The 238 * We enable the driver to be backward compatible wrt API version. The
237 * driver specifies which APIs it supports (with @ucode_api_max being the 239 * driver specifies which APIs it supports (with @ucode_api_max being the
@@ -288,6 +290,7 @@ struct iwl_cfg {
288 bool adv_thermal_throttle; 290 bool adv_thermal_throttle;
289 bool support_ct_kill_exit; 291 bool support_ct_kill_exit;
290 const bool support_wimax_coexist; 292 const bool support_wimax_coexist;
293 u8 plcp_delta_threshold;
291}; 294};
292 295
293/*************************** 296/***************************
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h
index d81b4f39bb1d..aff1dc0756fc 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debug.h
+++ b/drivers/net/wireless/iwlwifi/iwl-debug.h
@@ -114,6 +114,7 @@ struct iwl_debugfs {
114 struct dentry *file_fh_reg; 114 struct dentry *file_fh_reg;
115 struct dentry *file_missed_beacon; 115 struct dentry *file_missed_beacon;
116 struct dentry *file_internal_scan; 116 struct dentry *file_internal_scan;
117 struct dentry *file_plcp_delta;
117 } dbgfs_debug_files; 118 } dbgfs_debug_files;
118 u32 sram_offset; 119 u32 sram_offset;
119 u32 sram_len; 120 u32 sram_len;
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index 4944fdb31ba8..3f9c03998491 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -2195,6 +2195,47 @@ static ssize_t iwl_dbgfs_internal_scan_write(struct file *file,
2195 return count; 2195 return count;
2196} 2196}
2197 2197
2198static ssize_t iwl_dbgfs_plcp_delta_read(struct file *file,
2199 char __user *user_buf,
2200 size_t count, loff_t *ppos) {
2201
2202 struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
2203 int pos = 0;
2204 char buf[12];
2205 const size_t bufsz = sizeof(buf);
2206 ssize_t ret;
2207
2208 pos += scnprintf(buf + pos, bufsz - pos, "%u\n",
2209 priv->cfg->plcp_delta_threshold);
2210
2211 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
2212 return ret;
2213}
2214
2215static ssize_t iwl_dbgfs_plcp_delta_write(struct file *file,
2216 const char __user *user_buf,
2217 size_t count, loff_t *ppos) {
2218
2219 struct iwl_priv *priv = file->private_data;
2220 char buf[8];
2221 int buf_size;
2222 int plcp;
2223
2224 memset(buf, 0, sizeof(buf));
2225 buf_size = min(count, sizeof(buf) - 1);
2226 if (copy_from_user(buf, user_buf, buf_size))
2227 return -EFAULT;
2228 if (sscanf(buf, "%d", &plcp) != 1)
2229 return -EINVAL;
2230 if ((plcp <= IWL_MAX_PLCP_ERR_THRESHOLD_MIN) ||
2231 (plcp > IWL_MAX_PLCP_ERR_THRESHOLD_MAX))
2232 priv->cfg->plcp_delta_threshold =
2233 IWL_MAX_PLCP_ERR_THRESHOLD_DEF;
2234 else
2235 priv->cfg->plcp_delta_threshold = plcp;
2236 return count;
2237}
2238
2198DEBUGFS_READ_FILE_OPS(rx_statistics); 2239DEBUGFS_READ_FILE_OPS(rx_statistics);
2199DEBUGFS_READ_FILE_OPS(tx_statistics); 2240DEBUGFS_READ_FILE_OPS(tx_statistics);
2200DEBUGFS_READ_WRITE_FILE_OPS(traffic_log); 2241DEBUGFS_READ_WRITE_FILE_OPS(traffic_log);
@@ -2214,6 +2255,7 @@ DEBUGFS_READ_WRITE_FILE_OPS(ucode_tracing);
2214DEBUGFS_READ_FILE_OPS(fh_reg); 2255DEBUGFS_READ_FILE_OPS(fh_reg);
2215DEBUGFS_READ_WRITE_FILE_OPS(missed_beacon); 2256DEBUGFS_READ_WRITE_FILE_OPS(missed_beacon);
2216DEBUGFS_WRITE_FILE_OPS(internal_scan); 2257DEBUGFS_WRITE_FILE_OPS(internal_scan);
2258DEBUGFS_READ_WRITE_FILE_OPS(plcp_delta);
2217 2259
2218/* 2260/*
2219 * Create the debugfs files and directories 2261 * Create the debugfs files and directories
@@ -2268,6 +2310,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
2268 DEBUGFS_ADD_FILE(fh_reg, debug, S_IRUSR); 2310 DEBUGFS_ADD_FILE(fh_reg, debug, S_IRUSR);
2269 DEBUGFS_ADD_FILE(missed_beacon, debug, S_IWUSR); 2311 DEBUGFS_ADD_FILE(missed_beacon, debug, S_IWUSR);
2270 DEBUGFS_ADD_FILE(internal_scan, debug, S_IWUSR); 2312 DEBUGFS_ADD_FILE(internal_scan, debug, S_IWUSR);
2313 DEBUGFS_ADD_FILE(plcp_delta, debug, S_IWUSR | S_IRUSR);
2271 if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) { 2314 if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) {
2272 DEBUGFS_ADD_FILE(ucode_rx_stats, debug, S_IRUSR); 2315 DEBUGFS_ADD_FILE(ucode_rx_stats, debug, S_IRUSR);
2273 DEBUGFS_ADD_FILE(ucode_tx_stats, debug, S_IRUSR); 2316 DEBUGFS_ADD_FILE(ucode_tx_stats, debug, S_IRUSR);
@@ -2330,6 +2373,7 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv)
2330 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_fh_reg); 2373 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_fh_reg);
2331 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_missed_beacon); 2374 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_missed_beacon);
2332 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_internal_scan); 2375 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_internal_scan);
2376 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_plcp_delta);
2333 if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) { 2377 if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) {
2334 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files. 2378 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
2335 file_ucode_rx_stats); 2379 file_ucode_rx_stats);
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 86d38ae2ec7e..a1f3ecb69ed0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -1026,6 +1026,15 @@ struct iwl_event_log {
1026#define IWL_HOST_INT_CALIB_TIMEOUT_DEF (0x10) 1026#define IWL_HOST_INT_CALIB_TIMEOUT_DEF (0x10)
1027#define IWL_HOST_INT_CALIB_TIMEOUT_MIN (0x0) 1027#define IWL_HOST_INT_CALIB_TIMEOUT_MIN (0x0)
1028 1028
1029/*
1030 * This is the threshold value of plcp error rate per 100mSecs. It is
1031 * used to set and check for the validity of plcp_delta.
1032 */
1033#define IWL_MAX_PLCP_ERR_THRESHOLD_MIN (0)
1034#define IWL_MAX_PLCP_ERR_THRESHOLD_DEF (50)
1035#define IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF (100)
1036#define IWL_MAX_PLCP_ERR_THRESHOLD_MAX (255)
1037
1029struct iwl_priv { 1038struct iwl_priv {
1030 1039
1031 /* ieee device used by generic ieee processing code */ 1040 /* ieee device used by generic ieee processing code */
@@ -1055,6 +1064,9 @@ struct iwl_priv {
1055 u32 ucode_beacon_time; 1064 u32 ucode_beacon_time;
1056 int missed_beacon_threshold; 1065 int missed_beacon_threshold;
1057 1066
1067 /* storing the jiffies when the plcp error rate is received */
1068 unsigned long plcp_jiffies;
1069
1058 /* we allocate array of iwl4965_channel_info for NIC's valid channels. 1070 /* we allocate array of iwl4965_channel_info for NIC's valid channels.
1059 * Access via channel # using indirect index array */ 1071 * Access via channel # using indirect index array */
1060 struct iwl_channel_info *channel_info; /* channel info array */ 1072 struct iwl_channel_info *channel_info; /* channel info array */
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index dc06c7bb0f5c..ea309f42a78a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -602,11 +602,15 @@ static void iwl_accumulative_statistics(struct iwl_priv *priv,
602 602
603#define REG_RECALIB_PERIOD (60) 603#define REG_RECALIB_PERIOD (60)
604 604
605#define PLCP_MSG "plcp_err exceeded %u, %u, %u, %u, %u, %d, %u mSecs\n"
605void iwl_rx_statistics(struct iwl_priv *priv, 606void iwl_rx_statistics(struct iwl_priv *priv,
606 struct iwl_rx_mem_buffer *rxb) 607 struct iwl_rx_mem_buffer *rxb)
607{ 608{
608 int change; 609 int change;
609 struct iwl_rx_packet *pkt = rxb_addr(rxb); 610 struct iwl_rx_packet *pkt = rxb_addr(rxb);
611 int combined_plcp_delta;
612 unsigned int plcp_msec;
613 unsigned long plcp_received_jiffies;
610 614
611 IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n", 615 IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n",
612 (int)sizeof(priv->statistics), 616 (int)sizeof(priv->statistics),
@@ -621,6 +625,56 @@ void iwl_rx_statistics(struct iwl_priv *priv,
621#ifdef CONFIG_IWLWIFI_DEBUG 625#ifdef CONFIG_IWLWIFI_DEBUG
622 iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats); 626 iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats);
623#endif 627#endif
628 /*
629 * check for plcp_err and trigger radio reset if it exceeds
630 * the plcp error threshold plcp_delta.
631 */
632 plcp_received_jiffies = jiffies;
633 plcp_msec = jiffies_to_msecs((long) plcp_received_jiffies -
634 (long) priv->plcp_jiffies);
635 priv->plcp_jiffies = plcp_received_jiffies;
636 /*
637 * check to make sure plcp_msec is not 0 to prevent division
638 * by zero.
639 */
640 if (plcp_msec) {
641 combined_plcp_delta =
642 (le32_to_cpu(pkt->u.stats.rx.ofdm.plcp_err) -
643 le32_to_cpu(priv->statistics.rx.ofdm.plcp_err)) +
644 (le32_to_cpu(pkt->u.stats.rx.ofdm_ht.plcp_err) -
645 le32_to_cpu(priv->statistics.rx.ofdm_ht.plcp_err));
646
647 if ((combined_plcp_delta > 0) &&
648 ((combined_plcp_delta * 100) / plcp_msec) >
649 priv->cfg->plcp_delta_threshold) {
650 /*
651 * if plcp_err exceed the threshold, the following
652 * data is printed in csv format:
653 * Text: plcp_err exceeded %d,
654 * Received ofdm.plcp_err,
655 * Current ofdm.plcp_err,
656 * Received ofdm_ht.plcp_err,
657 * Current ofdm_ht.plcp_err,
658 * combined_plcp_delta,
659 * plcp_msec
660 */
661 IWL_DEBUG_RADIO(priv, PLCP_MSG,
662 priv->cfg->plcp_delta_threshold,
663 le32_to_cpu(pkt->u.stats.rx.ofdm.plcp_err),
664 le32_to_cpu(priv->statistics.rx.ofdm.plcp_err),
665 le32_to_cpu(pkt->u.stats.rx.ofdm_ht.plcp_err),
666 le32_to_cpu(
667 priv->statistics.rx.ofdm_ht.plcp_err),
668 combined_plcp_delta, plcp_msec);
669
670 /*
671 * Reset the RF radio due to the high plcp
672 * error rate
673 */
674 iwl_force_rf_reset(priv);
675 }
676 }
677
624 memcpy(&priv->statistics, &pkt->u.stats, sizeof(priv->statistics)); 678 memcpy(&priv->statistics, &pkt->u.stats, sizeof(priv->statistics));
625 679
626 set_bit(STATUS_STATISTICS, &priv->status); 680 set_bit(STATUS_STATISTICS, &priv->status);