wifi: mt76: mt7925: add rfkill_poll for hardware rfkill
authorAllan Wang <allan.wang@mediatek.com>
Wed, 7 May 2025 05:31:31 +0000 (13:31 +0800)
committerFelix Fietkau <nbd@nbd.name>
Thu, 22 May 2025 10:57:37 +0000 (12:57 +0200)
Add mac80211 rfkill_poll ops to monitor hardware rfkill state
and state change will be updated.

Signed-off-by: Allan Wang <allan.wang@mediatek.com>
Link: https://patch.msgid.link/20250507053131.4173691-1-allan.wang@mediatek.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h
drivers/net/wireless/mediatek/mt76/mt7925/main.c
drivers/net/wireless/mediatek/mt76/mt7925/mcu.c
drivers/net/wireless/mediatek/mt76/mt7925/mt7925.h
drivers/net/wireless/mediatek/mt76/mt7925/pci.c

index 97f9d6da39bd16265c3ba05758a6e9843688277e..27daf419560a57802ce057867e10e096d8ae96c6 100644 (file)
@@ -1306,6 +1306,7 @@ enum {
        MCU_UNI_CMD_PER_STA_INFO = 0x6d,
        MCU_UNI_CMD_ALL_STA_INFO = 0x6e,
        MCU_UNI_CMD_ASSERT_DUMP = 0x6f,
+       MCU_UNI_CMD_RADIO_STATUS = 0x80,
        MCU_UNI_CMD_SDO = 0x88,
 };
 
index f1d0e29ebd55ccb4786571dbd360e6be7e3a9d1a..94b0099dcd411b6064074135ca00c92a6792f07c 100644 (file)
@@ -334,6 +334,9 @@ int __mt7925_start(struct mt792x_phy *phy)
        ieee80211_queue_delayed_work(mphy->hw, &mphy->mac_work,
                                     MT792x_WATCHDOG_TIME);
 
+       if (phy->chip_cap & MT792x_CHIP_CAP_WF_RF_PIN_CTRL_EVT_EN)
+               wiphy_rfkill_start_polling(mphy->hw->wiphy);
+
        return 0;
 }
 EXPORT_SYMBOL_GPL(__mt7925_start);
@@ -2205,6 +2208,18 @@ static void mt7925_unassign_vif_chanctx(struct ieee80211_hw *hw,
        mutex_unlock(&dev->mt76.mutex);
 }
 
+static void mt7925_rfkill_poll(struct ieee80211_hw *hw)
+{
+       struct mt792x_phy *phy = mt792x_hw_phy(hw);
+       int ret;
+
+       mt792x_mutex_acquire(phy->dev);
+       ret = mt7925_mcu_wf_rf_pin_ctrl(phy);
+       mt792x_mutex_release(phy->dev);
+
+       wiphy_rfkill_set_hw_state(hw->wiphy, ret == 0);
+}
+
 const struct ieee80211_ops mt7925_ops = {
        .tx = mt792x_tx,
        .start = mt7925_start,
@@ -2267,6 +2282,7 @@ const struct ieee80211_ops mt7925_ops = {
        .link_info_changed = mt7925_link_info_changed,
        .change_vif_links = mt7925_change_vif_links,
        .change_sta_links = mt7925_change_sta_links,
+       .rfkill_poll = mt7925_rfkill_poll,
 };
 EXPORT_SYMBOL_GPL(mt7925_ops);
 
index 708be543954cbe91aecbf3644da103d4a80dfceb..9d6e7f328b493bf3c9ad9fe14d29564da742c39f 100644 (file)
@@ -3682,6 +3682,43 @@ int mt7925_mcu_set_rate_txpower(struct mt76_phy *phy)
        return 0;
 }
 
+int mt7925_mcu_wf_rf_pin_ctrl(struct mt792x_phy *phy)
+{
+#define UNI_CMD_RADIO_STATUS_GET       0
+       struct mt792x_dev *dev = phy->dev;
+       struct sk_buff *skb;
+       int ret;
+       struct {
+               __le16 tag;
+               __le16 len;
+               u8 rsv[4];
+       } __packed req = {
+               .tag = UNI_CMD_RADIO_STATUS_GET,
+               .len = cpu_to_le16(sizeof(req)),
+       };
+       struct mt7925_radio_status_event {
+               __le16 tag;
+               __le16 len;
+
+               u8 data;
+               u8 rsv[3];
+       } __packed *status;
+
+       ret = mt76_mcu_send_and_get_msg(&dev->mt76,
+                                       MCU_UNI_CMD(RADIO_STATUS),
+                                       &req, sizeof(req), true, &skb);
+       if (ret)
+               return ret;
+
+       skb_pull(skb, sizeof(struct tlv));
+       status = (struct mt7925_radio_status_event *)skb->data;
+       ret = status->data;
+
+       dev_kfree_skb(skb);
+
+       return ret;
+}
+
 int mt7925_mcu_set_rxfilter(struct mt792x_dev *dev, u32 fif,
                            u8 bit_op, u32 bit_map)
 {
index c507dcae07d4d17ffc6c1ddf31d72ef49f9f77ec..1b165d0d8bd39c510069f6ff222f206b1e9ceec7 100644 (file)
@@ -365,6 +365,7 @@ int mt7925_mcu_wtbl_update_hdr_trans(struct mt792x_dev *dev,
                                     struct ieee80211_vif *vif,
                                     struct ieee80211_sta *sta,
                                     int link_id);
+int mt7925_mcu_wf_rf_pin_ctrl(struct mt792x_phy *phy);
 
 int mt7925_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                        void *data, int len);
index 2e20ecc712071cc447b01e5f6362c0187bad10a0..89dc30f7c6b7a298e0c23bf6f45edca29fa261ac 100644 (file)
@@ -31,6 +31,10 @@ static void mt7925e_unregister_device(struct mt792x_dev *dev)
 {
        int i;
        struct mt76_connac_pm *pm = &dev->pm;
+       struct ieee80211_hw *hw = mt76_hw(dev);
+
+       if (dev->phy.chip_cap & MT792x_CHIP_CAP_WF_RF_PIN_CTRL_EVT_EN)
+               wiphy_rfkill_stop_polling(hw->wiphy);
 
        cancel_work_sync(&dev->init_work);
        mt76_unregister_device(&dev->mt76);