Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6db8fa53 authored by Vasanthakumar Thiagarajan's avatar Vasanthakumar Thiagarajan Committed by Kalle Valo
Browse files

ath6kl: Refactor ath6kl_destroy()



So that the deinitialization of ath6kl and vif are separated.

Signed-off-by: default avatarVasanthakumar Thiagarajan <vthiagar@qca.qualcomm.com>
Signed-off-by: default avatarKalle Valo <kvalo@qca.qualcomm.com>
parent e29f25f5
Loading
Loading
Loading
Loading
+0 −8
Original line number Diff line number Diff line
@@ -2143,14 +2143,6 @@ err:

void ath6kl_deinit_ieee80211_hw(struct ath6kl *ar)
{
	/* TODO: Findout vif */
	struct ath6kl_vif *vif = ar->vif;

	if (vif->scan_req) {
		cfg80211_scan_done(vif->scan_req, true);
		vif->scan_req = NULL;
	}

	wiphy_unregister(ar->wiphy);
	wiphy_free(ar->wiphy);
}
+1 −1
Original line number Diff line number Diff line
@@ -92,6 +92,6 @@ void ath6k_seek_credits(struct htc_credit_state_info *cred_inf,
			struct htc_endpoint_credit_dist *ep_dist);
struct ath6kl *ath6kl_core_alloc(struct device *sdev);
int ath6kl_core_init(struct ath6kl *ar);
int ath6kl_unavail_ev(struct ath6kl *ar);
void ath6kl_core_cleanup(struct ath6kl *ar);
struct sk_buff *ath6kl_buf_alloc(int size);
#endif /* COMMON_H */
+2 −3
Original line number Diff line number Diff line
@@ -584,7 +584,6 @@ static inline u32 ath6kl_get_hi_item_addr(struct ath6kl *ar,
	return addr;
}

void ath6kl_destroy(struct net_device *dev, unsigned int unregister);
int ath6kl_configure_target(struct ath6kl *ar);
void ath6kl_detect_error(unsigned long ptr);
void disconnect_timer_handler(unsigned long ptr);
@@ -604,8 +603,6 @@ int ath6kl_diag_read(struct ath6kl *ar, u32 address, void *data, u32 length);
int ath6kl_read_fwlogs(struct ath6kl *ar);
void ath6kl_init_profile_info(struct ath6kl_vif *vif);
void ath6kl_tx_data_cleanup(struct ath6kl *ar);
void ath6kl_stop_endpoint(struct net_device *dev, bool keep_profile,
			  bool get_dbglogs);

struct ath6kl_cookie *ath6kl_alloc_cookie(struct ath6kl *ar);
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,
void ath6kl_wakeup_event(void *dev);
void ath6kl_target_failure(struct ath6kl *ar);

void ath6kl_reset_device(struct ath6kl *ar, u32 target_type,
			 bool wait_fot_compltn, bool cold_reset);
void ath6kl_init_control_info(struct ath6kl_vif *vif);
void ath6kl_deinit_if_data(struct ath6kl_vif *vif);
void ath6kl_core_free(struct ath6kl *ar);
+73 −51
Original line number Diff line number Diff line
@@ -513,11 +513,27 @@ void ath6kl_core_free(struct ath6kl *ar)
	wiphy_free(ar->wiphy);
}

int ath6kl_unavail_ev(struct ath6kl *ar)
void ath6kl_core_cleanup(struct ath6kl *ar)
{
	ath6kl_destroy(ar->vif->ndev, 1);
	destroy_workqueue(ar->ath6kl_wq);

	return 0;
	if (ar->htc_target)
		ath6kl_htc_cleanup(ar->htc_target);

	ath6kl_cookie_cleanup(ar);

	ath6kl_cleanup_amsdu_rxbufs(ar);

	ath6kl_bmi_cleanup(ar);

	ath6kl_debug_cleanup(ar);

	kfree(ar->fw_board);
	kfree(ar->fw_otp);
	kfree(ar->fw);
	kfree(ar->fw_patch);

	ath6kl_deinit_ieee80211_hw(ar);
}

/* firmware upload */
@@ -1572,6 +1588,36 @@ err_wq:
	return ret;
}

static void ath6kl_cleanup_vif(struct ath6kl_vif *vif, bool wmi_ready)
{
	static u8 bcast_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
	bool discon_issued;

	netif_stop_queue(vif->ndev);

	clear_bit(WLAN_ENABLED, &vif->flags);

	if (wmi_ready) {
		discon_issued = test_bit(CONNECTED, &vif->flags) ||
				test_bit(CONNECT_PEND, &vif->flags);
		ath6kl_disconnect(vif);
		del_timer(&vif->disconnect_timer);

		if (discon_issued)
			ath6kl_disconnect_event(vif, DISCONNECT_CMD,
						(vif->nw_type & AP_NETWORK) ?
						bcast_mac : vif->bssid,
						0, NULL, 0);
	}

	if (vif->scan_req) {
		cfg80211_scan_done(vif->scan_req, true);
		vif->scan_req = NULL;
	}

	ath6kl_deinit_if_data(vif);
}

void ath6kl_stop_txrx(struct ath6kl *ar)
{
	struct ath6kl_vif *vif = ar->vif;
@@ -1587,58 +1633,34 @@ void ath6kl_stop_txrx(struct ath6kl *ar)
		return;
	}

	if (ar->wlan_pwr_state != WLAN_POWER_STATE_CUT_PWR)
		ath6kl_stop_endpoint(ndev, false, true);
	ath6kl_cleanup_vif(ar->vif, test_bit(WMI_READY, &ar->flag));

	clear_bit(WLAN_ENABLED, &vif->flags);
}
	clear_bit(WMI_READY, &ar->flag);

	/*
 * We need to differentiate between the surprise and planned removal of the
 * device because of the following consideration:
 *
 * - In case of surprise removal, the hcd already frees up the pending
 *   for the device and hence there is no need to unregister the function
 *   driver inorder to get these requests. For planned removal, the function
 *   driver has to explicitly unregister itself to have the hcd return all the
 *   pending requests before the data structures for the devices are freed up.
 *   Note that as per the current implementation, the function driver will
 *   end up releasing all the devices since there is no API to selectively
 *   release a particular device.
 *
 * - Certain commands issued to the target can be skipped for surprise
 *   removal since they will anyway not go through.
	 * After wmi_shudown all WMI events will be dropped. We
	 * need to cleanup the buffers allocated in AP mode and
	 * give disconnect notification to stack, which usually
	 * happens in the disconnect_event. Simulate the disconnect
	 * event by calling the function directly. Sometimes
	 * disconnect_event will be received when the debug logs
	 * are collected.
	 */
void ath6kl_destroy(struct net_device *dev, unsigned int unregister)
{
	struct ath6kl *ar;
	ath6kl_wmi_shutdown(ar->wmi);

	if (!dev || !ath6kl_priv(dev)) {
		ath6kl_err("failed to get device structure\n");
		return;
	clear_bit(WMI_ENABLED, &ar->flag);
	if (ar->htc_target) {
		ath6kl_dbg(ATH6KL_DBG_TRC, "%s: shut down htc\n", __func__);
		ath6kl_htc_stop(ar->htc_target);
	}

	ar = ath6kl_priv(dev);

	destroy_workqueue(ar->ath6kl_wq);

	if (ar->htc_target)
		ath6kl_htc_cleanup(ar->htc_target);

	ath6kl_cookie_cleanup(ar);

	ath6kl_cleanup_amsdu_rxbufs(ar);

	ath6kl_bmi_cleanup(ar);

	ath6kl_debug_cleanup(ar);

	ath6kl_deinit_if_data(netdev_priv(dev));

	kfree(ar->fw_board);
	kfree(ar->fw_otp);
	kfree(ar->fw);
	kfree(ar->fw_patch);
	/*
	 * Try to reset the device if we can. The driver may have been
	 * configure NOT to reset the target during a debug session.
	 */
	ath6kl_dbg(ATH6KL_DBG_TRC,
			"attempting to reset target on instance destroy\n");
	ath6kl_reset_device(ar, ar->target_type, true, true);

	ath6kl_deinit_ieee80211_hw(ar);
	clear_bit(WLAN_ENABLED, &ar->flag);
}
+2 −73
Original line number Diff line number Diff line
@@ -395,7 +395,7 @@ out:
#define AR6003_RESET_CONTROL_ADDRESS 0x00004000
#define AR6004_RESET_CONTROL_ADDRESS 0x00004000

static void ath6kl_reset_device(struct ath6kl *ar, u32 target_type,
void ath6kl_reset_device(struct ath6kl *ar, u32 target_type,
			 bool wait_fot_compltn, bool cold_reset)
{
	int status = 0;
@@ -427,77 +427,6 @@ static void ath6kl_reset_device(struct ath6kl *ar, u32 target_type,
		ath6kl_err("failed to reset target\n");
}

void ath6kl_stop_endpoint(struct net_device *dev, bool keep_profile,
			  bool get_dbglogs)
{
	struct ath6kl *ar = ath6kl_priv(dev);
	struct ath6kl_vif *vif = netdev_priv(dev);
	static u8 bcast_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
	bool discon_issued;

	netif_stop_queue(dev);

	/* disable the target and the interrupts associated with it */
	if (test_bit(WMI_READY, &ar->flag)) {
		discon_issued = (test_bit(CONNECTED, &vif->flags) ||
				 test_bit(CONNECT_PEND, &vif->flags));
		ath6kl_disconnect(vif);
		if (!keep_profile)
			ath6kl_init_profile_info(vif);

		del_timer(&vif->disconnect_timer);

		clear_bit(WMI_READY, &ar->flag);
		ath6kl_wmi_shutdown(ar->wmi);
		clear_bit(WMI_ENABLED, &ar->flag);
		ar->wmi = NULL;

		/*
		 * After wmi_shudown all WMI events will be dropped. We
		 * need to cleanup the buffers allocated in AP mode and
		 * give disconnect notification to stack, which usually
		 * happens in the disconnect_event. Simulate the disconnect
		 * event by calling the function directly. Sometimes
		 * disconnect_event will be received when the debug logs
		 * are collected.
		 */
		if (discon_issued)
			ath6kl_disconnect_event(vif, DISCONNECT_CMD,
						(vif->nw_type & AP_NETWORK) ?
						bcast_mac : vif->bssid,
						0, NULL, 0);

		ar->user_key_ctrl = 0;

	} else {
		ath6kl_dbg(ATH6KL_DBG_TRC,
			   "%s: wmi is not ready 0x%p 0x%p\n",
			   __func__, ar, ar->wmi);

		/* Shut down WMI if we have started it */
		if (test_bit(WMI_ENABLED, &ar->flag)) {
			ath6kl_dbg(ATH6KL_DBG_TRC,
				   "%s: shut down wmi\n", __func__);
			ath6kl_wmi_shutdown(ar->wmi);
			clear_bit(WMI_ENABLED, &ar->flag);
			ar->wmi = NULL;
		}
	}

	if (ar->htc_target) {
		ath6kl_dbg(ATH6KL_DBG_TRC, "%s: shut down htc\n", __func__);
		ath6kl_htc_stop(ar->htc_target);
	}

	/*
	 * Try to reset the device if we can. The driver may have been
	 * configure NOT to reset the target during a debug session.
	 */
	ath6kl_dbg(ATH6KL_DBG_TRC,
		   "attempting to reset target on instance destroy\n");
	ath6kl_reset_device(ar, ar->target_type, true, true);
}

static void ath6kl_install_static_wep_keys(struct ath6kl_vif *vif)
{
	u8 index;
Loading