aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorMichal Kazior <michal.kazior@tieto.com>2013-07-16 03:38:57 -0400
committerKalle Valo <kvalo@qca.qualcomm.com>2013-07-30 11:01:19 -0400
commit818bdd16b229919cfd07447d261154a1343871e1 (patch)
treeceb7c266179a2add8a729ea6b56265c4d7e8891f /drivers/net
parenta96d7745592274077e517173ec2cdac2a22d5b79 (diff)
ath10k: defer hw setup to start/stop mac80211 hooks
This fixes suspend-to-disk. The hardware is now re-initialized upon freeze/thaw properly. This also makes suspend/resume re-initialize the hardware as WoWLAN support is not done yet. With some little work it should be possible to support hw reconfiguration for hw/fw recovery. HW must be initialized once before registering to mac80211 because FW determinates what hw capabilities can be advertised. Signed-off-by: Michal Kazior <michal.kazior@tieto.com> Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/ath/ath10k/core.c46
-rw-r--r--drivers/net/wireless/ath/ath10k/mac.c56
-rw-r--r--drivers/net/wireless/ath/ath10k/pci.c11
3 files changed, 81 insertions, 32 deletions
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index 0e4a704516f7..1d4c24583f1d 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -601,6 +601,7 @@ err_wmi_detach:
601err: 601err:
602 return status; 602 return status;
603} 603}
604EXPORT_SYMBOL(ath10k_core_start);
604 605
605void ath10k_core_stop(struct ath10k *ar) 606void ath10k_core_stop(struct ath10k *ar)
606{ 607{
@@ -608,18 +609,49 @@ void ath10k_core_stop(struct ath10k *ar)
608 ath10k_htt_detach(&ar->htt); 609 ath10k_htt_detach(&ar->htt);
609 ath10k_wmi_detach(ar); 610 ath10k_wmi_detach(ar);
610} 611}
612EXPORT_SYMBOL(ath10k_core_stop);
613
614/* mac80211 manages fw/hw initialization through start/stop hooks. However in
615 * order to know what hw capabilities should be advertised to mac80211 it is
616 * necessary to load the firmware (and tear it down immediately since start
617 * hook will try to init it again) before registering */
618static int ath10k_core_probe_fw(struct ath10k *ar)
619{
620 int ret;
621
622 ret = ath10k_hif_power_up(ar);
623 if (ret) {
624 ath10k_err("could not start pci hif (%d)\n", ret);
625 return ret;
626 }
627
628 ret = ath10k_core_start(ar);
629 if (ret) {
630 ath10k_err("could not init core (%d)\n", ret);
631 ath10k_hif_power_down(ar);
632 return ret;
633 }
634
635 ath10k_core_stop(ar);
636 ath10k_hif_power_down(ar);
637 return 0;
638}
611 639
612int ath10k_core_register(struct ath10k *ar) 640int ath10k_core_register(struct ath10k *ar)
613{ 641{
614 int status; 642 int status;
615 643
616 status = ath10k_core_start(ar); 644 status = ath10k_core_probe_fw(ar);
617 if (status) 645 if (status) {
618 goto err; 646 ath10k_err("could not probe fw (%d)\n", status);
647 return status;
648 }
619 649
620 status = ath10k_mac_register(ar); 650 status = ath10k_mac_register(ar);
621 if (status) 651 if (status) {
622 goto err_core_stop; 652 ath10k_err("could not register to mac80211 (%d)\n", status);
653 return status;
654 }
623 655
624 status = ath10k_debug_create(ar); 656 status = ath10k_debug_create(ar);
625 if (status) { 657 if (status) {
@@ -631,9 +663,6 @@ int ath10k_core_register(struct ath10k *ar)
631 663
632err_unregister_mac: 664err_unregister_mac:
633 ath10k_mac_unregister(ar); 665 ath10k_mac_unregister(ar);
634err_core_stop:
635 ath10k_core_stop(ar);
636err:
637 return status; 666 return status;
638} 667}
639EXPORT_SYMBOL(ath10k_core_register); 668EXPORT_SYMBOL(ath10k_core_register);
@@ -644,7 +673,6 @@ void ath10k_core_unregister(struct ath10k *ar)
644 * Otherwise we will fail to submit commands to FW and mac80211 will be 673 * Otherwise we will fail to submit commands to FW and mac80211 will be
645 * unhappy about callback failures. */ 674 * unhappy about callback failures. */
646 ath10k_mac_unregister(ar); 675 ath10k_mac_unregister(ar);
647 ath10k_core_stop(ar);
648} 676}
649EXPORT_SYMBOL(ath10k_core_unregister); 677EXPORT_SYMBOL(ath10k_core_unregister);
650 678
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index b9663e94dba5..2dfd446251b1 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -1738,13 +1738,52 @@ static void ath10k_tx(struct ieee80211_hw *hw,
1738/* 1738/*
1739 * Initialize various parameters with default vaules. 1739 * Initialize various parameters with default vaules.
1740 */ 1740 */
1741static void ath10k_halt(struct ath10k *ar)
1742{
1743 lockdep_assert_held(&ar->conf_mutex);
1744
1745 del_timer_sync(&ar->scan.timeout);
1746 ath10k_offchan_tx_purge(ar);
1747 ath10k_peer_cleanup_all(ar);
1748 ath10k_core_stop(ar);
1749 ath10k_hif_power_down(ar);
1750
1751 spin_lock_bh(&ar->data_lock);
1752 if (ar->scan.in_progress) {
1753 del_timer(&ar->scan.timeout);
1754 ar->scan.in_progress = false;
1755 ieee80211_scan_completed(ar->hw, true);
1756 }
1757 spin_unlock_bh(&ar->data_lock);
1758}
1759
1741static int ath10k_start(struct ieee80211_hw *hw) 1760static int ath10k_start(struct ieee80211_hw *hw)
1742{ 1761{
1743 struct ath10k *ar = hw->priv; 1762 struct ath10k *ar = hw->priv;
1744 int ret; 1763 int ret = 0;
1745 1764
1746 mutex_lock(&ar->conf_mutex); 1765 mutex_lock(&ar->conf_mutex);
1747 1766
1767 if (ar->state != ATH10K_STATE_OFF) {
1768 ret = -EINVAL;
1769 goto exit;
1770 }
1771
1772 ret = ath10k_hif_power_up(ar);
1773 if (ret) {
1774 ath10k_err("could not init hif (%d)\n", ret);
1775 ar->state = ATH10K_STATE_OFF;
1776 goto exit;
1777 }
1778
1779 ret = ath10k_core_start(ar);
1780 if (ret) {
1781 ath10k_err("could not init core (%d)\n", ret);
1782 ath10k_hif_power_down(ar);
1783 ar->state = ATH10K_STATE_OFF;
1784 goto exit;
1785 }
1786
1748 ret = ath10k_wmi_pdev_set_param(ar, WMI_PDEV_PARAM_PMF_QOS, 1); 1787 ret = ath10k_wmi_pdev_set_param(ar, WMI_PDEV_PARAM_PMF_QOS, 1);
1749 if (ret) 1788 if (ret)
1750 ath10k_warn("could not enable WMI_PDEV_PARAM_PMF_QOS (%d)\n", 1789 ath10k_warn("could not enable WMI_PDEV_PARAM_PMF_QOS (%d)\n",
@@ -1755,9 +1794,9 @@ static int ath10k_start(struct ieee80211_hw *hw)
1755 ath10k_warn("could not init WMI_PDEV_PARAM_DYNAMIC_BW (%d)\n", 1794 ath10k_warn("could not init WMI_PDEV_PARAM_DYNAMIC_BW (%d)\n",
1756 ret); 1795 ret);
1757 1796
1758 ar->state = ATH10K_STATE_ON;
1759 ath10k_regd_update(ar); 1797 ath10k_regd_update(ar);
1760 1798
1799exit:
1761 mutex_unlock(&ar->conf_mutex); 1800 mutex_unlock(&ar->conf_mutex);
1762 return 0; 1801 return 0;
1763} 1802}
@@ -1767,17 +1806,8 @@ static void ath10k_stop(struct ieee80211_hw *hw)
1767 struct ath10k *ar = hw->priv; 1806 struct ath10k *ar = hw->priv;
1768 1807
1769 mutex_lock(&ar->conf_mutex); 1808 mutex_lock(&ar->conf_mutex);
1770 del_timer_sync(&ar->scan.timeout); 1809 if (ar->state == ATH10K_STATE_ON)
1771 ath10k_offchan_tx_purge(ar); 1810 ath10k_halt(ar);
1772 ath10k_peer_cleanup_all(ar);
1773
1774 spin_lock_bh(&ar->data_lock);
1775 if (ar->scan.in_progress) {
1776 del_timer(&ar->scan.timeout);
1777 ar->scan.in_progress = false;
1778 ieee80211_scan_completed(ar->hw, true);
1779 }
1780 spin_unlock_bh(&ar->data_lock);
1781 1811
1782 ar->state = ATH10K_STATE_OFF; 1812 ar->state = ATH10K_STATE_OFF;
1783 mutex_unlock(&ar->conf_mutex); 1813 mutex_unlock(&ar->conf_mutex);
diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c
index 75f5427bb416..bfe856166bb0 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -2362,22 +2362,14 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
2362 goto err_iomap; 2362 goto err_iomap;
2363 } 2363 }
2364 2364
2365 ret = ath10k_pci_hif_power_up(ar);
2366 if (ret) {
2367 ath10k_err("could not start pci hif (%d)\n", ret);
2368 goto err_intr;
2369 }
2370
2371 ret = ath10k_core_register(ar); 2365 ret = ath10k_core_register(ar);
2372 if (ret) { 2366 if (ret) {
2373 ath10k_err("could not register driver core (%d)\n", ret); 2367 ath10k_err("could not register driver core (%d)\n", ret);
2374 goto err_hif; 2368 goto err_intr;
2375 } 2369 }
2376 2370
2377 return 0; 2371 return 0;
2378 2372
2379err_hif:
2380 ath10k_pci_hif_power_down(ar);
2381err_intr: 2373err_intr:
2382 ath10k_pci_stop_intr(ar); 2374 ath10k_pci_stop_intr(ar);
2383err_iomap: 2375err_iomap:
@@ -2416,7 +2408,6 @@ static void ath10k_pci_remove(struct pci_dev *pdev)
2416 tasklet_kill(&ar_pci->msi_fw_err); 2408 tasklet_kill(&ar_pci->msi_fw_err);
2417 2409
2418 ath10k_core_unregister(ar); 2410 ath10k_core_unregister(ar);
2419 ath10k_pci_hif_power_down(ar);
2420 ath10k_pci_stop_intr(ar); 2411 ath10k_pci_stop_intr(ar);
2421 2412
2422 pci_set_drvdata(pdev, NULL); 2413 pci_set_drvdata(pdev, NULL);