qcacmn: Add support to get RSSI of Non associated clients

Add change in driver to get RSSI of non associated clients.

This is done in 2 levels of filtering
1. Send WMI to FW to configure BSSID in HW
2. Filter the neighbour BSSID packets received in host for
the configured client mac

Change-Id: I6b684b83cecb308dac326056aa77537aee07b933
CRs-Fixed: 2148773
This commit is contained in:
Soumya Bhat
2018-02-18 18:21:25 +05:30
committed by snandini
parent 96ad17d131
commit bc719e6b02
5 changed files with 156 additions and 4 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2016-2017 The Linux Foundation. All rights reserved.
* Copyright (c) 2016-2018 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -762,4 +762,35 @@ cdp_get_pldev(ol_txrx_soc_handle soc,
return soc->ops->ctrl_ops->txrx_get_pldev(pdev);
}
#ifdef ATH_SUPPORT_NAC_RSSI
/**
* cdp_vdev_config_for_nac_rssi(): To invoke dp callback for nac rssi config
* @soc: soc pointer
* @vdev: vdev pointer
* @nac_cmd: specfies nac_rss config action add, del, list
* @bssid: Neighbour bssid
* @client_macaddr: Non-Associated client MAC
* @chan_num: channel number to scan
*
* Return: QDF_STATUS
*/
static inline QDF_STATUS cdp_vdev_config_for_nac_rssi(ol_txrx_soc_handle soc,
struct cdp_vdev *vdev, enum cdp_nac_param_cmd nac_cmd,
char *bssid, char *client_macaddr, uint8_t chan_num)
{
if (!soc || !soc->ops) {
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
"%s invalid instance", __func__);
QDF_BUG(0);
return QDF_STATUS_E_FAILURE;
}
if (!soc->ops->ctrl_ops ||
!soc->ops->ctrl_ops->txrx_vdev_config_for_nac_rssi)
return QDF_STATUS_E_FAILURE;
return soc->ops->ctrl_ops->txrx_vdev_config_for_nac_rssi(vdev,
nac_cmd, bssid, client_macaddr, chan_num);
}
#endif
#endif

View File

@@ -45,6 +45,15 @@
#define CDP_PEER_DELETE_NO_SPECIAL 0
#define CDP_PEER_DO_NOT_START_UNMAP_TIMER 1
/* same as ieee80211_nac_param */
enum cdp_nac_param_cmd {
/* IEEE80211_NAC_PARAM_ADD */
CDP_NAC_PARAM_ADD = 1,
/* IEEE80211_NAC_PARAM_DEL */
CDP_NAC_PARAM_DEL,
/* IEEE80211_NAC_PARAM_LIST */
CDP_NAC_PARAM_LIST,
};
/******************************************************************************
*
* Control Interface (A Interface)
@@ -473,6 +482,12 @@ struct cdp_ctrl_ops {
int (*txrx_wdi_event_handler)(struct cdp_pdev *pdev,
uint32_t event, void *evt_data);
void * (*txrx_get_pldev)(struct cdp_pdev *pdev);
#ifdef ATH_SUPPORT_NAC_RSSI
QDF_STATUS (*txrx_vdev_config_for_nac_rssi)(struct cdp_vdev *vdev,
enum cdp_nac_param_cmd cmd, char *bssid, char *client_macaddr,
uint8_t chan_num);
#endif
};
struct cdp_me_ops {
@@ -699,7 +714,13 @@ struct ol_if_ops {
void (*record_act_change)(struct wlan_objmgr_pdev *pdev,
u_int8_t *dstmac, bool active);
#ifdef ATH_SUPPORT_NAC_RSSI
int (*config_fw_for_nac_rssi)(struct wlan_objmgr_pdev *pdev,
u_int8_t vdev_id, enum cdp_nac_param_cmd cmd, char *bssid,
char *client_macaddr, uint8_t chan_num);
int (*config_bssid_in_fw_for_nac_rssi)(struct wlan_objmgr_pdev *pdev,
u_int8_t vdev_id, enum cdp_nac_param_cmd cmd, char *bssid);
#endif
/* TODO: Add any other control path calls required to OL_IF/WMA layer */
};

View File

@@ -6303,6 +6303,43 @@ static void dp_peer_teardown_wifi3(struct cdp_vdev *vdev_hdl, void *peer_hdl)
}
#endif
#ifdef ATH_SUPPORT_NAC_RSSI
static QDF_STATUS dp_config_for_nac_rssi(struct cdp_vdev *vdev_handle,
enum cdp_nac_param_cmd cmd, char *bssid, char *client_macaddr,
uint8_t chan_num)
{
struct dp_vdev *vdev = (struct dp_vdev *)vdev_handle;
struct dp_pdev *pdev = (struct dp_pdev *)vdev->pdev;
struct dp_soc *soc = (struct dp_soc *) vdev->pdev->soc;
pdev->nac_rssi_filtering = 1;
/* Store address of NAC (neighbour peer) which will be checked
* against TA of received packets.
*/
if (cmd == CDP_NAC_PARAM_ADD) {
qdf_mem_copy(vdev->cdp_nac_rssi.client_mac,
client_macaddr, DP_MAC_ADDR_LEN);
vdev->cdp_nac_rssi_enabled = 1;
} else if (cmd == CDP_NAC_PARAM_DEL) {
if (!qdf_mem_cmp(vdev->cdp_nac_rssi.client_mac,
client_macaddr, DP_MAC_ADDR_LEN)) {
/* delete this peer from the list */
qdf_mem_zero(vdev->cdp_nac_rssi.client_mac,
DP_MAC_ADDR_LEN);
}
vdev->cdp_nac_rssi_enabled = 0;
}
if (soc->cdp_soc.ol_ops->config_bssid_in_fw_for_nac_rssi)
soc->cdp_soc.ol_ops->config_bssid_in_fw_for_nac_rssi
(vdev->pdev->osif_pdev, vdev->vdev_id, cmd, bssid);
return QDF_STATUS_SUCCESS;
}
#endif
static struct cdp_cmn_ops dp_ops_cmn = {
.txrx_soc_attach_target = dp_soc_attach_target_wifi3,
.txrx_vdev_attach = dp_vdev_attach_wifi3,
@@ -6391,6 +6428,9 @@ static struct cdp_ctrl_ops dp_ops_ctrl = {
.txrx_get_pldev = dp_get_pldev,
#endif
.txrx_set_pdev_param = dp_set_pdev_param,
#ifdef ATH_SUPPORT_NAC_RSSI
.txrx_vdev_config_for_nac_rssi = dp_config_for_nac_rssi,
#endif
};
static struct cdp_me_ops dp_ops_me = {
@@ -7101,3 +7141,4 @@ static void dp_pktlogmod_exit(struct dp_pdev *handle)
#else
static void dp_pktlogmod_exit(struct dp_pdev *handle) { }
#endif

View File

@@ -636,6 +636,45 @@ struct dp_vdev *dp_rx_nac_filter(struct dp_pdev *pdev,
return NULL;
}
/**
* dp_rx_process_nac_rssi_frames(): Store RSSI for configured NAC
* @pdev: DP pdev handle
* @rx_tlv_hdr: tlv hdr buf
*
* return: None
*/
#ifdef ATH_SUPPORT_NAC_RSSI
static void dp_rx_process_nac_rssi_frames(struct dp_pdev *pdev, uint8_t *rx_tlv_hdr)
{
struct dp_vdev *vdev = NULL;
struct dp_soc *soc = pdev->soc;
uint8_t *rx_pkt_hdr = hal_rx_pkt_hdr_get(rx_tlv_hdr);
struct ieee80211_frame *wh = (struct ieee80211_frame *)rx_pkt_hdr;
if (pdev->nac_rssi_filtering) {
TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) {
if (vdev->cdp_nac_rssi_enabled &&
(qdf_mem_cmp(vdev->cdp_nac_rssi.client_mac,
wh->i_addr1, DP_MAC_ADDR_LEN) == 0)) {
QDF_TRACE(QDF_MODULE_ID_DP,
QDF_TRACE_LEVEL_DEBUG, "RSSI updated");
vdev->cdp_nac_rssi.vdev_id = vdev->vdev_id;
vdev->cdp_nac_rssi.client_rssi =
hal_rx_msdu_start_get_rssi(rx_tlv_hdr);
dp_wdi_event_handler(WDI_EVENT_NAC_RSSI, soc,
(void *)&vdev->cdp_nac_rssi,
HTT_INVALID_PEER, WDI_NO_VAL,
pdev->pdev_id);
}
}
}
}
#else
static void dp_rx_process_nac_rssi_frames(struct dp_pdev *pdev, uint8_t *rx_tlv_hdr)
{
}
#endif
/**
* dp_rx_process_invalid_peer(): Function to pass invalid peer list to umac
* @soc: DP SOC handle
@@ -650,10 +689,10 @@ uint8_t dp_rx_process_invalid_peer(struct dp_soc *soc, qdf_nbuf_t mpdu)
struct dp_pdev *pdev = NULL;
struct ieee80211_frame *wh;
uint8_t i;
uint8_t *rx_pkt_hdr;
qdf_nbuf_t curr_nbuf, next_nbuf;
uint8_t *rx_tlv_hdr = qdf_nbuf_data(mpdu);
uint8_t *rx_pkt_hdr = hal_rx_pkt_hdr_get(rx_tlv_hdr);
rx_pkt_hdr = hal_rx_pkt_hdr_get(qdf_nbuf_data(mpdu));
wh = (struct ieee80211_frame *)rx_pkt_hdr;
if (!DP_FRAME_IS_DATA(wh)) {
@@ -687,7 +726,12 @@ uint8_t dp_rx_process_invalid_peer(struct dp_soc *soc, qdf_nbuf_t mpdu)
return 0;
}
}
dp_rx_process_nac_rssi_frames(pdev, rx_tlv_hdr);
TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) {
if (qdf_mem_cmp(wh->i_addr1, vdev->mac_addr.raw,
DP_MAC_ADDR_LEN) == 0) {
goto out;

View File

@@ -1129,6 +1129,10 @@ struct dp_pdev {
bool pktlog_ppdu_stats;
void *dp_txrx_handle; /* Advanced data path handle */
#ifdef ATH_SUPPORT_NAC_RSSI
bool nac_rssi_filtering;
#endif
};
struct dp_peer;
@@ -1268,6 +1272,17 @@ struct dp_vdev {
enum cdp_sec_type sec_type;
#ifdef ATH_SUPPORT_NAC_RSSI
bool cdp_nac_rssi_enabled;
struct {
uint8_t bssid_mac[6];
uint8_t client_mac[6];
uint8_t chan_num;
uint8_t client_rssi_valid;
uint8_t client_rssi;
uint8_t vdev_id;
} cdp_nac_rssi;
#endif
};