diff options
-rw-r--r-- | drivers/net/wireless/ath/ath6kl/bmi.c | 5 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath6kl/bmi.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath6kl/core.h | 4 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath6kl/htc.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath6kl/init.c | 35 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath6kl/main.c | 22 |
6 files changed, 64 insertions, 7 deletions
diff --git a/drivers/net/wireless/ath/ath6kl/bmi.c b/drivers/net/wireless/ath/ath6kl/bmi.c index 5a4c24d..a962fe4 100644 --- a/drivers/net/wireless/ath/ath6kl/bmi.c +++ b/drivers/net/wireless/ath/ath6kl/bmi.c @@ -670,6 +670,11 @@ int ath6kl_bmi_fast_download(struct ath6kl *ar, u32 addr, u8 *buf, u32 len) return ret; } +void ath6kl_bmi_reset(struct ath6kl *ar) +{ + ar->bmi.done_sent = false; +} + int ath6kl_bmi_init(struct ath6kl *ar) { ar->bmi.cmd_buf = kzalloc(MAX_BMI_CMDBUF_SZ, GFP_ATOMIC); diff --git a/drivers/net/wireless/ath/ath6kl/bmi.h b/drivers/net/wireless/ath/ath6kl/bmi.h index 96851d5..009e8f6 100644 --- a/drivers/net/wireless/ath/ath6kl/bmi.h +++ b/drivers/net/wireless/ath/ath6kl/bmi.h @@ -230,6 +230,8 @@ struct ath6kl_bmi_target_info { int ath6kl_bmi_init(struct ath6kl *ar); void ath6kl_bmi_cleanup(struct ath6kl *ar); +void ath6kl_bmi_reset(struct ath6kl *ar); + int ath6kl_bmi_done(struct ath6kl *ar); int ath6kl_bmi_get_target_info(struct ath6kl *ar, struct ath6kl_bmi_target_info *targ_info); diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h index 5ac415e..1ac0dd1 100644 --- a/drivers/net/wireless/ath/ath6kl/core.h +++ b/drivers/net/wireless/ath/ath6kl/core.h @@ -447,6 +447,7 @@ enum ath6kl_dev_state { DESTROY_IN_PROGRESS, SKIP_SCAN, ROAM_TBL_PEND, + FIRST_BOOT, }; struct ath6kl { @@ -662,4 +663,7 @@ void ath6kl_deinit_if_data(struct ath6kl_vif *vif); void ath6kl_core_free(struct ath6kl *ar); struct ath6kl_vif *ath6kl_vif_first(struct ath6kl *ar); void ath6kl_cleanup_vif(struct ath6kl_vif *vif, bool wmi_ready); +int ath6kl_init_hw_start(struct ath6kl *ar); +int ath6kl_init_hw_stop(struct ath6kl *ar); + #endif /* CORE_H */ diff --git a/drivers/net/wireless/ath/ath6kl/htc.c b/drivers/net/wireless/ath/ath6kl/htc.c index 04b4070..99220d4 100644 --- a/drivers/net/wireless/ath/ath6kl/htc.c +++ b/drivers/net/wireless/ath/ath6kl/htc.c @@ -2622,6 +2622,9 @@ int ath6kl_htc_start(struct htc_target *target) struct htc_packet *packet; int status; + memset(&target->dev->irq_proc_reg, 0, + sizeof(target->dev->irq_proc_reg)); + /* Disable interrupts at the chip level */ ath6kl_hif_disable_intrs(target->dev); diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c index 2ee6a5e..237b73c 100644 --- a/drivers/net/wireless/ath/ath6kl/init.c +++ b/drivers/net/wireless/ath/ath6kl/init.c @@ -1421,11 +1421,13 @@ static int ath6kl_init_hw_params(struct ath6kl *ar) return 0; } -static int ath6kl_hw_start(struct ath6kl *ar) +int ath6kl_init_hw_start(struct ath6kl *ar) { long timeleft; int ret, i; + ath6kl_dbg(ATH6KL_DBG_BOOT, "hw start\n"); + ret = ath6kl_hif_power_on(ar); if (ret) return ret; @@ -1517,6 +1519,25 @@ err_power_off: return ret; } +int ath6kl_init_hw_stop(struct ath6kl *ar) +{ + int ret; + + ath6kl_dbg(ATH6KL_DBG_BOOT, "hw stop\n"); + + ath6kl_htc_stop(ar->htc_target); + + ath6kl_hif_stop(ar); + + ath6kl_bmi_reset(ar); + + ret = ath6kl_hif_power_off(ar); + if (ret) + ath6kl_warn("failed to power off hif: %d\n", ret); + + return 0; +} + int ath6kl_core_init(struct ath6kl *ar) { struct ath6kl_bmi_target_info targ_info; @@ -1629,9 +1650,11 @@ int ath6kl_core_init(struct ath6kl *ar) ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM | WIPHY_FLAG_HAVE_AP_SME; - ret = ath6kl_hw_start(ar); + set_bit(FIRST_BOOT, &ar->flag); + + ret = ath6kl_init_hw_start(ar); if (ret) { - ath6kl_err("Failed to boot hardware: %d\n", ret); + ath6kl_err("Failed to start hardware: %d\n", ret); goto err_rxbuf_cleanup; } @@ -1641,6 +1664,12 @@ int ath6kl_core_init(struct ath6kl *ar) */ memcpy(ndev->dev_addr, ar->mac_addr, ETH_ALEN); + ret = ath6kl_init_hw_stop(ar); + if (ret) { + ath6kl_err("Failed to stop hardware: %d\n", ret); + goto err_htc_cleanup; + } + return ret; err_rxbuf_cleanup: diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c index 3b2a7e8..717ed22 100644 --- a/drivers/net/wireless/ath/ath6kl/main.c +++ b/drivers/net/wireless/ath/ath6kl/main.c @@ -673,10 +673,12 @@ void ath6kl_ready_event(void *devt, u8 *datap, u32 sw_ver, u32 abi_ver) set_bit(WMI_READY, &ar->flag); wake_up(&ar->event_wq); - ath6kl_info("hw %s fw %s%s\n", - get_hw_id_string(ar->wiphy->hw_version), - ar->wiphy->fw_version, - test_bit(TESTMODE, &ar->flag) ? " testmode" : ""); + if (test_and_clear_bit(FIRST_BOOT, &ar->flag)) { + ath6kl_info("hw %s fw %s%s\n", + get_hw_id_string(ar->wiphy->hw_version), + ar->wiphy->fw_version, + test_bit(TESTMODE, &ar->flag) ? " testmode" : ""); + } } void ath6kl_scan_complete_evt(struct ath6kl_vif *vif, int status) @@ -1112,6 +1114,12 @@ struct ath6kl_vif *ath6kl_vif_first(struct ath6kl *ar) static int ath6kl_open(struct net_device *dev) { struct ath6kl_vif *vif = netdev_priv(dev); + int ret; + + /* FIXME: how to handle multi vif support? */ + ret = ath6kl_init_hw_start(vif->ar); + if (ret) + return ret; set_bit(WLAN_ENABLED, &vif->flags); @@ -1128,6 +1136,7 @@ static int ath6kl_close(struct net_device *dev) { struct ath6kl *ar = ath6kl_priv(dev); struct ath6kl_vif *vif = netdev_priv(dev); + int ret; netif_stop_queue(dev); @@ -1143,6 +1152,11 @@ static int ath6kl_close(struct net_device *dev) ath6kl_cfg80211_scan_complete_event(vif, -ECANCELED); + /* FIXME: how to handle multi vif support? */ + ret = ath6kl_init_hw_stop(ar); + if (ret) + return ret; + return 0; } |