mirror of https://gitee.com/openkylin/linux.git
wlcore: report rssi from roaming statistics
report the average beacon rssi which is calculated by firmware for roaming statistics instead of the last rx packet rssi. this results a more accurate rssi reporting Signed-off-by: Nadim Zubidat <nadimz@ti.com> Signed-off-by: Luciano Coelho <coelho@ti.com>
This commit is contained in:
parent
93d5d10085
commit
0a9ffac09f
|
@ -1736,6 +1736,35 @@ int wl12xx_acx_config_hangover(struct wl1271 *wl)
|
|||
|
||||
}
|
||||
|
||||
int wlcore_acx_average_rssi(struct wl1271 *wl, struct wl12xx_vif *wlvif,
|
||||
s8 *avg_rssi)
|
||||
{
|
||||
struct acx_roaming_stats *acx;
|
||||
int ret = 0;
|
||||
|
||||
wl1271_debug(DEBUG_ACX, "acx roaming statistics");
|
||||
|
||||
acx = kzalloc(sizeof(*acx), GFP_KERNEL);
|
||||
if (!acx) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
acx->role_id = wlvif->role_id;
|
||||
ret = wl1271_cmd_interrogate(wl, ACX_ROAMING_STATISTICS_TBL,
|
||||
acx, sizeof(*acx));
|
||||
if (ret < 0) {
|
||||
wl1271_warning("acx roaming statistics failed: %d", ret);
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
*avg_rssi = acx->rssi_beacon;
|
||||
out:
|
||||
kfree(acx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
/* Set the global behaviour of RX filters - On/Off + default action */
|
||||
int wl1271_acx_default_rx_filter_enable(struct wl1271 *wl, bool enable,
|
||||
|
|
|
@ -953,6 +953,18 @@ struct acx_rx_filter_cfg {
|
|||
u8 fields[0];
|
||||
} __packed;
|
||||
|
||||
struct acx_roaming_stats {
|
||||
struct acx_header header;
|
||||
|
||||
u8 role_id;
|
||||
u8 pad[3];
|
||||
u32 missed_beacons;
|
||||
u8 snr_data;
|
||||
u8 snr_bacon;
|
||||
s8 rssi_data;
|
||||
s8 rssi_beacon;
|
||||
} __packed;
|
||||
|
||||
enum {
|
||||
ACX_WAKE_UP_CONDITIONS = 0x0000,
|
||||
ACX_MEM_CFG = 0x0001,
|
||||
|
@ -1110,6 +1122,8 @@ int wl1271_acx_set_inconnection_sta(struct wl1271 *wl, u8 *addr);
|
|||
int wl1271_acx_fm_coex(struct wl1271 *wl);
|
||||
int wl12xx_acx_set_rate_mgmt_params(struct wl1271 *wl);
|
||||
int wl12xx_acx_config_hangover(struct wl1271 *wl);
|
||||
int wlcore_acx_average_rssi(struct wl1271 *wl, struct wl12xx_vif *wlvif,
|
||||
s8 *avg_rssi);
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
int wl1271_acx_default_rx_filter_enable(struct wl1271 *wl, bool enable,
|
||||
|
|
|
@ -5094,6 +5094,39 @@ static void wlcore_op_sta_rc_update(struct ieee80211_hw *hw,
|
|||
wlcore_hw_sta_rc_update(wl, wlvif, sta, changed);
|
||||
}
|
||||
|
||||
static int wlcore_op_get_rssi(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta,
|
||||
s8 *rssi_dbm)
|
||||
{
|
||||
struct wl1271 *wl = hw->priv;
|
||||
struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
|
||||
int ret = 0;
|
||||
|
||||
wl1271_debug(DEBUG_MAC80211, "mac80211 get_rssi");
|
||||
|
||||
mutex_lock(&wl->mutex);
|
||||
|
||||
if (unlikely(wl->state != WLCORE_STATE_ON))
|
||||
goto out;
|
||||
|
||||
ret = wl1271_ps_elp_wakeup(wl);
|
||||
if (ret < 0)
|
||||
goto out_sleep;
|
||||
|
||||
ret = wlcore_acx_average_rssi(wl, wlvif, rssi_dbm);
|
||||
if (ret < 0)
|
||||
goto out_sleep;
|
||||
|
||||
out_sleep:
|
||||
wl1271_ps_elp_sleep(wl);
|
||||
|
||||
out:
|
||||
mutex_unlock(&wl->mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool wl1271_tx_frames_pending(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct wl1271 *wl = hw->priv;
|
||||
|
@ -5293,6 +5326,7 @@ static const struct ieee80211_ops wl1271_ops = {
|
|||
.assign_vif_chanctx = wlcore_op_assign_vif_chanctx,
|
||||
.unassign_vif_chanctx = wlcore_op_unassign_vif_chanctx,
|
||||
.sta_rc_update = wlcore_op_sta_rc_update,
|
||||
.get_rssi = wlcore_op_get_rssi,
|
||||
CFG80211_TESTMODE_CMD(wl1271_tm_cmd)
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue