Commit 4c9f8d11 authored by Yingying Tang's avatar Yingying Tang Committed by Kalle Valo
Browse files

ath10k: enable TDLS peer inactivity detection



Enable TDLS peer inactivity detetion feature.
QCA6174 firmware(version: WLAN.RM.4.4) support TDLS link inactivity detecting.
Set related parameters in TDLS WMI command to enable this feature.

Signed-off-by: default avatarYingying Tang <yintang@qti.qualcomm.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent 802ca335
Loading
Loading
Loading
Loading
+52 −0
Original line number Diff line number Diff line
@@ -426,6 +426,49 @@ static int ath10k_wmi_tlv_event_temperature(struct ath10k *ar,
	return 0;
}

static void ath10k_wmi_event_tdls_peer(struct ath10k *ar, struct sk_buff *skb)
{
	struct ieee80211_sta *station;
	const struct wmi_tlv_tdls_peer_event *ev;
	const void **tb;
	struct ath10k_vif *arvif;

	tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
	if (IS_ERR(tb)) {
		ath10k_warn(ar, "tdls peer failed to parse tlv");
		return;
	}
	ev = tb[WMI_TLV_TAG_STRUCT_TDLS_PEER_EVENT];
	if (!ev) {
		kfree(tb);
		ath10k_warn(ar, "tdls peer NULL event");
		return;
	}

	switch (__le32_to_cpu(ev->peer_reason)) {
	case WMI_TDLS_TEARDOWN_REASON_TX:
	case WMI_TDLS_TEARDOWN_REASON_RSSI:
	case WMI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT:
		station = ieee80211_find_sta_by_ifaddr(ar->hw,
						       ev->peer_macaddr.addr,
						       NULL);
		if (!station) {
			ath10k_warn(ar, "did not find station from tdls peer event");
			kfree(tb);
			return;
		}
		arvif = ath10k_get_arvif(ar, __le32_to_cpu(ev->vdev_id));
		ieee80211_tdls_oper_request(
					arvif->vif, station->addr,
					NL80211_TDLS_TEARDOWN,
					WLAN_REASON_TDLS_TEARDOWN_UNREACHABLE,
					GFP_ATOMIC
					);
		break;
	}
	kfree(tb);
}

/***********/
/* TLV ops */
/***********/
@@ -569,6 +612,9 @@ static void ath10k_wmi_tlv_op_rx(struct ath10k *ar, struct sk_buff *skb)
	case WMI_TLV_PDEV_TEMPERATURE_EVENTID:
		ath10k_wmi_tlv_event_temperature(ar, skb);
		break;
	case WMI_TLV_TDLS_PEER_EVENTID:
		ath10k_wmi_event_tdls_peer(ar, skb);
		break;
	default:
		ath10k_warn(ar, "Unknown eventid: %d\n", id);
		break;
@@ -2889,6 +2935,12 @@ ath10k_wmi_tlv_op_gen_update_fw_tdls_state(struct ath10k *ar, u32 vdev_id,
	if (test_bit(WMI_SERVICE_TDLS_UAPSD_BUFFER_STA, ar->wmi.svc_map))
		options |=  WMI_TLV_TDLS_BUFFER_STA_EN;

	/* WMI_TDLS_ENABLE_ACTIVE_EXTERNAL_CONTROL means firm will handle TDLS
	 * link inactivity detecting logic.
	 */
	if (state == WMI_TDLS_ENABLE_ACTIVE)
		state = WMI_TDLS_ENABLE_ACTIVE_EXTERNAL_CONTROL;

	len = sizeof(*tlv) + sizeof(*cmd);
	skb = ath10k_wmi_alloc_skb(ar, len);
	if (!skb)
+7 −0
Original line number Diff line number Diff line
@@ -1757,6 +1757,13 @@ struct wmi_tlv_tx_pause_ev {
	__le32 tid_map;
} __packed;

struct wmi_tlv_tdls_peer_event {
	struct wmi_mac_addr    peer_macaddr;
	__le32 peer_status;
	__le32 peer_reason;
	__le32 vdev_id;
} __packed;

void ath10k_wmi_tlv_attach(struct ath10k *ar);

struct wmi_tlv_mgmt_tx_cmd {
+1 −0
Original line number Diff line number Diff line
@@ -6792,6 +6792,7 @@ enum wmi_tdls_state {
	WMI_TDLS_DISABLE,
	WMI_TDLS_ENABLE_PASSIVE,
	WMI_TDLS_ENABLE_ACTIVE,
	WMI_TDLS_ENABLE_ACTIVE_EXTERNAL_CONTROL,
};

enum wmi_tdls_peer_state {