Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package xone for openSUSE:Factory checked in 
at 2026-03-15 14:32:33
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/xone (Old)
 and      /work/SRC/openSUSE:Factory/.xone.new.8177 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "xone"

Sun Mar 15 14:32:33 2026 rev:4 rq:1339041 version:0.5.7

Changes:
--------
--- /work/SRC/openSUSE:Factory/xone/xone.changes        2026-02-16 
13:14:44.699560717 +0100
+++ /work/SRC/openSUSE:Factory/.xone.new.8177/xone.changes      2026-03-15 
14:33:30.210195179 +0100
@@ -1,0 +2,12 @@
+Sat Mar 14 11:51:44 UTC 2026 - Tobias Görgens <[email protected]>
+
+- Update to release 0.5.7
+  * dongle, mt76: fix cold/warm firmware init and enable automatic controller 
reconnection
+  * Change timeout_secs to milliseconds for pairing work
+  * Simplify firmware loading cancellation logic
+- Update to release 0.5.6
+  * Add more info to the active_clients sysfs
+  * Fix small dongle pairing - add pairing scan channel rotation and 
diagnostics
+  * Add sleep before firmware reset
+
+-------------------------------------------------------------------

Old:
----
  v0.5.5.tar.gz

New:
----
  v0.5.7.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ xone.spec ++++++
--- /var/tmp/diff_new_pack.Jn9cge/_old  2026-03-15 14:33:30.706215596 +0100
+++ /var/tmp/diff_new_pack.Jn9cge/_new  2026-03-15 14:33:30.710215761 +0100
@@ -17,7 +17,7 @@
 
 
 Name:           xone
-Version:        0.5.5
+Version:        0.5.7
 Release:        0
 Summary:        Driver for Xbox One and Xbox Series X|S controllers
 License:        GPL-2.0-or-later

++++++ v0.5.5.tar.gz -> v0.5.7.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xone-0.5.5/README.md new/xone-0.5.7/README.md
--- old/xone-0.5.5/README.md    2026-02-05 13:22:01.000000000 +0100
+++ new/xone-0.5.7/README.md    2026-02-27 13:40:31.000000000 +0100
@@ -10,7 +10,10 @@
 `xone` is a Linux kernel driver for Xbox One and Xbox Series X|S accessories. 
It serves as a modern replacement for
 `xpad`, aiming to be compatible with Microsoft's *Game Input Protocol* (GIP).
 
-**NOTE**: This is a fork, please support the upstream project.
+> [!NOTE]
+> The original project is in maintance mode, please refer to this one for 
updates and issues.
+> 
+> Huge thanks to medusalix for all the work and creating this driver!
 
 ## Compatibility
 
@@ -229,6 +232,18 @@
 echo 1 | sudo tee /sys/bus/usb/drivers/xone-dongle/*/pairing
 ```
 
+## Number of active clients and forcing poweroff
+```
+# show number of connected controllers
+cat /sys/bus/usb/drivers/xone-dongle/*/active_clients
+
+# power off selected client (possible values from 0 to 15)
+sudo tee /sys/bus/usb/drivers/xone-dongle/*/poweroff <<< 1
+
+# power off all connected clients
+sudo tee /sys/bus/usb/drivers/xone-dongle/*/poweroff <<< -1
+```
+
 ## Troubleshooting
 
 Uninstall the release version and install a debug build of `xone` (see 
installation guide).
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xone-0.5.5/transport/dongle.c 
new/xone-0.5.7/transport/dongle.c
--- old/xone-0.5.5/transport/dongle.c   2026-02-05 13:22:01.000000000 +0100
+++ new/xone-0.5.7/transport/dongle.c   2026-02-27 13:40:31.000000000 +0100
@@ -30,7 +30,8 @@
 
 #define XONE_DONGLE_MAX_CLIENTS 16
 
-#define XONE_DONGLE_PAIRING_TIMEOUT msecs_to_jiffies(60000)
+#define XONE_DONGLE_PAIRING_TIMEOUT 60 // seconds
+#define XONE_DONGLE_PAIR_SCAN_INTERVAL msecs_to_jiffies(2000)
 #define XONE_DONGLE_PWR_OFF_TIMEOUT msecs_to_jiffies(5000)
 #define XONE_DONGLE_FW_REQ_TIMEOUT_MS 3000
 #define XONE_DONGLE_FW_REQ_RETRIES 11 // 30 seconds
@@ -91,7 +92,10 @@
        /* serializes pairing changes */
        struct mutex pairing_lock;
        struct delayed_work pairing_work;
+       struct delayed_work pairing_scan_work;
        bool pairing;
+       unsigned long last_wlan_rx;
+       u8 pairing_scan_idx;
 
        /* serializes access to clients array */
        spinlock_t clients_lock;
@@ -107,9 +111,22 @@
        u16 product;
 };
 
-static int xone_dongle_power_off_client(struct xone_dongle *dongle, int index);
+static int xone_dongle_power_off_client(struct xone_dongle *dongle, int index, 
bool silent);
 static int xone_dongle_power_off_clients(struct xone_dongle *dongle);
 
+static u8 xone_dongle_find_channel_idx(struct xone_dongle *dongle)
+{
+       if (!dongle->mt.channel)
+               return 0;
+
+       for (int i = 0; i < XONE_MT_NUM_CHANNELS; i++) {
+               if (dongle->mt.channels[i].index == dongle->mt.channel->index)
+                       return i;
+       }
+
+       return 0;
+}
+
 static void xone_dongle_prep_packet(struct xone_dongle_client *client,
                                    struct sk_buff *skb,
                                    enum xone_dongle_queue queue)
@@ -233,7 +250,8 @@
        .set_encryption_key = xone_dongle_set_encryption_key,
 };
 
-static int xone_dongle_toggle_pairing(struct xone_dongle *dongle, bool enable)
+static int xone_dongle_pairing_handler(struct xone_dongle *dongle, bool enable,
+                                      u8 timeout_secs)
 {
        enum xone_mt76_led_mode led;
        int err = 0;
@@ -262,9 +280,16 @@
        dev_dbg(dongle->mt.dev, "%s: enabled=%d\n", __func__, enable);
        dongle->pairing = enable;
 
-       if (enable)
+       if (enable) {
+               dongle->last_wlan_rx = jiffies;
+               dongle->pairing_scan_idx = xone_dongle_find_channel_idx(dongle);
                mod_delayed_work(system_wq, &dongle->pairing_work,
-                                XONE_DONGLE_PAIRING_TIMEOUT);
+                                msecs_to_jiffies(timeout_secs * 1000));
+               mod_delayed_work(system_wq, &dongle->pairing_scan_work,
+                                XONE_DONGLE_PAIR_SCAN_INTERVAL);
+       } else {
+               cancel_delayed_work(&dongle->pairing_scan_work);
+       }
 
 err_unlock:
        mutex_unlock(&dongle->pairing_lock);
@@ -272,6 +297,18 @@
        return err;
 }
 
+static int xone_dongle_toggle_pairing(struct xone_dongle *dongle, bool enable)
+{
+       return xone_dongle_pairing_handler(dongle, enable,
+                                          XONE_DONGLE_PAIRING_TIMEOUT);
+}
+
+static int xone_dongle_enable_pairing(struct xone_dongle *dongle,
+                                     u8 timeout_secs)
+{
+       return xone_dongle_pairing_handler(dongle, true, timeout_secs);
+}
+
 static void xone_dongle_pairing_timeout(struct work_struct *work)
 {
        struct xone_dongle *dongle = container_of(to_delayed_work(work),
@@ -288,6 +325,68 @@
                        __func__, err);
 }
 
+static void xone_dongle_pairing_scan(struct work_struct *work)
+{
+       struct xone_dongle *dongle = container_of(to_delayed_work(work),
+                                                 typeof(*dongle),
+                                                 pairing_scan_work);
+       struct xone_mt76_channel *chan;
+       u8 next_idx;
+       u8 prev_chan = 0;
+       u8 next_chan = 0;
+       int err;
+
+       mutex_lock(&dongle->pairing_lock);
+
+       if (!dongle->pairing)
+               goto out_unlock;
+
+       /*
+        * Once a controller has sent an association request the dongle and
+        * controller are both on the same channel. Switching channels while
+        * a client is connecting or actively communicating breaks the GIP
+        * handshake: the controller keeps transmitting on the old channel
+        * while the dongle is listening on the new one. Keep the channel
+        * stable for as long as any client slot is occupied.
+        */
+       if (atomic_read(&dongle->client_count) > 0)
+               goto out_resched;
+
+       if (time_before(jiffies, dongle->last_wlan_rx +
+                                XONE_DONGLE_PAIR_SCAN_INTERVAL))
+               goto out_resched;
+
+       next_idx = (dongle->pairing_scan_idx + 1) % XONE_MT_NUM_CHANNELS;
+       chan = &dongle->mt.channels[next_idx];
+
+       if (dongle->mt.channel)
+               prev_chan = dongle->mt.channel->index;
+
+       next_chan = chan->index;
+
+       err = xone_mt76_switch_channel(&dongle->mt, chan);
+
+       if (err) {
+               dev_dbg(dongle->mt.dev, "%s: switch failed: %d\n",
+                       __func__, err);
+       } else {
+               dongle->mt.channel = chan;
+
+               dev_dbg(dongle->mt.dev,
+                       "%s: channel switch %u -> %u\n",
+                       __func__, prev_chan, next_chan);
+       }
+
+       dongle->pairing_scan_idx = next_idx;
+       dongle->last_wlan_rx = jiffies;
+
+out_resched:
+       mod_delayed_work(system_wq, &dongle->pairing_scan_work,
+                        XONE_DONGLE_PAIR_SCAN_INTERVAL);
+out_unlock:
+       mutex_unlock(&dongle->pairing_lock);
+}
+
 static ssize_t pairing_show(struct device *dev, struct device_attribute *attr,
                            char *buf)
 {
@@ -321,8 +420,23 @@
 {
        struct usb_interface *intf = to_usb_interface(dev);
        struct xone_dongle *dongle = usb_get_intfdata(intf);
+       int half = XONE_DONGLE_MAX_CLIENTS / 2;
+       char local_buf[150] = {};
+       char temp_buf[10] = {};
+
+       sprintf(local_buf, "Active clients: %u\n", 
atomic_read(&dongle->client_count));
+       for (int i = 0; i < half; ++i) {
+               bool active1 = dongle->clients[i] != NULL;
+               bool active2 = dongle->clients[i + half] != NULL;
 
-       return sysfs_emit(buf, "%u\n", atomic_read(&dongle->client_count));
+               sprintf(temp_buf, "[%.2d]%s\t", i, active1 ? "*" : "");
+               strcat(local_buf, temp_buf);
+
+               sprintf(temp_buf, "[%.2d]%s\n", i + half, active2 ? "*" : "");
+               strcat(local_buf, temp_buf);
+       }
+
+       return sysfs_emit(buf, local_buf);
 }
 
 static ssize_t poweroff_show(struct device *dev, struct device_attribute *attr,
@@ -354,7 +468,7 @@
        if (val == -1)
                err = xone_dongle_power_off_clients(dongle);
        else
-               err = xone_dongle_power_off_client(dongle, val);
+               err = xone_dongle_power_off_client(dongle, val, false);
 
        return err ? err : count;
 }
@@ -588,8 +702,17 @@
        spin_lock_irqsave(&dongle->clients_lock, flags);
 
        client = dongle->clients[wcid - 1];
-       if (client)
+       if (client) {
+               /*
+                * Active data traffic is the strongest signal that we are on
+                * the right channel. Refresh last_wlan_rx so the pairing scan
+                * does not rotate away while a controller is mid-handshake,
+                * complementing the client_count guard in pairing_scan.
+                */
+               if (dongle->pairing)
+                       dongle->last_wlan_rx = jiffies;
                err = gip_process_buffer(client->adapter, skb->data, skb->len);
+       }
 
        spin_unlock_irqrestore(&dongle->clients_lock, flags);
 
@@ -600,6 +723,9 @@
 {
        struct xone_dongle_event *evt;
 
+       if (dongle->pairing)
+               dongle->last_wlan_rx = jiffies;
+
        evt = xone_dongle_alloc_event(dongle, XONE_DONGLE_EVT_ADD_CLIENT);
        if (!evt)
                return -ENOMEM;
@@ -642,6 +768,9 @@
 
        switch (skb->data[1]) {
        case XONE_MT_CLIENT_PAIR_REQ:
+               if (dongle->pairing)
+                       dongle->last_wlan_rx = jiffies;
+
                evt_type = XONE_DONGLE_EVT_PAIR_CLIENT;
                break;
        case XONE_MT_CLIENT_ENABLE_ENCRYPTION:
@@ -670,6 +799,15 @@
 {
        struct xone_dongle_event *evt;
 
+       /*
+        * Refresh last_wlan_rx immediately on a physical button press so the
+        * pairing scan does not rotate to a different channel in the narrow
+        * window between this event being queued and toggle_pairing() being
+        * called by the event handler.
+        */
+       if (dongle->pairing)
+               dongle->last_wlan_rx = jiffies;
+
        evt = xone_dongle_alloc_event(dongle, XONE_DONGLE_EVT_ENABLE_PAIRING);
        if (!evt)
                return -ENOMEM;
@@ -715,6 +853,14 @@
        case IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA:
                return xone_dongle_handle_qos_data(dongle, skb, wcid);
        case IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ASSOC_REQ:
+               /*
+                * The channel scan can trigger spurious association frames
+                * carrying multicast or all-zero source addresses (addr2).
+                * A real controller always uses a valid unicast address.
+                * Accepting invalid addresses exhausts the client table.
+                */
+               if (!is_valid_ether_addr(hdr->addr2))
+                       return 0;
                return xone_dongle_handle_association(dongle, hdr->addr2);
        case IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_DISASSOC:
                return xone_dongle_handle_disassociation(dongle, wcid);
@@ -1012,8 +1158,15 @@
                return;
        }
 
-       err = xone_mt76_init_radio(mt);
-       if (err){
+       for (int i = 0; i < 3; i++) {
+               err = xone_mt76_init_radio(mt);
+               if (err != -ETIMEDOUT)
+                       break;
+               dev_dbg(mt->dev, "%s: init radio timed out, retrying (%d/3)\n",
+                       __func__, i + 1);
+               msleep(500);
+       }
+       if (err) {
                dongle->fw_state = XONE_DONGLE_FW_STATE_ERROR;
                dev_err(mt->dev, "%s: init radio failed: %d\n", __func__, err);
                return;
@@ -1022,6 +1175,22 @@
        dongle->fw_state = XONE_DONGLE_FW_STATE_READY;
 
        device_wakeup_enable(&dongle->mt.udev->dev);
+
+       /*
+        * xone_mt76_init_radio() ends with xone_mt76_set_pairing(false),
+        * which sets the beacon pair flag to 0 and a restrictive RX filter.
+        * In this state already-paired controllers cannot reconnect: they see
+        * the beacon but are rejected by the filter.
+        *
+        * Enable pairing for 10 seconds so controllers present at boot or
+        * after a replug reconnect automatically without requiring a manual
+        * button press. The pairing timeout (XONE_DONGLE_PAIRING_TIMEOUT)
+        * disables it again once the window expires.
+        */
+       err = xone_dongle_enable_pairing(dongle, 10);
+       if (err)
+               dev_err(mt->dev, "%s: enable pairing failed: %d\n",
+                       __func__, err);
 }
 
 static int xone_dongle_init(struct xone_dongle *dongle)
@@ -1036,7 +1205,8 @@
        return 0;
 }
 
-static int xone_dongle_power_off_client(struct xone_dongle *dongle, int index)
+static int xone_dongle_power_off_client(struct xone_dongle *dongle, int index,
+                                       bool silent)
 {
        unsigned long flags = 0;
        int err = 0;
@@ -1048,6 +1218,8 @@
 
        if (dongle->clients[index])
                err = gip_power_off_adapter(dongle->clients[index]->adapter);
+       else if (!silent)
+               err = -ENODEV;
 
        spin_unlock_irqrestore(&dongle->clients_lock, flags);
        return err;
@@ -1055,16 +1227,11 @@
 
 static int xone_dongle_power_off_clients(struct xone_dongle *dongle)
 {
-       int err;
-
        if (dongle->fw_state != XONE_DONGLE_FW_STATE_READY)
                return 0;
 
-       for (int i = 0; i < XONE_DONGLE_MAX_CLIENTS; i++){
-               err = xone_dongle_power_off_client(dongle, i);
-               if (err)
-                       return err;
-       }
+       for (int i = 0; i < XONE_DONGLE_MAX_CLIENTS; i++)
+               xone_dongle_power_off_client(dongle, i, true);
 
        /* can time out if new client connects */
        if (!wait_event_timeout(dongle->disconnect_wait,
@@ -1081,21 +1248,18 @@
        struct urb *urb;
        int i;
 
-       usb_kill_anchored_urbs(&dongle->urbs_in_busy);
-       destroy_workqueue(dongle->event_wq);
-       cancel_delayed_work(&dongle->pairing_work);
-
        if (dongle->fw_state < XONE_DONGLE_FW_STATE_ERROR) {
                pr_debug("%s: Firmware not loaded, stopping work", __func__);
                dongle->fw_state = XONE_DONGLE_FW_STATE_STOP_LOADING;
-               pr_debug("%s: Waiting for fw load work to finish", __func__);
-
-               while (dongle->fw_state == XONE_DONGLE_FW_STATE_STOP_LOADING)
-                       msleep(500);
-
-               pr_debug("%s: FW loading cancelled", __func__);
        }
 
+       usb_kill_anchored_urbs(&dongle->urbs_in_busy);
+       /* cancel fw load before destroying workqueues to avoid use-after-free 
*/
+       cancel_work_sync(&dongle->load_fw_work);
+       destroy_workqueue(dongle->event_wq);
+       cancel_delayed_work_sync(&dongle->pairing_work);
+       cancel_delayed_work_sync(&dongle->pairing_scan_work);
+
        for (i = 0; i < XONE_DONGLE_MAX_CLIENTS; i++) {
                client = dongle->clients[i];
                if (!client)
@@ -1142,11 +1306,23 @@
 
        mutex_init(&dongle->pairing_lock);
        INIT_DELAYED_WORK(&dongle->pairing_work, xone_dongle_pairing_timeout);
+       INIT_DELAYED_WORK(&dongle->pairing_scan_work, xone_dongle_pairing_scan);
        INIT_WORK(&dongle->load_fw_work, xone_dongle_fw_load);
        spin_lock_init(&dongle->clients_lock);
        init_waitqueue_head(&dongle->disconnect_wait);
 
-       usb_reset_device(dongle->mt.udev);
+       /*
+        * Do not call usb_reset_device() here. On cold boot the MT76 chip
+        * disconnects from USB as a normal part of its firmware startup
+        * sequence (inside xone_mt76_load_ivb). A preceding USB reset leaves
+        * the XHCI port in a state where it cannot cleanly handle that
+        * subsequent disconnect/reconnect cycle, causing the chip to
+        * permanently disappear from the USB bus until a physical replug.
+        *
+        * On warm reboot the firmware survives in RAM, so the chip does not
+        * disconnect at all and the faster xone_mt76_reset_firmware() path
+        * is taken instead — a reset is equally unnecessary there.
+        */
        err = xone_dongle_init(dongle);
        if (err) {
                xone_dongle_destroy(dongle);
@@ -1200,7 +1376,8 @@
 
        usb_kill_anchored_urbs(&dongle->urbs_in_busy);
        usb_kill_anchored_urbs(&dongle->urbs_out_busy);
-       cancel_delayed_work(&dongle->pairing_work);
+       cancel_delayed_work_sync(&dongle->pairing_work);
+       cancel_delayed_work_sync(&dongle->pairing_scan_work);
 
        return xone_mt76_suspend_radio(&dongle->mt);
 }
@@ -1268,7 +1445,8 @@
        if (dongle->fw_state != XONE_DONGLE_FW_STATE_READY)
                dongle->fw_state = XONE_DONGLE_FW_STATE_STOP_LOADING;
 
-       cancel_delayed_work(&dongle->pairing_work);
+       cancel_delayed_work_sync(&dongle->pairing_work);
+       cancel_delayed_work_sync(&dongle->pairing_scan_work);
        usb_kill_anchored_urbs(&dongle->urbs_in_busy);
        usb_kill_anchored_urbs(&dongle->urbs_out_busy);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xone-0.5.5/transport/mt76.c 
new/xone-0.5.7/transport/mt76.c
--- old/xone-0.5.5/transport/mt76.c     2026-02-05 13:22:01.000000000 +0100
+++ new/xone-0.5.7/transport/mt76.c     2026-02-27 13:40:31.000000000 +0100
@@ -376,8 +376,8 @@
        return xone_mt76_send_command(mt, skb, MT_CMD_WOW_FEATURE);
 }
 
-static int xone_mt76_switch_channel(struct xone_mt76 *mt,
-                                   struct xone_mt76_channel *chan)
+int xone_mt76_switch_channel(struct xone_mt76 *mt,
+                            struct xone_mt76_channel *chan)
 {
        struct sk_buff *skb;
        struct xone_mt76_msg_switch_channel msg = {};
@@ -514,23 +514,64 @@
 
 int xone_mt76_load_firmware(struct xone_mt76 *mt, const struct firmware *fw)
 {
+       u32 val;
        int err;
 
        if (xone_mt76_read_register(mt, MT_FCE_DMA_ADDR | MT_VEND_TYPE_CFG)) {
+               msleep(2000);
                dev_dbg(mt->dev, "%s: resetting firmware...\n", __func__);
-               return xone_mt76_reset_firmware(mt);
+               err = xone_mt76_reset_firmware(mt);
+               if (err)
+                       return err;
+               /*
+                * The MCU needs time to complete its startup sequence after the
+                * firmware reset before it can handle the bulk USB commands 
sent
+                * by xone_mt76_init_radio(). Without this delay init_radio
+                * reliably times out (-ETIMEDOUT) on warm reboot.
+                */
+               msleep(500);
+               return 0;
        }
 
+       dev_dbg(mt->dev, "%s: loading firmware...\n", __func__);
+
        err = xone_mt76_send_firmware(mt, fw);
        if (err)
                return err;
 
        xone_mt76_write_register(mt, MT_FCE_DMA_ADDR | MT_VEND_TYPE_CFG, 0);
 
+       /*
+        * The warm-boot path (reset_firmware) applies an RF patch before
+        * triggering MCU execution via load_ivb. Without this patch the RF
+        * subsystem does not initialise correctly and the chip is silent —
+        * it accepts all subsequent MCU commands (init_radio appears to
+        * succeed) but never transmits beacons, so controllers cannot
+        * discover the dongle. Apply the same patch here before load_ivb
+        * so cold-boot firmware startup leaves the RF in the same state as
+        * a warm reset.
+        */
+       val = xone_mt76_read_register(mt, XONE_MT_RF_PATCH | MT_VEND_TYPE_CFG);
+       xone_mt76_write_register(mt, XONE_MT_RF_PATCH | MT_VEND_TYPE_CFG,
+                                val & ~BIT(19));
+
        err = xone_mt76_load_ivb(mt);
        if (err)
                return err;
 
+       /*
+        * After xone_mt76_load_ivb() the MT76 chip briefly disconnects from
+        * USB as part of its firmware startup sequence. Without a delay the
+        * poll below can read FCE_DMA_ADDR=0x01 in the narrow window before
+        * the kernel has marked the device as disconnected, producing a false
+        * success. xone_mt76_init_radio() then runs against a device the
+        * kernel considers gone and fails with -ENODEV.
+        *
+        * Wait long enough for the disconnect/reconnect cycle to complete so
+        * the poll reflects the true post-startup state of the device.
+        */
+       msleep(500);
+
        if (!xone_mt76_poll(mt, MT_FCE_DMA_ADDR | MT_VEND_TYPE_CFG, 0x01, 0x01))
                err = -ETIMEDOUT;
 
@@ -1042,6 +1083,11 @@
        int mgmt_len = sizeof(struct ieee80211_hdr_3addr) +
                       sizeof(mgmt.u.beacon);
        int err;
+       u8 chan = 1;
+
+       if (mt->channel)
+               chan = mt->channel->index;
+       data[14] = chan;
 
        skb = alloc_skb(sizeof(txwi) + mgmt_len + sizeof(data), GFP_KERNEL);
        if (!skb)
@@ -1079,6 +1125,11 @@
 {
        int err;
 
+       if (enable)
+               xone_mt76_write_register(mt, MT_RX_FILTR_CFG, 0x014f13);
+       else
+               xone_mt76_write_register(mt, MT_RX_FILTR_CFG, 0x017f17);
+
        err = xone_mt76_write_beacon(mt, enable);
        if (err)
                return err;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xone-0.5.5/transport/mt76.h 
new/xone-0.5.7/transport/mt76.h
--- old/xone-0.5.5/transport/mt76.h     2026-02-05 13:22:01.000000000 +0100
+++ new/xone-0.5.7/transport/mt76.h     2026-02-27 13:40:31.000000000 +0100
@@ -70,6 +70,8 @@
 int xone_mt76_init_radio(struct xone_mt76 *mt);
 int xone_mt76_suspend_radio(struct xone_mt76 *mt);
 int xone_mt76_resume_radio(struct xone_mt76 *mt);
+int xone_mt76_switch_channel(struct xone_mt76 *mt,
+                            struct xone_mt76_channel *chan);
 int xone_mt76_set_pairing(struct xone_mt76 *mt, bool enable);
 
 int xone_mt76_pair_client(struct xone_mt76 *mt, u8 *addr);

Reply via email to