mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-24 21:54:34 -04:00
qcacmn: Send per chain rssi to upper layer
Add support to send the per chain rssi to upper layer for each beacon and probe responses. Change-Id: Ife6cb9e8e65591baf485c54a985f84d842400321 CRs-Fixed: 2177638
This commit is contained in:
parent
3e25780223
commit
26f9833fb8
6 changed files with 144 additions and 24 deletions
|
|
@ -32,7 +32,7 @@
|
|||
#include <qdf_list.h>
|
||||
#include <qdf_types.h>
|
||||
#include <wlan_scan_ucfg_api.h>
|
||||
|
||||
#include <wlan_mgmt_txrx_utils_api.h>
|
||||
|
||||
/* Max number of scans allowed from userspace */
|
||||
#define WLAN_MAX_SCAN_COUNT 8
|
||||
|
|
@ -126,6 +126,25 @@ struct scan_params {
|
|||
struct element_info default_ie;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct wlan_cfg80211_inform_bss - BSS inform data
|
||||
* @chan: channel the frame was received on
|
||||
* @mgmt: beacon/probe resp frame
|
||||
* @frame_len: frame length
|
||||
* @rssi: signal strength in mBm (100*dBm)
|
||||
* @boottime_ns: timestamp (CLOCK_BOOTTIME) when the information was received.
|
||||
* @per_chain_snr: per chain snr received
|
||||
*/
|
||||
struct wlan_cfg80211_inform_bss {
|
||||
struct ieee80211_channel *chan;
|
||||
struct ieee80211_mgmt *mgmt;
|
||||
size_t frame_len;
|
||||
int rssi;
|
||||
uint64_t boottime_ns;
|
||||
uint8_t per_chain_snr[WLAN_MGMT_TXRX_HOST_MAX_ANTENNA];
|
||||
};
|
||||
|
||||
|
||||
#ifdef FEATURE_WLAN_SCAN_PNO
|
||||
/**
|
||||
* wlan_cfg80211_sched_scan_start() - cfg80211 scheduled scan(pno) start
|
||||
|
|
@ -211,6 +230,19 @@ int wlan_cfg80211_scan(struct wlan_objmgr_pdev *pdev,
|
|||
struct cfg80211_scan_request *request,
|
||||
struct scan_params *params);
|
||||
|
||||
/**
|
||||
* wlan_cfg80211_inform_bss_frame_data() - API to inform beacon to cfg80211
|
||||
* @wiphy: wiphy
|
||||
* @bss_data: bss data
|
||||
*
|
||||
* API to inform beacon to cfg80211
|
||||
*
|
||||
* Return: pointer to bss entry
|
||||
*/
|
||||
struct cfg80211_bss *
|
||||
wlan_cfg80211_inform_bss_frame_data(struct wiphy *wiphy,
|
||||
struct wlan_cfg80211_inform_bss *bss);
|
||||
|
||||
/**
|
||||
* wlan_cfg80211_inform_bss_frame() - API to inform beacon to cfg80211
|
||||
* @pdev: Pointer to pdev
|
||||
|
|
|
|||
|
|
@ -1574,16 +1574,82 @@ static inline void wlan_add_age_ie(uint8_t *mgmt_frame,
|
|||
}
|
||||
#endif /* WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS */
|
||||
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) || \
|
||||
defined(CFG80211_INFORM_BSS_FRAME_DATA)
|
||||
/**
|
||||
* wlan_fill_per_chain_rssi() - fill per chain RSSI in inform bss
|
||||
* @data: bss data
|
||||
* @per_chain_snr: per chain RSSI
|
||||
*
|
||||
* Return: void
|
||||
*/
|
||||
#if defined(CFG80211_SCAN_PER_CHAIN_RSSI_SUPPORT) || \
|
||||
(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 16, 0))
|
||||
static void wlan_fill_per_chain_rssi(struct cfg80211_inform_bss *data,
|
||||
struct wlan_cfg80211_inform_bss *bss)
|
||||
{
|
||||
|
||||
uint32_t i;
|
||||
|
||||
if (!bss || !data) {
|
||||
cfg80211_err("Received bss is NULL");
|
||||
return;
|
||||
}
|
||||
for (i = 0; i < WLAN_MGMT_TXRX_HOST_MAX_ANTENNA; i++) {
|
||||
if (!bss->per_chain_snr[i] ||
|
||||
(bss->per_chain_snr[i] == WLAN_INVALID_PER_CHAIN_RSSI))
|
||||
continue;
|
||||
/* Add noise margin to SNR to convert it to RSSI */
|
||||
data->chain_signal[i] = bss->per_chain_snr[i] +
|
||||
WLAN_NOISE_FLOOR_DBM_DEFAULT;
|
||||
data->chains |= BIT(i);
|
||||
}
|
||||
}
|
||||
#else
|
||||
static inline void
|
||||
wlan_fill_per_chain_rssi(struct cfg80211_inform_bss *data,
|
||||
struct wlan_cfg80211_inform_bss *bss)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
struct cfg80211_bss *
|
||||
wlan_cfg80211_inform_bss_frame_data(struct wiphy *wiphy,
|
||||
struct wlan_cfg80211_inform_bss *bss)
|
||||
{
|
||||
struct cfg80211_inform_bss data = {0};
|
||||
|
||||
if (!bss) {
|
||||
cfg80211_err("bss is null");
|
||||
return NULL;
|
||||
}
|
||||
wlan_fill_per_chain_rssi(&data, bss);
|
||||
|
||||
data.chan = bss->chan;
|
||||
data.boottime_ns = bss->boottime_ns;
|
||||
data.signal = bss->rssi;
|
||||
return cfg80211_inform_bss_frame_data(wiphy, &data, bss->mgmt,
|
||||
bss->frame_len, GFP_KERNEL);
|
||||
}
|
||||
#else
|
||||
struct cfg80211_bss *
|
||||
wlan_cfg80211_inform_bss_frame_data(struct wiphy *wiphy,
|
||||
struct wlan_cfg80211_inform_bss *bss)
|
||||
|
||||
{
|
||||
return cfg80211_inform_bss_frame(wiphy, bss->chan, bss->mgmt,
|
||||
bss->frame_len,
|
||||
bss->rssi, GFP_KERNEL);
|
||||
}
|
||||
#endif
|
||||
|
||||
void wlan_cfg80211_inform_bss_frame(struct wlan_objmgr_pdev *pdev,
|
||||
struct scan_cache_entry *scan_params)
|
||||
{
|
||||
struct pdev_osif_priv *pdev_ospriv = wlan_pdev_get_ospriv(pdev);
|
||||
struct wiphy *wiphy;
|
||||
int frame_len;
|
||||
struct ieee80211_mgmt *mgmt = NULL;
|
||||
struct ieee80211_channel *chan;
|
||||
int rssi = 0;
|
||||
struct cfg80211_bss *bss_status = NULL;
|
||||
struct wlan_cfg80211_inform_bss bss_data = {0};
|
||||
|
||||
if (!pdev_ospriv) {
|
||||
cfg80211_err("os_priv is NULL");
|
||||
|
|
@ -1592,31 +1658,31 @@ void wlan_cfg80211_inform_bss_frame(struct wlan_objmgr_pdev *pdev,
|
|||
|
||||
wiphy = pdev_ospriv->wiphy;
|
||||
|
||||
frame_len = wlan_get_frame_len(scan_params);
|
||||
mgmt = qdf_mem_malloc(frame_len);
|
||||
if (!mgmt) {
|
||||
bss_data.frame_len = wlan_get_frame_len(scan_params);
|
||||
bss_data.mgmt = qdf_mem_malloc(bss_data.frame_len);
|
||||
if (!bss_data.mgmt) {
|
||||
cfg80211_err("mem alloc failed");
|
||||
return;
|
||||
}
|
||||
qdf_mem_copy(mgmt,
|
||||
qdf_mem_copy(bss_data.mgmt,
|
||||
util_scan_entry_frame_ptr(scan_params),
|
||||
util_scan_entry_frame_len(scan_params));
|
||||
/*
|
||||
* Android does not want the timestamp from the frame.
|
||||
* Instead it wants a monotonic increasing value
|
||||
*/
|
||||
mgmt->u.probe_resp.timestamp = qdf_get_monotonic_boottime();
|
||||
wlan_add_age_ie((uint8_t *)mgmt, scan_params);
|
||||
bss_data.mgmt->u.probe_resp.timestamp = qdf_get_monotonic_boottime();
|
||||
wlan_add_age_ie((uint8_t *)bss_data.mgmt, scan_params);
|
||||
/*
|
||||
* Based on .ini configuration, raw rssi can be reported for bss.
|
||||
* Raw rssi is typically used for estimating power.
|
||||
*/
|
||||
rssi = scan_params->rssi_raw;
|
||||
bss_data.rssi = scan_params->rssi_raw;
|
||||
|
||||
chan = wlan_get_ieee80211_channel(wiphy,
|
||||
bss_data.chan = wlan_get_ieee80211_channel(wiphy,
|
||||
scan_params->channel.chan_idx);
|
||||
if (!chan) {
|
||||
qdf_mem_free(mgmt);
|
||||
if (!bss_data.chan) {
|
||||
qdf_mem_free(bss_data.mgmt);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1624,13 +1690,20 @@ void wlan_cfg80211_inform_bss_frame(struct wlan_objmgr_pdev *pdev,
|
|||
* Supplicant takes the signal strength in terms of
|
||||
* mBm (1 dBm = 100 mBm).
|
||||
*/
|
||||
rssi = QDF_MIN(rssi, 0) * 100;
|
||||
bss_data.rssi = QDF_MIN(bss_data.rssi, 0) * 100;
|
||||
|
||||
bss_data.boottime_ns = scan_params->boottime_ns;
|
||||
|
||||
qdf_mem_copy(bss_data.per_chain_snr, scan_params->per_chain_snr,
|
||||
WLAN_MGMT_TXRX_HOST_MAX_ANTENNA);
|
||||
|
||||
cfg80211_info("BSSID: %pM Channel:%d RSSI:%d",
|
||||
mgmt->bssid, chan->center_freq, (int)(rssi / 100));
|
||||
bss_data.mgmt->bssid, bss_data.chan->center_freq,
|
||||
(int)(bss_data.rssi / 100));
|
||||
|
||||
bss_status =
|
||||
cfg80211_inform_bss_frame(wiphy, chan, mgmt,
|
||||
frame_len, rssi, GFP_KERNEL);
|
||||
qdf_mem_free(mgmt);
|
||||
bss_status = wlan_cfg80211_inform_bss_frame_data(wiphy, &bss_data);
|
||||
if (!bss_status)
|
||||
cfg80211_err("failed to inform bss");
|
||||
|
||||
qdf_mem_free(bss_data.mgmt);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -644,8 +644,9 @@ enum mgmt_frame_type {
|
|||
MGMT_MAX_FRAME_TYPE,
|
||||
};
|
||||
|
||||
#define WLAN_MGMT_TXRX_HOST_MAX_ANTENNA 4
|
||||
|
||||
#define WLAN_MGMT_TXRX_HOST_MAX_ANTENNA 4
|
||||
#define WLAN_INVALID_PER_CHAIN_RSSI 0x80
|
||||
#define WLAN_NOISE_FLOOR_DBM_DEFAULT -96
|
||||
/**
|
||||
* struct mgmt_rx_event_params - host mgmt header params
|
||||
* @channel: channel on which this frame is received
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#include <qdf_list.h>
|
||||
#include <qdf_atomic.h>
|
||||
#include <wlan_cmn_ieee80211.h>
|
||||
#include <wlan_mgmt_txrx_utils_api.h>
|
||||
|
||||
typedef uint16_t wlan_scan_requester;
|
||||
typedef uint32_t wlan_scan_id;
|
||||
|
|
@ -278,6 +279,8 @@ struct security_info {
|
|||
* @tsf_delta: TSF delta
|
||||
* @bss_score: bss score calculated on basis of RSSI/caps etc.
|
||||
* @neg_sec_info: negotiated security info
|
||||
* @per_chain_snr: per chain SNR value received.
|
||||
* boottime_ns: boottime in ns.
|
||||
* @rrm_parent_tsf: RRM parent tsf
|
||||
* @mlme_info: Mlme info, this will be updated by MLME for the scan entry
|
||||
* @alt_wcn_ie: alternate WCN IE
|
||||
|
|
@ -314,6 +317,8 @@ struct scan_cache_entry {
|
|||
uint32_t tsf_delta;
|
||||
uint32_t bss_score;
|
||||
struct security_info neg_sec_info;
|
||||
uint8_t per_chain_snr[WLAN_MGMT_TXRX_HOST_MAX_ANTENNA];
|
||||
uint64_t boottime_ns;
|
||||
uint32_t rrm_parent_tsf;
|
||||
struct element_info alt_wcn_ie;
|
||||
struct ie_list ie_list;
|
||||
|
|
|
|||
|
|
@ -853,6 +853,9 @@ util_scan_unpack_beacon_frame(uint8_t *frame,
|
|||
(frame + sizeof(*hdr));
|
||||
hdr = (struct wlan_frame_hdr *)frame;
|
||||
|
||||
/* update timestamp in nanoseconds needed by kernel layers */
|
||||
scan_entry->boottime_ns = qdf_get_monotonic_boottime_ns();
|
||||
|
||||
scan_entry->frm_subtype = frm_subtype;
|
||||
qdf_mem_copy(scan_entry->bssid.bytes,
|
||||
hdr->i_addr3, QDF_MAC_ADDR_SIZE);
|
||||
|
|
@ -866,6 +869,10 @@ util_scan_unpack_beacon_frame(uint8_t *frame,
|
|||
scan_entry->avg_rssi = WLAN_RSSI_IN(scan_entry->rssi_raw);
|
||||
scan_entry->tsf_delta = rx_param->tsf_delta;
|
||||
|
||||
/* Copy per chain rssi to scan entry */
|
||||
qdf_mem_copy(scan_entry->per_chain_snr, rx_param->rssi_ctl,
|
||||
WLAN_MGMT_TXRX_HOST_MAX_ANTENNA);
|
||||
|
||||
/* store jiffies */
|
||||
scan_entry->rrm_parent_tsf = (u_int32_t) qdf_system_ticks();
|
||||
|
||||
|
|
|
|||
|
|
@ -18416,6 +18416,7 @@ static QDF_STATUS extract_mgmt_rx_params_tlv(wmi_unified_t wmi_handle,
|
|||
{
|
||||
WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs = NULL;
|
||||
wmi_mgmt_rx_hdr *ev_hdr = NULL;
|
||||
int i;
|
||||
|
||||
param_tlvs = (WMI_MGMT_RX_EVENTID_param_tlvs *) evt_buf;
|
||||
if (!param_tlvs) {
|
||||
|
|
@ -18441,7 +18442,8 @@ static QDF_STATUS extract_mgmt_rx_params_tlv(wmi_unified_t wmi_handle,
|
|||
hdr->flags = ev_hdr->flags;
|
||||
hdr->rssi = ev_hdr->rssi;
|
||||
hdr->tsf_delta = ev_hdr->tsf_delta;
|
||||
qdf_mem_copy(hdr->rssi_ctl, ev_hdr->rssi_ctl, sizeof(hdr->rssi_ctl));
|
||||
for (i = 0; i < ATH_MAX_ANTENNA; i++)
|
||||
hdr->rssi_ctl[i] = ev_hdr->rssi_ctl[i];
|
||||
|
||||
*bufp = param_tlvs->bufp;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue