From patchwork Thu Jul 7 07:23:50 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mohammed Shafi X-Patchwork-Id: 952232 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter2.kernel.org (8.14.4/8.14.4) with ESMTP id p677NtCD025446 for ; Thu, 7 Jul 2011 07:23:55 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751525Ab1GGHXx (ORCPT ); Thu, 7 Jul 2011 03:23:53 -0400 Received: from mail-wy0-f174.google.com ([74.125.82.174]:38982 "EHLO mail-wy0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750961Ab1GGHXw (ORCPT ); Thu, 7 Jul 2011 03:23:52 -0400 Received: by wyg8 with SMTP id 8so436977wyg.19 for ; Thu, 07 Jul 2011 00:23:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=IeGBbCOc/n94V0Sh6zl8h/vMz5GWQ44uw1pc9ubXaho=; b=k7hMdfDanX12NA+MTG5shy/eVbRgstuLRs+J80zLOrlW8tuyoBCMw/kVCWytkF8eXD 1Xlgcw0b+UEtMVghHSGaJRgzt4pueGijuMVTYopZGFhIE8vO4BPDiCC3HxzFCFtbtlq4 Ln9IVwiAGb+bIRW5VeI/mh0gTEbVxadYeFQvY= MIME-Version: 1.0 Received: by 10.227.37.83 with SMTP id w19mr376718wbd.101.1310023430628; Thu, 07 Jul 2011 00:23:50 -0700 (PDT) Received: by 10.227.11.8 with HTTP; Thu, 7 Jul 2011 00:23:50 -0700 (PDT) In-Reply-To: References: <20110701173237.GC7125@alittletooquiet.net> <20110704052410.GA1364@vmraj-lnx.users.atheros.com> <20110704095341.GA1380@vmraj-lnx.users.atheros.com> <20110705124914.GC26882@alittletooquiet.net> <20110705143029.GA28091@alittletooquiet.net> <20110705172022.GB28091@alittletooquiet.net> <20110706023943.GA11178@vmraj-lnx.users.atheros.com> <20110706182937.GE28091@alittletooquiet.net> Date: Thu, 7 Jul 2011 03:23:50 -0400 Message-ID: Subject: Re: ath9k_htc fails to initialize TL-WN721N with compat-wireless 3.0-rc4-1 From: Mohammed Shafi To: Forest Bond Cc: Rajkumar Manoharan , "Luis R. Rodriguez" , Jouni Malinen , Vasanthakumar Thiagarajan , Senthil Balasubramanian , linux-wireless@vger.kernel.org Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter2.kernel.org [140.211.167.43]); Thu, 07 Jul 2011 07:23:55 +0000 (UTC) attached a reverting patch for LED, did a basic test and looks fine. need to investigate in this for backporting. we have not tested in 2.6.24 kernel From 6e3aa6402bf1ee2090d72b57de7fa1dcc49d115a Mon Sep 17 00:00:00 2001 From: vasanth Date: Thu, 7 Jul 2011 12:25:07 +0530 Subject: [PATCH] Revert "ath9k_htc: Revamp LED management" This reverts commit d244f21e79162b829c9af09845421d9b4fac4253. --- drivers/net/wireless/ath/ath9k/htc.h | 65 +++++---- drivers/net/wireless/ath/ath9k/htc_drv_gpio.c | 188 +++++++++++++++++++++---- drivers/net/wireless/ath/ath9k/htc_drv_init.c | 22 --- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 6 +- 4 files changed, 196 insertions(+), 85 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 5bc0220..80a8f7d 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -373,6 +373,25 @@ static inline void ath9k_htc_err_stat_rx(struct ath9k_htc_priv *priv, #define ATH_LED_PIN_9287 10 #define ATH_LED_PIN_9271 15 #define ATH_LED_PIN_7010 12 +#define ATH_LED_ON_DURATION_IDLE 350 /* in msecs */ +#define ATH_LED_OFF_DURATION_IDLE 250 /* in msecs */ + +enum ath_led_type { + ATH_LED_RADIO, + ATH_LED_ASSOC, + ATH_LED_TX, + ATH_LED_RX +}; + +struct ath_led { + struct ath9k_htc_priv *priv; + struct led_classdev led_cdev; + enum ath_led_type led_type; + struct delayed_work brightness_work; + char name[32]; + bool registered; + int brightness; +}; #define BSTUCK_THRESHOLD 10 @@ -406,11 +425,14 @@ void ath_htc_cancel_btcoex_work(struct ath9k_htc_priv *priv); #define OP_INVALID BIT(0) #define OP_SCANNING BIT(1) -#define OP_ENABLE_BEACON BIT(2) -#define OP_BT_PRIORITY_DETECTED BIT(3) -#define OP_BT_SCAN BIT(4) -#define OP_ANI_RUNNING BIT(5) -#define OP_TSF_RESET BIT(6) +#define OP_LED_ASSOCIATED BIT(2) +#define OP_LED_ON BIT(3) +#define OP_ENABLE_BEACON BIT(4) +#define OP_LED_DEINIT BIT(5) +#define OP_BT_PRIORITY_DETECTED BIT(6) +#define OP_BT_SCAN BIT(7) +#define OP_ANI_RUNNING BIT(8) +#define OP_TSF_RESET BIT(9) struct ath9k_htc_priv { struct device *dev; @@ -471,13 +493,15 @@ struct ath9k_htc_priv { bool ps_enabled; bool ps_idle; -#ifdef CONFIG_MAC80211_LEDS - enum led_brightness brightness; - bool led_registered; - char led_name[32]; - struct led_classdev led_cdev; - struct work_struct led_work; -#endif + struct ath_led radio_led; + struct ath_led assoc_led; + struct ath_led tx_led; + struct ath_led rx_led; + struct delayed_work ath9k_led_blink_work; + int led_on_duration; + int led_off_duration; + int led_on_cnt; + int led_off_cnt; int beaconq; int cabq; @@ -562,24 +586,9 @@ void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv); void ath9k_htc_rfkill_poll_state(struct ieee80211_hw *hw); void ath9k_htc_radio_enable(struct ieee80211_hw *hw); void ath9k_htc_radio_disable(struct ieee80211_hw *hw); - -#ifdef CONFIG_MAC80211_LEDS +void ath9k_led_stop_brightness(struct ath9k_htc_priv *priv); void ath9k_init_leds(struct ath9k_htc_priv *priv); void ath9k_deinit_leds(struct ath9k_htc_priv *priv); -void ath9k_led_work(struct work_struct *work); -#else -static inline void ath9k_init_leds(struct ath9k_htc_priv *priv) -{ -} - -static inline void ath9k_deinit_leds(struct ath9k_htc_priv *priv) -{ -} - -static inline void ath9k_led_work(struct work_struct *work) -{ -} -#endif int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev, u16 devid, char *product, u32 drv_info); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c index db2352e..d88a2e3 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c @@ -154,41 +154,140 @@ void ath_htc_cancel_btcoex_work(struct ath9k_htc_priv *priv) /* LED */ /*******/ -#ifdef CONFIG_MAC80211_LEDS -void ath9k_led_work(struct work_struct *work) +static void ath9k_led_blink_work(struct work_struct *work) { - struct ath9k_htc_priv *priv = container_of(work, - struct ath9k_htc_priv, - led_work); + struct ath9k_htc_priv *priv = container_of(work, struct ath9k_htc_priv, + ath9k_led_blink_work.work); + + if (!(priv->op_flags & OP_LED_ASSOCIATED)) + return; - ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, - (priv->brightness == LED_OFF)); + if ((priv->led_on_duration == ATH_LED_ON_DURATION_IDLE) || + (priv->led_off_duration == ATH_LED_OFF_DURATION_IDLE)) + ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 0); + else + ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, + (priv->op_flags & OP_LED_ON) ? 1 : 0); + + ieee80211_queue_delayed_work(priv->hw, + &priv->ath9k_led_blink_work, + (priv->op_flags & OP_LED_ON) ? + msecs_to_jiffies(priv->led_off_duration) : + msecs_to_jiffies(priv->led_on_duration)); + + priv->led_on_duration = priv->led_on_cnt ? + max((ATH_LED_ON_DURATION_IDLE - priv->led_on_cnt), 25) : + ATH_LED_ON_DURATION_IDLE; + priv->led_off_duration = priv->led_off_cnt ? + max((ATH_LED_OFF_DURATION_IDLE - priv->led_off_cnt), 10) : + ATH_LED_OFF_DURATION_IDLE; + priv->led_on_cnt = priv->led_off_cnt = 0; + + if (priv->op_flags & OP_LED_ON) + priv->op_flags &= ~OP_LED_ON; + else + priv->op_flags |= OP_LED_ON; +} + +static void ath9k_led_brightness_work(struct work_struct *work) +{ + struct ath_led *led = container_of(work, struct ath_led, + brightness_work.work); + struct ath9k_htc_priv *priv = led->priv; + + switch (led->brightness) { + case LED_OFF: + if (led->led_type == ATH_LED_ASSOC || + led->led_type == ATH_LED_RADIO) { + ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, + (led->led_type == ATH_LED_RADIO)); + priv->op_flags &= ~OP_LED_ASSOCIATED; + if (led->led_type == ATH_LED_RADIO) + priv->op_flags &= ~OP_LED_ON; + } else { + priv->led_off_cnt++; + } + break; + case LED_FULL: + if (led->led_type == ATH_LED_ASSOC) { + priv->op_flags |= OP_LED_ASSOCIATED; + ieee80211_queue_delayed_work(priv->hw, + &priv->ath9k_led_blink_work, 0); + } else if (led->led_type == ATH_LED_RADIO) { + ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 0); + priv->op_flags |= OP_LED_ON; + } else { + priv->led_on_cnt++; + } + break; + default: + break; + } } static void ath9k_led_brightness(struct led_classdev *led_cdev, enum led_brightness brightness) { - struct ath9k_htc_priv *priv = container_of(led_cdev, - struct ath9k_htc_priv, - led_cdev); + struct ath_led *led = container_of(led_cdev, struct ath_led, led_cdev); + struct ath9k_htc_priv *priv = led->priv; - /* Not locked, but it's just a tiny green light..*/ - priv->brightness = brightness; - ieee80211_queue_work(priv->hw, &priv->led_work); + led->brightness = brightness; + if (!(priv->op_flags & OP_LED_DEINIT)) + ieee80211_queue_delayed_work(priv->hw, + &led->brightness_work, 0); } -void ath9k_deinit_leds(struct ath9k_htc_priv *priv) +void ath9k_led_stop_brightness(struct ath9k_htc_priv *priv) { - if (!priv->led_registered) - return; + cancel_delayed_work_sync(&priv->radio_led.brightness_work); + cancel_delayed_work_sync(&priv->assoc_led.brightness_work); + cancel_delayed_work_sync(&priv->tx_led.brightness_work); + cancel_delayed_work_sync(&priv->rx_led.brightness_work); +} + +static int ath9k_register_led(struct ath9k_htc_priv *priv, struct ath_led *led, + char *trigger) +{ + int ret; - ath9k_led_brightness(&priv->led_cdev, LED_OFF); - led_classdev_unregister(&priv->led_cdev); - cancel_work_sync(&priv->led_work); + led->priv = priv; + led->led_cdev.name = led->name; + led->led_cdev.default_trigger = trigger; + led->led_cdev.brightness_set = ath9k_led_brightness; + + ret = led_classdev_register(wiphy_dev(priv->hw->wiphy), &led->led_cdev); + if (ret) + ath_err(ath9k_hw_common(priv->ah), + "Failed to register led:%s", led->name); + else + led->registered = 1; + + INIT_DELAYED_WORK(&led->brightness_work, ath9k_led_brightness_work); + + return ret; +} + +static void ath9k_unregister_led(struct ath_led *led) +{ + if (led->registered) { + led_classdev_unregister(&led->led_cdev); + led->registered = 0; + } +} + +void ath9k_deinit_leds(struct ath9k_htc_priv *priv) +{ + priv->op_flags |= OP_LED_DEINIT; + ath9k_unregister_led(&priv->assoc_led); + priv->op_flags &= ~OP_LED_ASSOCIATED; + ath9k_unregister_led(&priv->tx_led); + ath9k_unregister_led(&priv->rx_led); + ath9k_unregister_led(&priv->radio_led); } void ath9k_init_leds(struct ath9k_htc_priv *priv) { + char *trigger; int ret; if (AR_SREV_9287(priv->ah)) @@ -206,21 +305,48 @@ void ath9k_init_leds(struct ath9k_htc_priv *priv) /* LED off, active low */ ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 1); - snprintf(priv->led_name, sizeof(priv->led_name), - "ath9k_htc-%s", wiphy_name(priv->hw->wiphy)); - priv->led_cdev.name = priv->led_name; - priv->led_cdev.brightness_set = ath9k_led_brightness; - - ret = led_classdev_register(wiphy_dev(priv->hw->wiphy), &priv->led_cdev); - if (ret < 0) - return; - - INIT_WORK(&priv->led_work, ath9k_led_work); - priv->led_registered = true; + INIT_DELAYED_WORK(&priv->ath9k_led_blink_work, ath9k_led_blink_work); + + trigger = ieee80211_get_radio_led_name(priv->hw); + snprintf(priv->radio_led.name, sizeof(priv->radio_led.name), + "ath9k-%s::radio", wiphy_name(priv->hw->wiphy)); + ret = ath9k_register_led(priv, &priv->radio_led, trigger); + priv->radio_led.led_type = ATH_LED_RADIO; + if (ret) + goto fail; + + trigger = ieee80211_get_assoc_led_name(priv->hw); + snprintf(priv->assoc_led.name, sizeof(priv->assoc_led.name), + "ath9k-%s::assoc", wiphy_name(priv->hw->wiphy)); + ret = ath9k_register_led(priv, &priv->assoc_led, trigger); + priv->assoc_led.led_type = ATH_LED_ASSOC; + if (ret) + goto fail; + + trigger = ieee80211_get_tx_led_name(priv->hw); + snprintf(priv->tx_led.name, sizeof(priv->tx_led.name), + "ath9k-%s::tx", wiphy_name(priv->hw->wiphy)); + ret = ath9k_register_led(priv, &priv->tx_led, trigger); + priv->tx_led.led_type = ATH_LED_TX; + if (ret) + goto fail; + + trigger = ieee80211_get_rx_led_name(priv->hw); + snprintf(priv->rx_led.name, sizeof(priv->rx_led.name), + "ath9k-%s::rx", wiphy_name(priv->hw->wiphy)); + ret = ath9k_register_led(priv, &priv->rx_led, trigger); + priv->rx_led.led_type = ATH_LED_RX; + if (ret) + goto fail; + + priv->op_flags &= ~OP_LED_DEINIT; return; + +fail: + cancel_delayed_work_sync(&priv->ath9k_led_blink_work); + ath9k_deinit_leds(priv); } -#endif /*******************/ /* Rfkill */ diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 61e6d39..b68af2c 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -117,21 +117,6 @@ static struct ieee80211_rate ath9k_legacy_rates[] = { RATE(540, 0x0c, 0), }; -#ifdef CONFIG_MAC80211_LEDS -static const struct ieee80211_tpt_blink ath9k_htc_tpt_blink[] = { - { .throughput = 0 * 1024, .blink_time = 334 }, - { .throughput = 1 * 1024, .blink_time = 260 }, - { .throughput = 5 * 1024, .blink_time = 220 }, - { .throughput = 10 * 1024, .blink_time = 190 }, - { .throughput = 20 * 1024, .blink_time = 170 }, - { .throughput = 50 * 1024, .blink_time = 150 }, - { .throughput = 70 * 1024, .blink_time = 130 }, - { .throughput = 100 * 1024, .blink_time = 110 }, - { .throughput = 200 * 1024, .blink_time = 80 }, - { .throughput = 300 * 1024, .blink_time = 50 }, -}; -#endif - static int ath9k_htc_wait_for_target(struct ath9k_htc_priv *priv) { int time_left; @@ -873,13 +858,6 @@ static int ath9k_init_device(struct ath9k_htc_priv *priv, if (error != 0) goto err_rx; -#ifdef CONFIG_MAC80211_LEDS - /* must be initialized before ieee80211_register_hw */ - priv->led_cdev.default_trigger = ieee80211_create_tpt_led_trigger(priv->hw, - IEEE80211_TPT_LEDTRIG_FL_RADIO, ath9k_htc_tpt_blink, - ARRAY_SIZE(ath9k_htc_tpt_blink)); -#endif - /* Register with mac80211 */ error = ieee80211_register_hw(hw); if (error) diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 7b77968..8678420 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -1002,11 +1002,9 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw) /* Cancel all the running timers/work .. */ cancel_work_sync(&priv->fatal_work); cancel_work_sync(&priv->ps_work); - -#ifdef CONFIG_MAC80211_LEDS - cancel_work_sync(&priv->led_work); -#endif + cancel_delayed_work_sync(&priv->ath9k_led_blink_work); ath9k_htc_stop_ani(priv); + ath9k_led_stop_brightness(priv); mutex_lock(&priv->mutex); -- 1.7.0.4