Prechádzať zdrojové kódy

qcacld-3.0: Add CFR support for Hastings

Add CFR build flag and support CFR vendor command for Hastings.

Change-Id: I296d08b532e35c09669091ec7896fd8ab3636d31
CRs-Fixed: 2865391
Chaoli Zhou 4 rokov pred
rodič
commit
a41677c73f
2 zmenil súbory, kde vykonal 140 pridanie a 5 odobranie
  1. 4 0
      Kbuild
  2. 136 5
      core/hdd/src/wlan_hdd_cfr.c

+ 4 - 0
Kbuild

@@ -1088,6 +1088,9 @@ endif
 ifeq ($(CONFIG_WLAN_CFR_ADRASTEA),y)
 WLAN_CFR_OBJS += $(WLAN_COMMON_ROOT)/target_if/cfr/src/target_if_cfr_adrastea.o
 endif
+ifeq ($(CONFIG_WLAN_CFR_DBR),y)
+WLAN_CFR_OBJS += $(WLAN_COMMON_ROOT)/target_if/cfr/src/target_if_cfr_dbr.o
+endif
 endif
 
 $(call add-wlan-objs,wlan_cfr,$(WLAN_CFR_OBJS))
@@ -2855,6 +2858,7 @@ cppflags-$(CONFIG_WLAN_CFR_ENABLE) += -DWLAN_CFR_ENABLE
 cppflags-$(CONFIG_WLAN_ENH_CFR_ENABLE) += -DWLAN_ENH_CFR_ENABLE
 cppflags-$(CONFIG_WLAN_ENH_CFR_ENABLE) += -DWLAN_CFR_PM
 cppflags-$(CONFIG_WLAN_CFR_ADRASTEA) += -DWLAN_CFR_ADRASTEA
+cppflags-$(CONFIG_WLAN_CFR_DBR) += -DWLAN_CFR_DBR
 cppflags-$(CONFIG_WLAN_CFR_ENABLE) += -DCFR_USE_FIXED_FOLDER
 cppflags-$(CONFIG_WLAN_FEATURE_MEDIUM_ASSESS) += -DWLAN_FEATURE_MEDIUM_ASSESS
 cppflags-$(CONFIG_FEATURE_RADAR_HISTORY) += -DFEATURE_RADAR_HISTORY

+ 136 - 5
core/hdd/src/wlan_hdd_cfr.c

@@ -29,6 +29,7 @@
 #include "wlan_hdd_cfr.h"
 #include "wlan_cfr_ucfg_api.h"
 #include "wlan_hdd_object_manager.h"
+#include "wlan_cmn.h"
 
 const struct nla_policy cfr_config_policy[
 		QCA_WLAN_VENDOR_ATTR_PEER_CFR_MAX + 1] = {
@@ -442,7 +443,7 @@ wlan_cfg80211_peer_cfr_capture_cfg_adrastea(struct hdd_adapter *adapter,
 	}
 
 	vdev = adapter->vdev;
-	status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_CFR_ID);
+	status = hdd_objmgr_get_vdev_by_user(vdev, WLAN_CFR_ID);
 	if (QDF_IS_STATUS_ERROR(status)) {
 		hdd_err("failed to get vdev");
 		return status;
@@ -451,21 +452,21 @@ wlan_cfg80211_peer_cfr_capture_cfg_adrastea(struct hdd_adapter *adapter,
 	pdev = wlan_vdev_get_pdev(vdev);
 	if (!pdev) {
 		hdd_err("failed to get pdev");
-		wlan_objmgr_vdev_release_ref(vdev, WLAN_CFR_ID);
+		hdd_objmgr_put_vdev_by_user(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);
+		hdd_objmgr_put_vdev_by_user(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);
+		hdd_objmgr_put_vdev_by_user(vdev, WLAN_CFR_ID);
 		return QDF_STATUS_E_INVAL;
 	}
 
@@ -514,10 +515,140 @@ wlan_cfg80211_peer_cfr_capture_cfg_adrastea(struct hdd_adapter *adapter,
 	}
 exit:
 	wlan_objmgr_peer_release_ref(peer, WLAN_CFR_ID);
-	wlan_objmgr_vdev_release_ref(vdev, WLAN_CFR_ID);
+	hdd_objmgr_put_vdev_by_user(vdev, WLAN_CFR_ID);
+
+	return status;
+}
+#elif defined(WLAN_CFR_DBR)
+static enum
+phy_ch_width convert_capture_bw(enum nl80211_chan_width capture_bw)
+{
+	switch (capture_bw) {
+	case NL80211_CHAN_WIDTH_20_NOHT:
+	case NL80211_CHAN_WIDTH_20:
+		return CH_WIDTH_20MHZ;
+	case NL80211_CHAN_WIDTH_40:
+		return CH_WIDTH_40MHZ;
+	case NL80211_CHAN_WIDTH_80:
+		return CH_WIDTH_80MHZ;
+	case NL80211_CHAN_WIDTH_80P80:
+		return CH_WIDTH_80P80MHZ;
+	case NL80211_CHAN_WIDTH_160:
+		return CH_WIDTH_160MHZ;
+	case NL80211_CHAN_WIDTH_5:
+		return CH_WIDTH_5MHZ;
+	case NL80211_CHAN_WIDTH_10:
+		return CH_WIDTH_10MHZ;
+	default:
+		hdd_err("invalid capture bw");
+		return CH_WIDTH_INVALID;
+	}
+}
+
+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;
+	int id;
+
+	id = QCA_WLAN_VENDOR_ATTR_CFR_PEER_MAC_ADDR;
+	if (!tb[id]) {
+		hdd_err("peer mac addr not given");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	nla_memcpy(peer_addr.bytes, tb[id],
+		   QDF_MAC_ADDR_SIZE);
+
+	id = QCA_WLAN_VENDOR_ATTR_PEER_CFR_ENABLE;
+	if (tb[id])
+		is_start_capture = nla_get_flag(tb[id]);
+
+	vdev = adapter->vdev;
+	status = hdd_objmgr_get_vdev_by_user(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");
+		hdd_objmgr_put_vdev_by_user(vdev, WLAN_CFR_ID);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	psoc = wlan_vdev_get_psoc(vdev);
+	if (!psoc) {
+		hdd_err("Failed to get psoc");
+		hdd_objmgr_put_vdev_by_user(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");
+		hdd_objmgr_put_vdev_by_user(vdev, WLAN_CFR_ID);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (is_start_capture) {
+		id = QCA_WLAN_VENDOR_ATTR_PEER_CFR_PERIODICITY;
+		if (tb[id]) {
+			params.period = nla_get_u32(tb[id]);
+			hdd_debug("params.periodicity %d", params.period);
+			/* Set the periodic CFR */
+			if (params.period)
+				ucfg_cfr_set_timer(pdev, params.period);
+		}
+		id = QCA_WLAN_VENDOR_ATTR_PEER_CFR_METHOD;
+		if (tb[id]) {
+			params.method = nla_get_u8(tb[id]);
+			/* 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;
+			}
+		}
+		id = QCA_WLAN_VENDOR_ATTR_PEER_CFR_BANDWIDTH;
+		if (tb[id]) {
+			params.bandwidth = nla_get_u8(tb[id]);
+			params.bandwidth = convert_capture_bw(params.bandwidth);
+			if (params.bandwidth > NL80211_CHAN_WIDTH_80) {
+				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);
+		ucfg_cfr_stop_indication(vdev);
+	}
+exit:
+	wlan_objmgr_peer_release_ref(peer, WLAN_CFR_ID);
+	hdd_objmgr_put_vdev_by_user(vdev, WLAN_CFR_ID);
 
 	return status;
 }
+
 #else
 static QDF_STATUS
 wlan_cfg80211_peer_cfr_capture_cfg_adrastea(struct hdd_adapter *adapter,