summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/mediatek/mt76/mt7921/mcu.c')
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7921/mcu.c110
1 files changed, 106 insertions, 4 deletions
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
index fb9c0f66cb27..c5e7ad06f877 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
@@ -174,7 +174,7 @@ mt7921_mcu_uni_roc_event(struct mt7921_dev *dev, struct sk_buff *skb)
wake_up(&dev->phy.roc_wait);
duration = le32_to_cpu(grant->max_interval);
mod_timer(&dev->phy.roc_timer,
- round_jiffies_up(jiffies + msecs_to_jiffies(duration)));
+ jiffies + msecs_to_jiffies(duration));
}
static void
@@ -1019,6 +1019,8 @@ int mt7921_mcu_set_beacon_filter(struct mt7921_dev *dev,
struct ieee80211_vif *vif,
bool enable)
{
+#define MT7921_FIF_BIT_CLR BIT(1)
+#define MT7921_FIF_BIT_SET BIT(0)
int err;
if (enable) {
@@ -1026,7 +1028,11 @@ int mt7921_mcu_set_beacon_filter(struct mt7921_dev *dev,
if (err)
return err;
- mt76_set(dev, MT_WF_RFCR(0), MT_WF_RFCR_DROP_OTHER_BEACON);
+ err = mt7921_mcu_set_rxfilter(dev, 0,
+ MT7921_FIF_BIT_SET,
+ MT_WF_RFCR_DROP_OTHER_BEACON);
+ if (err)
+ return err;
return 0;
}
@@ -1035,7 +1041,11 @@ int mt7921_mcu_set_beacon_filter(struct mt7921_dev *dev,
if (err)
return err;
- mt76_clear(dev, MT_WF_RFCR(0), MT_WF_RFCR_DROP_OTHER_BEACON);
+ err = mt7921_mcu_set_rxfilter(dev, 0,
+ MT7921_FIF_BIT_CLR,
+ MT_WF_RFCR_DROP_OTHER_BEACON);
+ if (err)
+ return err;
return 0;
}
@@ -1093,6 +1103,74 @@ int mt7921_mcu_set_sniffer(struct mt7921_dev *dev, struct ieee80211_vif *vif,
true);
}
+int mt7921_mcu_config_sniffer(struct mt7921_vif *vif,
+ struct ieee80211_chanctx_conf *ctx)
+{
+ struct cfg80211_chan_def *chandef = &ctx->def;
+ int freq1 = chandef->center_freq1, freq2 = chandef->center_freq2;
+ const u8 ch_band[] = {
+ [NL80211_BAND_2GHZ] = 1,
+ [NL80211_BAND_5GHZ] = 2,
+ [NL80211_BAND_6GHZ] = 3,
+ };
+ const u8 ch_width[] = {
+ [NL80211_CHAN_WIDTH_20_NOHT] = 0,
+ [NL80211_CHAN_WIDTH_20] = 0,
+ [NL80211_CHAN_WIDTH_40] = 0,
+ [NL80211_CHAN_WIDTH_80] = 1,
+ [NL80211_CHAN_WIDTH_160] = 2,
+ [NL80211_CHAN_WIDTH_80P80] = 3,
+ [NL80211_CHAN_WIDTH_5] = 4,
+ [NL80211_CHAN_WIDTH_10] = 5,
+ [NL80211_CHAN_WIDTH_320] = 6,
+ };
+ struct {
+ struct {
+ u8 band_idx;
+ u8 pad[3];
+ } __packed hdr;
+ struct config_tlv {
+ __le16 tag;
+ __le16 len;
+ u16 aid;
+ u8 ch_band;
+ u8 bw;
+ u8 control_ch;
+ u8 sco;
+ u8 center_ch;
+ u8 center_ch2;
+ u8 drop_err;
+ u8 pad[3];
+ } __packed tlv;
+ } __packed req = {
+ .hdr = {
+ .band_idx = vif->mt76.band_idx,
+ },
+ .tlv = {
+ .tag = cpu_to_le16(1),
+ .len = cpu_to_le16(sizeof(req.tlv)),
+ .control_ch = chandef->chan->hw_value,
+ .center_ch = ieee80211_frequency_to_channel(freq1),
+ .drop_err = 1,
+ },
+ };
+ if (chandef->chan->band < ARRAY_SIZE(ch_band))
+ req.tlv.ch_band = ch_band[chandef->chan->band];
+ if (chandef->width < ARRAY_SIZE(ch_width))
+ req.tlv.bw = ch_width[chandef->width];
+
+ if (freq2)
+ req.tlv.center_ch2 = ieee80211_frequency_to_channel(freq2);
+
+ if (req.tlv.control_ch < req.tlv.center_ch)
+ req.tlv.sco = 1; /* SCA */
+ else if (req.tlv.control_ch > req.tlv.center_ch)
+ req.tlv.sco = 3; /* SCB */
+
+ return mt76_mcu_send_msg(vif->phy->mt76->dev, MCU_UNI_CMD(SNIFFER),
+ &req, sizeof(req), true);
+}
+
int
mt7921_mcu_uni_add_beacon_offload(struct mt7921_dev *dev,
struct ieee80211_hw *hw,
@@ -1184,13 +1262,15 @@ int __mt7921_mcu_set_clc(struct mt7921_dev *dev, u8 *alpha2,
__le16 len;
u8 idx;
u8 env;
- u8 pad1[2];
+ u8 acpi_conf;
+ u8 pad1;
u8 alpha2[2];
u8 type[2];
u8 rsvd[64];
} __packed req = {
.idx = idx,
.env = env_cap,
+ .acpi_conf = mt7921_acpi_get_flags(&dev->phy),
};
int ret, valid_cnt = 0;
u8 i, *pos;
@@ -1253,3 +1333,25 @@ int mt7921_mcu_set_clc(struct mt7921_dev *dev, u8 *alpha2,
}
return 0;
}
+
+int mt7921_mcu_set_rxfilter(struct mt7921_dev *dev, u32 fif,
+ u8 bit_op, u32 bit_map)
+{
+ struct {
+ u8 rsv[4];
+ u8 mode;
+ u8 rsv2[3];
+ __le32 fif;
+ __le32 bit_map; /* bit_* for bitmap update */
+ u8 bit_op;
+ u8 pad[51];
+ } __packed data = {
+ .mode = fif ? 1 : 2,
+ .fif = cpu_to_le32(fif),
+ .bit_map = cpu_to_le32(bit_map),
+ .bit_op = bit_op,
+ };
+
+ return mt76_mcu_send_msg(&dev->mt76, MCU_CE_CMD(SET_RX_FILTER),
+ &data, sizeof(data), false);
+}