aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi
diff options
context:
space:
mode:
authorWey-Yi Guy <wey-yi.w.guy@intel.com>2009-05-21 16:44:23 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-05-22 14:06:03 -0400
commit62161aefa403a3f8d603b061f5688cf00928a2cc (patch)
treee4b6a51b9d25b2e068e299a972adb8b8fdd1367f /drivers/net/wireless/iwlwifi
parent2681b20ba2a255ea20a168c0ebe519c40b55e57e (diff)
iwlwifi: Temperature sensor voltage reading for 5150
The temperature measurement by uCode for 5150 and 5000 are different CSR_HW_REV_TYPE_5150: temperature sensor output voltage CSR_HW_REV_TYPE_5000: temperature in Celsius temperature related operation for 5150 is measured by temperature sensor output voltage; additional conversion is required for set and store the temperature. To make sure support different HW design; implement _ops method for temperature related functions (temperature reading and set ct kill threshold) Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com> Signed-off-by: Reinette Chatre <reinette.chatre@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c14
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000-hw.h12
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c108
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h28
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rx.c4
5 files changed, 131 insertions, 35 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index a98ff4ead720..97131e63397e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -788,6 +788,12 @@ static struct iwl_sensitivity_ranges iwl4965_sensitivity = {
788 .nrg_th_ofdm = 100, 788 .nrg_th_ofdm = 100,
789}; 789};
790 790
791static void iwl4965_set_ct_threshold(struct iwl_priv *priv)
792{
793 /* want Kelvin */
794 priv->hw_params.ct_kill_threshold = CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD);
795}
796
791/** 797/**
792 * iwl4965_hw_set_hw_params 798 * iwl4965_hw_set_hw_params
793 * 799 *
@@ -822,7 +828,8 @@ static int iwl4965_hw_set_hw_params(struct iwl_priv *priv)
822 priv->hw_params.rx_chains_num = 2; 828 priv->hw_params.rx_chains_num = 2;
823 priv->hw_params.valid_tx_ant = ANT_A | ANT_B; 829 priv->hw_params.valid_tx_ant = ANT_A | ANT_B;
824 priv->hw_params.valid_rx_ant = ANT_A | ANT_B; 830 priv->hw_params.valid_rx_ant = ANT_A | ANT_B;
825 priv->hw_params.ct_kill_threshold = CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD); 831 if (priv->cfg->ops->lib->temp_ops.set_ct_kill)
832 priv->cfg->ops->lib->temp_ops.set_ct_kill(priv);
826 833
827 priv->hw_params.sens = &iwl4965_sensitivity; 834 priv->hw_params.sens = &iwl4965_sensitivity;
828 835
@@ -2331,9 +2338,12 @@ static struct iwl_lib_ops iwl4965_lib = {
2331 }, 2338 },
2332 .send_tx_power = iwl4965_send_tx_power, 2339 .send_tx_power = iwl4965_send_tx_power,
2333 .update_chain_flags = iwl_update_chain_flags, 2340 .update_chain_flags = iwl_update_chain_flags,
2334 .temperature = iwl4965_temperature_calib,
2335 .post_associate = iwl_post_associate, 2341 .post_associate = iwl_post_associate,
2336 .config_ap = iwl_config_ap, 2342 .config_ap = iwl_config_ap,
2343 .temp_ops = {
2344 .temperature = iwl4965_temperature_calib,
2345 .set_ct_kill = iwl4965_set_ct_threshold,
2346 },
2337}; 2347};
2338 2348
2339static struct iwl_ops iwl4965_ops = { 2349static struct iwl_ops iwl4965_ops = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
index 15cac70e36e2..4ef6804a455a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
@@ -87,6 +87,18 @@
87#define IWL50_NUM_AMPDU_QUEUES 10 87#define IWL50_NUM_AMPDU_QUEUES 10
88#define IWL50_FIRST_AMPDU_QUEUE 10 88#define IWL50_FIRST_AMPDU_QUEUE 10
89 89
90/* 5150 only */
91#define IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF (-5)
92
93static inline s32 iwl_temp_calib_to_offset(struct iwl_priv *priv)
94{
95 u16 *temp_calib = (u16 *)iwl_eeprom_query_addr(priv,
96 EEPROM_5000_TEMPERATURE);
97 /* offset = temperature - voltage / coef */
98 s32 offset = (s32)(temp_calib[0] - temp_calib[1] / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF);
99 return offset;
100}
101
90/* Fixed (non-configurable) rx data from phy */ 102/* Fixed (non-configurable) rx data from phy */
91 103
92/** 104/**
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index d731a836e6c8..e61b67d0a18b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -434,15 +434,19 @@ static const u8 *iwl5000_eeprom_query_addr(const struct iwl_priv *priv,
434 return &priv->eeprom[address]; 434 return &priv->eeprom[address];
435} 435}
436 436
437static s32 iwl5150_get_ct_threshold(struct iwl_priv *priv) 437static void iwl5150_set_ct_threshold(struct iwl_priv *priv)
438{ 438{
439 const s32 volt2temp_coef = -5; 439 const s32 volt2temp_coef = IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF;
440 u16 *temp_calib = (u16 *)iwl_eeprom_query_addr(priv, 440 s32 threshold = (s32)CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD) -
441 EEPROM_5000_TEMPERATURE); 441 iwl_temp_calib_to_offset(priv);
442 /* offset = temperate - voltage / coef */ 442
443 s32 offset = temp_calib[0] - temp_calib[1] / volt2temp_coef; 443 priv->hw_params.ct_kill_threshold = threshold * volt2temp_coef;
444 s32 threshold = (s32)CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD) - offset; 444}
445 return threshold * volt2temp_coef; 445
446static void iwl5000_set_ct_threshold(struct iwl_priv *priv)
447{
448 /* want Celsius */
449 priv->hw_params.ct_kill_threshold = CT_KILL_THRESHOLD;
446} 450}
447 451
448/* 452/*
@@ -868,17 +872,8 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
868 priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant; 872 priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant;
869 priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant; 873 priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant;
870 874
871 switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) { 875 if (priv->cfg->ops->lib->temp_ops.set_ct_kill)
872 case CSR_HW_REV_TYPE_5150: 876 priv->cfg->ops->lib->temp_ops.set_ct_kill(priv);
873 /* 5150 wants in Kelvin */
874 priv->hw_params.ct_kill_threshold =
875 iwl5150_get_ct_threshold(priv);
876 break;
877 default:
878 /* all others want Celsius */
879 priv->hw_params.ct_kill_threshold = CT_KILL_THRESHOLD;
880 break;
881 }
882 877
883 /* Set initial calibration set */ 878 /* Set initial calibration set */
884 switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) { 879 switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {
@@ -900,7 +895,6 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
900 break; 895 break;
901 } 896 }
902 897
903
904 return 0; 898 return 0;
905} 899}
906 900
@@ -1434,6 +1428,17 @@ static void iwl5000_temperature(struct iwl_priv *priv)
1434 priv->temperature = le32_to_cpu(priv->statistics.general.temperature); 1428 priv->temperature = le32_to_cpu(priv->statistics.general.temperature);
1435} 1429}
1436 1430
1431static void iwl5150_temperature(struct iwl_priv *priv)
1432{
1433 u32 vt = 0;
1434 s32 offset = iwl_temp_calib_to_offset(priv);
1435
1436 vt = le32_to_cpu(priv->statistics.general.temperature);
1437 vt = vt / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF + offset;
1438 /* now vt hold the temperature in Kelvin */
1439 priv->temperature = KELVIN_TO_CELSIUS(vt);
1440}
1441
1437/* Calc max signal level (dBm) among 3 possible receivers */ 1442/* Calc max signal level (dBm) among 3 possible receivers */
1438int iwl5000_calc_rssi(struct iwl_priv *priv, 1443int iwl5000_calc_rssi(struct iwl_priv *priv,
1439 struct iwl_rx_phy_res *rx_resp) 1444 struct iwl_rx_phy_res *rx_resp)
@@ -1511,7 +1516,6 @@ struct iwl_lib_ops iwl5000_lib = {
1511 .init_alive_start = iwl5000_init_alive_start, 1516 .init_alive_start = iwl5000_init_alive_start,
1512 .alive_notify = iwl5000_alive_notify, 1517 .alive_notify = iwl5000_alive_notify,
1513 .send_tx_power = iwl5000_send_tx_power, 1518 .send_tx_power = iwl5000_send_tx_power,
1514 .temperature = iwl5000_temperature,
1515 .update_chain_flags = iwl_update_chain_flags, 1519 .update_chain_flags = iwl_update_chain_flags,
1516 .apm_ops = { 1520 .apm_ops = {
1517 .init = iwl5000_apm_init, 1521 .init = iwl5000_apm_init,
@@ -1538,6 +1542,59 @@ struct iwl_lib_ops iwl5000_lib = {
1538 }, 1542 },
1539 .post_associate = iwl_post_associate, 1543 .post_associate = iwl_post_associate,
1540 .config_ap = iwl_config_ap, 1544 .config_ap = iwl_config_ap,
1545 .temp_ops = {
1546 .temperature = iwl5000_temperature,
1547 .set_ct_kill = iwl5000_set_ct_threshold,
1548 },
1549};
1550
1551static struct iwl_lib_ops iwl5150_lib = {
1552 .set_hw_params = iwl5000_hw_set_hw_params,
1553 .txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl,
1554 .txq_inval_byte_cnt_tbl = iwl5000_txq_inval_byte_cnt_tbl,
1555 .txq_set_sched = iwl5000_txq_set_sched,
1556 .txq_agg_enable = iwl5000_txq_agg_enable,
1557 .txq_agg_disable = iwl5000_txq_agg_disable,
1558 .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd,
1559 .txq_free_tfd = iwl_hw_txq_free_tfd,
1560 .txq_init = iwl_hw_tx_queue_init,
1561 .rx_handler_setup = iwl5000_rx_handler_setup,
1562 .setup_deferred_work = iwl5000_setup_deferred_work,
1563 .is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr,
1564 .load_ucode = iwl5000_load_ucode,
1565 .init_alive_start = iwl5000_init_alive_start,
1566 .alive_notify = iwl5000_alive_notify,
1567 .send_tx_power = iwl5000_send_tx_power,
1568 .update_chain_flags = iwl_update_chain_flags,
1569 .apm_ops = {
1570 .init = iwl5000_apm_init,
1571 .reset = iwl5000_apm_reset,
1572 .stop = iwl5000_apm_stop,
1573 .config = iwl5000_nic_config,
1574 .set_pwr_src = iwl_set_pwr_src,
1575 },
1576 .eeprom_ops = {
1577 .regulatory_bands = {
1578 EEPROM_5000_REG_BAND_1_CHANNELS,
1579 EEPROM_5000_REG_BAND_2_CHANNELS,
1580 EEPROM_5000_REG_BAND_3_CHANNELS,
1581 EEPROM_5000_REG_BAND_4_CHANNELS,
1582 EEPROM_5000_REG_BAND_5_CHANNELS,
1583 EEPROM_5000_REG_BAND_24_FAT_CHANNELS,
1584 EEPROM_5000_REG_BAND_52_FAT_CHANNELS
1585 },
1586 .verify_signature = iwlcore_eeprom_verify_signature,
1587 .acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
1588 .release_semaphore = iwlcore_eeprom_release_semaphore,
1589 .calib_version = iwl5000_eeprom_calib_version,
1590 .query_addr = iwl5000_eeprom_query_addr,
1591 },
1592 .post_associate = iwl_post_associate,
1593 .config_ap = iwl_config_ap,
1594 .temp_ops = {
1595 .temperature = iwl5150_temperature,
1596 .set_ct_kill = iwl5150_set_ct_threshold,
1597 },
1541}; 1598};
1542 1599
1543struct iwl_ops iwl5000_ops = { 1600struct iwl_ops iwl5000_ops = {
@@ -1547,6 +1604,13 @@ struct iwl_ops iwl5000_ops = {
1547 .smgmt = &iwl5000_station_mgmt, 1604 .smgmt = &iwl5000_station_mgmt,
1548}; 1605};
1549 1606
1607static struct iwl_ops iwl5150_ops = {
1608 .lib = &iwl5150_lib,
1609 .hcmd = &iwl5000_hcmd,
1610 .utils = &iwl5000_hcmd_utils,
1611 .smgmt = &iwl5000_station_mgmt,
1612};
1613
1550struct iwl_mod_params iwl50_mod_params = { 1614struct iwl_mod_params iwl50_mod_params = {
1551 .num_of_queues = IWL50_NUM_QUEUES, 1615 .num_of_queues = IWL50_NUM_QUEUES,
1552 .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES, 1616 .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES,
@@ -1642,7 +1706,7 @@ struct iwl_cfg iwl5150_agn_cfg = {
1642 .ucode_api_max = IWL5150_UCODE_API_MAX, 1706 .ucode_api_max = IWL5150_UCODE_API_MAX,
1643 .ucode_api_min = IWL5150_UCODE_API_MIN, 1707 .ucode_api_min = IWL5150_UCODE_API_MIN,
1644 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, 1708 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
1645 .ops = &iwl5000_ops, 1709 .ops = &iwl5150_ops,
1646 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, 1710 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
1647 .eeprom_ver = EEPROM_5050_EEPROM_VERSION, 1711 .eeprom_ver = EEPROM_5050_EEPROM_VERSION,
1648 .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, 1712 .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index f3544ea559a2..a0ed4156e25d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -112,6 +112,19 @@ struct iwl_hcmd_utils_ops {
112 struct iwl_rx_phy_res *rx_resp); 112 struct iwl_rx_phy_res *rx_resp);
113}; 113};
114 114
115struct iwl_apm_ops {
116 int (*init)(struct iwl_priv *priv);
117 int (*reset)(struct iwl_priv *priv);
118 void (*stop)(struct iwl_priv *priv);
119 void (*config)(struct iwl_priv *priv);
120 int (*set_pwr_src)(struct iwl_priv *priv, enum iwl_pwr_src src);
121};
122
123struct iwl_temp_ops {
124 void (*temperature)(struct iwl_priv *priv);
125 void (*set_ct_kill)(struct iwl_priv *priv);
126};
127
115struct iwl_lib_ops { 128struct iwl_lib_ops {
116 /* set hw dependent parameters */ 129 /* set hw dependent parameters */
117 int (*set_hw_params)(struct iwl_priv *priv); 130 int (*set_hw_params)(struct iwl_priv *priv);
@@ -149,23 +162,20 @@ struct iwl_lib_ops {
149 int (*is_valid_rtc_data_addr)(u32 addr); 162 int (*is_valid_rtc_data_addr)(u32 addr);
150 /* 1st ucode load */ 163 /* 1st ucode load */
151 int (*load_ucode)(struct iwl_priv *priv); 164 int (*load_ucode)(struct iwl_priv *priv);
152 /* power management */ 165 /* power management */
153 struct { 166 struct iwl_apm_ops apm_ops;
154 int (*init)(struct iwl_priv *priv); 167
155 int (*reset)(struct iwl_priv *priv);
156 void (*stop)(struct iwl_priv *priv);
157 void (*config)(struct iwl_priv *priv);
158 int (*set_pwr_src)(struct iwl_priv *priv, enum iwl_pwr_src src);
159 } apm_ops;
160 /* power */ 168 /* power */
161 int (*send_tx_power) (struct iwl_priv *priv); 169 int (*send_tx_power) (struct iwl_priv *priv);
162 void (*update_chain_flags)(struct iwl_priv *priv); 170 void (*update_chain_flags)(struct iwl_priv *priv);
163 void (*temperature) (struct iwl_priv *priv);
164 void (*post_associate) (struct iwl_priv *priv); 171 void (*post_associate) (struct iwl_priv *priv);
165 void (*config_ap) (struct iwl_priv *priv); 172 void (*config_ap) (struct iwl_priv *priv);
166 173
167 /* eeprom operations (as defined in iwl-eeprom.h) */ 174 /* eeprom operations (as defined in iwl-eeprom.h) */
168 struct iwl_eeprom_ops eeprom_ops; 175 struct iwl_eeprom_ops eeprom_ops;
176
177 /* temperature */
178 struct iwl_temp_ops temp_ops;
169}; 179};
170 180
171struct iwl_ops { 181struct iwl_ops {
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index fae84262efb6..73739cfd8047 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -582,8 +582,8 @@ void iwl_rx_statistics(struct iwl_priv *priv,
582 582
583 iwl_leds_background(priv); 583 iwl_leds_background(priv);
584 584
585 if (priv->cfg->ops->lib->temperature && change) 585 if (priv->cfg->ops->lib->temp_ops.temperature && change)
586 priv->cfg->ops->lib->temperature(priv); 586 priv->cfg->ops->lib->temp_ops.temperature(priv);
587} 587}
588EXPORT_SYMBOL(iwl_rx_statistics); 588EXPORT_SYMBOL(iwl_rx_statistics);
589 589