diff options
author | Wey-Yi Guy <wey-yi.w.guy@intel.com> | 2009-05-21 16:44:23 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-05-22 14:06:03 -0400 |
commit | 62161aefa403a3f8d603b061f5688cf00928a2cc (patch) | |
tree | e4b6a51b9d25b2e068e299a972adb8b8fdd1367f /drivers/net/wireless | |
parent | 2681b20ba2a255ea20a168c0ebe519c40b55e57e (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')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-4965.c | 14 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-5000-hw.h | 12 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-5000.c | 108 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-core.h | 28 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-rx.c | 4 |
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 | ||
791 | static 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 | ||
2339 | static struct iwl_ops iwl4965_ops = { | 2349 | static 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 | |||
93 | static 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 | ||
437 | static s32 iwl5150_get_ct_threshold(struct iwl_priv *priv) | 437 | static 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 | |
446 | static 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 | ||
1431 | static 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 */ |
1438 | int iwl5000_calc_rssi(struct iwl_priv *priv, | 1443 | int 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 | |||
1551 | static 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 | ||
1543 | struct iwl_ops iwl5000_ops = { | 1600 | struct 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 | ||
1607 | static 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 | |||
1550 | struct iwl_mod_params iwl50_mod_params = { | 1614 | struct 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 | ||
115 | struct 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 | |||
123 | struct iwl_temp_ops { | ||
124 | void (*temperature)(struct iwl_priv *priv); | ||
125 | void (*set_ct_kill)(struct iwl_priv *priv); | ||
126 | }; | ||
127 | |||
115 | struct iwl_lib_ops { | 128 | struct 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 | ||
171 | struct iwl_ops { | 181 | struct 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 | } |
588 | EXPORT_SYMBOL(iwl_rx_statistics); | 588 | EXPORT_SYMBOL(iwl_rx_statistics); |
589 | 589 | ||