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
This commit is contained in:
Surabhi Vishnoi
2020-04-28 11:52:55 +05:30
committed by nshrivas
parent 361476e01b
commit 07fd1a8fe9
2 changed files with 120 additions and 1 deletions

View File

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

View File

@@ -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;
}