Search Linux Wireless

Re: [PATCH 3/3] wifi: rt2x00: restart beacon queue when hardware reset

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, 1 Nov 2023 10:07:10 +0100, Stanislaw Gruszka wrote:

>On Sat, Oct 28, 2023 at 08:15:32PM +0800, Shiji Yang wrote:
>> When a hardware reset is triggered, all registers are reset, so all
>> queues are forced to stop in hardware interface. However, mac80211
>> will not automatically stop the queue. If we don't manually stop the
>> beacon queue, the queue will be deadlocked and unable to start again.
>> This patch fixes the issue where Apple devices cannot connect to the
>> AP after calling ieee80211_restart_hw().
>
>Should not this be solved in mac80211 then? ieee80211_restart_work
>does a lot o diffrent things, why beconing is not also
>stoped/started there ? 
>
>Regards
>Stanislaw
>

Hi! Thanks for your review.

I think this issue is a bug of the rt2x00. When restart is called,
mac80211 didn't call rt2x00mac_bss_info_changed() to update the
flag (This may be expected? I'm not sure. But all other Tx/Rx queues
are also manually disabled). And after resetting,
'bss_conf->enable_beacon' and 'intf->enable_beacon' are still true.
Though mac80211 will call this function and try to enable the beacon
queue again. However, both 'if' and 'else if' blocks will never be
entered anymore because all conditions are false. This patch just
fixes this dead lock.

Maybe Kalle Valo knows if it's a mac80211 bug. This issue has been
here for several years.

Looking forward to your reply.

By the way, it seems that 'intf_beaconing' variable is useless. Does
it really can be increased to '2'? Maybe in multi ssid mode?

```
void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
				struct ieee80211_vif *vif,
				struct ieee80211_bss_conf *bss_conf,
				u64 changes)
{
......
		if (!bss_conf->enable_beacon && intf->enable_beacon) {
			rt2x00dev->intf_beaconing--;
			intf->enable_beacon = false;

			if (rt2x00dev->intf_beaconing == 0) {
				/*
				 * Last beaconing interface disabled
				 * -> stop beacon queue.
				 */
				rt2x00queue_stop_queue(rt2x00dev->bcn);
			}
			/*
			 * Clear beacon in the H/W for this vif. This is needed
			 * to disable beaconing on this particular interface
			 * and keep it running on other interfaces.
			 */
			rt2x00queue_clear_beacon(rt2x00dev, vif);
		} else if (bss_conf->enable_beacon && !intf->enable_beacon) {
			rt2x00dev->intf_beaconing++;
			intf->enable_beacon = true;
			/*
			 * Upload beacon to the H/W. This is only required on
			 * USB devices. PCI devices fetch beacons periodically.
			 */
			if (rt2x00_is_usb(rt2x00dev))
				rt2x00queue_update_beacon(rt2x00dev, vif);

			if (rt2x00dev->intf_beaconing == 1) {
				/*
				 * First beaconing interface enabled
				 * -> start beacon queue.
				 */
				rt2x00queue_start_queue(rt2x00dev->bcn);
			}
		}
```

Regards,
Shiji Yang



[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Wireless Regulations]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux