Parcourir la source

qcacld-3.0: Add support to handle CFR vendor command for adrastea

Adrastea target expects different attributes in vendor command
QCA_NL80211_VENDOR_SUBCMD_PEER_CFR_CAPTURE_CFG. So add an api to parse
the vendor command  QCA_NL80211_VENDOR_SUBCMD_PEER_CFR_CAPTURE_CFG
which will be called based on CFR version type.

Change-Id: I965b3cd6b93a288f1074ea0c09306cfff9f6ced0
CRs-Fixed: 2687075
Surabhi Vishnoi il y a 5 ans
Parent
commit
07fd1a8fe9
2 fichiers modifiés avec 120 ajouts et 1 suppressions
  1. 1 0
      core/hdd/inc/wlan_hdd_cfr.h
  2. 119 1
      core/hdd/src/wlan_hdd_cfr.c

+ 1 - 0
core/hdd/inc/wlan_hdd_cfr.h

@@ -27,6 +27,7 @@
 #ifdef WLAN_CFR_ENABLE
 
 #define HDD_INVALID_GROUP_ID 16
+#define LEGACY_CFR_VERSION 1
 #define ENHANCED_CFR_VERSION 2
 
 /**

+ 119 - 1
core/hdd/src/wlan_hdd_cfr.c

@@ -281,6 +281,119 @@ wlan_cfg80211_cfr_set_config(struct wlan_objmgr_vdev *vdev,
 	return 0;
 }
 
+#ifdef WLAN_CFR_ADRASTEA
+static QDF_STATUS
+wlan_cfg80211_peer_cfr_capture_cfg_adrastea(struct hdd_adapter *adapter,
+					    struct nlattr **tb)
+{
+	struct cfr_capture_params params = { 0 };
+	struct wlan_objmgr_vdev *vdev;
+	struct wlan_objmgr_pdev *pdev;
+	struct wlan_objmgr_peer *peer;
+	struct wlan_objmgr_psoc *psoc;
+	struct qdf_mac_addr peer_addr;
+	bool is_start_capture = false;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	if (!tb[QCA_WLAN_VENDOR_ATTR_CFR_PEER_MAC_ADDR]) {
+		hdd_err("peer mac addr not given");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	nla_memcpy(peer_addr.bytes, tb[QCA_WLAN_VENDOR_ATTR_CFR_PEER_MAC_ADDR],
+		   QDF_MAC_ADDR_SIZE);
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_PEER_CFR_ENABLE]) {
+		is_start_capture = nla_get_flag(tb[
+			QCA_WLAN_VENDOR_ATTR_PEER_CFR_ENABLE]);
+	}
+
+	vdev = adapter->vdev;
+	status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_CFR_ID);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("failed to get vdev");
+		return status;
+	}
+
+	pdev = wlan_vdev_get_pdev(vdev);
+	if (!pdev) {
+		hdd_err("failed to get pdev");
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_CFR_ID);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	psoc = wlan_vdev_get_psoc(vdev);
+	if (!psoc) {
+		hdd_err("Failed to get psoc");
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_CFR_ID);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	peer = wlan_objmgr_get_peer_by_mac(psoc, peer_addr.bytes, WLAN_CFR_ID);
+	if (!peer) {
+		hdd_err("No peer object found");
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_CFR_ID);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (is_start_capture) {
+		if (tb[QCA_WLAN_VENDOR_ATTR_PEER_CFR_PERIODICITY]) {
+			params.period = nla_get_u32(tb[
+				QCA_WLAN_VENDOR_ATTR_PEER_CFR_PERIODICITY]);
+			hdd_debug("params.periodicity %d", params.period);
+			/* Set the periodic CFR */
+			if (params.period)
+				ucfg_cfr_set_timer(pdev, params.period);
+		}
+
+		if (tb[QCA_WLAN_VENDOR_ATTR_PEER_CFR_METHOD]) {
+			params.method = nla_get_u8(tb[
+				QCA_WLAN_VENDOR_ATTR_PEER_CFR_METHOD]);
+			/* Adrastea supports only QOS NULL METHOD */
+			if (params.method !=
+					QCA_WLAN_VENDOR_CFR_METHOD_QOS_NULL) {
+				hdd_err_rl("invalid capture method %d",
+					   params.method);
+				status = QDF_STATUS_E_INVAL;
+				goto exit;
+			}
+		}
+
+		if (tb[QCA_WLAN_VENDOR_ATTR_PEER_CFR_BANDWIDTH]) {
+			params.bandwidth = nla_get_u8(tb[
+				QCA_WLAN_VENDOR_ATTR_PEER_CFR_BANDWIDTH]);
+			/* Adrastea supports only 20Mhz bandwidth CFR capture */
+			if (params.bandwidth != NL80211_CHAN_WIDTH_20_NOHT) {
+				hdd_err_rl("invalid capture bandwidth %d",
+					   params.bandwidth);
+				status = QDF_STATUS_E_INVAL;
+				goto exit;
+			}
+		}
+		ucfg_cfr_start_capture(pdev, peer, &params);
+	} else {
+		/* Disable the periodic CFR if enabled */
+		if (ucfg_cfr_get_timer(pdev))
+			ucfg_cfr_set_timer(pdev, 0);
+
+		/* Disable the peer CFR capture */
+		ucfg_cfr_stop_capture(pdev, peer);
+	}
+exit:
+	wlan_objmgr_peer_release_ref(peer, WLAN_CFR_ID);
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_CFR_ID);
+
+	return status;
+}
+#else
+static QDF_STATUS
+wlan_cfg80211_peer_cfr_capture_cfg_adrastea(struct hdd_adapter *adapter,
+					    struct nlattr **tb)
+{
+	return QDF_STATUS_E_NOSUPPORT;
+}
+#endif
+
 static int
 wlan_cfg80211_peer_enh_cfr_capture(struct hdd_adapter *adapter,
 				   struct nlattr **tb)
@@ -352,6 +465,7 @@ wlan_cfg80211_peer_cfr_capture_cfg(struct wiphy *wiphy,
 {
 	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_PEER_CFR_MAX + 1];
 	uint8_t version = 0;
+	QDF_STATUS status;
 
 	if (wlan_cfg80211_nla_parse(
 			tb,
@@ -367,7 +481,11 @@ wlan_cfg80211_peer_cfr_capture_cfg(struct wiphy *wiphy,
 		version = nla_get_u8(tb[
 			QCA_WLAN_VENDOR_ATTR_PEER_CFR_VERSION]);
 		hdd_debug("version %d", version);
-		if (version != ENHANCED_CFR_VERSION) {
+		if (version == LEGACY_CFR_VERSION) {
+			status = wlan_cfg80211_peer_cfr_capture_cfg_adrastea(
+								adapter, tb);
+			return qdf_status_to_os_return(status);
+		} else if (version != ENHANCED_CFR_VERSION) {
 			hdd_err("unsupported version");
 			return -EFAULT;
 		}