Commit f2d0d0e2 authored by Wey-Yi Guy's avatar Wey-Yi Guy Committed by John W. Linville

iwlwifi: Adjust blink rate to compensate Clock difference

Adjust led blink rate to compensate on a MAC Clock difference on every
HW. Led blink rate analysis showed an average deviation of 0% on 3945,
5% on 4965 HW and 20% on 5000 series and up.
Need to compensate on the led on/off time per HW according to the
deviation to achieve the desired led frequency
The calculation is: (100-averageDeviation)/100 * blinkTime
For code efficiency the calculation will be:
    compensation = (100 - averageDeviation) * 64 / 100
    NewBlinkTime = (compensation * BlinkTime) / 64
Signed-off-by: default avatarWey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: default avatarReinette Chatre <reinette.chatre@intel.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent c812ee24
...@@ -164,5 +164,6 @@ struct iwl_cfg iwl1000_bgn_cfg = { ...@@ -164,5 +164,6 @@ struct iwl_cfg iwl1000_bgn_cfg = {
.max_ll_items = OTP_MAX_LL_ITEMS_1000, .max_ll_items = OTP_MAX_LL_ITEMS_1000,
.shadow_ram_support = false, .shadow_ram_support = false,
.ht_greenfield_support = true, .ht_greenfield_support = true,
.led_compensation = 51,
}; };
...@@ -2894,6 +2894,7 @@ static struct iwl_cfg iwl3945_bg_cfg = { ...@@ -2894,6 +2894,7 @@ static struct iwl_cfg iwl3945_bg_cfg = {
.mod_params = &iwl3945_mod_params, .mod_params = &iwl3945_mod_params,
.use_isr_legacy = true, .use_isr_legacy = true,
.ht_greenfield_support = false, .ht_greenfield_support = false,
.led_compensation = 64,
}; };
static struct iwl_cfg iwl3945_abg_cfg = { static struct iwl_cfg iwl3945_abg_cfg = {
...@@ -2908,6 +2909,7 @@ static struct iwl_cfg iwl3945_abg_cfg = { ...@@ -2908,6 +2909,7 @@ static struct iwl_cfg iwl3945_abg_cfg = {
.mod_params = &iwl3945_mod_params, .mod_params = &iwl3945_mod_params,
.use_isr_legacy = true, .use_isr_legacy = true,
.ht_greenfield_support = false, .ht_greenfield_support = false,
.led_compensation = 64,
}; };
struct pci_device_id iwl3945_hw_card_ids[] = { struct pci_device_id iwl3945_hw_card_ids[] = {
......
...@@ -2355,6 +2355,7 @@ struct iwl_cfg iwl4965_agn_cfg = { ...@@ -2355,6 +2355,7 @@ struct iwl_cfg iwl4965_agn_cfg = {
.use_isr_legacy = true, .use_isr_legacy = true,
.ht_greenfield_support = false, .ht_greenfield_support = false,
.broken_powersave = true, .broken_powersave = true,
.led_compensation = 61,
}; };
/* Module firmware */ /* Module firmware */
......
...@@ -1656,6 +1656,7 @@ struct iwl_cfg iwl5300_agn_cfg = { ...@@ -1656,6 +1656,7 @@ struct iwl_cfg iwl5300_agn_cfg = {
.valid_rx_ant = ANT_ABC, .valid_rx_ant = ANT_ABC,
.need_pll_cfg = true, .need_pll_cfg = true,
.ht_greenfield_support = true, .ht_greenfield_support = true,
.led_compensation = 51,
}; };
struct iwl_cfg iwl5100_bg_cfg = { struct iwl_cfg iwl5100_bg_cfg = {
...@@ -1673,6 +1674,7 @@ struct iwl_cfg iwl5100_bg_cfg = { ...@@ -1673,6 +1674,7 @@ struct iwl_cfg iwl5100_bg_cfg = {
.valid_rx_ant = ANT_AB, .valid_rx_ant = ANT_AB,
.need_pll_cfg = true, .need_pll_cfg = true,
.ht_greenfield_support = true, .ht_greenfield_support = true,
.led_compensation = 51,
}; };
struct iwl_cfg iwl5100_abg_cfg = { struct iwl_cfg iwl5100_abg_cfg = {
...@@ -1690,6 +1692,7 @@ struct iwl_cfg iwl5100_abg_cfg = { ...@@ -1690,6 +1692,7 @@ struct iwl_cfg iwl5100_abg_cfg = {
.valid_rx_ant = ANT_AB, .valid_rx_ant = ANT_AB,
.need_pll_cfg = true, .need_pll_cfg = true,
.ht_greenfield_support = true, .ht_greenfield_support = true,
.led_compensation = 51,
}; };
struct iwl_cfg iwl5100_agn_cfg = { struct iwl_cfg iwl5100_agn_cfg = {
...@@ -1707,6 +1710,7 @@ struct iwl_cfg iwl5100_agn_cfg = { ...@@ -1707,6 +1710,7 @@ struct iwl_cfg iwl5100_agn_cfg = {
.valid_rx_ant = ANT_AB, .valid_rx_ant = ANT_AB,
.need_pll_cfg = true, .need_pll_cfg = true,
.ht_greenfield_support = true, .ht_greenfield_support = true,
.led_compensation = 51,
}; };
struct iwl_cfg iwl5350_agn_cfg = { struct iwl_cfg iwl5350_agn_cfg = {
...@@ -1724,6 +1728,7 @@ struct iwl_cfg iwl5350_agn_cfg = { ...@@ -1724,6 +1728,7 @@ struct iwl_cfg iwl5350_agn_cfg = {
.valid_rx_ant = ANT_ABC, .valid_rx_ant = ANT_ABC,
.need_pll_cfg = true, .need_pll_cfg = true,
.ht_greenfield_support = true, .ht_greenfield_support = true,
.led_compensation = 51,
}; };
struct iwl_cfg iwl5150_agn_cfg = { struct iwl_cfg iwl5150_agn_cfg = {
...@@ -1741,6 +1746,7 @@ struct iwl_cfg iwl5150_agn_cfg = { ...@@ -1741,6 +1746,7 @@ struct iwl_cfg iwl5150_agn_cfg = {
.valid_rx_ant = ANT_AB, .valid_rx_ant = ANT_AB,
.need_pll_cfg = true, .need_pll_cfg = true,
.ht_greenfield_support = true, .ht_greenfield_support = true,
.led_compensation = 51,
}; };
MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX));
......
...@@ -258,6 +258,7 @@ struct iwl_cfg iwl6000h_2agn_cfg = { ...@@ -258,6 +258,7 @@ struct iwl_cfg iwl6000h_2agn_cfg = {
.max_ll_items = OTP_MAX_LL_ITEMS_6x00, .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
.shadow_ram_support = true, .shadow_ram_support = true,
.ht_greenfield_support = true, .ht_greenfield_support = true,
.led_compensation = 51,
}; };
/* /*
...@@ -281,6 +282,7 @@ struct iwl_cfg iwl6000i_2agn_cfg = { ...@@ -281,6 +282,7 @@ struct iwl_cfg iwl6000i_2agn_cfg = {
.max_ll_items = OTP_MAX_LL_ITEMS_6x00, .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
.shadow_ram_support = true, .shadow_ram_support = true,
.ht_greenfield_support = true, .ht_greenfield_support = true,
.led_compensation = 51,
}; };
struct iwl_cfg iwl6050_2agn_cfg = { struct iwl_cfg iwl6050_2agn_cfg = {
...@@ -301,6 +303,7 @@ struct iwl_cfg iwl6050_2agn_cfg = { ...@@ -301,6 +303,7 @@ struct iwl_cfg iwl6050_2agn_cfg = {
.max_ll_items = OTP_MAX_LL_ITEMS_6x00, .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
.shadow_ram_support = true, .shadow_ram_support = true,
.ht_greenfield_support = true, .ht_greenfield_support = true,
.led_compensation = 51,
}; };
struct iwl_cfg iwl6000_3agn_cfg = { struct iwl_cfg iwl6000_3agn_cfg = {
...@@ -321,6 +324,7 @@ struct iwl_cfg iwl6000_3agn_cfg = { ...@@ -321,6 +324,7 @@ struct iwl_cfg iwl6000_3agn_cfg = {
.max_ll_items = OTP_MAX_LL_ITEMS_6x00, .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
.shadow_ram_support = true, .shadow_ram_support = true,
.ht_greenfield_support = true, .ht_greenfield_support = true,
.led_compensation = 51,
}; };
struct iwl_cfg iwl6050_3agn_cfg = { struct iwl_cfg iwl6050_3agn_cfg = {
...@@ -341,6 +345,7 @@ struct iwl_cfg iwl6050_3agn_cfg = { ...@@ -341,6 +345,7 @@ struct iwl_cfg iwl6050_3agn_cfg = {
.max_ll_items = OTP_MAX_LL_ITEMS_6x00, .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
.shadow_ram_support = true, .shadow_ram_support = true,
.ht_greenfield_support = true, .ht_greenfield_support = true,
.led_compensation = 51,
}; };
MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX));
......
...@@ -213,6 +213,9 @@ struct iwl_mod_params { ...@@ -213,6 +213,9 @@ struct iwl_mod_params {
* @pa_type: used by 6000 series only to identify the type of Power Amplifier * @pa_type: used by 6000 series only to identify the type of Power Amplifier
* @max_ll_items: max number of OTP blocks * @max_ll_items: max number of OTP blocks
* @shadow_ram_support: shadow support for OTP memory * @shadow_ram_support: shadow support for OTP memory
* @led_compensation: compensate on the led on/off time per HW according
* to the deviation to achieve the desired led frequency.
* The detail algorithm is described in iwl-led.c
* *
* We enable the driver to be backward compatible wrt API version. The * We enable the driver to be backward compatible wrt API version. The
* driver specifies which APIs it supports (with @ucode_api_max being the * driver specifies which APIs it supports (with @ucode_api_max being the
...@@ -255,6 +258,7 @@ struct iwl_cfg { ...@@ -255,6 +258,7 @@ struct iwl_cfg {
const bool shadow_ram_support; const bool shadow_ram_support;
const bool ht_greenfield_support; const bool ht_greenfield_support;
const bool broken_powersave; const bool broken_powersave;
u16 led_compensation;
}; };
/*************************** /***************************
......
...@@ -78,6 +78,29 @@ static const struct { ...@@ -78,6 +78,29 @@ static const struct {
#define IWL_MAX_BLINK_TBL (ARRAY_SIZE(blink_tbl) - 1) /* exclude SOLID_ON */ #define IWL_MAX_BLINK_TBL (ARRAY_SIZE(blink_tbl) - 1) /* exclude SOLID_ON */
#define IWL_SOLID_BLINK_IDX (ARRAY_SIZE(blink_tbl) - 1) #define IWL_SOLID_BLINK_IDX (ARRAY_SIZE(blink_tbl) - 1)
/*
* Adjust led blink rate to compensate on a MAC Clock difference on every HW
* Led blink rate analysis showed an average deviation of 0% on 3945,
* 5% on 4965 HW and 20% on 5000 series and up.
* Need to compensate on the led on/off time per HW according to the deviation
* to achieve the desired led frequency
* The calculation is: (100-averageDeviation)/100 * blinkTime
* For code efficiency the calculation will be:
* compensation = (100 - averageDeviation) * 64 / 100
* NewBlinkTime = (compensation * BlinkTime) / 64
*/
static inline u8 iwl_blink_compensation(struct iwl_priv *priv,
u8 time, u16 compensation)
{
if (!compensation) {
IWL_ERR(priv, "undefined blink compensation: "
"use pre-defined blinking time\n");
return time;
}
return (u8)((time * compensation) >> 6);
}
/* [0-256] -> [0..8] FIXME: we need [0..10] */ /* [0-256] -> [0..8] FIXME: we need [0..10] */
static inline int iwl_brightness_to_idx(enum led_brightness brightness) static inline int iwl_brightness_to_idx(enum led_brightness brightness)
{ {
...@@ -114,8 +137,14 @@ static int iwl_led_pattern(struct iwl_priv *priv, int led_id, ...@@ -114,8 +137,14 @@ static int iwl_led_pattern(struct iwl_priv *priv, int led_id,
BUG_ON(idx > IWL_MAX_BLINK_TBL); BUG_ON(idx > IWL_MAX_BLINK_TBL);
led_cmd.on = blink_tbl[idx].on_time; IWL_DEBUG_LED(priv, "Led blink time compensation= %u\n",
led_cmd.off = blink_tbl[idx].off_time; priv->cfg->led_compensation);
led_cmd.on =
iwl_blink_compensation(priv, blink_tbl[idx].on_time,
priv->cfg->led_compensation);
led_cmd.off =
iwl_blink_compensation(priv, blink_tbl[idx].off_time,
priv->cfg->led_compensation);
return iwl_send_led_cmd(priv, &led_cmd); return iwl_send_led_cmd(priv, &led_cmd);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment