aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath
diff options
context:
space:
mode:
authorVasanthakumar Thiagarajan <vthiagar@qca.qualcomm.com>2011-10-25 10:04:16 -0400
committerKalle Valo <kvalo@qca.qualcomm.com>2011-11-11 05:58:49 -0500
commit6db8fa53ad4fa6d4b390e9bdd68f1238a01070ee (patch)
tree91b4504748f4fa4d28094a0c16417dd4daa89e80 /drivers/net/wireless/ath
parente29f25f5cd23d705b3a186e53cfddd3663875c45 (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.c8
-rw-r--r--drivers/net/wireless/ath/ath6kl/common.h2
-rw-r--r--drivers/net/wireless/ath/ath6kl/core.h5
-rw-r--r--drivers/net/wireless/ath/ath6kl/init.c124
-rw-r--r--drivers/net/wireless/ath/ath6kl/main.c75
-rw-r--r--drivers/net/wireless/ath/ath6kl/sdio.c2
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
2144void ath6kl_deinit_ieee80211_hw(struct ath6kl *ar) 2144void 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);
93struct ath6kl *ath6kl_core_alloc(struct device *sdev); 93struct ath6kl *ath6kl_core_alloc(struct device *sdev);
94int ath6kl_core_init(struct ath6kl *ar); 94int ath6kl_core_init(struct ath6kl *ar);
95int ath6kl_unavail_ev(struct ath6kl *ar); 95void ath6kl_core_cleanup(struct ath6kl *ar);
96struct sk_buff *ath6kl_buf_alloc(int size); 96struct 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
587void ath6kl_destroy(struct net_device *dev, unsigned int unregister);
588int ath6kl_configure_target(struct ath6kl *ar); 587int ath6kl_configure_target(struct ath6kl *ar);
589void ath6kl_detect_error(unsigned long ptr); 588void ath6kl_detect_error(unsigned long ptr);
590void disconnect_timer_handler(unsigned long ptr); 589void disconnect_timer_handler(unsigned long ptr);
@@ -604,8 +603,6 @@ int ath6kl_diag_read(struct ath6kl *ar, u32 address, void *data, u32 length);
604int ath6kl_read_fwlogs(struct ath6kl *ar); 603int ath6kl_read_fwlogs(struct ath6kl *ar);
605void ath6kl_init_profile_info(struct ath6kl_vif *vif); 604void ath6kl_init_profile_info(struct ath6kl_vif *vif);
606void ath6kl_tx_data_cleanup(struct ath6kl *ar); 605void ath6kl_tx_data_cleanup(struct ath6kl *ar);
607void ath6kl_stop_endpoint(struct net_device *dev, bool keep_profile,
608 bool get_dbglogs);
609 606
610struct ath6kl_cookie *ath6kl_alloc_cookie(struct ath6kl *ar); 607struct ath6kl_cookie *ath6kl_alloc_cookie(struct ath6kl *ar);
611void ath6kl_free_cookie(struct ath6kl *ar, struct ath6kl_cookie *cookie); 608void 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,
657void ath6kl_wakeup_event(void *dev); 654void ath6kl_wakeup_event(void *dev);
658void ath6kl_target_failure(struct ath6kl *ar); 655void ath6kl_target_failure(struct ath6kl *ar);
659 656
657void ath6kl_reset_device(struct ath6kl *ar, u32 target_type,
658 bool wait_fot_compltn, bool cold_reset);
660void ath6kl_init_control_info(struct ath6kl_vif *vif); 659void ath6kl_init_control_info(struct ath6kl_vif *vif);
661void ath6kl_deinit_if_data(struct ath6kl_vif *vif); 660void ath6kl_deinit_if_data(struct ath6kl_vif *vif);
662void ath6kl_core_free(struct ath6kl *ar); 661void 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
516int ath6kl_unavail_ev(struct ath6kl *ar) 516void 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
1591static 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
1575void ath6kl_stop_txrx(struct ath6kl *ar) 1621void 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 */
1612void 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
398static void ath6kl_reset_device(struct ath6kl *ar, u32 target_type, 398void 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
430void 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
501static void ath6kl_install_static_wep_keys(struct ath6kl_vif *vif) 430static 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