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.  */
        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
        .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 = {
 
                                       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,
        .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,
 
 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;
  * 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;
 
 
 #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);
 
  */
 #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));
 
  */
 #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;
                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;
 
        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;
 };
 /* 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 */
 
 
 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);
 
        struct iwl_power_mgr power_data;
 
-       struct iwl4965_notif_statistics statistics;
+       struct iwl_notif_statistics statistics;
        unsigned long last_statistics_time;
 
        /* context information */
 
        }
 }
 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);
 
         * 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);
 
                               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;