Message ID | 608cc2bb1c10c2f53a6bf26711bf49fe2c491e59.1712806947.git.quan.zhou@mediatek.com (mailing list archive) |
---|---|
State | Accepted |
Delegated to: | Felix Fietkau |
Headers | show |
Series | [v2] wifi: mt76: mt7921e: add LED control support | expand |
> From: Hao Zhang <hao.zhang@mediatek.com> > > Introduce wifi LED switch control, add flow to Control a wifi > gpio pin based on the status of WIFI radio, if the pin is connected > to an LED, the LED will indicate the status of the WiFi radio. > > Signed-off-by: Hao Zhang <hao.zhang@mediatek.com> > Co-developed-by: Quan Zhou <quan.zhou@mediatek.com> > Signed-off-by: Quan Zhou <quan.zhou@mediatek.com> Acked-by: Lorenzo Bianconi <lorenzo@kernel.org> > --- > v2: > fix to avoid wake device when Hardware interface not pcie > --- > .../wireless/mediatek/mt76/mt76_connac_mcu.h | 1 + > .../net/wireless/mediatek/mt76/mt7921/main.c | 27 ++++++++++++++++++- > .../net/wireless/mediatek/mt76/mt7921/mcu.c | 14 ++++++++++ > .../wireless/mediatek/mt76/mt7921/mt7921.h | 5 ++++ > .../net/wireless/mediatek/mt76/mt7921/pci.c | 8 +++++- > 5 files changed, 53 insertions(+), 2 deletions(-) > > diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h > index 836cc4d5b1d2..4c2de556dee1 100644 > --- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h > +++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h > @@ -1189,6 +1189,7 @@ enum { > MCU_EXT_CMD_EFUSE_ACCESS = 0x01, > MCU_EXT_CMD_RF_REG_ACCESS = 0x02, > MCU_EXT_CMD_RF_TEST = 0x04, > + MCU_EXT_CMD_ID_RADIO_ON_OFF_CTRL = 0x05, > MCU_EXT_CMD_PM_STATE_CTRL = 0x07, > MCU_EXT_CMD_CHANNEL_SWITCH = 0x08, > MCU_EXT_CMD_SET_TX_POWER_CTRL = 0x11, > diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/main.c b/drivers/net/wireless/mediatek/mt76/mt7921/main.c > index ca36de34171b..ea6a113b7b36 100644 > --- a/drivers/net/wireless/mediatek/mt76/mt7921/main.c > +++ b/drivers/net/wireless/mediatek/mt76/mt7921/main.c > @@ -242,6 +242,15 @@ int __mt7921_start(struct mt792x_phy *phy) > > ieee80211_queue_delayed_work(mphy->hw, &mphy->mac_work, > MT792x_WATCHDOG_TIME); > + if (mt76_is_mmio(mphy->dev)) { > + err = mt7921_mcu_radio_led_ctrl(phy->dev, EXT_CMD_RADIO_LED_CTRL_ENABLE); > + if (err) > + return err; > + > + err = mt7921_mcu_radio_led_ctrl(phy->dev, EXT_CMD_RADIO_ON_LED); > + if (err) > + return err; > + } > > return 0; > } > @@ -259,6 +268,22 @@ static int mt7921_start(struct ieee80211_hw *hw) > return err; > } > > +static void mt7921_stop(struct ieee80211_hw *hw) > +{ > + struct mt792x_dev *dev = mt792x_hw_dev(hw); > + int err = 0; > + > + if (mt76_is_mmio(&dev->mt76)) { > + mt792x_mutex_acquire(dev); > + err = mt7921_mcu_radio_led_ctrl(dev, EXT_CMD_RADIO_OFF_LED); > + mt792x_mutex_release(dev); > + if (err) > + return; > + } > + > + mt792x_stop(hw); > +} > + > static int > mt7921_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) > { > @@ -1372,7 +1397,7 @@ static void mt7921_mgd_complete_tx(struct ieee80211_hw *hw, > const struct ieee80211_ops mt7921_ops = { > .tx = mt792x_tx, > .start = mt7921_start, > - .stop = mt792x_stop, > + .stop = mt7921_stop, > .add_interface = mt7921_add_interface, > .remove_interface = mt792x_remove_interface, > .config = mt7921_config, > diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c > index 8b4ce32a2cd1..2ebf0ffe78d5 100644 > --- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c > +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c > @@ -606,6 +606,20 @@ int mt7921_run_firmware(struct mt792x_dev *dev) > } > EXPORT_SYMBOL_GPL(mt7921_run_firmware); > > +int mt7921_mcu_radio_led_ctrl(struct mt792x_dev *dev, u8 value) > +{ > + struct { > + u8 ctrlid; > + u8 rsv[3]; > + } __packed req = { > + .ctrlid = value, > + }; > + > + return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(ID_RADIO_ON_OFF_CTRL), > + &req, sizeof(req), false); > +} > +EXPORT_SYMBOL_GPL(mt7921_mcu_radio_led_ctrl); > + > int mt7921_mcu_set_tx(struct mt792x_dev *dev, struct ieee80211_vif *vif) > { > struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv; > diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h > index 3016636d18c6..07023eb9e5b5 100644 > --- a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h > +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h > @@ -27,6 +27,10 @@ > #define MCU_UNI_EVENT_ROC 0x27 > #define MCU_UNI_EVENT_CLC 0x80 > > +#define EXT_CMD_RADIO_LED_CTRL_ENABLE 0x1 > +#define EXT_CMD_RADIO_ON_LED 0x2 > +#define EXT_CMD_RADIO_OFF_LED 0x3 > + > enum { > UNI_ROC_ACQUIRE, > UNI_ROC_ABORT, > @@ -196,6 +200,7 @@ int mt7921_mcu_fw_log_2_host(struct mt792x_dev *dev, u8 ctrl); > void mt7921_mcu_rx_event(struct mt792x_dev *dev, struct sk_buff *skb); > int mt7921_mcu_set_rxfilter(struct mt792x_dev *dev, u32 fif, > u8 bit_op, u32 bit_map); > +int mt7921_mcu_radio_led_ctrl(struct mt792x_dev *dev, u8 value); > > static inline u32 > mt7921_reg_map_l1(struct mt792x_dev *dev, u32 addr) > diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c > index 0b69b225bc16..f768e9389ac6 100644 > --- a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c > +++ b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c > @@ -427,6 +427,10 @@ static int mt7921_pci_suspend(struct device *device) > wait_event_timeout(dev->wait, > !dev->regd_in_progress, 5 * HZ); > > + err = mt7921_mcu_radio_led_ctrl(dev, EXT_CMD_RADIO_OFF_LED); > + if (err < 0) > + goto restore_suspend; > + > err = mt76_connac_mcu_set_hif_suspend(mdev, true); > if (err) > goto restore_suspend; > @@ -525,9 +529,11 @@ static int mt7921_pci_resume(struct device *device) > mt76_connac_mcu_set_deep_sleep(&dev->mt76, false); > > err = mt76_connac_mcu_set_hif_suspend(mdev, false); > + if (err < 0) > + goto failed; > > mt7921_regd_update(dev); > - > + err = mt7921_mcu_radio_led_ctrl(dev, EXT_CMD_RADIO_ON_LED); > failed: > pm->suspended = false; > > -- > 2.18.0 >
HI Quan, On Wed, Apr 10, 2024 at 11:00 PM Quan Zhou <quan.zhou@mediatek.com> wrote: > > From: Hao Zhang <hao.zhang@mediatek.com> > > Introduce wifi LED switch control, add flow to Control a wifi > gpio pin based on the status of WIFI radio, if the pin is connected > to an LED, the LED will indicate the status of the WiFi radio. > > Signed-off-by: Hao Zhang <hao.zhang@mediatek.com> > Co-developed-by: Quan Zhou <quan.zhou@mediatek.com> > Signed-off-by: Quan Zhou <quan.zhou@mediatek.com> > --- > v2: > fix to avoid wake device when Hardware interface not pcie > --- > .../wireless/mediatek/mt76/mt76_connac_mcu.h | 1 + > .../net/wireless/mediatek/mt76/mt7921/main.c | 27 ++++++++++++++++++- > .../net/wireless/mediatek/mt76/mt7921/mcu.c | 14 ++++++++++ > .../wireless/mediatek/mt76/mt7921/mt7921.h | 5 ++++ > .../net/wireless/mediatek/mt76/mt7921/pci.c | 8 +++++- > 5 files changed, 53 insertions(+), 2 deletions(-) > > diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h > index 836cc4d5b1d2..4c2de556dee1 100644 > --- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h > +++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h > @@ -1189,6 +1189,7 @@ enum { > MCU_EXT_CMD_EFUSE_ACCESS = 0x01, > MCU_EXT_CMD_RF_REG_ACCESS = 0x02, > MCU_EXT_CMD_RF_TEST = 0x04, > + MCU_EXT_CMD_ID_RADIO_ON_OFF_CTRL = 0x05, > MCU_EXT_CMD_PM_STATE_CTRL = 0x07, > MCU_EXT_CMD_CHANNEL_SWITCH = 0x08, > MCU_EXT_CMD_SET_TX_POWER_CTRL = 0x11, > diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/main.c b/drivers/net/wireless/mediatek/mt76/mt7921/main.c > index ca36de34171b..ea6a113b7b36 100644 > --- a/drivers/net/wireless/mediatek/mt76/mt7921/main.c > +++ b/drivers/net/wireless/mediatek/mt76/mt7921/main.c > @@ -242,6 +242,15 @@ int __mt7921_start(struct mt792x_phy *phy) > > ieee80211_queue_delayed_work(mphy->hw, &mphy->mac_work, > MT792x_WATCHDOG_TIME); > + if (mt76_is_mmio(mphy->dev)) { I guess the led control MCU command is not limited to PCIe devices, they should be able to be extended even on MT7921 USB and SDIO devices, right ? if so, I think we can drop the MMIO limitation condition to support more scenarios and to make it easier to understand. > + err = mt7921_mcu_radio_led_ctrl(phy->dev, EXT_CMD_RADIO_LED_CTRL_ENABLE); > + if (err) > + return err; > + > + err = mt7921_mcu_radio_led_ctrl(phy->dev, EXT_CMD_RADIO_ON_LED); > + if (err) > + return err; > + } > > return 0; > } > @@ -259,6 +268,22 @@ static int mt7921_start(struct ieee80211_hw *hw) > return err; > } > > +static void mt7921_stop(struct ieee80211_hw *hw) > +{ > + struct mt792x_dev *dev = mt792x_hw_dev(hw); > + int err = 0; > + > + if (mt76_is_mmio(&dev->mt76)) { > + mt792x_mutex_acquire(dev); > + err = mt7921_mcu_radio_led_ctrl(dev, EXT_CMD_RADIO_OFF_LED); > + mt792x_mutex_release(dev); > + if (err) > + return; > + } > + > + mt792x_stop(hw); > +} > + > static int > mt7921_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) > { > @@ -1372,7 +1397,7 @@ static void mt7921_mgd_complete_tx(struct ieee80211_hw *hw, > const struct ieee80211_ops mt7921_ops = { > .tx = mt792x_tx, > .start = mt7921_start, > - .stop = mt792x_stop, > + .stop = mt7921_stop, > .add_interface = mt7921_add_interface, > .remove_interface = mt792x_remove_interface, > .config = mt7921_config, > diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c > index 8b4ce32a2cd1..2ebf0ffe78d5 100644 > --- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c > +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c > @@ -606,6 +606,20 @@ int mt7921_run_firmware(struct mt792x_dev *dev) > } > EXPORT_SYMBOL_GPL(mt7921_run_firmware); > > +int mt7921_mcu_radio_led_ctrl(struct mt792x_dev *dev, u8 value) > +{ > + struct { > + u8 ctrlid; > + u8 rsv[3]; > + } __packed req = { > + .ctrlid = value, > + }; > + > + return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(ID_RADIO_ON_OFF_CTRL), > + &req, sizeof(req), false); > +} > +EXPORT_SYMBOL_GPL(mt7921_mcu_radio_led_ctrl); > + > int mt7921_mcu_set_tx(struct mt792x_dev *dev, struct ieee80211_vif *vif) > { > struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv; > diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h > index 3016636d18c6..07023eb9e5b5 100644 > --- a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h > +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h > @@ -27,6 +27,10 @@ > #define MCU_UNI_EVENT_ROC 0x27 > #define MCU_UNI_EVENT_CLC 0x80 > > +#define EXT_CMD_RADIO_LED_CTRL_ENABLE 0x1 > +#define EXT_CMD_RADIO_ON_LED 0x2 > +#define EXT_CMD_RADIO_OFF_LED 0x3 > + > enum { > UNI_ROC_ACQUIRE, > UNI_ROC_ABORT, > @@ -196,6 +200,7 @@ int mt7921_mcu_fw_log_2_host(struct mt792x_dev *dev, u8 ctrl); > void mt7921_mcu_rx_event(struct mt792x_dev *dev, struct sk_buff *skb); > int mt7921_mcu_set_rxfilter(struct mt792x_dev *dev, u32 fif, > u8 bit_op, u32 bit_map); > +int mt7921_mcu_radio_led_ctrl(struct mt792x_dev *dev, u8 value); > > static inline u32 > mt7921_reg_map_l1(struct mt792x_dev *dev, u32 addr) > diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c > index 0b69b225bc16..f768e9389ac6 100644 > --- a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c > +++ b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c > @@ -427,6 +427,10 @@ static int mt7921_pci_suspend(struct device *device) > wait_event_timeout(dev->wait, > !dev->regd_in_progress, 5 * HZ); > > + err = mt7921_mcu_radio_led_ctrl(dev, EXT_CMD_RADIO_OFF_LED); > + if (err < 0) > + goto restore_suspend; > + > err = mt76_connac_mcu_set_hif_suspend(mdev, true); > if (err) > goto restore_suspend; > @@ -525,9 +529,11 @@ static int mt7921_pci_resume(struct device *device) > mt76_connac_mcu_set_deep_sleep(&dev->mt76, false); > > err = mt76_connac_mcu_set_hif_suspend(mdev, false); > + if (err < 0) > + goto failed; > > mt7921_regd_update(dev); > - > + err = mt7921_mcu_radio_led_ctrl(dev, EXT_CMD_RADIO_ON_LED); > failed: > pm->suspended = false; > > -- > 2.18.0 > >
On Wed, 2024-04-17 at 15:06 -0700, Sean Wang wrote: > > External email : Please do not click links or open attachments until > you have verified the sender or the content. > HI Quan, > > On Wed, Apr 10, 2024 at 11:00 PM Quan Zhou <quan.zhou@mediatek.com> > wrote: > > > > From: Hao Zhang <hao.zhang@mediatek.com> > > > > Introduce wifi LED switch control, add flow to Control a wifi > > gpio pin based on the status of WIFI radio, if the pin is connected > > to an LED, the LED will indicate the status of the WiFi radio. > > > > Signed-off-by: Hao Zhang <hao.zhang@mediatek.com> > > Co-developed-by: Quan Zhou <quan.zhou@mediatek.com> > > Signed-off-by: Quan Zhou <quan.zhou@mediatek.com> > > --- > > v2: > > fix to avoid wake device when Hardware interface not pcie > > --- > > .../wireless/mediatek/mt76/mt76_connac_mcu.h | 1 + > > .../net/wireless/mediatek/mt76/mt7921/main.c | 27 > ++++++++++++++++++- > > .../net/wireless/mediatek/mt76/mt7921/mcu.c | 14 ++++++++++ > > .../wireless/mediatek/mt76/mt7921/mt7921.h | 5 ++++ > > .../net/wireless/mediatek/mt76/mt7921/pci.c | 8 +++++- > > 5 files changed, 53 insertions(+), 2 deletions(-) > > > > diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h > b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h > > index 836cc4d5b1d2..4c2de556dee1 100644 > > --- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h > > +++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h > > @@ -1189,6 +1189,7 @@ enum { > > MCU_EXT_CMD_EFUSE_ACCESS = 0x01, > > MCU_EXT_CMD_RF_REG_ACCESS = 0x02, > > MCU_EXT_CMD_RF_TEST = 0x04, > > + MCU_EXT_CMD_ID_RADIO_ON_OFF_CTRL = 0x05, > > MCU_EXT_CMD_PM_STATE_CTRL = 0x07, > > MCU_EXT_CMD_CHANNEL_SWITCH = 0x08, > > MCU_EXT_CMD_SET_TX_POWER_CTRL = 0x11, > > diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/main.c > b/drivers/net/wireless/mediatek/mt76/mt7921/main.c > > index ca36de34171b..ea6a113b7b36 100644 > > --- a/drivers/net/wireless/mediatek/mt76/mt7921/main.c > > +++ b/drivers/net/wireless/mediatek/mt76/mt7921/main.c > > @@ -242,6 +242,15 @@ int __mt7921_start(struct mt792x_phy *phy) > > > > ieee80211_queue_delayed_work(mphy->hw, &mphy->mac_work, > > MT792x_WATCHDOG_TIME); > > + if (mt76_is_mmio(mphy->dev)) { > > I guess the led control MCU command is not limited to PCIe devices, > they should be able to be extended even on MT7921 USB and SDIO > devices, right ? if so, I think we can drop the MMIO limitation > condition to support more scenarios and to make it easier to > understand. > Hi Sean, This software flow involves chip GPIO control and is related to the module's circuit design. Only the PCIe module can provide support for this, so can't drop. > > + err = mt7921_mcu_radio_led_ctrl(phy->dev, > EXT_CMD_RADIO_LED_CTRL_ENABLE); > > + if (err) > > + return err; > > + > > + err = mt7921_mcu_radio_led_ctrl(phy->dev, > EXT_CMD_RADIO_ON_LED); > > + if (err) > > + return err; > > + } > > > > return 0; > > } > > @@ -259,6 +268,22 @@ static int mt7921_start(struct ieee80211_hw > *hw) > > return err; > > } > > > > +static void mt7921_stop(struct ieee80211_hw *hw) > > +{ > > + struct mt792x_dev *dev = mt792x_hw_dev(hw); > > + int err = 0; > > + > > + if (mt76_is_mmio(&dev->mt76)) { > > + mt792x_mutex_acquire(dev); > > + err = mt7921_mcu_radio_led_ctrl(dev, > EXT_CMD_RADIO_OFF_LED); > > + mt792x_mutex_release(dev); > > + if (err) > > + return; > > + } > > + > > + mt792x_stop(hw); > > +} > > + > > static int > > mt7921_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif > *vif) > > { > > @@ -1372,7 +1397,7 @@ static void mt7921_mgd_complete_tx(struct > ieee80211_hw *hw, > > const struct ieee80211_ops mt7921_ops = { > > .tx = mt792x_tx, > > .start = mt7921_start, > > - .stop = mt792x_stop, > > + .stop = mt7921_stop, > > .add_interface = mt7921_add_interface, > > .remove_interface = mt792x_remove_interface, > > .config = mt7921_config, > > diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c > b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c > > index 8b4ce32a2cd1..2ebf0ffe78d5 100644 > > --- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c > > +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c > > @@ -606,6 +606,20 @@ int mt7921_run_firmware(struct mt792x_dev > *dev) > > } > > EXPORT_SYMBOL_GPL(mt7921_run_firmware); > > > > +int mt7921_mcu_radio_led_ctrl(struct mt792x_dev *dev, u8 value) > > +{ > > + struct { > > + u8 ctrlid; > > + u8 rsv[3]; > > + } __packed req = { > > + .ctrlid = value, > > + }; > > + > > + return mt76_mcu_send_msg(&dev->mt76, > MCU_EXT_CMD(ID_RADIO_ON_OFF_CTRL), > > + &req, sizeof(req), false); > > +} > > +EXPORT_SYMBOL_GPL(mt7921_mcu_radio_led_ctrl); > > + > > int mt7921_mcu_set_tx(struct mt792x_dev *dev, struct ieee80211_vif > *vif) > > { > > struct mt792x_vif *mvif = (struct mt792x_vif *)vif- > >drv_priv; > > diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h > b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h > > index 3016636d18c6..07023eb9e5b5 100644 > > --- a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h > > +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h > > @@ -27,6 +27,10 @@ > > #define MCU_UNI_EVENT_ROC 0x27 > > #define MCU_UNI_EVENT_CLC 0x80 > > > > +#define EXT_CMD_RADIO_LED_CTRL_ENABLE 0x1 > > +#define EXT_CMD_RADIO_ON_LED 0x2 > > +#define EXT_CMD_RADIO_OFF_LED 0x3 > > + > > enum { > > UNI_ROC_ACQUIRE, > > UNI_ROC_ABORT, > > @@ -196,6 +200,7 @@ int mt7921_mcu_fw_log_2_host(struct mt792x_dev > *dev, u8 ctrl); > > void mt7921_mcu_rx_event(struct mt792x_dev *dev, struct sk_buff > *skb); > > int mt7921_mcu_set_rxfilter(struct mt792x_dev *dev, u32 fif, > > u8 bit_op, u32 bit_map); > > +int mt7921_mcu_radio_led_ctrl(struct mt792x_dev *dev, u8 value); > > > > static inline u32 > > mt7921_reg_map_l1(struct mt792x_dev *dev, u32 addr) > > diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c > b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c > > index 0b69b225bc16..f768e9389ac6 100644 > > --- a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c > > +++ b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c > > @@ -427,6 +427,10 @@ static int mt7921_pci_suspend(struct device > *device) > > wait_event_timeout(dev->wait, > > !dev->regd_in_progress, 5 * HZ); > > > > + err = mt7921_mcu_radio_led_ctrl(dev, > EXT_CMD_RADIO_OFF_LED); > > + if (err < 0) > > + goto restore_suspend; > > + > > err = mt76_connac_mcu_set_hif_suspend(mdev, true); > > if (err) > > goto restore_suspend; > > @@ -525,9 +529,11 @@ static int mt7921_pci_resume(struct device > *device) > > mt76_connac_mcu_set_deep_sleep(&dev->mt76, false); > > > > err = mt76_connac_mcu_set_hif_suspend(mdev, false); > > + if (err < 0) > > + goto failed; > > > > mt7921_regd_update(dev); > > - > > + err = mt7921_mcu_radio_led_ctrl(dev, EXT_CMD_RADIO_ON_LED); > > failed: > > pm->suspended = false; > > > > -- > > 2.18.0 > > > >
On Wed, Apr 17, 2024 at 6:43 PM Quan Zhou (周全) <Quan.Zhou@mediatek.com> wrote: > > On Wed, 2024-04-17 at 15:06 -0700, Sean Wang wrote: > > > > External email : Please do not click links or open attachments until > > you have verified the sender or the content. > > HI Quan, > > > > On Wed, Apr 10, 2024 at 11:00 PM Quan Zhou <quan.zhou@mediatek.com> > > wrote: > > > > > > From: Hao Zhang <hao.zhang@mediatek.com> > > > > > > Introduce wifi LED switch control, add flow to Control a wifi > > > gpio pin based on the status of WIFI radio, if the pin is connected > > > to an LED, the LED will indicate the status of the WiFi radio. > > > > > > Signed-off-by: Hao Zhang <hao.zhang@mediatek.com> > > > Co-developed-by: Quan Zhou <quan.zhou@mediatek.com> > > > Signed-off-by: Quan Zhou <quan.zhou@mediatek.com> > > > --- > > > v2: > > > fix to avoid wake device when Hardware interface not pcie > > > --- > > > .../wireless/mediatek/mt76/mt76_connac_mcu.h | 1 + > > > .../net/wireless/mediatek/mt76/mt7921/main.c | 27 > > ++++++++++++++++++- > > > .../net/wireless/mediatek/mt76/mt7921/mcu.c | 14 ++++++++++ > > > .../wireless/mediatek/mt76/mt7921/mt7921.h | 5 ++++ > > > .../net/wireless/mediatek/mt76/mt7921/pci.c | 8 +++++- > > > 5 files changed, 53 insertions(+), 2 deletions(-) > > > > > > diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h > > b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h > > > index 836cc4d5b1d2..4c2de556dee1 100644 > > > --- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h > > > +++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h > > > @@ -1189,6 +1189,7 @@ enum { > > > MCU_EXT_CMD_EFUSE_ACCESS = 0x01, > > > MCU_EXT_CMD_RF_REG_ACCESS = 0x02, > > > MCU_EXT_CMD_RF_TEST = 0x04, > > > + MCU_EXT_CMD_ID_RADIO_ON_OFF_CTRL = 0x05, > > > MCU_EXT_CMD_PM_STATE_CTRL = 0x07, > > > MCU_EXT_CMD_CHANNEL_SWITCH = 0x08, > > > MCU_EXT_CMD_SET_TX_POWER_CTRL = 0x11, > > > diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/main.c > > b/drivers/net/wireless/mediatek/mt76/mt7921/main.c > > > index ca36de34171b..ea6a113b7b36 100644 > > > --- a/drivers/net/wireless/mediatek/mt76/mt7921/main.c > > > +++ b/drivers/net/wireless/mediatek/mt76/mt7921/main.c > > > @@ -242,6 +242,15 @@ int __mt7921_start(struct mt792x_phy *phy) > > > > > > ieee80211_queue_delayed_work(mphy->hw, &mphy->mac_work, > > > MT792x_WATCHDOG_TIME); > > > + if (mt76_is_mmio(mphy->dev)) { > > > > I guess the led control MCU command is not limited to PCIe devices, > > they should be able to be extended even on MT7921 USB and SDIO > > devices, right ? if so, I think we can drop the MMIO limitation > > condition to support more scenarios and to make it easier to > > understand. > > > Hi Sean, > > This software flow involves chip GPIO control and is related to the > module's circuit design. Only the PCIe module can provide support for > this, so can't drop. Hi Quan, Thanks for clearing that up quickly. I guess we can add it just for MT7921E. I have another question: Will the new command you added work with older firmware, or is it made only for the most recent firmware? I'm worried it might not be compatible with the older MT7921 firmware. Sean > > > > + err = mt7921_mcu_radio_led_ctrl(phy->dev, > > EXT_CMD_RADIO_LED_CTRL_ENABLE); > > > + if (err) > > > + return err; > > > + > > > + err = mt7921_mcu_radio_led_ctrl(phy->dev, > > EXT_CMD_RADIO_ON_LED); > > > + if (err) > > > + return err; > > > + } > > > > > > return 0; > > > } > > > @@ -259,6 +268,22 @@ static int mt7921_start(struct ieee80211_hw > > *hw) > > > return err; > > > } > > > > > > +static void mt7921_stop(struct ieee80211_hw *hw) > > > +{ > > > + struct mt792x_dev *dev = mt792x_hw_dev(hw); > > > + int err = 0; > > > + > > > + if (mt76_is_mmio(&dev->mt76)) { > > > + mt792x_mutex_acquire(dev); > > > + err = mt7921_mcu_radio_led_ctrl(dev, > > EXT_CMD_RADIO_OFF_LED); > > > + mt792x_mutex_release(dev); > > > + if (err) > > > + return; > > > + } > > > + > > > + mt792x_stop(hw); > > > +} > > > + > > > static int > > > mt7921_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif > > *vif) > > > { > > > @@ -1372,7 +1397,7 @@ static void mt7921_mgd_complete_tx(struct > > ieee80211_hw *hw, > > > const struct ieee80211_ops mt7921_ops = { > > > .tx = mt792x_tx, > > > .start = mt7921_start, > > > - .stop = mt792x_stop, > > > + .stop = mt7921_stop, > > > .add_interface = mt7921_add_interface, > > > .remove_interface = mt792x_remove_interface, > > > .config = mt7921_config, > > > diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c > > b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c > > > index 8b4ce32a2cd1..2ebf0ffe78d5 100644 > > > --- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c > > > +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c > > > @@ -606,6 +606,20 @@ int mt7921_run_firmware(struct mt792x_dev > > *dev) > > > } > > > EXPORT_SYMBOL_GPL(mt7921_run_firmware); > > > > > > +int mt7921_mcu_radio_led_ctrl(struct mt792x_dev *dev, u8 value) > > > +{ > > > + struct { > > > + u8 ctrlid; > > > + u8 rsv[3]; > > > + } __packed req = { > > > + .ctrlid = value, > > > + }; > > > + > > > + return mt76_mcu_send_msg(&dev->mt76, > > MCU_EXT_CMD(ID_RADIO_ON_OFF_CTRL), > > > + &req, sizeof(req), false); > > > +} > > > +EXPORT_SYMBOL_GPL(mt7921_mcu_radio_led_ctrl); > > > + > > > int mt7921_mcu_set_tx(struct mt792x_dev *dev, struct ieee80211_vif > > *vif) > > > { > > > struct mt792x_vif *mvif = (struct mt792x_vif *)vif- > > >drv_priv; > > > diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h > > b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h > > > index 3016636d18c6..07023eb9e5b5 100644 > > > --- a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h > > > +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h > > > @@ -27,6 +27,10 @@ > > > #define MCU_UNI_EVENT_ROC 0x27 > > > #define MCU_UNI_EVENT_CLC 0x80 > > > > > > +#define EXT_CMD_RADIO_LED_CTRL_ENABLE 0x1 > > > +#define EXT_CMD_RADIO_ON_LED 0x2 > > > +#define EXT_CMD_RADIO_OFF_LED 0x3 > > > + > > > enum { > > > UNI_ROC_ACQUIRE, > > > UNI_ROC_ABORT, > > > @@ -196,6 +200,7 @@ int mt7921_mcu_fw_log_2_host(struct mt792x_dev > > *dev, u8 ctrl); > > > void mt7921_mcu_rx_event(struct mt792x_dev *dev, struct sk_buff > > *skb); > > > int mt7921_mcu_set_rxfilter(struct mt792x_dev *dev, u32 fif, > > > u8 bit_op, u32 bit_map); > > > +int mt7921_mcu_radio_led_ctrl(struct mt792x_dev *dev, u8 value); > > > > > > static inline u32 > > > mt7921_reg_map_l1(struct mt792x_dev *dev, u32 addr) > > > diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c > > b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c > > > index 0b69b225bc16..f768e9389ac6 100644 > > > --- a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c > > > +++ b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c > > > @@ -427,6 +427,10 @@ static int mt7921_pci_suspend(struct device > > *device) > > > wait_event_timeout(dev->wait, > > > !dev->regd_in_progress, 5 * HZ); > > > > > > + err = mt7921_mcu_radio_led_ctrl(dev, > > EXT_CMD_RADIO_OFF_LED); > > > + if (err < 0) > > > + goto restore_suspend; > > > + > > > err = mt76_connac_mcu_set_hif_suspend(mdev, true); > > > if (err) > > > goto restore_suspend; > > > @@ -525,9 +529,11 @@ static int mt7921_pci_resume(struct device > > *device) > > > mt76_connac_mcu_set_deep_sleep(&dev->mt76, false); > > > > > > err = mt76_connac_mcu_set_hif_suspend(mdev, false); > > > + if (err < 0) > > > + goto failed; > > > > > > mt7921_regd_update(dev); > > > - > > > + err = mt7921_mcu_radio_led_ctrl(dev, EXT_CMD_RADIO_ON_LED); > > > failed: > > > pm->suspended = false; > > > > > > -- > > > 2.18.0 > > > > > >
On Wed, 2024-04-17 at 19:50 -0700, Sean Wang wrote: > > External email : Please do not click links or open attachments until > you have verified the sender or the content. > On Wed, Apr 17, 2024 at 6:43 PM Quan Zhou (周全) < > Quan.Zhou@mediatek.com> wrote: > > > > On Wed, 2024-04-17 at 15:06 -0700, Sean Wang wrote: > > > > > > External email : Please do not click links or open attachments > until > > > you have verified the sender or the content. > > > HI Quan, > > > > > > On Wed, Apr 10, 2024 at 11:00 PM Quan Zhou < > quan.zhou@mediatek.com> > > > wrote: > > > > > > > > From: Hao Zhang <hao.zhang@mediatek.com> > > > > > > > > Introduce wifi LED switch control, add flow to Control a wifi > > > > gpio pin based on the status of WIFI radio, if the pin is > connected > > > > to an LED, the LED will indicate the status of the WiFi radio. > > > > > > > > Signed-off-by: Hao Zhang <hao.zhang@mediatek.com> > > > > Co-developed-by: Quan Zhou <quan.zhou@mediatek.com> > > > > Signed-off-by: Quan Zhou <quan.zhou@mediatek.com> > > > > --- > > > > v2: > > > > fix to avoid wake device when Hardware interface not pcie > > > > --- > > > > .../wireless/mediatek/mt76/mt76_connac_mcu.h | 1 + > > > > .../net/wireless/mediatek/mt76/mt7921/main.c | 27 > > > ++++++++++++++++++- > > > > .../net/wireless/mediatek/mt76/mt7921/mcu.c | 14 ++++++++++ > > > > .../wireless/mediatek/mt76/mt7921/mt7921.h | 5 ++++ > > > > .../net/wireless/mediatek/mt76/mt7921/pci.c | 8 +++++- > > > > 5 files changed, 53 insertions(+), 2 deletions(-) > > > > > > > > diff --git > a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h > > > b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h > > > > index 836cc4d5b1d2..4c2de556dee1 100644 > > > > --- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h > > > > +++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h > > > > @@ -1189,6 +1189,7 @@ enum { > > > > MCU_EXT_CMD_EFUSE_ACCESS = 0x01, > > > > MCU_EXT_CMD_RF_REG_ACCESS = 0x02, > > > > MCU_EXT_CMD_RF_TEST = 0x04, > > > > + MCU_EXT_CMD_ID_RADIO_ON_OFF_CTRL = 0x05, > > > > MCU_EXT_CMD_PM_STATE_CTRL = 0x07, > > > > MCU_EXT_CMD_CHANNEL_SWITCH = 0x08, > > > > MCU_EXT_CMD_SET_TX_POWER_CTRL = 0x11, > > > > diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/main.c > > > b/drivers/net/wireless/mediatek/mt76/mt7921/main.c > > > > index ca36de34171b..ea6a113b7b36 100644 > > > > --- a/drivers/net/wireless/mediatek/mt76/mt7921/main.c > > > > +++ b/drivers/net/wireless/mediatek/mt76/mt7921/main.c > > > > @@ -242,6 +242,15 @@ int __mt7921_start(struct mt792x_phy *phy) > > > > > > > > ieee80211_queue_delayed_work(mphy->hw, &mphy->mac_work, > > > > MT792x_WATCHDOG_TIME); > > > > + if (mt76_is_mmio(mphy->dev)) { > > > > > > I guess the led control MCU command is not limited to PCIe > devices, > > > they should be able to be extended even on MT7921 USB and SDIO > > > devices, right ? if so, I think we can drop the MMIO limitation > > > condition to support more scenarios and to make it easier to > > > understand. > > > > > Hi Sean, > > > > This software flow involves chip GPIO control and is related to the > > module's circuit design. Only the PCIe module can provide support > for > > this, so can't drop. > > Hi Quan, > > Thanks for clearing that up quickly. I guess we can add it just for > MT7921E. I have another question: Will the new command you added work > with older firmware, or is it made only for the most recent firmware? > I'm worried it might not be compatible with the older MT7921 > firmware. > > Sean Hi Sean, We had completed compatible test for this modify, no side-effect have been found for the combination that with this modify and old version firmware, However, in this combination, the LED function will not be effective and requires a new version of firmware for the LED function to work. B.R > > > > > > + err = mt7921_mcu_radio_led_ctrl(phy->dev, > > > EXT_CMD_RADIO_LED_CTRL_ENABLE); > > > > + if (err) > > > > + return err; > > > > + > > > > + err = mt7921_mcu_radio_led_ctrl(phy->dev, > > > EXT_CMD_RADIO_ON_LED); > > > > + if (err) > > > > + return err; > > > > + } > > > > > > > > return 0; > > > > } > > > > @@ -259,6 +268,22 @@ static int mt7921_start(struct > ieee80211_hw > > > *hw) > > > > return err; > > > > } > > > > > > > > +static void mt7921_stop(struct ieee80211_hw *hw) > > > > +{ > > > > + struct mt792x_dev *dev = mt792x_hw_dev(hw); > > > > + int err = 0; > > > > + > > > > + if (mt76_is_mmio(&dev->mt76)) { > > > > + mt792x_mutex_acquire(dev); > > > > + err = mt7921_mcu_radio_led_ctrl(dev, > > > EXT_CMD_RADIO_OFF_LED); > > > > + mt792x_mutex_release(dev); > > > > + if (err) > > > > + return; > > > > + } > > > > + > > > > + mt792x_stop(hw); > > > > +} > > > > + > > > > static int > > > > mt7921_add_interface(struct ieee80211_hw *hw, struct > ieee80211_vif > > > *vif) > > > > { > > > > @@ -1372,7 +1397,7 @@ static void mt7921_mgd_complete_tx(struct > > > ieee80211_hw *hw, > > > > const struct ieee80211_ops mt7921_ops = { > > > > .tx = mt792x_tx, > > > > .start = mt7921_start, > > > > - .stop = mt792x_stop, > > > > + .stop = mt7921_stop, > > > > .add_interface = mt7921_add_interface, > > > > .remove_interface = mt792x_remove_interface, > > > > .config = mt7921_config, > > > > diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c > > > b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c > > > > index 8b4ce32a2cd1..2ebf0ffe78d5 100644 > > > > --- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c > > > > +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c > > > > @@ -606,6 +606,20 @@ int mt7921_run_firmware(struct mt792x_dev > > > *dev) > > > > } > > > > EXPORT_SYMBOL_GPL(mt7921_run_firmware); > > > > > > > > +int mt7921_mcu_radio_led_ctrl(struct mt792x_dev *dev, u8 > value) > > > > +{ > > > > + struct { > > > > + u8 ctrlid; > > > > + u8 rsv[3]; > > > > + } __packed req = { > > > > + .ctrlid = value, > > > > + }; > > > > + > > > > + return mt76_mcu_send_msg(&dev->mt76, > > > MCU_EXT_CMD(ID_RADIO_ON_OFF_CTRL), > > > > + &req, sizeof(req), false); > > > > +} > > > > +EXPORT_SYMBOL_GPL(mt7921_mcu_radio_led_ctrl); > > > > + > > > > int mt7921_mcu_set_tx(struct mt792x_dev *dev, struct > ieee80211_vif > > > *vif) > > > > { > > > > struct mt792x_vif *mvif = (struct mt792x_vif *)vif- > > > >drv_priv; > > > > diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h > > > b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h > > > > index 3016636d18c6..07023eb9e5b5 100644 > > > > --- a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h > > > > +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h > > > > @@ -27,6 +27,10 @@ > > > > #define MCU_UNI_EVENT_ROC 0x27 > > > > #define MCU_UNI_EVENT_CLC 0x80 > > > > > > > > +#define EXT_CMD_RADIO_LED_CTRL_ENABLE 0x1 > > > > +#define EXT_CMD_RADIO_ON_LED 0x2 > > > > +#define EXT_CMD_RADIO_OFF_LED 0x3 > > > > + > > > > enum { > > > > UNI_ROC_ACQUIRE, > > > > UNI_ROC_ABORT, > > > > @@ -196,6 +200,7 @@ int mt7921_mcu_fw_log_2_host(struct > mt792x_dev > > > *dev, u8 ctrl); > > > > void mt7921_mcu_rx_event(struct mt792x_dev *dev, struct > sk_buff > > > *skb); > > > > int mt7921_mcu_set_rxfilter(struct mt792x_dev *dev, u32 fif, > > > > u8 bit_op, u32 bit_map); > > > > +int mt7921_mcu_radio_led_ctrl(struct mt792x_dev *dev, u8 > value); > > > > > > > > static inline u32 > > > > mt7921_reg_map_l1(struct mt792x_dev *dev, u32 addr) > > > > diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c > > > b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c > > > > index 0b69b225bc16..f768e9389ac6 100644 > > > > --- a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c > > > > +++ b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c > > > > @@ -427,6 +427,10 @@ static int mt7921_pci_suspend(struct > device > > > *device) > > > > wait_event_timeout(dev->wait, > > > > !dev->regd_in_progress, 5 * HZ); > > > > > > > > + err = mt7921_mcu_radio_led_ctrl(dev, > > > EXT_CMD_RADIO_OFF_LED); > > > > + if (err < 0) > > > > + goto restore_suspend; > > > > + > > > > err = mt76_connac_mcu_set_hif_suspend(mdev, true); > > > > if (err) > > > > goto restore_suspend; > > > > @@ -525,9 +529,11 @@ static int mt7921_pci_resume(struct device > > > *device) > > > > mt76_connac_mcu_set_deep_sleep(&dev->mt76, > false); > > > > > > > > err = mt76_connac_mcu_set_hif_suspend(mdev, false); > > > > + if (err < 0) > > > > + goto failed; > > > > > > > > mt7921_regd_update(dev); > > > > - > > > > + err = mt7921_mcu_radio_led_ctrl(dev, > EXT_CMD_RADIO_ON_LED); > > > > failed: > > > > pm->suspended = false; > > > > > > > > -- > > > > 2.18.0 > > > > > > > >
diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h index 836cc4d5b1d2..4c2de556dee1 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h +++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h @@ -1189,6 +1189,7 @@ enum { MCU_EXT_CMD_EFUSE_ACCESS = 0x01, MCU_EXT_CMD_RF_REG_ACCESS = 0x02, MCU_EXT_CMD_RF_TEST = 0x04, + MCU_EXT_CMD_ID_RADIO_ON_OFF_CTRL = 0x05, MCU_EXT_CMD_PM_STATE_CTRL = 0x07, MCU_EXT_CMD_CHANNEL_SWITCH = 0x08, MCU_EXT_CMD_SET_TX_POWER_CTRL = 0x11, diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/main.c b/drivers/net/wireless/mediatek/mt76/mt7921/main.c index ca36de34171b..ea6a113b7b36 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/main.c @@ -242,6 +242,15 @@ int __mt7921_start(struct mt792x_phy *phy) ieee80211_queue_delayed_work(mphy->hw, &mphy->mac_work, MT792x_WATCHDOG_TIME); + if (mt76_is_mmio(mphy->dev)) { + err = mt7921_mcu_radio_led_ctrl(phy->dev, EXT_CMD_RADIO_LED_CTRL_ENABLE); + if (err) + return err; + + err = mt7921_mcu_radio_led_ctrl(phy->dev, EXT_CMD_RADIO_ON_LED); + if (err) + return err; + } return 0; } @@ -259,6 +268,22 @@ static int mt7921_start(struct ieee80211_hw *hw) return err; } +static void mt7921_stop(struct ieee80211_hw *hw) +{ + struct mt792x_dev *dev = mt792x_hw_dev(hw); + int err = 0; + + if (mt76_is_mmio(&dev->mt76)) { + mt792x_mutex_acquire(dev); + err = mt7921_mcu_radio_led_ctrl(dev, EXT_CMD_RADIO_OFF_LED); + mt792x_mutex_release(dev); + if (err) + return; + } + + mt792x_stop(hw); +} + static int mt7921_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { @@ -1372,7 +1397,7 @@ static void mt7921_mgd_complete_tx(struct ieee80211_hw *hw, const struct ieee80211_ops mt7921_ops = { .tx = mt792x_tx, .start = mt7921_start, - .stop = mt792x_stop, + .stop = mt7921_stop, .add_interface = mt7921_add_interface, .remove_interface = mt792x_remove_interface, .config = mt7921_config, diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c index 8b4ce32a2cd1..2ebf0ffe78d5 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c @@ -606,6 +606,20 @@ int mt7921_run_firmware(struct mt792x_dev *dev) } EXPORT_SYMBOL_GPL(mt7921_run_firmware); +int mt7921_mcu_radio_led_ctrl(struct mt792x_dev *dev, u8 value) +{ + struct { + u8 ctrlid; + u8 rsv[3]; + } __packed req = { + .ctrlid = value, + }; + + return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(ID_RADIO_ON_OFF_CTRL), + &req, sizeof(req), false); +} +EXPORT_SYMBOL_GPL(mt7921_mcu_radio_led_ctrl); + int mt7921_mcu_set_tx(struct mt792x_dev *dev, struct ieee80211_vif *vif) { struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv; diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h index 3016636d18c6..07023eb9e5b5 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h @@ -27,6 +27,10 @@ #define MCU_UNI_EVENT_ROC 0x27 #define MCU_UNI_EVENT_CLC 0x80 +#define EXT_CMD_RADIO_LED_CTRL_ENABLE 0x1 +#define EXT_CMD_RADIO_ON_LED 0x2 +#define EXT_CMD_RADIO_OFF_LED 0x3 + enum { UNI_ROC_ACQUIRE, UNI_ROC_ABORT, @@ -196,6 +200,7 @@ int mt7921_mcu_fw_log_2_host(struct mt792x_dev *dev, u8 ctrl); void mt7921_mcu_rx_event(struct mt792x_dev *dev, struct sk_buff *skb); int mt7921_mcu_set_rxfilter(struct mt792x_dev *dev, u32 fif, u8 bit_op, u32 bit_map); +int mt7921_mcu_radio_led_ctrl(struct mt792x_dev *dev, u8 value); static inline u32 mt7921_reg_map_l1(struct mt792x_dev *dev, u32 addr) diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c index 0b69b225bc16..f768e9389ac6 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c @@ -427,6 +427,10 @@ static int mt7921_pci_suspend(struct device *device) wait_event_timeout(dev->wait, !dev->regd_in_progress, 5 * HZ); + err = mt7921_mcu_radio_led_ctrl(dev, EXT_CMD_RADIO_OFF_LED); + if (err < 0) + goto restore_suspend; + err = mt76_connac_mcu_set_hif_suspend(mdev, true); if (err) goto restore_suspend; @@ -525,9 +529,11 @@ static int mt7921_pci_resume(struct device *device) mt76_connac_mcu_set_deep_sleep(&dev->mt76, false); err = mt76_connac_mcu_set_hif_suspend(mdev, false); + if (err < 0) + goto failed; mt7921_regd_update(dev); - + err = mt7921_mcu_radio_led_ctrl(dev, EXT_CMD_RADIO_ON_LED); failed: pm->suspended = false;