diff options
author | Wey-Yi Guy <wey-yi.w.guy@intel.com> | 2011-01-21 18:26:39 -0500 |
---|---|---|
committer | Wey-Yi Guy <wey-yi.w.guy@intel.com> | 2011-01-21 18:26:39 -0500 |
commit | 5ed540aecc2aae92d5c97b9a9306a5bf88ad5574 (patch) | |
tree | 0b19e77d0f5ed9ac4d88ab733440d7ea6348ea4e /drivers/net/wireless | |
parent | 4a4fdf2e0b9e3534f6ec4f3e7077470bd66924ab (diff) |
iwlwifi: use mac80211 throughput trigger
Instead of keeping track of LED blink speed
in the driver, use the new mac80211 trigger
and link it up with an LED classdev that we
now register. This also allows users more
flexibility in how they want to have the LED
blink or not.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r-- | drivers/net/wireless/iwlwifi/Kconfig | 4 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-3945-led.c | 27 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn-led.c | 14 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn-led.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn.c | 10 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-core.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-core.h | 14 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-debugfs.c | 25 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-dev.h | 18 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-led.c | 201 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-led.h | 16 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-legacy.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl3945-base.c | 8 |
14 files changed, 106 insertions, 240 deletions
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig index ed424574160e..8994d3072715 100644 --- a/drivers/net/wireless/iwlwifi/Kconfig +++ b/drivers/net/wireless/iwlwifi/Kconfig | |||
@@ -2,6 +2,10 @@ config IWLWIFI | |||
2 | tristate "Intel Wireless Wifi" | 2 | tristate "Intel Wireless Wifi" |
3 | depends on PCI && MAC80211 | 3 | depends on PCI && MAC80211 |
4 | select FW_LOADER | 4 | select FW_LOADER |
5 | select NEW_LEDS | ||
6 | select LEDS_CLASS | ||
7 | select LEDS_TRIGGERS | ||
8 | select MAC80211_LEDS | ||
5 | 9 | ||
6 | menu "Debugging Options" | 10 | menu "Debugging Options" |
7 | depends on IWLWIFI | 11 | depends on IWLWIFI |
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-led.c b/drivers/net/wireless/iwlwifi/iwl-3945-led.c index abe2b739c4dc..dc7c3a4167a9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945-led.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945-led.c | |||
@@ -59,33 +59,6 @@ static int iwl3945_send_led_cmd(struct iwl_priv *priv, | |||
59 | return iwl_send_cmd(priv, &cmd); | 59 | return iwl_send_cmd(priv, &cmd); |
60 | } | 60 | } |
61 | 61 | ||
62 | /* Set led on command */ | ||
63 | static int iwl3945_led_on(struct iwl_priv *priv) | ||
64 | { | ||
65 | struct iwl_led_cmd led_cmd = { | ||
66 | .id = IWL_LED_LINK, | ||
67 | .on = IWL_LED_SOLID, | ||
68 | .off = 0, | ||
69 | .interval = IWL_DEF_LED_INTRVL | ||
70 | }; | ||
71 | return iwl3945_send_led_cmd(priv, &led_cmd); | ||
72 | } | ||
73 | |||
74 | /* Set led off command */ | ||
75 | static int iwl3945_led_off(struct iwl_priv *priv) | ||
76 | { | ||
77 | struct iwl_led_cmd led_cmd = { | ||
78 | .id = IWL_LED_LINK, | ||
79 | .on = 0, | ||
80 | .off = 0, | ||
81 | .interval = IWL_DEF_LED_INTRVL | ||
82 | }; | ||
83 | IWL_DEBUG_LED(priv, "led off\n"); | ||
84 | return iwl3945_send_led_cmd(priv, &led_cmd); | ||
85 | } | ||
86 | |||
87 | const struct iwl_led_ops iwl3945_led_ops = { | 62 | const struct iwl_led_ops iwl3945_led_ops = { |
88 | .cmd = iwl3945_send_led_cmd, | 63 | .cmd = iwl3945_send_led_cmd, |
89 | .on = iwl3945_led_on, | ||
90 | .off = iwl3945_led_off, | ||
91 | }; | 64 | }; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-led.c b/drivers/net/wireless/iwlwifi/iwl-agn-led.c index 1a24946bc203..c1190d965614 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-led.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-led.c | |||
@@ -63,23 +63,11 @@ static int iwl_send_led_cmd(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd) | |||
63 | } | 63 | } |
64 | 64 | ||
65 | /* Set led register off */ | 65 | /* Set led register off */ |
66 | static int iwl_led_on_reg(struct iwl_priv *priv) | 66 | void iwlagn_led_enable(struct iwl_priv *priv) |
67 | { | 67 | { |
68 | IWL_DEBUG_LED(priv, "led on\n"); | ||
69 | iwl_write32(priv, CSR_LED_REG, CSR_LED_REG_TRUN_ON); | 68 | iwl_write32(priv, CSR_LED_REG, CSR_LED_REG_TRUN_ON); |
70 | return 0; | ||
71 | } | ||
72 | |||
73 | /* Set led register off */ | ||
74 | static int iwl_led_off_reg(struct iwl_priv *priv) | ||
75 | { | ||
76 | IWL_DEBUG_LED(priv, "LED Reg off\n"); | ||
77 | iwl_write32(priv, CSR_LED_REG, CSR_LED_REG_TRUN_OFF); | ||
78 | return 0; | ||
79 | } | 69 | } |
80 | 70 | ||
81 | const struct iwl_led_ops iwlagn_led_ops = { | 71 | const struct iwl_led_ops iwlagn_led_ops = { |
82 | .cmd = iwl_send_led_cmd, | 72 | .cmd = iwl_send_led_cmd, |
83 | .on = iwl_led_on_reg, | ||
84 | .off = iwl_led_off_reg, | ||
85 | }; | 73 | }; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-led.h b/drivers/net/wireless/iwlwifi/iwl-agn-led.h index a594e4fdc6b8..96f323dc5dd6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-led.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn-led.h | |||
@@ -28,5 +28,6 @@ | |||
28 | #define __iwl_agn_led_h__ | 28 | #define __iwl_agn_led_h__ |
29 | 29 | ||
30 | extern const struct iwl_led_ops iwlagn_led_ops; | 30 | extern const struct iwl_led_ops iwlagn_led_ops; |
31 | void iwlagn_led_enable(struct iwl_priv *priv); | ||
31 | 32 | ||
32 | #endif /* __iwl_agn_led_h__ */ | 33 | #endif /* __iwl_agn_led_h__ */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index 6e80f1070c52..f693293b6bd1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | |||
@@ -557,12 +557,10 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, | |||
557 | 557 | ||
558 | if (changes & BSS_CHANGED_ASSOC) { | 558 | if (changes & BSS_CHANGED_ASSOC) { |
559 | if (bss_conf->assoc) { | 559 | if (bss_conf->assoc) { |
560 | iwl_led_associate(priv); | ||
561 | priv->timestamp = bss_conf->timestamp; | 560 | priv->timestamp = bss_conf->timestamp; |
562 | ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; | 561 | ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; |
563 | } else { | 562 | } else { |
564 | ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; | 563 | ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; |
565 | iwl_led_disassociate(priv); | ||
566 | } | 564 | } |
567 | } | 565 | } |
568 | 566 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 97657d04aa68..9240abf425c7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -59,6 +59,7 @@ | |||
59 | #include "iwl-sta.h" | 59 | #include "iwl-sta.h" |
60 | #include "iwl-agn-calib.h" | 60 | #include "iwl-agn-calib.h" |
61 | #include "iwl-agn.h" | 61 | #include "iwl-agn.h" |
62 | #include "iwl-agn-led.h" | ||
62 | 63 | ||
63 | 64 | ||
64 | /****************************************************************************** | 65 | /****************************************************************************** |
@@ -2741,8 +2742,6 @@ static void iwl_alive_start(struct iwl_priv *priv) | |||
2741 | /* At this point, the NIC is initialized and operational */ | 2742 | /* At this point, the NIC is initialized and operational */ |
2742 | iwl_rf_kill_ct_config(priv); | 2743 | iwl_rf_kill_ct_config(priv); |
2743 | 2744 | ||
2744 | iwl_leds_init(priv); | ||
2745 | |||
2746 | IWL_DEBUG_INFO(priv, "ALIVE processing complete.\n"); | 2745 | IWL_DEBUG_INFO(priv, "ALIVE processing complete.\n"); |
2747 | wake_up_interruptible(&priv->wait_command_queue); | 2746 | wake_up_interruptible(&priv->wait_command_queue); |
2748 | 2747 | ||
@@ -3234,6 +3233,8 @@ static int iwl_mac_setup_register(struct iwl_priv *priv, | |||
3234 | priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = | 3233 | priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = |
3235 | &priv->bands[IEEE80211_BAND_5GHZ]; | 3234 | &priv->bands[IEEE80211_BAND_5GHZ]; |
3236 | 3235 | ||
3236 | iwl_leds_init(priv); | ||
3237 | |||
3237 | ret = ieee80211_register_hw(priv->hw); | 3238 | ret = ieee80211_register_hw(priv->hw); |
3238 | if (ret) { | 3239 | if (ret) { |
3239 | IWL_ERR(priv, "Failed to register hw (error %d)\n", ret); | 3240 | IWL_ERR(priv, "Failed to register hw (error %d)\n", ret); |
@@ -3278,7 +3279,7 @@ int iwlagn_mac_start(struct ieee80211_hw *hw) | |||
3278 | } | 3279 | } |
3279 | } | 3280 | } |
3280 | 3281 | ||
3281 | iwl_led_start(priv); | 3282 | iwlagn_led_enable(priv); |
3282 | 3283 | ||
3283 | out: | 3284 | out: |
3284 | priv->is_open = 1; | 3285 | priv->is_open = 1; |
@@ -4288,6 +4289,9 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev) | |||
4288 | * we need to set STATUS_EXIT_PENDING bit. | 4289 | * we need to set STATUS_EXIT_PENDING bit. |
4289 | */ | 4290 | */ |
4290 | set_bit(STATUS_EXIT_PENDING, &priv->status); | 4291 | set_bit(STATUS_EXIT_PENDING, &priv->status); |
4292 | |||
4293 | iwl_leds_exit(priv); | ||
4294 | |||
4291 | if (priv->mac80211_registered) { | 4295 | if (priv->mac80211_registered) { |
4292 | ieee80211_unregister_hw(priv->hw); | 4296 | ieee80211_unregister_hw(priv->hw); |
4293 | priv->mac80211_registered = 0; | 4297 | priv->mac80211_registered = 0; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index a8d4a936a2e7..8e1b8014ddc1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -1676,7 +1676,6 @@ void iwl_clear_traffic_stats(struct iwl_priv *priv) | |||
1676 | { | 1676 | { |
1677 | memset(&priv->tx_stats, 0, sizeof(struct traffic_stats)); | 1677 | memset(&priv->tx_stats, 0, sizeof(struct traffic_stats)); |
1678 | memset(&priv->rx_stats, 0, sizeof(struct traffic_stats)); | 1678 | memset(&priv->rx_stats, 0, sizeof(struct traffic_stats)); |
1679 | priv->led_tpt = 0; | ||
1680 | } | 1679 | } |
1681 | 1680 | ||
1682 | /* | 1681 | /* |
@@ -1769,7 +1768,6 @@ void iwl_update_stats(struct iwl_priv *priv, bool is_tx, __le16 fc, u16 len) | |||
1769 | stats->data_cnt++; | 1768 | stats->data_cnt++; |
1770 | stats->data_bytes += len; | 1769 | stats->data_bytes += len; |
1771 | } | 1770 | } |
1772 | iwl_leds_background(priv); | ||
1773 | } | 1771 | } |
1774 | EXPORT_SYMBOL(iwl_update_stats); | 1772 | EXPORT_SYMBOL(iwl_update_stats); |
1775 | #endif | 1773 | #endif |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index a3474376fdbc..bbc5aa7a7f2f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h | |||
@@ -227,8 +227,6 @@ struct iwl_lib_ops { | |||
227 | 227 | ||
228 | struct iwl_led_ops { | 228 | struct iwl_led_ops { |
229 | int (*cmd)(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd); | 229 | int (*cmd)(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd); |
230 | int (*on)(struct iwl_priv *priv); | ||
231 | int (*off)(struct iwl_priv *priv); | ||
232 | }; | 230 | }; |
233 | 231 | ||
234 | /* NIC specific ops */ | 232 | /* NIC specific ops */ |
@@ -494,18 +492,6 @@ static inline void iwl_dbg_log_rx_data_frame(struct iwl_priv *priv, | |||
494 | static inline void iwl_update_stats(struct iwl_priv *priv, bool is_tx, | 492 | static inline void iwl_update_stats(struct iwl_priv *priv, bool is_tx, |
495 | __le16 fc, u16 len) | 493 | __le16 fc, u16 len) |
496 | { | 494 | { |
497 | struct traffic_stats *stats; | ||
498 | |||
499 | if (is_tx) | ||
500 | stats = &priv->tx_stats; | ||
501 | else | ||
502 | stats = &priv->rx_stats; | ||
503 | |||
504 | if (ieee80211_is_data(fc)) { | ||
505 | /* data */ | ||
506 | stats->data_bytes += len; | ||
507 | } | ||
508 | iwl_leds_background(priv); | ||
509 | } | 495 | } |
510 | #endif | 496 | #endif |
511 | /***************************************************** | 497 | /***************************************************** |
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 6fe80b5e7a15..7f11a448d518 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c | |||
@@ -668,29 +668,6 @@ static ssize_t iwl_dbgfs_qos_read(struct file *file, char __user *user_buf, | |||
668 | return simple_read_from_buffer(user_buf, count, ppos, buf, pos); | 668 | return simple_read_from_buffer(user_buf, count, ppos, buf, pos); |
669 | } | 669 | } |
670 | 670 | ||
671 | static ssize_t iwl_dbgfs_led_read(struct file *file, char __user *user_buf, | ||
672 | size_t count, loff_t *ppos) | ||
673 | { | ||
674 | struct iwl_priv *priv = file->private_data; | ||
675 | int pos = 0; | ||
676 | char buf[256]; | ||
677 | const size_t bufsz = sizeof(buf); | ||
678 | |||
679 | pos += scnprintf(buf + pos, bufsz - pos, | ||
680 | "allow blinking: %s\n", | ||
681 | (priv->allow_blinking) ? "True" : "False"); | ||
682 | if (priv->allow_blinking) { | ||
683 | pos += scnprintf(buf + pos, bufsz - pos, | ||
684 | "Led blinking rate: %u\n", | ||
685 | priv->last_blink_rate); | ||
686 | pos += scnprintf(buf + pos, bufsz - pos, | ||
687 | "Last blink time: %lu\n", | ||
688 | priv->last_blink_time); | ||
689 | } | ||
690 | |||
691 | return simple_read_from_buffer(user_buf, count, ppos, buf, pos); | ||
692 | } | ||
693 | |||
694 | static ssize_t iwl_dbgfs_thermal_throttling_read(struct file *file, | 671 | static ssize_t iwl_dbgfs_thermal_throttling_read(struct file *file, |
695 | char __user *user_buf, | 672 | char __user *user_buf, |
696 | size_t count, loff_t *ppos) | 673 | size_t count, loff_t *ppos) |
@@ -856,7 +833,6 @@ DEBUGFS_READ_FILE_OPS(channels); | |||
856 | DEBUGFS_READ_FILE_OPS(status); | 833 | DEBUGFS_READ_FILE_OPS(status); |
857 | DEBUGFS_READ_WRITE_FILE_OPS(interrupt); | 834 | DEBUGFS_READ_WRITE_FILE_OPS(interrupt); |
858 | DEBUGFS_READ_FILE_OPS(qos); | 835 | DEBUGFS_READ_FILE_OPS(qos); |
859 | DEBUGFS_READ_FILE_OPS(led); | ||
860 | DEBUGFS_READ_FILE_OPS(thermal_throttling); | 836 | DEBUGFS_READ_FILE_OPS(thermal_throttling); |
861 | DEBUGFS_READ_WRITE_FILE_OPS(disable_ht40); | 837 | DEBUGFS_READ_WRITE_FILE_OPS(disable_ht40); |
862 | DEBUGFS_READ_WRITE_FILE_OPS(sleep_level_override); | 838 | DEBUGFS_READ_WRITE_FILE_OPS(sleep_level_override); |
@@ -1725,7 +1701,6 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) | |||
1725 | DEBUGFS_ADD_FILE(status, dir_data, S_IRUSR); | 1701 | DEBUGFS_ADD_FILE(status, dir_data, S_IRUSR); |
1726 | DEBUGFS_ADD_FILE(interrupt, dir_data, S_IWUSR | S_IRUSR); | 1702 | DEBUGFS_ADD_FILE(interrupt, dir_data, S_IWUSR | S_IRUSR); |
1727 | DEBUGFS_ADD_FILE(qos, dir_data, S_IRUSR); | 1703 | DEBUGFS_ADD_FILE(qos, dir_data, S_IRUSR); |
1728 | DEBUGFS_ADD_FILE(led, dir_data, S_IRUSR); | ||
1729 | if (!priv->cfg->base_params->broken_powersave) { | 1704 | if (!priv->cfg->base_params->broken_powersave) { |
1730 | DEBUGFS_ADD_FILE(sleep_level_override, dir_data, | 1705 | DEBUGFS_ADD_FILE(sleep_level_override, dir_data, |
1731 | S_IWUSR | S_IRUSR); | 1706 | S_IWUSR | S_IRUSR); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 2ec680bb8f6d..6dd6508c93b0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/pci.h> /* for struct pci_device_id */ | 35 | #include <linux/pci.h> /* for struct pci_device_id */ |
36 | #include <linux/kernel.h> | 36 | #include <linux/kernel.h> |
37 | #include <linux/wait.h> | 37 | #include <linux/wait.h> |
38 | #include <linux/leds.h> | ||
38 | #include <net/ieee80211_radiotap.h> | 39 | #include <net/ieee80211_radiotap.h> |
39 | 40 | ||
40 | #include "iwl-eeprom.h" | 41 | #include "iwl-eeprom.h" |
@@ -996,7 +997,6 @@ struct reply_agg_tx_error_statistics { | |||
996 | u32 unknown; | 997 | u32 unknown; |
997 | }; | 998 | }; |
998 | 999 | ||
999 | #ifdef CONFIG_IWLWIFI_DEBUGFS | ||
1000 | /* management statistics */ | 1000 | /* management statistics */ |
1001 | enum iwl_mgmt_stats { | 1001 | enum iwl_mgmt_stats { |
1002 | MANAGEMENT_ASSOC_REQ = 0, | 1002 | MANAGEMENT_ASSOC_REQ = 0, |
@@ -1027,16 +1027,13 @@ enum iwl_ctrl_stats { | |||
1027 | }; | 1027 | }; |
1028 | 1028 | ||
1029 | struct traffic_stats { | 1029 | struct traffic_stats { |
1030 | #ifdef CONFIG_IWLWIFI_DEBUGFS | ||
1030 | u32 mgmt[MANAGEMENT_MAX]; | 1031 | u32 mgmt[MANAGEMENT_MAX]; |
1031 | u32 ctrl[CONTROL_MAX]; | 1032 | u32 ctrl[CONTROL_MAX]; |
1032 | u32 data_cnt; | 1033 | u32 data_cnt; |
1033 | u64 data_bytes; | 1034 | u64 data_bytes; |
1034 | }; | ||
1035 | #else | ||
1036 | struct traffic_stats { | ||
1037 | u64 data_bytes; | ||
1038 | }; | ||
1039 | #endif | 1035 | #endif |
1036 | }; | ||
1040 | 1037 | ||
1041 | /* | 1038 | /* |
1042 | * iwl_switch_rxon: "channel switch" structure | 1039 | * iwl_switch_rxon: "channel switch" structure |
@@ -1338,11 +1335,6 @@ struct iwl_priv { | |||
1338 | struct iwl_init_alive_resp card_alive_init; | 1335 | struct iwl_init_alive_resp card_alive_init; |
1339 | struct iwl_alive_resp card_alive; | 1336 | struct iwl_alive_resp card_alive; |
1340 | 1337 | ||
1341 | unsigned long last_blink_time; | ||
1342 | u8 last_blink_rate; | ||
1343 | u8 allow_blinking; | ||
1344 | u64 led_tpt; | ||
1345 | |||
1346 | u16 active_rate; | 1338 | u16 active_rate; |
1347 | 1339 | ||
1348 | u8 start_calib; | 1340 | u8 start_calib; |
@@ -1580,6 +1572,10 @@ struct iwl_priv { | |||
1580 | bool hw_ready; | 1572 | bool hw_ready; |
1581 | 1573 | ||
1582 | struct iwl_event_log event_log; | 1574 | struct iwl_event_log event_log; |
1575 | |||
1576 | struct led_classdev led; | ||
1577 | unsigned long blink_on, blink_off; | ||
1578 | bool led_registered; | ||
1583 | }; /*iwl_priv */ | 1579 | }; /*iwl_priv */ |
1584 | 1580 | ||
1585 | static inline void iwl_txq_ctx_activate(struct iwl_priv *priv, int txq_id) | 1581 | static inline void iwl_txq_ctx_activate(struct iwl_priv *priv, int txq_id) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c index 46ccdf406e8e..074ad2275228 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.c +++ b/drivers/net/wireless/iwlwifi/iwl-led.c | |||
@@ -48,31 +48,19 @@ module_param(led_mode, int, S_IRUGO); | |||
48 | MODULE_PARM_DESC(led_mode, "0=system default, " | 48 | MODULE_PARM_DESC(led_mode, "0=system default, " |
49 | "1=On(RF On)/Off(RF Off), 2=blinking"); | 49 | "1=On(RF On)/Off(RF Off), 2=blinking"); |
50 | 50 | ||
51 | static const struct { | 51 | static const struct ieee80211_tpt_blink iwl_blink[] = { |
52 | u16 tpt; /* Mb/s */ | 52 | { .throughput = 0 * 1024 - 1, .blink_time = 334 }, |
53 | u8 on_time; | 53 | { .throughput = 1 * 1024 - 1, .blink_time = 260 }, |
54 | u8 off_time; | 54 | { .throughput = 5 * 1024 - 1, .blink_time = 220 }, |
55 | } blink_tbl[] = | 55 | { .throughput = 10 * 1024 - 1, .blink_time = 190 }, |
56 | { | 56 | { .throughput = 20 * 1024 - 1, .blink_time = 170 }, |
57 | {300, 25, 25}, | 57 | { .throughput = 50 * 1024 - 1, .blink_time = 150 }, |
58 | {200, 40, 40}, | 58 | { .throughput = 70 * 1024 - 1, .blink_time = 130 }, |
59 | {100, 55, 55}, | 59 | { .throughput = 100 * 1024 - 1, .blink_time = 110 }, |
60 | {70, 65, 65}, | 60 | { .throughput = 200 * 1024 - 1, .blink_time = 80 }, |
61 | {50, 75, 75}, | 61 | { .throughput = 300 * 1024 - 1, .blink_time = 50 }, |
62 | {20, 85, 85}, | ||
63 | {10, 95, 95}, | ||
64 | {5, 110, 110}, | ||
65 | {1, 130, 130}, | ||
66 | {0, 167, 167}, | ||
67 | /* SOLID_ON */ | ||
68 | {-1, IWL_LED_SOLID, 0} | ||
69 | }; | 62 | }; |
70 | 63 | ||
71 | #define IWL_1MB_RATE (128 * 1024) | ||
72 | #define IWL_LED_THRESHOLD (16) | ||
73 | #define IWL_MAX_BLINK_TBL (ARRAY_SIZE(blink_tbl) - 1) /* exclude SOLID_ON */ | ||
74 | #define IWL_SOLID_BLINK_IDX (ARRAY_SIZE(blink_tbl) - 1) | ||
75 | |||
76 | /* | 64 | /* |
77 | * Adjust led blink rate to compensate on a MAC Clock difference on every HW | 65 | * Adjust led blink rate to compensate on a MAC Clock difference on every HW |
78 | * Led blink rate analysis showed an average deviation of 0% on 3945, | 66 | * Led blink rate analysis showed an average deviation of 0% on 3945, |
@@ -97,133 +85,104 @@ static inline u8 iwl_blink_compensation(struct iwl_priv *priv, | |||
97 | } | 85 | } |
98 | 86 | ||
99 | /* Set led pattern command */ | 87 | /* Set led pattern command */ |
100 | static int iwl_led_pattern(struct iwl_priv *priv, unsigned int idx) | 88 | static int iwl_led_cmd(struct iwl_priv *priv, |
89 | unsigned long on, | ||
90 | unsigned long off) | ||
101 | { | 91 | { |
102 | struct iwl_led_cmd led_cmd = { | 92 | struct iwl_led_cmd led_cmd = { |
103 | .id = IWL_LED_LINK, | 93 | .id = IWL_LED_LINK, |
104 | .interval = IWL_DEF_LED_INTRVL | 94 | .interval = IWL_DEF_LED_INTRVL |
105 | }; | 95 | }; |
96 | int ret; | ||
106 | 97 | ||
107 | BUG_ON(idx > IWL_MAX_BLINK_TBL); | 98 | if (!test_bit(STATUS_READY, &priv->status)) |
99 | return -EBUSY; | ||
108 | 100 | ||
109 | IWL_DEBUG_LED(priv, "Led blink time compensation= %u\n", | 101 | if (priv->blink_on == on && priv->blink_off == off) |
102 | return 0; | ||
103 | |||
104 | IWL_DEBUG_LED(priv, "Led blink time compensation=%u\n", | ||
110 | priv->cfg->base_params->led_compensation); | 105 | priv->cfg->base_params->led_compensation); |
111 | led_cmd.on = | 106 | led_cmd.on = iwl_blink_compensation(priv, on, |
112 | iwl_blink_compensation(priv, blink_tbl[idx].on_time, | ||
113 | priv->cfg->base_params->led_compensation); | 107 | priv->cfg->base_params->led_compensation); |
114 | led_cmd.off = | 108 | led_cmd.off = iwl_blink_compensation(priv, off, |
115 | iwl_blink_compensation(priv, blink_tbl[idx].off_time, | ||
116 | priv->cfg->base_params->led_compensation); | 109 | priv->cfg->base_params->led_compensation); |
117 | 110 | ||
118 | return priv->cfg->ops->led->cmd(priv, &led_cmd); | 111 | ret = priv->cfg->ops->led->cmd(priv, &led_cmd); |
112 | if (!ret) { | ||
113 | priv->blink_on = on; | ||
114 | priv->blink_off = off; | ||
115 | } | ||
116 | return ret; | ||
119 | } | 117 | } |
120 | 118 | ||
121 | int iwl_led_start(struct iwl_priv *priv) | 119 | static void iwl_led_brightness_set(struct led_classdev *led_cdev, |
120 | enum led_brightness brightness) | ||
122 | { | 121 | { |
123 | return priv->cfg->ops->led->on(priv); | 122 | struct iwl_priv *priv = container_of(led_cdev, struct iwl_priv, led); |
124 | } | 123 | unsigned long on = 0; |
125 | EXPORT_SYMBOL(iwl_led_start); | ||
126 | 124 | ||
127 | int iwl_led_associate(struct iwl_priv *priv) | 125 | if (brightness > 0) |
128 | { | 126 | on = IWL_LED_SOLID; |
129 | IWL_DEBUG_LED(priv, "Associated\n"); | ||
130 | if (priv->cfg->led_mode == IWL_LED_BLINK) | ||
131 | priv->allow_blinking = 1; | ||
132 | priv->last_blink_time = jiffies; | ||
133 | 127 | ||
134 | return 0; | 128 | iwl_led_cmd(priv, on, 0); |
135 | } | 129 | } |
136 | EXPORT_SYMBOL(iwl_led_associate); | ||
137 | 130 | ||
138 | int iwl_led_disassociate(struct iwl_priv *priv) | 131 | static int iwl_led_blink_set(struct led_classdev *led_cdev, |
132 | unsigned long *delay_on, | ||
133 | unsigned long *delay_off) | ||
139 | { | 134 | { |
140 | priv->allow_blinking = 0; | 135 | struct iwl_priv *priv = container_of(led_cdev, struct iwl_priv, led); |
141 | 136 | ||
142 | return 0; | 137 | return iwl_led_cmd(priv, *delay_on, *delay_off); |
143 | } | 138 | } |
144 | EXPORT_SYMBOL(iwl_led_disassociate); | ||
145 | 139 | ||
146 | /* | 140 | void iwl_leds_init(struct iwl_priv *priv) |
147 | * calculate blink rate according to last second Tx/Rx activities | ||
148 | */ | ||
149 | static int iwl_get_blink_rate(struct iwl_priv *priv) | ||
150 | { | ||
151 | int i; | ||
152 | /* count both tx and rx traffic to be able to | ||
153 | * handle traffic in either direction | ||
154 | */ | ||
155 | u64 current_tpt = priv->tx_stats.data_bytes + | ||
156 | priv->rx_stats.data_bytes; | ||
157 | s64 tpt = current_tpt - priv->led_tpt; | ||
158 | |||
159 | if (tpt < 0) /* wraparound */ | ||
160 | tpt = -tpt; | ||
161 | |||
162 | IWL_DEBUG_LED(priv, "tpt %lld current_tpt %llu\n", | ||
163 | (long long)tpt, | ||
164 | (unsigned long long)current_tpt); | ||
165 | priv->led_tpt = current_tpt; | ||
166 | |||
167 | if (!priv->allow_blinking) | ||
168 | i = IWL_MAX_BLINK_TBL; | ||
169 | else | ||
170 | for (i = 0; i < IWL_MAX_BLINK_TBL; i++) | ||
171 | if (tpt > (blink_tbl[i].tpt * IWL_1MB_RATE)) | ||
172 | break; | ||
173 | |||
174 | IWL_DEBUG_LED(priv, "LED BLINK IDX=%d\n", i); | ||
175 | return i; | ||
176 | } | ||
177 | |||
178 | /* | ||
179 | * this function called from handler. Since setting Led command can | ||
180 | * happen very frequent we postpone led command to be called from | ||
181 | * REPLY handler so we know ucode is up | ||
182 | */ | ||
183 | void iwl_leds_background(struct iwl_priv *priv) | ||
184 | { | 141 | { |
185 | u8 blink_idx; | 142 | int mode = led_mode; |
186 | 143 | int ret; | |
187 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { | 144 | |
188 | priv->last_blink_time = 0; | 145 | if (mode == IWL_LED_DEFAULT) |
189 | return; | 146 | mode = priv->cfg->led_mode; |
190 | } | 147 | |
191 | if (iwl_is_rfkill(priv)) { | 148 | priv->led.name = kasprintf(GFP_KERNEL, "%s-led", |
192 | priv->last_blink_time = 0; | 149 | wiphy_name(priv->hw->wiphy)); |
193 | return; | 150 | priv->led.brightness_set = iwl_led_brightness_set; |
151 | priv->led.blink_set = iwl_led_blink_set; | ||
152 | priv->led.max_brightness = 1; | ||
153 | |||
154 | switch (mode) { | ||
155 | case IWL_LED_DEFAULT: | ||
156 | WARN_ON(1); | ||
157 | break; | ||
158 | case IWL_LED_BLINK: | ||
159 | priv->led.default_trigger = | ||
160 | ieee80211_create_tpt_led_trigger(priv->hw, | ||
161 | IEEE80211_TPT_LEDTRIG_FL_CONNECTED, | ||
162 | iwl_blink, ARRAY_SIZE(iwl_blink)); | ||
163 | break; | ||
164 | case IWL_LED_RF_STATE: | ||
165 | priv->led.default_trigger = | ||
166 | ieee80211_get_radio_led_name(priv->hw); | ||
167 | break; | ||
194 | } | 168 | } |
195 | 169 | ||
196 | if (!priv->allow_blinking) { | 170 | ret = led_classdev_register(&priv->pci_dev->dev, &priv->led); |
197 | priv->last_blink_time = 0; | 171 | if (ret) { |
198 | if (priv->last_blink_rate != IWL_SOLID_BLINK_IDX) { | 172 | kfree(priv->led.name); |
199 | priv->last_blink_rate = IWL_SOLID_BLINK_IDX; | ||
200 | iwl_led_pattern(priv, IWL_SOLID_BLINK_IDX); | ||
201 | } | ||
202 | return; | 173 | return; |
203 | } | 174 | } |
204 | if (!priv->last_blink_time || | ||
205 | !time_after(jiffies, priv->last_blink_time + | ||
206 | msecs_to_jiffies(1000))) | ||
207 | return; | ||
208 | |||
209 | blink_idx = iwl_get_blink_rate(priv); | ||
210 | 175 | ||
211 | /* call only if blink rate change */ | 176 | priv->led_registered = true; |
212 | if (blink_idx != priv->last_blink_rate) | ||
213 | iwl_led_pattern(priv, blink_idx); | ||
214 | |||
215 | priv->last_blink_time = jiffies; | ||
216 | priv->last_blink_rate = blink_idx; | ||
217 | } | 177 | } |
218 | EXPORT_SYMBOL(iwl_leds_background); | 178 | EXPORT_SYMBOL(iwl_leds_init); |
219 | 179 | ||
220 | void iwl_leds_init(struct iwl_priv *priv) | 180 | void iwl_leds_exit(struct iwl_priv *priv) |
221 | { | 181 | { |
222 | priv->last_blink_rate = 0; | 182 | if (!priv->led_registered) |
223 | priv->last_blink_time = 0; | 183 | return; |
224 | priv->allow_blinking = 0; | 184 | |
225 | if (led_mode != IWL_LED_DEFAULT && | 185 | led_classdev_unregister(&priv->led); |
226 | led_mode != priv->cfg->led_mode) | 186 | kfree(priv->led.name); |
227 | priv->cfg->led_mode = led_mode; | ||
228 | } | 187 | } |
229 | EXPORT_SYMBOL(iwl_leds_init); | 188 | EXPORT_SYMBOL(iwl_leds_exit); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.h b/drivers/net/wireless/iwlwifi/iwl-led.h index 9079b33486ef..101eef12b3bb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.h +++ b/drivers/net/wireless/iwlwifi/iwl-led.h | |||
@@ -31,23 +31,14 @@ | |||
31 | struct iwl_priv; | 31 | struct iwl_priv; |
32 | 32 | ||
33 | #define IWL_LED_SOLID 11 | 33 | #define IWL_LED_SOLID 11 |
34 | #define IWL_LED_NAME_LEN 31 | ||
35 | #define IWL_DEF_LED_INTRVL cpu_to_le32(1000) | 34 | #define IWL_DEF_LED_INTRVL cpu_to_le32(1000) |
36 | 35 | ||
37 | #define IWL_LED_ACTIVITY (0<<1) | 36 | #define IWL_LED_ACTIVITY (0<<1) |
38 | #define IWL_LED_LINK (1<<1) | 37 | #define IWL_LED_LINK (1<<1) |
39 | 38 | ||
40 | enum led_type { | ||
41 | IWL_LED_TRG_TX, | ||
42 | IWL_LED_TRG_RX, | ||
43 | IWL_LED_TRG_ASSOC, | ||
44 | IWL_LED_TRG_RADIO, | ||
45 | IWL_LED_TRG_MAX, | ||
46 | }; | ||
47 | |||
48 | /* | 39 | /* |
49 | * LED mode | 40 | * LED mode |
50 | * IWL_LED_DEFAULT: use system default | 41 | * IWL_LED_DEFAULT: use device default |
51 | * IWL_LED_RF_STATE: turn LED on/off based on RF state | 42 | * IWL_LED_RF_STATE: turn LED on/off based on RF state |
52 | * LED ON = RF ON | 43 | * LED ON = RF ON |
53 | * LED OFF = RF OFF | 44 | * LED OFF = RF OFF |
@@ -60,9 +51,6 @@ enum iwl_led_mode { | |||
60 | }; | 51 | }; |
61 | 52 | ||
62 | void iwl_leds_init(struct iwl_priv *priv); | 53 | void iwl_leds_init(struct iwl_priv *priv); |
63 | void iwl_leds_background(struct iwl_priv *priv); | 54 | void iwl_leds_exit(struct iwl_priv *priv); |
64 | int iwl_led_start(struct iwl_priv *priv); | ||
65 | int iwl_led_associate(struct iwl_priv *priv); | ||
66 | int iwl_led_disassociate(struct iwl_priv *priv); | ||
67 | 55 | ||
68 | #endif /* __iwl_leds_h__ */ | 56 | #endif /* __iwl_leds_h__ */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-legacy.c b/drivers/net/wireless/iwlwifi/iwl-legacy.c index bb1a742a98a0..927fe37a43ab 100644 --- a/drivers/net/wireless/iwlwifi/iwl-legacy.c +++ b/drivers/net/wireless/iwlwifi/iwl-legacy.c | |||
@@ -332,7 +332,6 @@ static inline void iwl_set_no_assoc(struct iwl_priv *priv, | |||
332 | { | 332 | { |
333 | struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); | 333 | struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); |
334 | 334 | ||
335 | iwl_led_disassociate(priv); | ||
336 | /* | 335 | /* |
337 | * inform the ucode that there is no longer an | 336 | * inform the ucode that there is no longer an |
338 | * association and that no more packets should be | 337 | * association and that no more packets should be |
@@ -520,8 +519,6 @@ void iwl_legacy_mac_bss_info_changed(struct ieee80211_hw *hw, | |||
520 | if (bss_conf->assoc) { | 519 | if (bss_conf->assoc) { |
521 | priv->timestamp = bss_conf->timestamp; | 520 | priv->timestamp = bss_conf->timestamp; |
522 | 521 | ||
523 | iwl_led_associate(priv); | ||
524 | |||
525 | if (!iwl_is_rfkill(priv)) | 522 | if (!iwl_is_rfkill(priv)) |
526 | priv->cfg->ops->legacy->post_associate(priv); | 523 | priv->cfg->ops->legacy->post_associate(priv); |
527 | } else | 524 | } else |
@@ -545,7 +542,6 @@ void iwl_legacy_mac_bss_info_changed(struct ieee80211_hw *hw, | |||
545 | memcpy(ctx->staging.bssid_addr, | 542 | memcpy(ctx->staging.bssid_addr, |
546 | bss_conf->bssid, ETH_ALEN); | 543 | bss_conf->bssid, ETH_ALEN); |
547 | memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN); | 544 | memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN); |
548 | iwl_led_associate(priv); | ||
549 | priv->cfg->ops->legacy->config_ap(priv); | 545 | priv->cfg->ops->legacy->config_ap(priv); |
550 | } else | 546 | } else |
551 | iwl_set_no_assoc(priv, vif); | 547 | iwl_set_no_assoc(priv, vif); |
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 371abbf60eac..9c986f272c2d 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
@@ -2540,8 +2540,6 @@ static void iwl3945_alive_start(struct iwl_priv *priv) | |||
2540 | 2540 | ||
2541 | iwl3945_reg_txpower_periodic(priv); | 2541 | iwl3945_reg_txpower_periodic(priv); |
2542 | 2542 | ||
2543 | iwl_leds_init(priv); | ||
2544 | |||
2545 | IWL_DEBUG_INFO(priv, "ALIVE processing complete.\n"); | 2543 | IWL_DEBUG_INFO(priv, "ALIVE processing complete.\n"); |
2546 | set_bit(STATUS_READY, &priv->status); | 2544 | set_bit(STATUS_READY, &priv->status); |
2547 | wake_up_interruptible(&priv->wait_command_queue); | 2545 | wake_up_interruptible(&priv->wait_command_queue); |
@@ -3170,8 +3168,6 @@ static int iwl3945_mac_start(struct ieee80211_hw *hw) | |||
3170 | * no need to poll the killswitch state anymore */ | 3168 | * no need to poll the killswitch state anymore */ |
3171 | cancel_delayed_work(&priv->_3945.rfkill_poll); | 3169 | cancel_delayed_work(&priv->_3945.rfkill_poll); |
3172 | 3170 | ||
3173 | iwl_led_start(priv); | ||
3174 | |||
3175 | priv->is_open = 1; | 3171 | priv->is_open = 1; |
3176 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 3172 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
3177 | return 0; | 3173 | return 0; |
@@ -3935,6 +3931,8 @@ static int iwl3945_setup_mac(struct iwl_priv *priv) | |||
3935 | priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = | 3931 | priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = |
3936 | &priv->bands[IEEE80211_BAND_5GHZ]; | 3932 | &priv->bands[IEEE80211_BAND_5GHZ]; |
3937 | 3933 | ||
3934 | iwl_leds_init(priv); | ||
3935 | |||
3938 | ret = ieee80211_register_hw(priv->hw); | 3936 | ret = ieee80211_register_hw(priv->hw); |
3939 | if (ret) { | 3937 | if (ret) { |
3940 | IWL_ERR(priv, "Failed to register hw (error %d)\n", ret); | 3938 | IWL_ERR(priv, "Failed to register hw (error %d)\n", ret); |
@@ -4194,6 +4192,8 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev) | |||
4194 | 4192 | ||
4195 | set_bit(STATUS_EXIT_PENDING, &priv->status); | 4193 | set_bit(STATUS_EXIT_PENDING, &priv->status); |
4196 | 4194 | ||
4195 | iwl_leds_exit(priv); | ||
4196 | |||
4197 | if (priv->mac80211_registered) { | 4197 | if (priv->mac80211_registered) { |
4198 | ieee80211_unregister_hw(priv->hw); | 4198 | ieee80211_unregister_hw(priv->hw); |
4199 | priv->mac80211_registered = 0; | 4199 | priv->mac80211_registered = 0; |