diff options
author | Vasanthakumar Thiagarajan <vthiagar@qca.qualcomm.com> | 2011-10-25 10:04:16 -0400 |
---|---|---|
committer | Kalle Valo <kvalo@qca.qualcomm.com> | 2011-11-11 05:58:49 -0500 |
commit | 6db8fa53ad4fa6d4b390e9bdd68f1238a01070ee (patch) | |
tree | 91b4504748f4fa4d28094a0c16417dd4daa89e80 /drivers/net/wireless/ath | |
parent | e29f25f5cd23d705b3a186e53cfddd3663875c45 (diff) |
ath6kl: Refactor ath6kl_destroy()
So that the deinitialization of ath6kl and vif are separated.
Signed-off-by: Vasanthakumar Thiagarajan <vthiagar@qca.qualcomm.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
Diffstat (limited to 'drivers/net/wireless/ath')
-rw-r--r-- | drivers/net/wireless/ath/ath6kl/cfg80211.c | 8 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath6kl/common.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath6kl/core.h | 5 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath6kl/init.c | 124 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath6kl/main.c | 75 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath6kl/sdio.c | 2 |
6 files changed, 79 insertions, 137 deletions
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index 1a29fecf0489..b242b31eb19e 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c | |||
@@ -2143,14 +2143,6 @@ err: | |||
2143 | 2143 | ||
2144 | void ath6kl_deinit_ieee80211_hw(struct ath6kl *ar) | 2144 | void ath6kl_deinit_ieee80211_hw(struct ath6kl *ar) |
2145 | { | 2145 | { |
2146 | /* TODO: Findout vif */ | ||
2147 | struct ath6kl_vif *vif = ar->vif; | ||
2148 | |||
2149 | if (vif->scan_req) { | ||
2150 | cfg80211_scan_done(vif->scan_req, true); | ||
2151 | vif->scan_req = NULL; | ||
2152 | } | ||
2153 | |||
2154 | wiphy_unregister(ar->wiphy); | 2146 | wiphy_unregister(ar->wiphy); |
2155 | wiphy_free(ar->wiphy); | 2147 | wiphy_free(ar->wiphy); |
2156 | } | 2148 | } |
diff --git a/drivers/net/wireless/ath/ath6kl/common.h b/drivers/net/wireless/ath/ath6kl/common.h index b92f0e5d2336..877cb7017383 100644 --- a/drivers/net/wireless/ath/ath6kl/common.h +++ b/drivers/net/wireless/ath/ath6kl/common.h | |||
@@ -92,6 +92,6 @@ void ath6k_seek_credits(struct htc_credit_state_info *cred_inf, | |||
92 | struct htc_endpoint_credit_dist *ep_dist); | 92 | struct htc_endpoint_credit_dist *ep_dist); |
93 | struct ath6kl *ath6kl_core_alloc(struct device *sdev); | 93 | struct ath6kl *ath6kl_core_alloc(struct device *sdev); |
94 | int ath6kl_core_init(struct ath6kl *ar); | 94 | int ath6kl_core_init(struct ath6kl *ar); |
95 | int ath6kl_unavail_ev(struct ath6kl *ar); | 95 | void ath6kl_core_cleanup(struct ath6kl *ar); |
96 | struct sk_buff *ath6kl_buf_alloc(int size); | 96 | struct sk_buff *ath6kl_buf_alloc(int size); |
97 | #endif /* COMMON_H */ | 97 | #endif /* COMMON_H */ |
diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h index de288ffe02c1..498b626b3637 100644 --- a/drivers/net/wireless/ath/ath6kl/core.h +++ b/drivers/net/wireless/ath/ath6kl/core.h | |||
@@ -584,7 +584,6 @@ static inline u32 ath6kl_get_hi_item_addr(struct ath6kl *ar, | |||
584 | return addr; | 584 | return addr; |
585 | } | 585 | } |
586 | 586 | ||
587 | void ath6kl_destroy(struct net_device *dev, unsigned int unregister); | ||
588 | int ath6kl_configure_target(struct ath6kl *ar); | 587 | int ath6kl_configure_target(struct ath6kl *ar); |
589 | void ath6kl_detect_error(unsigned long ptr); | 588 | void ath6kl_detect_error(unsigned long ptr); |
590 | void disconnect_timer_handler(unsigned long ptr); | 589 | void disconnect_timer_handler(unsigned long ptr); |
@@ -604,8 +603,6 @@ int ath6kl_diag_read(struct ath6kl *ar, u32 address, void *data, u32 length); | |||
604 | int ath6kl_read_fwlogs(struct ath6kl *ar); | 603 | int ath6kl_read_fwlogs(struct ath6kl *ar); |
605 | void ath6kl_init_profile_info(struct ath6kl_vif *vif); | 604 | void ath6kl_init_profile_info(struct ath6kl_vif *vif); |
606 | void ath6kl_tx_data_cleanup(struct ath6kl *ar); | 605 | void ath6kl_tx_data_cleanup(struct ath6kl *ar); |
607 | void ath6kl_stop_endpoint(struct net_device *dev, bool keep_profile, | ||
608 | bool get_dbglogs); | ||
609 | 606 | ||
610 | struct ath6kl_cookie *ath6kl_alloc_cookie(struct ath6kl *ar); | 607 | struct ath6kl_cookie *ath6kl_alloc_cookie(struct ath6kl *ar); |
611 | void ath6kl_free_cookie(struct ath6kl *ar, struct ath6kl_cookie *cookie); | 608 | void ath6kl_free_cookie(struct ath6kl *ar, struct ath6kl_cookie *cookie); |
@@ -657,6 +654,8 @@ void aggr_recv_addba_req_evt(struct ath6kl_vif *vif, u8 tid, u16 seq_no, | |||
657 | void ath6kl_wakeup_event(void *dev); | 654 | void ath6kl_wakeup_event(void *dev); |
658 | void ath6kl_target_failure(struct ath6kl *ar); | 655 | void ath6kl_target_failure(struct ath6kl *ar); |
659 | 656 | ||
657 | void ath6kl_reset_device(struct ath6kl *ar, u32 target_type, | ||
658 | bool wait_fot_compltn, bool cold_reset); | ||
660 | void ath6kl_init_control_info(struct ath6kl_vif *vif); | 659 | void ath6kl_init_control_info(struct ath6kl_vif *vif); |
661 | void ath6kl_deinit_if_data(struct ath6kl_vif *vif); | 660 | void ath6kl_deinit_if_data(struct ath6kl_vif *vif); |
662 | void ath6kl_core_free(struct ath6kl *ar); | 661 | void ath6kl_core_free(struct ath6kl *ar); |
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c index 7968c2b751a5..05d54bca3d9d 100644 --- a/drivers/net/wireless/ath/ath6kl/init.c +++ b/drivers/net/wireless/ath/ath6kl/init.c | |||
@@ -513,11 +513,27 @@ void ath6kl_core_free(struct ath6kl *ar) | |||
513 | wiphy_free(ar->wiphy); | 513 | wiphy_free(ar->wiphy); |
514 | } | 514 | } |
515 | 515 | ||
516 | int ath6kl_unavail_ev(struct ath6kl *ar) | 516 | void ath6kl_core_cleanup(struct ath6kl *ar) |
517 | { | 517 | { |
518 | ath6kl_destroy(ar->vif->ndev, 1); | 518 | destroy_workqueue(ar->ath6kl_wq); |
519 | 519 | ||
520 | return 0; | 520 | if (ar->htc_target) |
521 | ath6kl_htc_cleanup(ar->htc_target); | ||
522 | |||
523 | ath6kl_cookie_cleanup(ar); | ||
524 | |||
525 | ath6kl_cleanup_amsdu_rxbufs(ar); | ||
526 | |||
527 | ath6kl_bmi_cleanup(ar); | ||
528 | |||
529 | ath6kl_debug_cleanup(ar); | ||
530 | |||
531 | kfree(ar->fw_board); | ||
532 | kfree(ar->fw_otp); | ||
533 | kfree(ar->fw); | ||
534 | kfree(ar->fw_patch); | ||
535 | |||
536 | ath6kl_deinit_ieee80211_hw(ar); | ||
521 | } | 537 | } |
522 | 538 | ||
523 | /* firmware upload */ | 539 | /* firmware upload */ |
@@ -1572,6 +1588,36 @@ err_wq: | |||
1572 | return ret; | 1588 | return ret; |
1573 | } | 1589 | } |
1574 | 1590 | ||
1591 | static void ath6kl_cleanup_vif(struct ath6kl_vif *vif, bool wmi_ready) | ||
1592 | { | ||
1593 | static u8 bcast_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; | ||
1594 | bool discon_issued; | ||
1595 | |||
1596 | netif_stop_queue(vif->ndev); | ||
1597 | |||
1598 | clear_bit(WLAN_ENABLED, &vif->flags); | ||
1599 | |||
1600 | if (wmi_ready) { | ||
1601 | discon_issued = test_bit(CONNECTED, &vif->flags) || | ||
1602 | test_bit(CONNECT_PEND, &vif->flags); | ||
1603 | ath6kl_disconnect(vif); | ||
1604 | del_timer(&vif->disconnect_timer); | ||
1605 | |||
1606 | if (discon_issued) | ||
1607 | ath6kl_disconnect_event(vif, DISCONNECT_CMD, | ||
1608 | (vif->nw_type & AP_NETWORK) ? | ||
1609 | bcast_mac : vif->bssid, | ||
1610 | 0, NULL, 0); | ||
1611 | } | ||
1612 | |||
1613 | if (vif->scan_req) { | ||
1614 | cfg80211_scan_done(vif->scan_req, true); | ||
1615 | vif->scan_req = NULL; | ||
1616 | } | ||
1617 | |||
1618 | ath6kl_deinit_if_data(vif); | ||
1619 | } | ||
1620 | |||
1575 | void ath6kl_stop_txrx(struct ath6kl *ar) | 1621 | void ath6kl_stop_txrx(struct ath6kl *ar) |
1576 | { | 1622 | { |
1577 | struct ath6kl_vif *vif = ar->vif; | 1623 | struct ath6kl_vif *vif = ar->vif; |
@@ -1587,58 +1633,34 @@ void ath6kl_stop_txrx(struct ath6kl *ar) | |||
1587 | return; | 1633 | return; |
1588 | } | 1634 | } |
1589 | 1635 | ||
1590 | if (ar->wlan_pwr_state != WLAN_POWER_STATE_CUT_PWR) | 1636 | ath6kl_cleanup_vif(ar->vif, test_bit(WMI_READY, &ar->flag)); |
1591 | ath6kl_stop_endpoint(ndev, false, true); | ||
1592 | 1637 | ||
1593 | clear_bit(WLAN_ENABLED, &vif->flags); | 1638 | clear_bit(WMI_READY, &ar->flag); |
1594 | } | ||
1595 | 1639 | ||
1596 | /* | 1640 | /* |
1597 | * We need to differentiate between the surprise and planned removal of the | 1641 | * After wmi_shudown all WMI events will be dropped. We |
1598 | * device because of the following consideration: | 1642 | * need to cleanup the buffers allocated in AP mode and |
1599 | * | 1643 | * give disconnect notification to stack, which usually |
1600 | * - In case of surprise removal, the hcd already frees up the pending | 1644 | * happens in the disconnect_event. Simulate the disconnect |
1601 | * for the device and hence there is no need to unregister the function | 1645 | * event by calling the function directly. Sometimes |
1602 | * driver inorder to get these requests. For planned removal, the function | 1646 | * disconnect_event will be received when the debug logs |
1603 | * driver has to explicitly unregister itself to have the hcd return all the | 1647 | * are collected. |
1604 | * pending requests before the data structures for the devices are freed up. | 1648 | */ |
1605 | * Note that as per the current implementation, the function driver will | 1649 | ath6kl_wmi_shutdown(ar->wmi); |
1606 | * end up releasing all the devices since there is no API to selectively | ||
1607 | * release a particular device. | ||
1608 | * | ||
1609 | * - Certain commands issued to the target can be skipped for surprise | ||
1610 | * removal since they will anyway not go through. | ||
1611 | */ | ||
1612 | void ath6kl_destroy(struct net_device *dev, unsigned int unregister) | ||
1613 | { | ||
1614 | struct ath6kl *ar; | ||
1615 | 1650 | ||
1616 | if (!dev || !ath6kl_priv(dev)) { | 1651 | clear_bit(WMI_ENABLED, &ar->flag); |
1617 | ath6kl_err("failed to get device structure\n"); | 1652 | if (ar->htc_target) { |
1618 | return; | 1653 | ath6kl_dbg(ATH6KL_DBG_TRC, "%s: shut down htc\n", __func__); |
1654 | ath6kl_htc_stop(ar->htc_target); | ||
1619 | } | 1655 | } |
1620 | 1656 | ||
1621 | ar = ath6kl_priv(dev); | 1657 | /* |
1622 | 1658 | * Try to reset the device if we can. The driver may have been | |
1623 | destroy_workqueue(ar->ath6kl_wq); | 1659 | * configure NOT to reset the target during a debug session. |
1624 | 1660 | */ | |
1625 | if (ar->htc_target) | 1661 | ath6kl_dbg(ATH6KL_DBG_TRC, |
1626 | ath6kl_htc_cleanup(ar->htc_target); | 1662 | "attempting to reset target on instance destroy\n"); |
1627 | 1663 | ath6kl_reset_device(ar, ar->target_type, true, true); | |
1628 | ath6kl_cookie_cleanup(ar); | ||
1629 | |||
1630 | ath6kl_cleanup_amsdu_rxbufs(ar); | ||
1631 | |||
1632 | ath6kl_bmi_cleanup(ar); | ||
1633 | |||
1634 | ath6kl_debug_cleanup(ar); | ||
1635 | |||
1636 | ath6kl_deinit_if_data(netdev_priv(dev)); | ||
1637 | |||
1638 | kfree(ar->fw_board); | ||
1639 | kfree(ar->fw_otp); | ||
1640 | kfree(ar->fw); | ||
1641 | kfree(ar->fw_patch); | ||
1642 | 1664 | ||
1643 | ath6kl_deinit_ieee80211_hw(ar); | 1665 | clear_bit(WLAN_ENABLED, &ar->flag); |
1644 | } | 1666 | } |
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c index 08af257b6b41..a10002de8247 100644 --- a/drivers/net/wireless/ath/ath6kl/main.c +++ b/drivers/net/wireless/ath/ath6kl/main.c | |||
@@ -395,8 +395,8 @@ out: | |||
395 | #define AR6003_RESET_CONTROL_ADDRESS 0x00004000 | 395 | #define AR6003_RESET_CONTROL_ADDRESS 0x00004000 |
396 | #define AR6004_RESET_CONTROL_ADDRESS 0x00004000 | 396 | #define AR6004_RESET_CONTROL_ADDRESS 0x00004000 |
397 | 397 | ||
398 | static void ath6kl_reset_device(struct ath6kl *ar, u32 target_type, | 398 | void ath6kl_reset_device(struct ath6kl *ar, u32 target_type, |
399 | bool wait_fot_compltn, bool cold_reset) | 399 | bool wait_fot_compltn, bool cold_reset) |
400 | { | 400 | { |
401 | int status = 0; | 401 | int status = 0; |
402 | u32 address; | 402 | u32 address; |
@@ -427,77 +427,6 @@ static void ath6kl_reset_device(struct ath6kl *ar, u32 target_type, | |||
427 | ath6kl_err("failed to reset target\n"); | 427 | ath6kl_err("failed to reset target\n"); |
428 | } | 428 | } |
429 | 429 | ||
430 | void ath6kl_stop_endpoint(struct net_device *dev, bool keep_profile, | ||
431 | bool get_dbglogs) | ||
432 | { | ||
433 | struct ath6kl *ar = ath6kl_priv(dev); | ||
434 | struct ath6kl_vif *vif = netdev_priv(dev); | ||
435 | static u8 bcast_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; | ||
436 | bool discon_issued; | ||
437 | |||
438 | netif_stop_queue(dev); | ||
439 | |||
440 | /* disable the target and the interrupts associated with it */ | ||
441 | if (test_bit(WMI_READY, &ar->flag)) { | ||
442 | discon_issued = (test_bit(CONNECTED, &vif->flags) || | ||
443 | test_bit(CONNECT_PEND, &vif->flags)); | ||
444 | ath6kl_disconnect(vif); | ||
445 | if (!keep_profile) | ||
446 | ath6kl_init_profile_info(vif); | ||
447 | |||
448 | del_timer(&vif->disconnect_timer); | ||
449 | |||
450 | clear_bit(WMI_READY, &ar->flag); | ||
451 | ath6kl_wmi_shutdown(ar->wmi); | ||
452 | clear_bit(WMI_ENABLED, &ar->flag); | ||
453 | ar->wmi = NULL; | ||
454 | |||
455 | /* | ||
456 | * After wmi_shudown all WMI events will be dropped. We | ||
457 | * need to cleanup the buffers allocated in AP mode and | ||
458 | * give disconnect notification to stack, which usually | ||
459 | * happens in the disconnect_event. Simulate the disconnect | ||
460 | * event by calling the function directly. Sometimes | ||
461 | * disconnect_event will be received when the debug logs | ||
462 | * are collected. | ||
463 | */ | ||
464 | if (discon_issued) | ||
465 | ath6kl_disconnect_event(vif, DISCONNECT_CMD, | ||
466 | (vif->nw_type & AP_NETWORK) ? | ||
467 | bcast_mac : vif->bssid, | ||
468 | 0, NULL, 0); | ||
469 | |||
470 | ar->user_key_ctrl = 0; | ||
471 | |||
472 | } else { | ||
473 | ath6kl_dbg(ATH6KL_DBG_TRC, | ||
474 | "%s: wmi is not ready 0x%p 0x%p\n", | ||
475 | __func__, ar, ar->wmi); | ||
476 | |||
477 | /* Shut down WMI if we have started it */ | ||
478 | if (test_bit(WMI_ENABLED, &ar->flag)) { | ||
479 | ath6kl_dbg(ATH6KL_DBG_TRC, | ||
480 | "%s: shut down wmi\n", __func__); | ||
481 | ath6kl_wmi_shutdown(ar->wmi); | ||
482 | clear_bit(WMI_ENABLED, &ar->flag); | ||
483 | ar->wmi = NULL; | ||
484 | } | ||
485 | } | ||
486 | |||
487 | if (ar->htc_target) { | ||
488 | ath6kl_dbg(ATH6KL_DBG_TRC, "%s: shut down htc\n", __func__); | ||
489 | ath6kl_htc_stop(ar->htc_target); | ||
490 | } | ||
491 | |||
492 | /* | ||
493 | * Try to reset the device if we can. The driver may have been | ||
494 | * configure NOT to reset the target during a debug session. | ||
495 | */ | ||
496 | ath6kl_dbg(ATH6KL_DBG_TRC, | ||
497 | "attempting to reset target on instance destroy\n"); | ||
498 | ath6kl_reset_device(ar, ar->target_type, true, true); | ||
499 | } | ||
500 | |||
501 | static void ath6kl_install_static_wep_keys(struct ath6kl_vif *vif) | 430 | static void ath6kl_install_static_wep_keys(struct ath6kl_vif *vif) |
502 | { | 431 | { |
503 | u8 index; | 432 | u8 index; |
diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c index f73e14f75aee..b7c05668fc0c 100644 --- a/drivers/net/wireless/ath/ath6kl/sdio.c +++ b/drivers/net/wireless/ath/ath6kl/sdio.c | |||
@@ -897,7 +897,7 @@ static void ath6kl_sdio_remove(struct sdio_func *func) | |||
897 | ath6kl_stop_txrx(ar_sdio->ar); | 897 | ath6kl_stop_txrx(ar_sdio->ar); |
898 | cancel_work_sync(&ar_sdio->wr_async_work); | 898 | cancel_work_sync(&ar_sdio->wr_async_work); |
899 | 899 | ||
900 | ath6kl_unavail_ev(ar_sdio->ar); | 900 | ath6kl_core_cleanup(ar_sdio->ar); |
901 | 901 | ||
902 | ath6kl_sdio_power_off(ar_sdio); | 902 | ath6kl_sdio_power_off(ar_sdio); |
903 | 903 | ||