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

Commit 9e97d14b authored by John W. Linville's avatar John W. Linville
Browse files

Merge branch 'for-linville' of git://github.com/kvalo/ath6kl

parents ded652a6 6f7c1adb
Loading
Loading
Loading
Loading
+69 −40
Original line number Original line Diff line number Diff line
@@ -427,6 +427,30 @@ static bool ath6kl_is_tx_pending(struct ath6kl *ar)
	return ar->tx_pending[ath6kl_wmi_get_control_ep(ar->wmi)] == 0;
	return ar->tx_pending[ath6kl_wmi_get_control_ep(ar->wmi)] == 0;
}
}


static void ath6kl_cfg80211_sta_bmiss_enhance(struct ath6kl_vif *vif,
					      bool enable)
{
	int err;

	if (WARN_ON(!test_bit(WMI_READY, &vif->ar->flag)))
		return;

	if (vif->nw_type != INFRA_NETWORK)
		return;

	if (!test_bit(ATH6KL_FW_CAPABILITY_BMISS_ENHANCE,
		      vif->ar->fw_capabilities))
		return;

	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s fw bmiss enhance\n",
		   enable ? "enable" : "disable");

	err = ath6kl_wmi_sta_bmiss_enhance_cmd(vif->ar->wmi,
					       vif->fw_vif_idx, enable);
	if (err)
		ath6kl_err("failed to %s enhanced bmiss detection: %d\n",
			   enable ? "enable" : "disable", err);
}


static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
				   struct cfg80211_connect_params *sme)
				   struct cfg80211_connect_params *sme)
@@ -616,13 +640,13 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
					vif->req_bssid, vif->ch_hint,
					vif->req_bssid, vif->ch_hint,
					ar->connect_ctrl_flags, nw_subtype);
					ar->connect_ctrl_flags, nw_subtype);


	if (sme->bg_scan_period == 0) {
		/* disable background scan if period is 0 */
		/* disable background scan if period is 0 */
	if (sme->bg_scan_period == 0)
		sme->bg_scan_period = 0xffff;
		sme->bg_scan_period = 0xffff;

	} else if (sme->bg_scan_period == -1) {
		/* configure default value if not specified */
		/* configure default value if not specified */
	if (sme->bg_scan_period == -1)
		sme->bg_scan_period = DEFAULT_BG_SCAN_PERIOD;
		sme->bg_scan_period = DEFAULT_BG_SCAN_PERIOD;
	}


	ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx, 0, 0,
	ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx, 0, 0,
				  sme->bg_scan_period, 0, 0, 0, 3, 0, 0, 0);
				  sme->bg_scan_period, 0, 0, 0, 3, 0, 0, 0);
@@ -1454,10 +1478,10 @@ static int ath6kl_cfg80211_set_power_mgmt(struct wiphy *wiphy,
		return -EIO;
		return -EIO;


	if (pmgmt) {
	if (pmgmt) {
		ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: max perf\n", __func__);
		ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: rec power\n", __func__);
		mode.pwr_mode = REC_POWER;
		mode.pwr_mode = REC_POWER;
	} else {
	} else {
		ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: rec power\n", __func__);
		ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: max perf\n", __func__);
		mode.pwr_mode = MAX_PERF_POWER;
		mode.pwr_mode = MAX_PERF_POWER;
	}
	}


@@ -1509,7 +1533,7 @@ static int ath6kl_cfg80211_del_iface(struct wiphy *wiphy,
	list_del(&vif->list);
	list_del(&vif->list);
	spin_unlock_bh(&ar->list_lock);
	spin_unlock_bh(&ar->list_lock);


	ath6kl_cleanup_vif(vif, test_bit(WMI_READY, &ar->flag));
	ath6kl_cfg80211_vif_stop(vif, test_bit(WMI_READY, &ar->flag));


	ath6kl_cfg80211_vif_cleanup(vif);
	ath6kl_cfg80211_vif_cleanup(vif);


@@ -1559,17 +1583,13 @@ static int ath6kl_cfg80211_change_iface(struct wiphy *wiphy,
set_iface_type:
set_iface_type:
	switch (type) {
	switch (type) {
	case NL80211_IFTYPE_STATION:
	case NL80211_IFTYPE_STATION:
	case NL80211_IFTYPE_P2P_CLIENT:
		vif->next_mode = INFRA_NETWORK;
		vif->next_mode = INFRA_NETWORK;
		break;
		break;
	case NL80211_IFTYPE_ADHOC:
	case NL80211_IFTYPE_ADHOC:
		vif->next_mode = ADHOC_NETWORK;
		vif->next_mode = ADHOC_NETWORK;
		break;
		break;
	case NL80211_IFTYPE_AP:
	case NL80211_IFTYPE_AP:
		vif->next_mode = AP_NETWORK;
		break;
	case NL80211_IFTYPE_P2P_CLIENT:
		vif->next_mode = INFRA_NETWORK;
		break;
	case NL80211_IFTYPE_P2P_GO:
	case NL80211_IFTYPE_P2P_GO:
		vif->next_mode = AP_NETWORK;
		vif->next_mode = AP_NETWORK;
		break;
		break;
@@ -2673,30 +2693,6 @@ static int ath6kl_set_ies(struct ath6kl_vif *vif,
	return 0;
	return 0;
}
}


void ath6kl_cfg80211_sta_bmiss_enhance(struct ath6kl_vif *vif, bool enable)
{
	int err;

	if (WARN_ON(!test_bit(WMI_READY, &vif->ar->flag)))
		return;

	if (vif->nw_type != INFRA_NETWORK)
		return;

	if (!test_bit(ATH6KL_FW_CAPABILITY_BMISS_ENHANCE,
		      vif->ar->fw_capabilities))
		return;

	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s fw bmiss enhance\n",
		   enable ? "enable" : "disable");

	err = ath6kl_wmi_sta_bmiss_enhance_cmd(vif->ar->wmi,
					       vif->fw_vif_idx, enable);
	if (err)
		ath6kl_err("failed to %s enhanced bmiss detection: %d\n",
			   enable ? "enable" : "disable", err);
}

static int ath6kl_get_rsn_capab(struct cfg80211_beacon_data *beacon,
static int ath6kl_get_rsn_capab(struct cfg80211_beacon_data *beacon,
				u8 *rsn_capab)
				u8 *rsn_capab)
{
{
@@ -2776,9 +2772,11 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev,


	ar->ap_mode_bkey.valid = false;
	ar->ap_mode_bkey.valid = false;


	/* TODO:
	ret = ath6kl_wmi_ap_set_beacon_intvl_cmd(ar->wmi, vif->fw_vif_idx,
	 * info->interval
						 info->beacon_interval);
	 */

	if (ret)
		ath6kl_warn("Failed to set beacon interval: %d\n", ret);


	ret = ath6kl_wmi_ap_set_dtim_cmd(ar->wmi, vif->fw_vif_idx,
	ret = ath6kl_wmi_ap_set_dtim_cmd(ar->wmi, vif->fw_vif_idx,
					 info->dtim_period);
					 info->dtim_period);
@@ -3557,6 +3555,37 @@ static int ath6kl_cfg80211_vif_init(struct ath6kl_vif *vif)
	return 0;
	return 0;
}
}


void ath6kl_cfg80211_vif_stop(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;
	}

	/* need to clean up enhanced bmiss detection fw state */
	ath6kl_cfg80211_sta_bmiss_enhance(vif, false);
}

void ath6kl_cfg80211_vif_cleanup(struct ath6kl_vif *vif)
void ath6kl_cfg80211_vif_cleanup(struct ath6kl_vif *vif)
{
{
	struct ath6kl *ar = vif->ar;
	struct ath6kl *ar = vif->ar;
+0 −2
Original line number Original line Diff line number Diff line
@@ -61,7 +61,5 @@ void ath6kl_cfg80211_cleanup(struct ath6kl *ar);


struct ath6kl *ath6kl_cfg80211_create(void);
struct ath6kl *ath6kl_cfg80211_create(void);
void ath6kl_cfg80211_destroy(struct ath6kl *ar);
void ath6kl_cfg80211_destroy(struct ath6kl *ar);
/* TODO: remove this once ath6kl_vif_cleanup() is moved to cfg80211.c */
void ath6kl_cfg80211_sta_bmiss_enhance(struct ath6kl_vif *vif, bool enable);


#endif /* ATH6KL_CFG80211_H */
#endif /* ATH6KL_CFG80211_H */
+1 −1
Original line number Original line Diff line number Diff line
@@ -940,7 +940,7 @@ void ath6kl_reset_device(struct ath6kl *ar, u32 target_type,
			 bool wait_fot_compltn, bool cold_reset);
			 bool wait_fot_compltn, bool cold_reset);
void ath6kl_init_control_info(struct ath6kl_vif *vif);
void ath6kl_init_control_info(struct ath6kl_vif *vif);
struct ath6kl_vif *ath6kl_vif_first(struct ath6kl *ar);
struct ath6kl_vif *ath6kl_vif_first(struct ath6kl *ar);
void ath6kl_cleanup_vif(struct ath6kl_vif *vif, bool wmi_ready);
void ath6kl_cfg80211_vif_stop(struct ath6kl_vif *vif, bool wmi_ready);
int ath6kl_init_hw_start(struct ath6kl *ar);
int ath6kl_init_hw_start(struct ath6kl *ar);
int ath6kl_init_hw_stop(struct ath6kl *ar);
int ath6kl_init_hw_stop(struct ath6kl *ar);
int ath6kl_init_fetch_firmwares(struct ath6kl *ar);
int ath6kl_init_fetch_firmwares(struct ath6kl *ar);
+20 −6
Original line number Original line Diff line number Diff line
@@ -509,9 +509,7 @@ static void destroy_htc_txctrl_packet(struct htc_packet *packet)
{
{
	struct sk_buff *skb;
	struct sk_buff *skb;
	skb = packet->skb;
	skb = packet->skb;
	if (skb != NULL)
	dev_kfree_skb(skb);
	dev_kfree_skb(skb);

	kfree(packet);
	kfree(packet);
}
}


@@ -969,6 +967,22 @@ static int ath6kl_htc_pipe_rx_complete(struct ath6kl *ar, struct sk_buff *skb,
	u16 payload_len;
	u16 payload_len;
	int status = 0;
	int status = 0;


	/*
	 * ar->htc_target can be NULL due to a race condition that can occur
	 * during driver initialization(we do 'ath6kl_hif_power_on' before
	 * initializing 'ar->htc_target' via 'ath6kl_htc_create').
	 * 'ath6kl_hif_power_on' assigns 'ath6kl_recv_complete' as
	 * usb_complete_t/callback function for 'usb_fill_bulk_urb'.
	 * Thus the possibility of ar->htc_target being NULL
	 * via ath6kl_recv_complete -> ath6kl_usb_io_comp_work.
	 */
	if (WARN_ON_ONCE(!target)) {
		ath6kl_err("Target not yet initialized\n");
		status = -EINVAL;
		goto free_skb;
	}


	netdata = skb->data;
	netdata = skb->data;
	netlen = skb->len;
	netlen = skb->len;


@@ -1054,6 +1068,7 @@ static int ath6kl_htc_pipe_rx_complete(struct ath6kl *ar, struct sk_buff *skb,


		dev_kfree_skb(skb);
		dev_kfree_skb(skb);
		skb = NULL;
		skb = NULL;

		goto free_skb;
		goto free_skb;
	}
	}


@@ -1089,7 +1104,6 @@ static int ath6kl_htc_pipe_rx_complete(struct ath6kl *ar, struct sk_buff *skb,
	skb = NULL;
	skb = NULL;


free_skb:
free_skb:
	if (skb != NULL)
	dev_kfree_skb(skb);
	dev_kfree_skb(skb);


	return status;
	return status;
@@ -1184,7 +1198,7 @@ static void reset_endpoint_states(struct htc_target *target)
		INIT_LIST_HEAD(&ep->pipe.tx_lookup_queue);
		INIT_LIST_HEAD(&ep->pipe.tx_lookup_queue);
		INIT_LIST_HEAD(&ep->rx_bufq);
		INIT_LIST_HEAD(&ep->rx_bufq);
		ep->target = target;
		ep->target = target;
		ep->pipe.tx_credit_flow_enabled = (bool) 1; /* FIXME */
		ep->pipe.tx_credit_flow_enabled = true;
	}
	}
}
}


+1 −35
Original line number Original line Diff line number Diff line
@@ -1715,38 +1715,6 @@ void ath6kl_init_hw_restart(struct ath6kl *ar)
	}
	}
}
}


/* FIXME: move this to cfg80211.c and rename to ath6kl_cfg80211_vif_stop() */
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;
	}

	/* need to clean up enhanced bmiss detection fw state */
	ath6kl_cfg80211_sta_bmiss_enhance(vif, false);
}

void ath6kl_stop_txrx(struct ath6kl *ar)
void ath6kl_stop_txrx(struct ath6kl *ar)
{
{
	struct ath6kl_vif *vif, *tmp_vif;
	struct ath6kl_vif *vif, *tmp_vif;
@@ -1766,7 +1734,7 @@ void ath6kl_stop_txrx(struct ath6kl *ar)
	list_for_each_entry_safe(vif, tmp_vif, &ar->vif_list, list) {
	list_for_each_entry_safe(vif, tmp_vif, &ar->vif_list, list) {
		list_del(&vif->list);
		list_del(&vif->list);
		spin_unlock_bh(&ar->list_lock);
		spin_unlock_bh(&ar->list_lock);
		ath6kl_cleanup_vif(vif, test_bit(WMI_READY, &ar->flag));
		ath6kl_cfg80211_vif_stop(vif, test_bit(WMI_READY, &ar->flag));
		rtnl_lock();
		rtnl_lock();
		ath6kl_cfg80211_vif_cleanup(vif);
		ath6kl_cfg80211_vif_cleanup(vif);
		rtnl_unlock();
		rtnl_unlock();
@@ -1801,8 +1769,6 @@ void ath6kl_stop_txrx(struct ath6kl *ar)
		   "attempting to reset target on instance destroy\n");
		   "attempting to reset target on instance destroy\n");
	ath6kl_reset_device(ar, ar->target_type, true, true);
	ath6kl_reset_device(ar, ar->target_type, true, true);


	clear_bit(WLAN_ENABLED, &ar->flag);

	up(&ar->sem);
	up(&ar->sem);
}
}
EXPORT_SYMBOL(ath6kl_stop_txrx);
EXPORT_SYMBOL(ath6kl_stop_txrx);
Loading