Commit 42e85997 authored by Rong Yan's avatar Rong Yan Committed by Felix Fietkau

wifi: mt76: mt7921: cqm rssi low/high event notify

The implementation amounts to setting the driver flag
IEEE80211_VIF_SUPPORTS_CQM_RSSI, and then providing
mechanisms for continuously updating enough information
to be able to provide notifications to userspace when
RSSI drops below a certain threshold
Signed-off-by: default avatarRong Yan <rong.yan@mediatek.com>
Signed-off-by: default avatarMing Yen Hsieh <mingyen.hsieh@mediatek.com>
Signed-off-by: default avatarFelix Fietkau <nbd@nbd.name>
parent 39db5a54
...@@ -1011,6 +1011,7 @@ enum { ...@@ -1011,6 +1011,7 @@ enum {
MCU_EVENT_CH_PRIVILEGE = 0x18, MCU_EVENT_CH_PRIVILEGE = 0x18,
MCU_EVENT_SCHED_SCAN_DONE = 0x23, MCU_EVENT_SCHED_SCAN_DONE = 0x23,
MCU_EVENT_DBG_MSG = 0x27, MCU_EVENT_DBG_MSG = 0x27,
MCU_EVENT_RSSI_NOTIFY = 0x96,
MCU_EVENT_TXPWR = 0xd0, MCU_EVENT_TXPWR = 0xd0,
MCU_EVENT_EXT = 0xed, MCU_EVENT_EXT = 0xed,
MCU_EVENT_RESTART_DL = 0xef, MCU_EVENT_RESTART_DL = 0xef,
...@@ -1311,6 +1312,7 @@ enum { ...@@ -1311,6 +1312,7 @@ enum {
MCU_CE_CMD_SCHED_SCAN_ENABLE = 0x61, MCU_CE_CMD_SCHED_SCAN_ENABLE = 0x61,
MCU_CE_CMD_SCHED_SCAN_REQ = 0x62, MCU_CE_CMD_SCHED_SCAN_REQ = 0x62,
MCU_CE_CMD_GET_NIC_CAPAB = 0x8a, MCU_CE_CMD_GET_NIC_CAPAB = 0x8a,
MCU_CE_CMD_RSSI_MONITOR = 0xa1,
MCU_CE_CMD_SET_MU_EDCA_PARMS = 0xb0, MCU_CE_CMD_SET_MU_EDCA_PARMS = 0xb0,
MCU_CE_CMD_REG_WRITE = 0xc0, MCU_CE_CMD_REG_WRITE = 0xc0,
MCU_CE_CMD_REG_READ = 0xc0, MCU_CE_CMD_REG_READ = 0xc0,
...@@ -1456,6 +1458,10 @@ struct mt76_connac_beacon_loss_event { ...@@ -1456,6 +1458,10 @@ struct mt76_connac_beacon_loss_event {
u8 pad[2]; u8 pad[2];
} __packed; } __packed;
struct mt76_connac_rssi_notify_event {
__le32 rssi[4];
} __packed;
struct mt76_connac_mcu_bss_event { struct mt76_connac_mcu_bss_event {
u8 bss_idx; u8 bss_idx;
u8 is_absent; u8 is_absent;
......
...@@ -310,6 +310,8 @@ mt7921_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) ...@@ -310,6 +310,8 @@ mt7921_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
} }
vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER; vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER;
if (phy->chip_cap & MT792x_CHIP_CAP_RSSI_NOTIFY_EVT_EN)
vif->driver_flags |= IEEE80211_VIF_SUPPORTS_CQM_RSSI;
out: out:
mt792x_mutex_release(dev); mt792x_mutex_release(dev);
...@@ -679,6 +681,9 @@ static void mt7921_bss_info_changed(struct ieee80211_hw *hw, ...@@ -679,6 +681,9 @@ static void mt7921_bss_info_changed(struct ieee80211_hw *hw,
if (changed & BSS_CHANGED_PS) if (changed & BSS_CHANGED_PS)
mt7921_mcu_uni_bss_ps(dev, vif); mt7921_mcu_uni_bss_ps(dev, vif);
if (changed & BSS_CHANGED_CQM)
mt7921_mcu_set_rssimonitor(dev, vif);
if (changed & BSS_CHANGED_ASSOC) { if (changed & BSS_CHANGED_ASSOC) {
mt7921_mcu_sta_update(dev, NULL, vif, true, mt7921_mcu_sta_update(dev, NULL, vif, true,
MT76_STA_INFO_STATE_ASSOC); MT76_STA_INFO_STATE_ASSOC);
......
...@@ -253,6 +253,42 @@ mt7921_mcu_tx_done_event(struct mt792x_dev *dev, struct sk_buff *skb) ...@@ -253,6 +253,42 @@ mt7921_mcu_tx_done_event(struct mt792x_dev *dev, struct sk_buff *skb)
mt7921_mac_add_txs(dev, event->txs); mt7921_mac_add_txs(dev, event->txs);
} }
static void
mt7921_mcu_rssi_monitor_iter(void *priv, u8 *mac,
struct ieee80211_vif *vif)
{
struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv;
struct mt76_connac_rssi_notify_event *event = priv;
enum nl80211_cqm_rssi_threshold_event nl_event;
s32 rssi = le32_to_cpu(event->rssi[mvif->mt76.idx]);
if (!rssi)
return;
if (!(vif->driver_flags & IEEE80211_VIF_SUPPORTS_CQM_RSSI))
return;
if (rssi > vif->bss_conf.cqm_rssi_thold)
nl_event = NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH;
else
nl_event = NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW;
ieee80211_cqm_rssi_notify(vif, nl_event, rssi, GFP_KERNEL);
}
static void
mt7921_mcu_rssi_monitor_event(struct mt792x_dev *dev, struct sk_buff *skb)
{
struct mt76_connac_rssi_notify_event *event;
skb_pull(skb, sizeof(struct mt76_connac2_mcu_rxd));
event = (struct mt76_connac_rssi_notify_event *)skb->data;
ieee80211_iterate_active_interfaces_atomic(mt76_hw(dev),
IEEE80211_IFACE_ITER_RESUME_ALL,
mt7921_mcu_rssi_monitor_iter, event);
}
static void static void
mt7921_mcu_rx_unsolicited_event(struct mt792x_dev *dev, struct sk_buff *skb) mt7921_mcu_rx_unsolicited_event(struct mt792x_dev *dev, struct sk_buff *skb)
{ {
...@@ -281,6 +317,9 @@ mt7921_mcu_rx_unsolicited_event(struct mt792x_dev *dev, struct sk_buff *skb) ...@@ -281,6 +317,9 @@ mt7921_mcu_rx_unsolicited_event(struct mt792x_dev *dev, struct sk_buff *skb)
case MCU_EVENT_TX_DONE: case MCU_EVENT_TX_DONE:
mt7921_mcu_tx_done_event(dev, skb); mt7921_mcu_tx_done_event(dev, skb);
break; break;
case MCU_EVENT_RSSI_NOTIFY:
mt7921_mcu_rssi_monitor_event(dev, skb);
break;
default: default:
break; break;
} }
...@@ -327,6 +366,7 @@ void mt7921_mcu_rx_event(struct mt792x_dev *dev, struct sk_buff *skb) ...@@ -327,6 +366,7 @@ void mt7921_mcu_rx_event(struct mt792x_dev *dev, struct sk_buff *skb)
if (rxd->ext_eid == MCU_EXT_EVENT_RATE_REPORT || if (rxd->ext_eid == MCU_EXT_EVENT_RATE_REPORT ||
rxd->eid == MCU_EVENT_BSS_BEACON_LOSS || rxd->eid == MCU_EVENT_BSS_BEACON_LOSS ||
rxd->eid == MCU_EVENT_SCHED_SCAN_DONE || rxd->eid == MCU_EVENT_SCHED_SCAN_DONE ||
rxd->eid == MCU_EVENT_RSSI_NOTIFY ||
rxd->eid == MCU_EVENT_SCAN_DONE || rxd->eid == MCU_EVENT_SCAN_DONE ||
rxd->eid == MCU_EVENT_TX_DONE || rxd->eid == MCU_EVENT_TX_DONE ||
rxd->eid == MCU_EVENT_DBG_MSG || rxd->eid == MCU_EVENT_DBG_MSG ||
...@@ -1391,3 +1431,24 @@ int mt7921_mcu_set_rxfilter(struct mt792x_dev *dev, u32 fif, ...@@ -1391,3 +1431,24 @@ int mt7921_mcu_set_rxfilter(struct mt792x_dev *dev, u32 fif,
return mt76_mcu_send_msg(&dev->mt76, MCU_CE_CMD(SET_RX_FILTER), return mt76_mcu_send_msg(&dev->mt76, MCU_CE_CMD(SET_RX_FILTER),
&data, sizeof(data), false); &data, sizeof(data), false);
} }
int mt7921_mcu_set_rssimonitor(struct mt792x_dev *dev, struct ieee80211_vif *vif)
{
struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv;
struct {
u8 enable;
s8 cqm_rssi_high;
s8 cqm_rssi_low;
u8 bss_idx;
u16 duration;
u8 rsv2[2];
} __packed data = {
.enable = vif->cfg.assoc,
.cqm_rssi_high = vif->bss_conf.cqm_rssi_thold + vif->bss_conf.cqm_rssi_hyst,
.cqm_rssi_low = vif->bss_conf.cqm_rssi_thold - vif->bss_conf.cqm_rssi_hyst,
.bss_idx = mvif->mt76.idx,
};
return mt76_mcu_send_msg(&dev->mt76, MCU_CE_CMD(RSSI_MONITOR),
&data, sizeof(data), false);
}
...@@ -323,4 +323,5 @@ int mt7921_mcu_set_roc(struct mt792x_phy *phy, struct mt792x_vif *vif, ...@@ -323,4 +323,5 @@ int mt7921_mcu_set_roc(struct mt792x_phy *phy, struct mt792x_vif *vif,
int mt7921_mcu_abort_roc(struct mt792x_phy *phy, struct mt792x_vif *vif, int mt7921_mcu_abort_roc(struct mt792x_phy *phy, struct mt792x_vif *vif,
u8 token_id); u8 token_id);
void mt7921_roc_abort_sync(struct mt792x_dev *dev); void mt7921_roc_abort_sync(struct mt792x_dev *dev);
int mt7921_mcu_set_rssimonitor(struct mt792x_dev *dev, struct ieee80211_vif *vif);
#endif #endif
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#define MT792x_FW_CAP_CNM BIT(7) #define MT792x_FW_CAP_CNM BIT(7)
#define MT792x_CHIP_CAP_CLC_EVT_EN BIT(0) #define MT792x_CHIP_CAP_CLC_EVT_EN BIT(0)
#define MT792x_CHIP_CAP_RSSI_NOTIFY_EVT_EN BIT(1)
/* NOTE: used to map mt76_rates. idx may change if firmware expands table */ /* NOTE: used to map mt76_rates. idx may change if firmware expands table */
#define MT792x_BASIC_RATES_TBL 11 #define MT792x_BASIC_RATES_TBL 11
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment