qcacld-3.0: Add peer ops support for SON

Add support for below SON peer ops:

PEER_SET_KICKOUT
PEER_SET_EXT_STATS
PEER_REQ_INST_STAT
PEER_GET_MAX_MCS

Change-Id: Iafadd17d6a13cfbba2884e50a0432c34115cd7f7
CRs-Fixed: 3141862
This commit is contained in:
Rachit Kankane
2021-10-13 18:53:59 +05:30
committed by Madan Koyyalamudi
parent 937e42e0a5
commit 95c7d2ecf8
8 changed files with 218 additions and 0 deletions

View File

@@ -206,6 +206,35 @@ QDF_STATUS
wlan_son_register_mlme_deliver_cb(struct wlan_objmgr_psoc *psoc,
mlme_deliver_cb cb,
enum SON_MLME_DELIVER_CB_TYPE type);
/**
* wlan_son_peer_ext_stat_enable() - sends EXT stats command to FW
* @pdev: pointer to pdev
* @mac_addr: MAC address of the target peer
* @vdev: Pointer to vdev
* @stats_count: Stats count
* @enable: Enable / disable ext stats
*
* Return: QDF_STATUS_SUCCESS on success else failure
*/
QDF_STATUS wlan_son_peer_ext_stat_enable(struct wlan_objmgr_pdev *pdev,
uint8_t *mac_addr,
struct wlan_objmgr_vdev *vdev,
uint32_t stats_count,
uint32_t enable);
/**
* wlan_son_peer_req_inst_stats() - Requests for instantaneous stats for
* the target mac_addr from FW via
* WMI_REQUEST_STATS_CMDID.
* @pdev: pointer to pdev
* @mac_addr: MAC address of the target peer
* @vdev: Pointer to vdev
*
* Return: QDF_STATUS_SUCCESS on success else failure
*/
QDF_STATUS wlan_son_peer_req_inst_stats(struct wlan_objmgr_pdev *pdev,
uint8_t *mac_addr,
struct wlan_objmgr_vdev *vdev);
/**
* wlan_son_get_chan_flag() - get chan flag

View File

@@ -91,6 +91,65 @@ static void wlan_son_is_he_supported(struct wlan_objmgr_psoc *psoc,
}
#endif /*WLAN_FEATURE_11AX*/
QDF_STATUS wlan_son_peer_ext_stat_enable(struct wlan_objmgr_pdev *pdev,
uint8_t *mac_addr,
struct wlan_objmgr_vdev *vdev,
uint32_t stats_count,
uint32_t enable)
{
struct wlan_lmac_if_tx_ops *tx_ops;
struct wlan_objmgr_psoc *psoc;
if (!pdev) {
qdf_err("invalid pdev");
return QDF_STATUS_E_NULL_VALUE;
}
psoc = wlan_pdev_get_psoc(pdev);
if (!psoc) {
qdf_err("invalid psoc");
return QDF_STATUS_E_NULL_VALUE;
}
tx_ops = wlan_psoc_get_lmac_if_txops(psoc);
if (!tx_ops) {
qdf_err("invalid tx_ops");
return QDF_STATUS_E_NULL_VALUE;
}
if (tx_ops->son_tx_ops.peer_ext_stats_enable)
return tx_ops->son_tx_ops.peer_ext_stats_enable(pdev,
mac_addr, vdev,
stats_count,
enable);
return QDF_STATUS_E_NULL_VALUE;
}
QDF_STATUS wlan_son_peer_req_inst_stats(struct wlan_objmgr_pdev *pdev,
uint8_t *mac_addr,
struct wlan_objmgr_vdev *vdev)
{
struct wlan_lmac_if_tx_ops *tx_ops;
struct wlan_objmgr_psoc *psoc;
if (!pdev) {
qdf_err("invalid pdev");
return QDF_STATUS_E_NULL_VALUE;
}
psoc = wlan_pdev_get_psoc(pdev);
if (!psoc) {
qdf_err("invalid psoc");
return QDF_STATUS_E_NULL_VALUE;
}
tx_ops = wlan_psoc_get_lmac_if_txops(psoc);
if (!tx_ops) {
qdf_err("invalid tx_ops");
return QDF_STATUS_E_NULL_VALUE;
}
if (tx_ops->son_tx_ops.son_send_null)
return tx_ops->son_tx_ops.son_send_null(pdev, mac_addr, vdev);
return QDF_STATUS_E_NULL_VALUE;
}
uint32_t wlan_son_get_chan_flag(struct wlan_objmgr_pdev *pdev,
qdf_freq_t freq, bool flag_160,
struct ch_params *chan_params)

View File

@@ -2372,6 +2372,37 @@ static QDF_STATUS hdd_son_get_peer_capability(struct wlan_objmgr_vdev *vdev,
return QDF_STATUS_SUCCESS;
}
uint32_t hdd_son_get_peer_max_mcs_idx(struct wlan_objmgr_vdev *vdev,
struct wlan_objmgr_peer *peer)
{
uint32_t ret = 0;
struct hdd_station_info *sta_info = NULL;
struct hdd_adapter *adapter = NULL;
adapter = wlan_hdd_get_adapter_from_objmgr(vdev);
if (!adapter) {
hdd_err("null adapter");
return ret;
}
sta_info = hdd_get_sta_info_by_mac(&adapter->sta_info_list,
peer->macaddr,
STA_INFO_SOFTAP_GET_STA_INFO);
if (!sta_info) {
hdd_err("sta_info NULL");
return ret;
}
ret = sta_info->max_mcs_idx;
hdd_put_sta_info_ref(&adapter->sta_info_list, &sta_info, true,
STA_INFO_SOFTAP_GET_STA_INFO);
hdd_debug("Peer " QDF_MAC_ADDR_FMT " max MCS index: %u",
QDF_MAC_ADDR_REF(peer->macaddr), ret);
return ret;
}
void hdd_son_register_callbacks(struct hdd_context *hdd_ctx)
{
struct son_callbacks cb_obj = {0};
@@ -2409,6 +2440,7 @@ void hdd_son_register_callbacks(struct hdd_context *hdd_ctx)
cb_obj.os_if_get_acs_report = hdd_son_get_acs_report;
cb_obj.os_if_get_node_info = hdd_son_get_node_info;
cb_obj.os_if_get_peer_capability = hdd_son_get_peer_capability;
cb_obj.os_if_get_peer_max_mcs_idx = hdd_son_get_peer_max_mcs_idx;
os_if_son_register_hdd_callbacks(hdd_ctx->psoc, &cb_obj);

View File

@@ -112,6 +112,15 @@ int hdd_son_send_get_wifi_generic_command(struct wiphy *wiphy,
struct wireless_dev *wdev,
struct nlattr **tb);
/**
* hdd_son_get_peer_max_mcs_idx() - Get peer max mcs index
* @vdev: vdev object
* @peer: peer obj
*
* Return: number of max mcs on succes or 0 on failure
*/
uint32_t hdd_son_get_peer_max_mcs_idx(struct wlan_objmgr_vdev *vdev,
struct wlan_objmgr_peer *peer);
#else
static inline void hdd_son_register_callbacks(struct hdd_context *hdd_ctx)
@@ -161,5 +170,13 @@ int hdd_son_send_get_wifi_generic_command(struct wiphy *wiphy,
{
return -EINVAL;
}
static inline
uint32_t hdd_son_get_peer_max_mcs_idx(struct wlan_objmgr_vdev *vdev,
struct wlan_objmgr_peer *peer)
{
return 0;
}
#endif /* WLAN_FEATURE_SON */
#endif

View File

@@ -290,6 +290,12 @@
#define WMA_DEFAULT_HW_MODE_INDEX 0xFFFF
#define TWO_THIRD (2/3)
#ifdef WLAN_FEATURE_SON
#define WMA_SON_MAX_PEER_EXT_STATS 16
#else
#define WMA_SON_MAX_PEER_EXT_STATS 0
#endif
/**
* WMA hardware mode list bit-mask definitions.
* Bits 4:0, 31:29 are unused.

View File

@@ -6923,6 +6923,7 @@ int wma_rx_service_ready_ext_event(void *handle, uint8_t *event,
wlan_res_cfg->pktcapture_support = true;
else
wlan_res_cfg->pktcapture_support = false;
wlan_res_cfg->max_peer_ext_stats = WMA_SON_MAX_PEER_EXT_STATS;
if (wmi_service_enabled(wmi_handle,
wmi_service_sae_eapol_offload_support))

View File

@@ -68,6 +68,7 @@
* @os_if_get_acs_report: Gets the ACS report
* @os_if_get_node_info: Gets the datarate info for node
* @os_if_get_peer_capability: Gets peer capability
* @os_if_get_peer_max_mcs_idx: Gets peer max MCS index
*/
struct son_callbacks {
uint32_t (*os_if_is_acs_in_progress)(struct wlan_objmgr_vdev *vdev);
@@ -133,6 +134,8 @@ struct son_callbacks {
QDF_STATUS (*os_if_get_peer_capability)(struct wlan_objmgr_vdev *vdev,
struct wlan_objmgr_peer *peer,
wlan_peer_cap *cap);
uint32_t (*os_if_get_peer_max_mcs_idx)(struct wlan_objmgr_vdev *vdev,
struct wlan_objmgr_peer *peer);
};
/**
@@ -764,4 +767,14 @@ int os_if_son_parse_generic_nl_cmd(struct wiphy *wiphy,
QDF_STATUS os_if_son_get_node_datarate_info(struct wlan_objmgr_vdev *vdev,
uint8_t *mac_addr,
wlan_node_info *node_info);
/**
* os_if_son_get_peer_max_mcs_idx() - Get max mcs index of the peer
* @vdev: vdev obj
* @peer: peer obj
*
* Return: max mcs index on success / 0 on failure
*/
uint32_t os_if_son_get_peer_max_mcs_idx(struct wlan_objmgr_vdev *vdev,
struct wlan_objmgr_peer *peer);
#endif

View File

@@ -975,6 +975,9 @@ QDF_STATUS os_if_son_peer_ops(struct wlan_objmgr_peer *peer,
struct wlan_objmgr_pdev *pdev;
struct wlan_objmgr_psoc *psoc;
QDF_STATUS status = QDF_STATUS_SUCCESS;
struct qdf_mac_addr mac;
int ret_val;
static uint32_t peer_ext_stats_count;
if (!peer) {
osif_err("null peer");
@@ -1000,6 +1003,18 @@ QDF_STATUS os_if_son_peer_ops(struct wlan_objmgr_peer *peer,
osif_debug("type %d", type);
/* All PEER MLME operations exported to SON component */
switch (type) {
/* SET/CLR API start */
case PEER_SET_KICKOUT:
qdf_mem_copy(&mac.bytes, peer->macaddr, QDF_MAC_ADDR_SIZE);
ret_val =
g_son_os_if_cb.os_if_kickout_mac(vdev->vdev_objmgr.vdev_id,
&mac);
if (ret_val) {
osif_err("Failed to kickout peer " QDF_MAC_ADDR_FMT,
QDF_MAC_ADDR_REF(peer->macaddr));
return QDF_STATUS_E_INVAL;
}
break;
case PEER_SET_KICKOUT_ALLOW:
if (!in) {
osif_err("invalid input parameter");
@@ -1007,6 +1022,38 @@ QDF_STATUS os_if_son_peer_ops(struct wlan_objmgr_peer *peer,
}
status = ucfg_son_set_peer_kickout_allow(vdev, peer,
in->enable);
osif_debug("kickout allow %d, status %d", in->enable, status);
break;
case PEER_SET_EXT_STATS:
if (!in)
return QDF_STATUS_E_INVAL;
ret_val = wlan_peer_mlme_flag_get(peer, WLAN_PEER_F_EXT_STATS);
osif_debug("Enable: %d peer_ext_stats_count: %u ret_val: %d",
in->enable, peer_ext_stats_count, ret_val);
if ((!!ret_val) != in->enable) {
status =
wlan_son_peer_ext_stat_enable(pdev, peer->macaddr,
vdev,
peer_ext_stats_count,
in->enable);
osif_debug("status: %u", status);
if (status == QDF_STATUS_SUCCESS) {
peer_ext_stats_count++;
wlan_peer_mlme_flag_set(peer,
WLAN_PEER_F_EXT_STATS);
} else {
if (peer_ext_stats_count)
peer_ext_stats_count--;
wlan_peer_mlme_flag_clear
(peer, WLAN_PEER_F_EXT_STATS);
}
}
break;
case PEER_REQ_INST_STAT:
status = wlan_son_peer_req_inst_stats(pdev, peer->macaddr,
vdev);
if (status != QDF_STATUS_SUCCESS)
osif_err("Type: %d is failed", type);
break;
case PEER_GET_CAPABILITY:
if (!out)
@@ -1014,6 +1061,11 @@ QDF_STATUS os_if_son_peer_ops(struct wlan_objmgr_peer *peer,
status = os_if_son_get_peer_capability(vdev, peer,
&out->peercap);
break;
case PEER_GET_MAX_MCS:
if (!out)
return QDF_STATUS_E_INVAL;
out->mcs = os_if_son_get_peer_max_mcs_idx(vdev, peer);
break;
default:
osif_err("invalid type: %d", type);
status = QDF_STATUS_E_INVAL;
@@ -1644,3 +1696,12 @@ QDF_STATUS os_if_son_get_node_datarate_info(struct wlan_objmgr_vdev *vdev,
}
return status;
}
uint32_t os_if_son_get_peer_max_mcs_idx(struct wlan_objmgr_vdev *vdev,
struct wlan_objmgr_peer *peer)
{
if (g_son_os_if_cb.os_if_get_peer_max_mcs_idx)
return g_son_os_if_cb.os_if_get_peer_max_mcs_idx(vdev, peer);
return 0;
}