openwrt / openwrt/mt76

MT7915e: mt7915_start() could be called prior HW init is finished, resulting in message timeout and board crash

Open
#959 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
C
Stars
888
Forks
436
PR merge metrics
No merged PRs in 30d

Description

Exact issue flow seen in my case:

CPU0:
	mt7915_register_device()
		mt76_register_device()
			ieee80211_register_hw()
				wiphy_register()
					nl80211_notify_wiphy(rdev, NL80211_CMD_NEW_WIPHY);
		continues mt7915_register_device() processing, but not reached ieee80211_queue_work(mt76_hw(dev), &dev->init_work) yet

CPU1:
	user space receives NL80211_CMD_NEW_WIPHY
	creates iface (if not created already) and issues ioctl(SIOCSIFFLAGS, IFF_UP)
		acquire RTNL
		ndo_open()->ieee80211_open()->...->mt7915_start()
			flush_work(&dev->init_work); #### init_work is not yet scheduled by CPU0, so execution continues an is not blocked
			mt7915_run()
				mt7915_mcu_set_chan_info(phy, MCU_EXT_CMD(SET_RX_PATH));
					message timeout->mt7915_mcu_parse_response()->queue_work(dev->mt76.wq, &dev->reset_work)
						reset_work is scheduled wihtout checking dev->recovery.hw_init_done, whish is fals in this case, is it expected?
		release RTNL
					
CPU0:
		continues mt7915_register_device(), gets unblocked if were waiting for rtnl lock (for ext phy register in my case)
		ieee80211_queue_work(mt76_hw(dev), &dev->init_work)
		returns mt7915_register_device and probe()

CPU_ANY:
	mt7915_mac_reset_work()
		this results in call trace an automatic board reboot

mt7915_start() already waits for dev->init_work to be finished, but the issue in this case is that it did not event yet get scheduled.
Seems like some rework is needed.

If you find this helpful:
on my setup I have tried calling mt7915_init_work() directly in mt7915_register_device() prior mt76_register_device(), with exception of mt7915_init_led_mux(), as some leds config is filled here later, and this seem to solve the issue

From looking at the code, similar issue seems to be also for mt7996?

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by tracing mt7915_register_device(), mt7915_start(), init_work, and reset_work through the reported CPU interleaving. Compare the analogous mt7996 flow, then reproduce or instrument the registration and interface-up sequence to verify that initialization completes safely before startup and recovery can run.

Written by the indexing model from the issue text.

Assessment

Tech stack
c
Domain
networking
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.