iwlwifi: move RX stats to core, and move temperature to handler
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Mon, 30 Jun 2008 09:23:07 +0000 (17:23 +0800)
committerJohn W. Linville <linville@tuxdriver.com>
Mon, 30 Jun 2008 21:37:39 +0000 (17:37 -0400)
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>
drivers/net/wireless/iwlwifi/iwl-4965.c
drivers/net/wireless/iwlwifi/iwl-5000.c
drivers/net/wireless/iwlwifi/iwl-calib.c
drivers/net/wireless/iwlwifi/iwl-calib.h
drivers/net/wireless/iwlwifi/iwl-commands.h
drivers/net/wireless/iwlwifi/iwl-core.h
drivers/net/wireless/iwlwifi/iwl-dev.h
drivers/net/wireless/iwlwifi/iwl-rx.c
drivers/net/wireless/iwlwifi/iwl4965-base.c

index ab5027345a012ccb609380e2dc44dfdb3045c8a8..1688803af5821c4c64b36fcc61ea7f9f84d819da 100644 (file)
@@ -555,8 +555,6 @@ out:
        return ret;
 }
 
-#define REG_RECALIB_PERIOD (60)
-
 /* Reset differential Rx gains in NIC to prepare for chain noise calibration.
  * Called after every association, but this runs only once!
  *  ... 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)
        return 1;
 }
 
-/* Calculate noise level, based on measurements during network silence just
- *   before arriving beacon.  This measurement can be done only if we know
- *   exactly when to expect beacons, therefore only when we're associated. */
-static void iwl4965_rx_calc_noise(struct iwl_priv *priv)
+static void iwl4965_temperature_calib(struct iwl_priv *priv,
+                                     struct iwl_notif_statistics *stats)
 {
-       struct statistics_rx_non_phy *rx_info
-                               = &(priv->statistics.rx.general);
-       int num_active_rx = 0;
-       int total_silence = 0;
-       int bcn_silence_a =
-               le32_to_cpu(rx_info->beacon_silence_rssi_a) & IN_BAND_FILTER;
-       int bcn_silence_b =
-               le32_to_cpu(rx_info->beacon_silence_rssi_b) & IN_BAND_FILTER;
-       int bcn_silence_c =
-               le32_to_cpu(rx_info->beacon_silence_rssi_c) & IN_BAND_FILTER;
-
-       if (bcn_silence_a) {
-               total_silence += bcn_silence_a;
-               num_active_rx++;
-       }
-       if (bcn_silence_b) {
-               total_silence += bcn_silence_b;
-               num_active_rx++;
-       }
-       if (bcn_silence_c) {
-               total_silence += bcn_silence_c;
-               num_active_rx++;
-       }
-
-       /* Average among active antennas */
-       if (num_active_rx)
-               priv->last_rx_noise = (total_silence / num_active_rx) - 107;
-       else
-               priv->last_rx_noise = IWL_NOISE_MEAS_NOT_AVAILABLE;
-
-       IWL_DEBUG_CALIB("inband silence a %u, b %u, c %u, dBm %d\n",
-                       bcn_silence_a, bcn_silence_b, bcn_silence_c,
-                       priv->last_rx_noise);
-}
-
-void iwl4965_hw_rx_statistics(struct iwl_priv *priv,
-                             struct iwl_rx_mem_buffer *rxb)
-{
-       struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
-       int change;
        s32 temp;
-
-       IWL_DEBUG_RX("Statistics notification received (%d vs %d).\n",
-                    (int)sizeof(priv->statistics), pkt->len);
-
-       change = ((priv->statistics.general.temperature !=
-                  pkt->u.stats.general.temperature) ||
+       int change = ((priv->statistics.general.temperature !=
+                  stats->general.temperature) ||
                  ((priv->statistics.flag &
                    STATISTICS_REPLY_FLG_FAT_MODE_MSK) !=
-                  (pkt->u.stats.flag & STATISTICS_REPLY_FLG_FAT_MODE_MSK)));
-
-       memcpy(&priv->statistics, &pkt->u.stats, sizeof(priv->statistics));
-
-       set_bit(STATUS_STATISTICS, &priv->status);
-
-       /* Reschedule the statistics timer to occur in
-        * REG_RECALIB_PERIOD seconds to ensure we get a
-        * thermal update even if the uCode doesn't give
-        * us one */
-       mod_timer(&priv->statistics_periodic, jiffies +
-                 msecs_to_jiffies(REG_RECALIB_PERIOD * 1000));
-
-       if (unlikely(!test_bit(STATUS_SCANNING, &priv->status)) &&
-           (pkt->hdr.cmd == STATISTICS_NOTIFICATION)) {
-               iwl4965_rx_calc_noise(priv);
-               queue_work(priv->workqueue, &priv->run_time_calib_work);
-       }
-
-       iwl_leds_background(priv);
+                  (stats->flag & STATISTICS_REPLY_FLG_FAT_MODE_MSK)));
 
        /* If the hardware hasn't reported a change in
         * temperature then don't bother computing a
@@ -3391,6 +3324,7 @@ static struct iwl_lib_ops iwl4965_lib = {
        .set_power = iwl4965_set_power,
        .send_tx_power  = iwl4965_send_tx_power,
        .update_chain_flags = iwl4965_update_chain_flags,
+       .temperature = iwl4965_temperature_calib,
 };
 
 static struct iwl_ops iwl4965_ops = {
index 2b48f1b1914070985c4789f0b0d8fe5575712661..5abfd56e9bb4e3cde3d5869e56731e5e90a0fb46 100644 (file)
@@ -1433,6 +1433,12 @@ static int  iwl5000_send_tx_power(struct iwl_priv *priv)
                                       NULL);
 }
 
+static void iwl5000_temperature(struct iwl_priv *priv,
+                               struct iwl_notif_statistics *stats)
+{
+       /* store temperature from statistics (in Celsius) */
+       priv->temperature = le32_to_cpu(stats->general.temperature);
+}
 
 static struct iwl_hcmd_ops iwl5000_hcmd = {
        .rxon_assoc = iwl5000_send_rxon_assoc,
@@ -1462,6 +1468,7 @@ static struct iwl_lib_ops iwl5000_lib = {
        .init_alive_start = iwl5000_init_alive_start,
        .alive_notify = iwl5000_alive_notify,
        .send_tx_power = iwl5000_send_tx_power,
+       .temperature = iwl5000_temperature,
        .apm_ops = {
                .init = iwl5000_apm_init,
                .reset = iwl5000_apm_reset,
index 48f58000b64b1d09bdfd28c2654786314c7b319d..ef49440bd7f6ac71c9fbb3a1f79316c0148ede2b 100644 (file)
@@ -470,7 +470,7 @@ void iwl_init_sensitivity(struct iwl_priv *priv)
 EXPORT_SYMBOL(iwl_init_sensitivity);
 
 void iwl_sensitivity_calibration(struct iwl_priv *priv,
-                                   struct iwl4965_notif_statistics *resp)
+                                   struct iwl_notif_statistics *resp)
 {
        u32 rx_enable_time;
        u32 fa_cck;
@@ -584,7 +584,7 @@ EXPORT_SYMBOL(iwl_sensitivity_calibration);
  * 2)  Differential rx gain settings to balance the 3 receivers.
  */
 void iwl_chain_noise_calibration(struct iwl_priv *priv,
-                             struct iwl4965_notif_statistics *stat_resp)
+                                struct iwl_notif_statistics *stat_resp)
 {
        struct iwl_chain_noise_data *data = NULL;
 
index 5524a29e22d8f48ae10b82b6e70f5dac083493b1..94c8e316382a4a9140dae3ede569dc34b770d29d 100644 (file)
@@ -67,9 +67,9 @@
 #include "iwl-commands.h"
 
 void iwl_chain_noise_calibration(struct iwl_priv *priv,
-                               struct iwl4965_notif_statistics *stat_resp);
+                               struct iwl_notif_statistics *stat_resp);
 void iwl_sensitivity_calibration(struct iwl_priv *priv,
-                               struct iwl4965_notif_statistics *resp);
+                               struct iwl_notif_statistics *resp);
 
 void iwl_init_sensitivity(struct iwl_priv *priv);
 void iwl_reset_run_time_calib(struct iwl_priv *priv);
index 6957b2208240968cfdb20637fdb0944a87edc839..9f8446c5a1bc4ee2af4fae74b52b6b777a111214 100644 (file)
@@ -2506,7 +2506,7 @@ struct statistics_general {
  */
 #define IWL_STATS_CONF_CLEAR_STATS __constant_cpu_to_le32(0x1) /* see above */
 #define IWL_STATS_CONF_DISABLE_NOTIF __constant_cpu_to_le32(0x2)/* see above */
-struct iwl4965_statistics_cmd {
+struct iwl_statistics_cmd {
        __le32 configuration_flags;     /* IWL_STATS_CONF_* */
 } __attribute__ ((packed));
 
@@ -2527,7 +2527,7 @@ struct iwl4965_statistics_cmd {
  */
 #define STATISTICS_REPLY_FLG_BAND_24G_MSK         __constant_cpu_to_le32(0x2)
 #define STATISTICS_REPLY_FLG_FAT_MODE_MSK         __constant_cpu_to_le32(0x8)
-struct iwl4965_notif_statistics {
+struct iwl_notif_statistics {
        __le32 flag;
        struct statistics_rx rx;
        struct statistics_tx tx;
@@ -3000,7 +3000,7 @@ struct iwl_rx_packet {
                struct iwl_rem_sta_resp rem_sta;
                struct iwl4965_sleep_notification sleep_notif;
                struct iwl4965_spectrum_resp spectrum;
-               struct iwl4965_notif_statistics stats;
+               struct iwl_notif_statistics stats;
                struct iwl4965_compressed_ba_resp compressed_ba;
                struct iwl4965_missed_beacon_notif missed_beacon;
                struct iwl5000_calibration calib;
index 2838093b44595930013b987c5934e4e7a1160627..375afe15b54b7e5b5a8349590ae78965f05165f2 100644 (file)
@@ -140,6 +140,8 @@ struct iwl_lib_ops {
        int (*set_power)(struct iwl_priv *priv, void *cmd);
        int (*send_tx_power) (struct iwl_priv *priv);
        void (*update_chain_flags)(struct iwl_priv *priv);
+       void (*temperature) (struct iwl_priv *priv,
+               struct iwl_notif_statistics *stats);
        /* eeprom operations (as defined in iwl-eeprom.h) */
        struct iwl_eeprom_ops eeprom_ops;
 };
@@ -218,6 +220,8 @@ int iwl_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index);
 /* Handlers */
 void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
                               struct iwl_rx_mem_buffer *rxb);
+void iwl_rx_statistics(struct iwl_priv *priv,
+                             struct iwl_rx_mem_buffer *rxb);
 
 /* TX helpers */
 
index 81ff4c2c6a5abb30aa7b031c981774c1c16e59d1..fd008ab63bd9351d725c67094b651e8b25df375a 100644 (file)
@@ -624,8 +624,6 @@ extern int iwl_rxq_stop(struct iwl_priv *priv);
 extern void iwl_txq_ctx_stop(struct iwl_priv *priv);
 extern unsigned int iwl4965_hw_get_beacon_cmd(struct iwl_priv *priv,
                                 struct iwl_frame *frame, u8 rate);
-extern void iwl4965_hw_rx_statistics(struct iwl_priv *priv,
-                                struct iwl_rx_mem_buffer *rxb);
 extern void iwl4965_disable_events(struct iwl_priv *priv);
 extern void iwl4965_rx_reply_rx(struct iwl_priv *priv,
                                struct iwl_rx_mem_buffer *rxb);
@@ -994,7 +992,7 @@ struct iwl_priv {
 
        struct iwl_power_mgr power_data;
 
-       struct iwl4965_notif_statistics statistics;
+       struct iwl_notif_statistics statistics;
        unsigned long last_statistics_time;
 
        /* context information */
index c24844802a885e2d28644df2cc96a824da8348e5..b3ca1375c01aecdc80a64b94e97bac95d41c2e4b 100644 (file)
@@ -466,3 +466,78 @@ void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
        }
 }
 EXPORT_SYMBOL(iwl_rx_missed_beacon_notif);
+
+
+/* Calculate noise level, based on measurements during network silence just
+ *   before arriving beacon.  This measurement can be done only if we know
+ *   exactly when to expect beacons, therefore only when we're associated. */
+static void iwl_rx_calc_noise(struct iwl_priv *priv)
+{
+       struct statistics_rx_non_phy *rx_info
+                               = &(priv->statistics.rx.general);
+       int num_active_rx = 0;
+       int total_silence = 0;
+       int bcn_silence_a =
+               le32_to_cpu(rx_info->beacon_silence_rssi_a) & IN_BAND_FILTER;
+       int bcn_silence_b =
+               le32_to_cpu(rx_info->beacon_silence_rssi_b) & IN_BAND_FILTER;
+       int bcn_silence_c =
+               le32_to_cpu(rx_info->beacon_silence_rssi_c) & IN_BAND_FILTER;
+
+       if (bcn_silence_a) {
+               total_silence += bcn_silence_a;
+               num_active_rx++;
+       }
+       if (bcn_silence_b) {
+               total_silence += bcn_silence_b;
+               num_active_rx++;
+       }
+       if (bcn_silence_c) {
+               total_silence += bcn_silence_c;
+               num_active_rx++;
+       }
+
+       /* Average among active antennas */
+       if (num_active_rx)
+               priv->last_rx_noise = (total_silence / num_active_rx) - 107;
+       else
+               priv->last_rx_noise = IWL_NOISE_MEAS_NOT_AVAILABLE;
+
+       IWL_DEBUG_CALIB("inband silence a %u, b %u, c %u, dBm %d\n",
+                       bcn_silence_a, bcn_silence_b, bcn_silence_c,
+                       priv->last_rx_noise);
+}
+
+#define REG_RECALIB_PERIOD (60)
+
+void iwl_rx_statistics(struct iwl_priv *priv,
+                             struct iwl_rx_mem_buffer *rxb)
+{
+       struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
+
+       IWL_DEBUG_RX("Statistics notification received (%d vs %d).\n",
+                    (int)sizeof(priv->statistics), pkt->len);
+
+       memcpy(&priv->statistics, &pkt->u.stats, sizeof(priv->statistics));
+
+       set_bit(STATUS_STATISTICS, &priv->status);
+
+       /* Reschedule the statistics timer to occur in
+        * REG_RECALIB_PERIOD seconds to ensure we get a
+        * thermal update even if the uCode doesn't give
+        * us one */
+       mod_timer(&priv->statistics_periodic, jiffies +
+                 msecs_to_jiffies(REG_RECALIB_PERIOD * 1000));
+
+       if (unlikely(!test_bit(STATUS_SCANNING, &priv->status)) &&
+           (pkt->hdr.cmd == STATISTICS_NOTIFICATION)) {
+               iwl_rx_calc_noise(priv);
+               queue_work(priv->workqueue, &priv->run_time_calib_work);
+       }
+
+       iwl_leds_background(priv);
+
+       if (priv->cfg->ops->lib->temperature)
+               priv->cfg->ops->lib->temperature(priv, &pkt->u.stats);
+}
+EXPORT_SYMBOL(iwl_rx_statistics);
index 0a279d15e058a55232eb932b8cc42b431d705ae2..13d53f3009d83f264cc3420b1cdab0c375b977a4 100644 (file)
@@ -1387,8 +1387,8 @@ static void iwl4965_setup_rx_handlers(struct iwl_priv *priv)
         * statistics request from the host as well as for the periodic
         * statistics notifications (after received beacons) from the uCode.
         */
-       priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl4965_hw_rx_statistics;
-       priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl4965_hw_rx_statistics;
+       priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl_rx_statistics;
+       priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl_rx_statistics;
 
        iwl_setup_rx_scan_handlers(priv);
 
@@ -4130,7 +4130,7 @@ static ssize_t show_statistics(struct device *d,
                               struct device_attribute *attr, char *buf)
 {
        struct iwl_priv *priv = dev_get_drvdata(d);
-       u32 size = sizeof(struct iwl4965_notif_statistics);
+       u32 size = sizeof(struct iwl_notif_statistics);
        u32 len = 0, ofs = 0;
        u8 *data = (u8 *) & priv->statistics;
        int rc = 0;