On Sat, 2022-11-12 at 17:13 +0100, Lorenzo Bianconi wrote: > > > From: Bo Jiao <bo.jiao@xxxxxxxxxxxx> > > > > > > Add mt7915_reset() and refactor mt7915_mac_reset_work() to > > > support > > > full system recovery. > > > > > > Co-developed-by: Ryder Lee <ryder.lee@xxxxxxxxxxxx> > > > Signed-off-by: Ryder Lee <ryder.lee@xxxxxxxxxxxx> > > > Signed-off-by: Bo Jiao <bo.jiao@xxxxxxxxxxxx> > > > --- > > > change since v2 - change dev_info to make it easier to see that > > > firmware crashed while looking at dmesg. > > > --- > > > .../net/wireless/mediatek/mt76/mt7915/init.c | 11 +- > > > .../net/wireless/mediatek/mt76/mt7915/mac.c | 214 > > > +++++++++++++++++- > > > .../net/wireless/mediatek/mt76/mt7915/main.c | 18 +- > > > .../net/wireless/mediatek/mt76/mt7915/mcu.c | 24 +- > > > .../net/wireless/mediatek/mt76/mt7915/mmio.c | 7 +- > > > .../wireless/mediatek/mt76/mt7915/mt7915.h | 15 +- > > > .../net/wireless/mediatek/mt76/mt7915/regs.h | 4 + > > > 7 files changed, 267 insertions(+), 26 deletions(-) > > > > > > diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/init.c > > > b/drivers/net/wireless/mediatek/mt76/mt7915/init.c > > > index 324db5291c85..1f39aa3e3f3d 100644 > > > --- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c > > > +++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c > > > @@ -262,9 +262,8 @@ static void mt7915_led_set_brightness(struct > > > led_classdev *led_cdev, > > > mt7915_led_set_config(led_cdev, 0xff, 0); > > > } > > > > > > -static void > > > -mt7915_init_txpower(struct mt7915_dev *dev, > > > - struct ieee80211_supported_band *sband) > > > +void mt7915_init_txpower(struct mt7915_dev *dev, > > > + struct ieee80211_supported_band *sband) > > > { > > > int i, n_chains = hweight8(dev->mphy.antenna_mask); > > > int nss_delta = mt76_tx_power_nss_delta(n_chains); > > > @@ -446,7 +445,7 @@ mt7915_mac_init_band(struct mt7915_dev *dev, > > > u8 band) > > > mt76_clear(dev, MT_DMA_DCR0(band), MT_DMA_DCR0_RXD_G5_EN); > > > } > > > > > > -static void mt7915_mac_init(struct mt7915_dev *dev) > > > +void mt7915_mac_init(struct mt7915_dev *dev) > > > { > > > int i; > > > u32 rx_len = is_mt7915(&dev->mt76) ? 0x400 : 0x680; > > > @@ -476,7 +475,7 @@ static void mt7915_mac_init(struct mt7915_dev > > > *dev) > > > } > > > } > > > > > > -static int mt7915_txbf_init(struct mt7915_dev *dev) > > > +int mt7915_txbf_init(struct mt7915_dev *dev) > > > { > > > int ret; > > > > > > @@ -1117,6 +1116,8 @@ int mt7915_register_device(struct > > > mt7915_dev *dev) > > > goto unreg_thermal; > > > } > > > > > > + dev->recovery.hw_init_done = true; > > > + > > > mt7915_init_debugfs(&dev->phy); > > > > > > return 0; > > > diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c > > > b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c > > > index 3b1259f14de6..69ce3b39aa53 100644 > > > --- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c > > > +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c > > > @@ -1265,7 +1265,7 @@ mt7915_wait_reset_state(struct mt7915_dev > > > *dev, u32 state) > > > bool ret; > > > > > > ret = wait_event_timeout(dev->reset_wait, > > > - (READ_ONCE(dev->reset_state) & state), > > > + (READ_ONCE(dev->recovery.state) & > > > state), > > > MT7915_RESET_TIMEOUT); > > > > > > WARN(!ret, "Timeout waiting for MCU reset state %x\n", state); > > > @@ -1320,6 +1320,171 @@ void mt7915_tx_token_put(struct > > > mt7915_dev *dev) > > > idr_destroy(&dev->mt76.token); > > > } > > > > > > +static int > > > +mt7915_mac_restart(struct mt7915_dev *dev) > > > +{ > > > + struct mt7915_phy *phy2; > > > + struct mt76_phy *ext_phy; > > > + struct mt76_dev *mdev = &dev->mt76; > > > + int i, ret; > > > + u32 irq_mask; > > > + > > > + ext_phy = dev->mt76.phys[MT_BAND1]; > > > + phy2 = ext_phy ? ext_phy->priv : NULL; > > > + > > > + if (dev->hif2) { > > > + mt76_wr(dev, MT_INT1_MASK_CSR, 0x0); > > > + mt76_wr(dev, MT_INT1_SOURCE_CSR, ~0); > > > + } > > > + > > > + if (dev_is_pci(mdev->dev)) { > > > + mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0x0); > > > + if (dev->hif2) > > > + mt76_wr(dev, MT_PCIE1_MAC_INT_ENABLE, 0x0); > > > + } > > > + > > > + set_bit(MT76_RESET, &dev->mphy.state); > > > + set_bit(MT76_MCU_RESET, &dev->mphy.state); > > > + wake_up(&dev->mt76.mcu.wait); > > > + if (ext_phy) { > > > + set_bit(MT76_RESET, &ext_phy->state); > > > + set_bit(MT76_MCU_RESET, &ext_phy->state); > > > + } > > > + > > > + /* lock/unlock all queues to ensure that no tx is pending */ > > > + mt76_txq_schedule_all(&dev->mphy); > > > + if (ext_phy) > > > + mt76_txq_schedule_all(ext_phy); > > > + > > > + /* disable all tx/rx napi */ > > > + mt76_worker_disable(&dev->mt76.tx_worker); > > > + mt76_for_each_q_rx(mdev, i) { > > > + if (mdev->q_rx[i].ndesc) > > > + napi_disable(&dev->mt76.napi[i]); > > > + } > > > + napi_disable(&dev->mt76.tx_napi); > > > + > > > + /* token reinit */ > > > + mt7915_tx_token_put(dev); > > > + idr_init(&dev->mt76.token); > > > + > > > + mt7915_dma_reset(dev, true); > > > + > > > + local_bh_disable(); > > > + mt76_for_each_q_rx(mdev, i) { > > > + if (mdev->q_rx[i].ndesc) { > > > + napi_enable(&dev->mt76.napi[i]); > > > + napi_schedule(&dev->mt76.napi[i]); > > > + } > > > + } > > > + local_bh_enable(); > > > + clear_bit(MT76_MCU_RESET, &dev->mphy.state); > > > + clear_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state); > > > + > > > + mt76_wr(dev, MT_INT_MASK_CSR, dev->mt76.mmio.irqmask); > > > + mt76_wr(dev, MT_INT_SOURCE_CSR, ~0); > > > + > > > + if (dev->hif2) { > > > + mt76_wr(dev, MT_INT1_MASK_CSR, irq_mask); > > > > irq_mask is used uninitialized here. > > Moreover is mt7915_mac_restart() and full-reset compatible with wed > > support? > > it seems in mt7915_dual_hif_set_irq_mask() we took a different > > approach. > > > > Regards, > > Lorenzo > > should we do something similar to the patch below? > > diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c > index c76c5cc398e9..9c99c3014a79 100644 > --- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c > +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c > @@ -1386,7 +1386,6 @@ mt7915_mac_restart(struct mt7915_dev *dev) > struct mt76_phy *ext_phy; > struct mt76_dev *mdev = &dev->mt76; > int i, ret; > - u32 irq_mask; > > ext_phy = dev->mt76.phys[MT_BAND1]; > phy2 = ext_phy ? ext_phy->priv : NULL; > @@ -1440,11 +1439,17 @@ mt7915_mac_restart(struct mt7915_dev *dev) > clear_bit(MT76_MCU_RESET, &dev->mphy.state); > clear_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state); > > - mt76_wr(dev, MT_INT_MASK_CSR, dev->mt76.mmio.irqmask); > - mt76_wr(dev, MT_INT_SOURCE_CSR, ~0); > + if (mtk_wed_device_active(&mdev->mmio.wed)) { > + mtk_wed_device_irq_set_mask(&mdev->mmio.wed, > + mdev->mmio.irqmask); > + mtk_wed_device_irq_get(wed, ~0); > + } else { > + mt76_wr(dev, MT_INT_MASK_CSR, mdev->mmio.irqmask); > + mt76_wr(dev, MT_INT_SOURCE_CSR, ~0); > + } > > if (dev->hif2) { > - mt76_wr(dev, MT_INT1_MASK_CSR, irq_mask); > + mt76_wr(dev, MT_INT1_MASK_CSR, dev->mt76.mmio.irqmask); > mt76_wr(dev, MT_INT1_SOURCE_CSR, ~0); Yes we should use dev->mt76.mmio.irqmask...somehow we added irq_mask here. @Felix, could you help to fold this? As for wed_device I think we need another patch to suppor its SER as it needs to take mtk_eth into account, and actually there's a patch in MTK's git01 repo. Ryder