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

Commit 46acf7bb authored by Ben Greear's avatar Ben Greear Committed by Kalle Valo
Browse files

ath10k: support get/set antenna configurations.



Verified that target's tx/rx chain register is set appropriately,
and that the tx rate goes down as number of chains
decrease, but I did not actually try to verify antenna
ceased to transmit when disabled.

kvalo: move ar->supp_*_chainmask initialisation to ath10k_mac_register()

Signed-off-by: default avatarBen Greear <greearb@candelatech.com>
Signed-off-by: default avatarAvery Pennarun <apenwarr@gmail.com>
Signed-off-by: default avatarKalle Valo <kvalo@qca.qualcomm.com>
parent eeab266c
Loading
Loading
Loading
Loading
+6 −0
Original line number Original line Diff line number Diff line
@@ -440,6 +440,12 @@ struct ath10k {
	bool radar_enabled;
	bool radar_enabled;
	int num_started_vdevs;
	int num_started_vdevs;


	/* Protected by conf-mutex */
	u8 supp_tx_chainmask;
	u8 supp_rx_chainmask;
	u8 cfg_tx_chainmask;
	u8 cfg_rx_chainmask;

	struct wmi_pdev_set_wmm_params_arg wmm_params;
	struct wmi_pdev_set_wmm_params_arg wmm_params;
	struct completion install_key_done;
	struct completion install_key_done;


+80 −0
Original line number Original line Diff line number Diff line
@@ -2332,6 +2332,68 @@ void ath10k_halt(struct ath10k *ar)
	spin_unlock_bh(&ar->data_lock);
	spin_unlock_bh(&ar->data_lock);
}
}


static int ath10k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant)
{
	struct ath10k *ar = hw->priv;

	mutex_lock(&ar->conf_mutex);

	if (ar->cfg_tx_chainmask) {
		*tx_ant = ar->cfg_tx_chainmask;
		*rx_ant = ar->cfg_rx_chainmask;
	} else {
		*tx_ant = ar->supp_tx_chainmask;
		*rx_ant = ar->supp_rx_chainmask;
	}

	mutex_unlock(&ar->conf_mutex);

	return 0;
}

static int __ath10k_set_antenna(struct ath10k *ar, u32 tx_ant, u32 rx_ant)
{
	int ret;

	lockdep_assert_held(&ar->conf_mutex);

	ar->cfg_tx_chainmask = tx_ant;
	ar->cfg_rx_chainmask = rx_ant;

	if ((ar->state != ATH10K_STATE_ON) &&
	    (ar->state != ATH10K_STATE_RESTARTED))
		return 0;

	ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->tx_chain_mask,
					tx_ant);
	if (ret) {
		ath10k_warn("failed to set tx-chainmask: %d, req 0x%x\n",
			    ret, tx_ant);
		return ret;
	}

	ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->rx_chain_mask,
					rx_ant);
	if (ret) {
		ath10k_warn("failed to set rx-chainmask: %d, req 0x%x\n",
			    ret, rx_ant);
		return ret;
	}

	return 0;
}

static int ath10k_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
{
	struct ath10k *ar = hw->priv;
	int ret;

	mutex_lock(&ar->conf_mutex);
	ret = __ath10k_set_antenna(ar, tx_ant, rx_ant);
	mutex_unlock(&ar->conf_mutex);
	return ret;
}

static int ath10k_start(struct ieee80211_hw *hw)
static int ath10k_start(struct ieee80211_hw *hw)
{
{
	struct ath10k *ar = hw->priv;
	struct ath10k *ar = hw->priv;
@@ -2373,6 +2435,10 @@ static int ath10k_start(struct ieee80211_hw *hw)
	if (ret)
	if (ret)
		ath10k_warn("failed to enable dynamic BW: %d\n", ret);
		ath10k_warn("failed to enable dynamic BW: %d\n", ret);


	if (ar->cfg_tx_chainmask)
		__ath10k_set_antenna(ar, ar->cfg_tx_chainmask,
				     ar->cfg_rx_chainmask);

	/*
	/*
	 * By default FW set ARP frames ac to voice (6). In that case ARP
	 * By default FW set ARP frames ac to voice (6). In that case ARP
	 * exchange is not working properly for UAPSD enabled AP. ARP requests
	 * exchange is not working properly for UAPSD enabled AP. ARP requests
@@ -4256,6 +4322,8 @@ static const struct ieee80211_ops ath10k_ops = {
	.set_frag_threshold		= ath10k_set_frag_threshold,
	.set_frag_threshold		= ath10k_set_frag_threshold,
	.flush				= ath10k_flush,
	.flush				= ath10k_flush,
	.tx_last_beacon			= ath10k_tx_last_beacon,
	.tx_last_beacon			= ath10k_tx_last_beacon,
	.set_antenna			= ath10k_set_antenna,
	.get_antenna			= ath10k_get_antenna,
	.restart_complete		= ath10k_restart_complete,
	.restart_complete		= ath10k_restart_complete,
	.get_survey			= ath10k_get_survey,
	.get_survey			= ath10k_get_survey,
	.set_bitrate_mask		= ath10k_set_bitrate_mask,
	.set_bitrate_mask		= ath10k_set_bitrate_mask,
@@ -4605,6 +4673,18 @@ int ath10k_mac_register(struct ath10k *ar)
		BIT(NL80211_IFTYPE_ADHOC) |
		BIT(NL80211_IFTYPE_ADHOC) |
		BIT(NL80211_IFTYPE_AP);
		BIT(NL80211_IFTYPE_AP);


	if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) {
		/* TODO:  Have to deal with 2x2 chips if/when the come out. */
		ar->supp_tx_chainmask = TARGET_10X_TX_CHAIN_MASK;
		ar->supp_rx_chainmask = TARGET_10X_RX_CHAIN_MASK;
	} else {
		ar->supp_tx_chainmask = TARGET_TX_CHAIN_MASK;
		ar->supp_rx_chainmask = TARGET_RX_CHAIN_MASK;
	}

	ar->hw->wiphy->available_antennas_rx = ar->supp_rx_chainmask;
	ar->hw->wiphy->available_antennas_tx = ar->supp_tx_chainmask;

	if (!test_bit(ATH10K_FW_FEATURE_NO_P2P, ar->fw_features))
	if (!test_bit(ATH10K_FW_FEATURE_NO_P2P, ar->fw_features))
		ar->hw->wiphy->interface_modes |=
		ar->hw->wiphy->interface_modes |=
			BIT(NL80211_IFTYPE_P2P_CLIENT) |
			BIT(NL80211_IFTYPE_P2P_CLIENT) |