aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>2008-06-30 05:23:07 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-06-30 17:37:39 -0400
commit8f91aecb4cdc2d786df8941e827b9dff3c10a4e4 (patch)
tree868178c41e3559b7f91bda02a78f4a9caea79fe6 /drivers
parent43d59b323743b8a01e9ad1a1b31b0d7c0ef6e35a (diff)
iwlwifi: move RX stats to core, and move temperature to handler
This patch moves RX stats flow to core modules, and moves temperature calibration to handler since it is not needed in 5000. Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Signed-off-by: Zhu Yi <yi.zhu@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c78
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-calib.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-calib.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rx.c75
-rw-r--r--drivers/net/wireless/iwlwifi/iwl4965-base.c6
9 files changed, 103 insertions, 85 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index ab5027345a01..1688803af582 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -555,8 +555,6 @@ out:
555 return ret; 555 return ret;
556} 556}
557 557
558#define REG_RECALIB_PERIOD (60)
559
560/* Reset differential Rx gains in NIC to prepare for chain noise calibration. 558/* Reset differential Rx gains in NIC to prepare for chain noise calibration.
561 * Called after every association, but this runs only once! 559 * Called after every association, but this runs only once!
562 * ... once chain noise is calibrated the first time, it's good forever. */ 560 * ... once chain noise is calibrated the first time, it's good forever. */
@@ -1890,80 +1888,15 @@ static int iwl4965_is_temp_calib_needed(struct iwl_priv *priv)
1890 return 1; 1888 return 1;
1891} 1889}
1892 1890
1893/* Calculate noise level, based on measurements during network silence just 1891static void iwl4965_temperature_calib(struct iwl_priv *priv,
1894 * before arriving beacon. This measurement can be done only if we know 1892 struct iwl_notif_statistics *stats)
1895 * exactly when to expect beacons, therefore only when we're associated. */
1896static void iwl4965_rx_calc_noise(struct iwl_priv *priv)
1897{ 1893{
1898 struct statistics_rx_non_phy *rx_info
1899 = &(priv->statistics.rx.general);
1900 int num_active_rx = 0;
1901 int total_silence = 0;
1902 int bcn_silence_a =
1903 le32_to_cpu(rx_info->beacon_silence_rssi_a) & IN_BAND_FILTER;
1904 int bcn_silence_b =
1905 le32_to_cpu(rx_info->beacon_silence_rssi_b) & IN_BAND_FILTER;
1906 int bcn_silence_c =
1907 le32_to_cpu(rx_info->beacon_silence_rssi_c) & IN_BAND_FILTER;
1908
1909 if (bcn_silence_a) {
1910 total_silence += bcn_silence_a;
1911 num_active_rx++;
1912 }
1913 if (bcn_silence_b) {
1914 total_silence += bcn_silence_b;
1915 num_active_rx++;
1916 }
1917 if (bcn_silence_c) {
1918 total_silence += bcn_silence_c;
1919 num_active_rx++;
1920 }
1921
1922 /* Average among active antennas */
1923 if (num_active_rx)
1924 priv->last_rx_noise = (total_silence / num_active_rx) - 107;
1925 else
1926 priv->last_rx_noise = IWL_NOISE_MEAS_NOT_AVAILABLE;
1927
1928 IWL_DEBUG_CALIB("inband silence a %u, b %u, c %u, dBm %d\n",
1929 bcn_silence_a, bcn_silence_b, bcn_silence_c,
1930 priv->last_rx_noise);
1931}
1932
1933void iwl4965_hw_rx_statistics(struct iwl_priv *priv,
1934 struct iwl_rx_mem_buffer *rxb)
1935{
1936 struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
1937 int change;
1938 s32 temp; 1894 s32 temp;
1939 1895 int change = ((priv->statistics.general.temperature !=
1940 IWL_DEBUG_RX("Statistics notification received (%d vs %d).\n", 1896 stats->general.temperature) ||
1941 (int)sizeof(priv->statistics), pkt->len);
1942
1943 change = ((priv->statistics.general.temperature !=
1944 pkt->u.stats.general.temperature) ||
1945 ((priv->statistics.flag & 1897 ((priv->statistics.flag &
1946 STATISTICS_REPLY_FLG_FAT_MODE_MSK) != 1898 STATISTICS_REPLY_FLG_FAT_MODE_MSK) !=
1947 (pkt->u.stats.flag & STATISTICS_REPLY_FLG_FAT_MODE_MSK))); 1899 (stats->flag & STATISTICS_REPLY_FLG_FAT_MODE_MSK)));
1948
1949 memcpy(&priv->statistics, &pkt->u.stats, sizeof(priv->statistics));
1950
1951 set_bit(STATUS_STATISTICS, &priv->status);
1952
1953 /* Reschedule the statistics timer to occur in
1954 * REG_RECALIB_PERIOD seconds to ensure we get a
1955 * thermal update even if the uCode doesn't give
1956 * us one */
1957 mod_timer(&priv->statistics_periodic, jiffies +
1958 msecs_to_jiffies(REG_RECALIB_PERIOD * 1000));
1959
1960 if (unlikely(!test_bit(STATUS_SCANNING, &priv->status)) &&
1961 (pkt->hdr.cmd == STATISTICS_NOTIFICATION)) {
1962 iwl4965_rx_calc_noise(priv);
1963 queue_work(priv->workqueue, &priv->run_time_calib_work);
1964 }
1965
1966 iwl_leds_background(priv);
1967 1900
1968 /* If the hardware hasn't reported a change in 1901 /* If the hardware hasn't reported a change in
1969 * temperature then don't bother computing a 1902 * temperature then don't bother computing a
@@ -3391,6 +3324,7 @@ static struct iwl_lib_ops iwl4965_lib = {
3391 .set_power = iwl4965_set_power, 3324 .set_power = iwl4965_set_power,
3392 .send_tx_power = iwl4965_send_tx_power, 3325 .send_tx_power = iwl4965_send_tx_power,
3393 .update_chain_flags = iwl4965_update_chain_flags, 3326 .update_chain_flags = iwl4965_update_chain_flags,
3327 .temperature = iwl4965_temperature_calib,
3394}; 3328};
3395 3329
3396static struct iwl_ops iwl4965_ops = { 3330static struct iwl_ops iwl4965_ops = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 2b48f1b19140..5abfd56e9bb4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -1433,6 +1433,12 @@ static int iwl5000_send_tx_power(struct iwl_priv *priv)
1433 NULL); 1433 NULL);
1434} 1434}
1435 1435
1436static void iwl5000_temperature(struct iwl_priv *priv,
1437 struct iwl_notif_statistics *stats)
1438{
1439 /* store temperature from statistics (in Celsius) */
1440 priv->temperature = le32_to_cpu(stats->general.temperature);
1441}
1436 1442
1437static struct iwl_hcmd_ops iwl5000_hcmd = { 1443static struct iwl_hcmd_ops iwl5000_hcmd = {
1438 .rxon_assoc = iwl5000_send_rxon_assoc, 1444 .rxon_assoc = iwl5000_send_rxon_assoc,
@@ -1462,6 +1468,7 @@ static struct iwl_lib_ops iwl5000_lib = {
1462 .init_alive_start = iwl5000_init_alive_start, 1468 .init_alive_start = iwl5000_init_alive_start,
1463 .alive_notify = iwl5000_alive_notify, 1469 .alive_notify = iwl5000_alive_notify,
1464 .send_tx_power = iwl5000_send_tx_power, 1470 .send_tx_power = iwl5000_send_tx_power,
1471 .temperature = iwl5000_temperature,
1465 .apm_ops = { 1472 .apm_ops = {
1466 .init = iwl5000_apm_init, 1473 .init = iwl5000_apm_init,
1467 .reset = iwl5000_apm_reset, 1474 .reset = iwl5000_apm_reset,
diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.c b/drivers/net/wireless/iwlwifi/iwl-calib.c
index 48f58000b64b..ef49440bd7f6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-calib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-calib.c
@@ -470,7 +470,7 @@ void iwl_init_sensitivity(struct iwl_priv *priv)
470EXPORT_SYMBOL(iwl_init_sensitivity); 470EXPORT_SYMBOL(iwl_init_sensitivity);
471 471
472void iwl_sensitivity_calibration(struct iwl_priv *priv, 472void iwl_sensitivity_calibration(struct iwl_priv *priv,
473 struct iwl4965_notif_statistics *resp) 473 struct iwl_notif_statistics *resp)
474{ 474{
475 u32 rx_enable_time; 475 u32 rx_enable_time;
476 u32 fa_cck; 476 u32 fa_cck;
@@ -584,7 +584,7 @@ EXPORT_SYMBOL(iwl_sensitivity_calibration);
584 * 2) Differential rx gain settings to balance the 3 receivers. 584 * 2) Differential rx gain settings to balance the 3 receivers.
585 */ 585 */
586void iwl_chain_noise_calibration(struct iwl_priv *priv, 586void iwl_chain_noise_calibration(struct iwl_priv *priv,
587 struct iwl4965_notif_statistics *stat_resp) 587 struct iwl_notif_statistics *stat_resp)
588{ 588{
589 struct iwl_chain_noise_data *data = NULL; 589 struct iwl_chain_noise_data *data = NULL;
590 590
diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.h b/drivers/net/wireless/iwlwifi/iwl-calib.h
index 5524a29e22d8..94c8e316382a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-calib.h
+++ b/drivers/net/wireless/iwlwifi/iwl-calib.h
@@ -67,9 +67,9 @@
67#include "iwl-commands.h" 67#include "iwl-commands.h"
68 68
69void iwl_chain_noise_calibration(struct iwl_priv *priv, 69void iwl_chain_noise_calibration(struct iwl_priv *priv,
70 struct iwl4965_notif_statistics *stat_resp); 70 struct iwl_notif_statistics *stat_resp);
71void iwl_sensitivity_calibration(struct iwl_priv *priv, 71void iwl_sensitivity_calibration(struct iwl_priv *priv,
72 struct iwl4965_notif_statistics *resp); 72 struct iwl_notif_statistics *resp);
73 73
74void iwl_init_sensitivity(struct iwl_priv *priv); 74void iwl_init_sensitivity(struct iwl_priv *priv);
75void iwl_reset_run_time_calib(struct iwl_priv *priv); 75void iwl_reset_run_time_calib(struct iwl_priv *priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index 6957b2208240..9f8446c5a1bc 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -2506,7 +2506,7 @@ struct statistics_general {
2506 */ 2506 */
2507#define IWL_STATS_CONF_CLEAR_STATS __constant_cpu_to_le32(0x1) /* see above */ 2507#define IWL_STATS_CONF_CLEAR_STATS __constant_cpu_to_le32(0x1) /* see above */
2508#define IWL_STATS_CONF_DISABLE_NOTIF __constant_cpu_to_le32(0x2)/* see above */ 2508#define IWL_STATS_CONF_DISABLE_NOTIF __constant_cpu_to_le32(0x2)/* see above */
2509struct iwl4965_statistics_cmd { 2509struct iwl_statistics_cmd {
2510 __le32 configuration_flags; /* IWL_STATS_CONF_* */ 2510 __le32 configuration_flags; /* IWL_STATS_CONF_* */
2511} __attribute__ ((packed)); 2511} __attribute__ ((packed));
2512 2512
@@ -2527,7 +2527,7 @@ struct iwl4965_statistics_cmd {
2527 */ 2527 */
2528#define STATISTICS_REPLY_FLG_BAND_24G_MSK __constant_cpu_to_le32(0x2) 2528#define STATISTICS_REPLY_FLG_BAND_24G_MSK __constant_cpu_to_le32(0x2)
2529#define STATISTICS_REPLY_FLG_FAT_MODE_MSK __constant_cpu_to_le32(0x8) 2529#define STATISTICS_REPLY_FLG_FAT_MODE_MSK __constant_cpu_to_le32(0x8)
2530struct iwl4965_notif_statistics { 2530struct iwl_notif_statistics {
2531 __le32 flag; 2531 __le32 flag;
2532 struct statistics_rx rx; 2532 struct statistics_rx rx;
2533 struct statistics_tx tx; 2533 struct statistics_tx tx;
@@ -3000,7 +3000,7 @@ struct iwl_rx_packet {
3000 struct iwl_rem_sta_resp rem_sta; 3000 struct iwl_rem_sta_resp rem_sta;
3001 struct iwl4965_sleep_notification sleep_notif; 3001 struct iwl4965_sleep_notification sleep_notif;
3002 struct iwl4965_spectrum_resp spectrum; 3002 struct iwl4965_spectrum_resp spectrum;
3003 struct iwl4965_notif_statistics stats; 3003 struct iwl_notif_statistics stats;
3004 struct iwl4965_compressed_ba_resp compressed_ba; 3004 struct iwl4965_compressed_ba_resp compressed_ba;
3005 struct iwl4965_missed_beacon_notif missed_beacon; 3005 struct iwl4965_missed_beacon_notif missed_beacon;
3006 struct iwl5000_calibration calib; 3006 struct iwl5000_calibration calib;
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 2838093b4459..375afe15b54b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -140,6 +140,8 @@ struct iwl_lib_ops {
140 int (*set_power)(struct iwl_priv *priv, void *cmd); 140 int (*set_power)(struct iwl_priv *priv, void *cmd);
141 int (*send_tx_power) (struct iwl_priv *priv); 141 int (*send_tx_power) (struct iwl_priv *priv);
142 void (*update_chain_flags)(struct iwl_priv *priv); 142 void (*update_chain_flags)(struct iwl_priv *priv);
143 void (*temperature) (struct iwl_priv *priv,
144 struct iwl_notif_statistics *stats);
143 /* eeprom operations (as defined in iwl-eeprom.h) */ 145 /* eeprom operations (as defined in iwl-eeprom.h) */
144 struct iwl_eeprom_ops eeprom_ops; 146 struct iwl_eeprom_ops eeprom_ops;
145}; 147};
@@ -218,6 +220,8 @@ int iwl_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index);
218/* Handlers */ 220/* Handlers */
219void iwl_rx_missed_beacon_notif(struct iwl_priv *priv, 221void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
220 struct iwl_rx_mem_buffer *rxb); 222 struct iwl_rx_mem_buffer *rxb);
223void iwl_rx_statistics(struct iwl_priv *priv,
224 struct iwl_rx_mem_buffer *rxb);
221 225
222/* TX helpers */ 226/* TX helpers */
223 227
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 81ff4c2c6a5a..fd008ab63bd9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -624,8 +624,6 @@ extern int iwl_rxq_stop(struct iwl_priv *priv);
624extern void iwl_txq_ctx_stop(struct iwl_priv *priv); 624extern void iwl_txq_ctx_stop(struct iwl_priv *priv);
625extern unsigned int iwl4965_hw_get_beacon_cmd(struct iwl_priv *priv, 625extern unsigned int iwl4965_hw_get_beacon_cmd(struct iwl_priv *priv,
626 struct iwl_frame *frame, u8 rate); 626 struct iwl_frame *frame, u8 rate);
627extern void iwl4965_hw_rx_statistics(struct iwl_priv *priv,
628 struct iwl_rx_mem_buffer *rxb);
629extern void iwl4965_disable_events(struct iwl_priv *priv); 627extern void iwl4965_disable_events(struct iwl_priv *priv);
630extern void iwl4965_rx_reply_rx(struct iwl_priv *priv, 628extern void iwl4965_rx_reply_rx(struct iwl_priv *priv,
631 struct iwl_rx_mem_buffer *rxb); 629 struct iwl_rx_mem_buffer *rxb);
@@ -994,7 +992,7 @@ struct iwl_priv {
994 992
995 struct iwl_power_mgr power_data; 993 struct iwl_power_mgr power_data;
996 994
997 struct iwl4965_notif_statistics statistics; 995 struct iwl_notif_statistics statistics;
998 unsigned long last_statistics_time; 996 unsigned long last_statistics_time;
999 997
1000 /* context information */ 998 /* context information */
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index c24844802a88..b3ca1375c01a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -466,3 +466,78 @@ void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
466 } 466 }
467} 467}
468EXPORT_SYMBOL(iwl_rx_missed_beacon_notif); 468EXPORT_SYMBOL(iwl_rx_missed_beacon_notif);
469
470
471/* Calculate noise level, based on measurements during network silence just
472 * before arriving beacon. This measurement can be done only if we know
473 * exactly when to expect beacons, therefore only when we're associated. */
474static void iwl_rx_calc_noise(struct iwl_priv *priv)
475{
476 struct statistics_rx_non_phy *rx_info
477 = &(priv->statistics.rx.general);
478 int num_active_rx = 0;
479 int total_silence = 0;
480 int bcn_silence_a =
481 le32_to_cpu(rx_info->beacon_silence_rssi_a) & IN_BAND_FILTER;
482 int bcn_silence_b =
483 le32_to_cpu(rx_info->beacon_silence_rssi_b) & IN_BAND_FILTER;
484 int bcn_silence_c =
485 le32_to_cpu(rx_info->beacon_silence_rssi_c) & IN_BAND_FILTER;
486
487 if (bcn_silence_a) {
488 total_silence += bcn_silence_a;
489 num_active_rx++;
490 }
491 if (bcn_silence_b) {
492 total_silence += bcn_silence_b;
493 num_active_rx++;
494 }
495 if (bcn_silence_c) {
496 total_silence += bcn_silence_c;
497 num_active_rx++;
498 }
499
500 /* Average among active antennas */
501 if (num_active_rx)
502 priv->last_rx_noise = (total_silence / num_active_rx) - 107;
503 else
504 priv->last_rx_noise = IWL_NOISE_MEAS_NOT_AVAILABLE;
505
506 IWL_DEBUG_CALIB("inband silence a %u, b %u, c %u, dBm %d\n",
507 bcn_silence_a, bcn_silence_b, bcn_silence_c,
508 priv->last_rx_noise);
509}
510
511#define REG_RECALIB_PERIOD (60)
512
513void iwl_rx_statistics(struct iwl_priv *priv,
514 struct iwl_rx_mem_buffer *rxb)
515{
516 struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
517
518 IWL_DEBUG_RX("Statistics notification received (%d vs %d).\n",
519 (int)sizeof(priv->statistics), pkt->len);
520
521 memcpy(&priv->statistics, &pkt->u.stats, sizeof(priv->statistics));
522
523 set_bit(STATUS_STATISTICS, &priv->status);
524
525 /* Reschedule the statistics timer to occur in
526 * REG_RECALIB_PERIOD seconds to ensure we get a
527 * thermal update even if the uCode doesn't give
528 * us one */
529 mod_timer(&priv->statistics_periodic, jiffies +
530 msecs_to_jiffies(REG_RECALIB_PERIOD * 1000));
531
532 if (unlikely(!test_bit(STATUS_SCANNING, &priv->status)) &&
533 (pkt->hdr.cmd == STATISTICS_NOTIFICATION)) {
534 iwl_rx_calc_noise(priv);
535 queue_work(priv->workqueue, &priv->run_time_calib_work);
536 }
537
538 iwl_leds_background(priv);
539
540 if (priv->cfg->ops->lib->temperature)
541 priv->cfg->ops->lib->temperature(priv, &pkt->u.stats);
542}
543EXPORT_SYMBOL(iwl_rx_statistics);
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c
index 0a279d15e058..13d53f3009d8 100644
--- a/drivers/net/wireless/iwlwifi/iwl4965-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c
@@ -1387,8 +1387,8 @@ static void iwl4965_setup_rx_handlers(struct iwl_priv *priv)
1387 * statistics request from the host as well as for the periodic 1387 * statistics request from the host as well as for the periodic
1388 * statistics notifications (after received beacons) from the uCode. 1388 * statistics notifications (after received beacons) from the uCode.
1389 */ 1389 */
1390 priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl4965_hw_rx_statistics; 1390 priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl_rx_statistics;
1391 priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl4965_hw_rx_statistics; 1391 priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl_rx_statistics;
1392 1392
1393 iwl_setup_rx_scan_handlers(priv); 1393 iwl_setup_rx_scan_handlers(priv);
1394 1394
@@ -4130,7 +4130,7 @@ static ssize_t show_statistics(struct device *d,
4130 struct device_attribute *attr, char *buf) 4130 struct device_attribute *attr, char *buf)
4131{ 4131{
4132 struct iwl_priv *priv = dev_get_drvdata(d); 4132 struct iwl_priv *priv = dev_get_drvdata(d);
4133 u32 size = sizeof(struct iwl4965_notif_statistics); 4133 u32 size = sizeof(struct iwl_notif_statistics);
4134 u32 len = 0, ofs = 0; 4134 u32 len = 0, ofs = 0;
4135 u8 *data = (u8 *) & priv->statistics; 4135 u8 *data = (u8 *) & priv->statistics;
4136 int rc = 0; 4136 int rc = 0;