On Wed, 25 Mar 2026 11:59:36 +0100,
Stefan Sperling <[email protected]> wrote:
> 
> On Tue, Mar 24, 2026 at 06:52:14PM +0100, Kirill A. Korinsky wrote:
> > Thanks for detailed explanation, and because I'm in context of iwx driver it
> > ineed trivial implement. I haven't touched other dirvers, but iwx is tested
> > and seems works.
> > 
> > Also, I've checked Linux and it treats both CSA and eCSA/XCSA, so I did the 
> > same.
> > 
> > The diff:
> 
> Thanks, the diff makes sense, ok stsp@
> 
> Please also update IEEE80211_NODEREQ_ASSOCFAIL and the _BITS string
> in ieee80211_ioctl.h for the new CSA failure case. Otherwise ifconfig
> won't be able to display the failure.
> 

Do you mean something like that?

Index: sys/dev/pci/if_iwx.c
===================================================================
RCS file: /home/cvs/src/sys/dev/pci/if_iwx.c,v
diff -u -p -r1.223 if_iwx.c
--- sys/dev/pci/if_iwx.c        14 Mar 2026 15:37:44 -0000      1.223
+++ sys/dev/pci/if_iwx.c        25 Mar 2026 16:15:30 -0000
@@ -10994,6 +10994,22 @@ iwx_rx_pkt(struct iwx_softc *sc, struct 
                        break;
                }
 
+               case IWX_WIDE_ID(IWX_MAC_CONF_GROUP,
+                   IWX_CHANNEL_SWITCH_START_NOTIF): {
+                       if (sc->sc_ic.ic_opmode != IEEE80211_M_STA ||
+                           sc->sc_ic.ic_state != IEEE80211_S_RUN)
+                               break;
+
+                       if (ifp->if_flags & IFF_DEBUG)
+                               printf("%s: firmware channel switch "
+                                   "notification 0x%x\n",
+                                   DEVNAME(sc), code);
+
+                       if ((sc->sc_flags & IWX_FLAG_SHUTDOWN) == 0)
+                               task_add(systq, &sc->init_task);
+                       break;
+               }
+
                case IWX_WIDE_ID(IWX_SYSTEM_GROUP,
                    IWX_FSEQ_VER_MISMATCH_NOTIFICATION):
                    break;
Index: sys/dev/pci/if_iwxreg.h
===================================================================
RCS file: /home/cvs/src/sys/dev/pci/if_iwxreg.h,v
diff -u -p -r1.73 if_iwxreg.h
--- sys/dev/pci/if_iwxreg.h     13 Mar 2026 11:11:02 -0000      1.73
+++ sys/dev/pci/if_iwxreg.h     25 Mar 2026 16:14:30 -0000
@@ -2079,6 +2079,7 @@ struct iwx_tx_queue_cfg_rsp {
 #define IWX_STA_REMOVE_CMD             0x0c
 #define IWX_SESSION_PROTECTION_NOTIF   0xfb
 #define IWX_MISSED_BEACONS_NOTIF       0xf6
+#define IWX_CHANNEL_SWITCH_START_NOTIF 0xff
 
 /* DATA_PATH group subcommand IDs */
 #define IWX_DQA_ENABLE_CMD     0x00
Index: sys/net80211/ieee80211_input.c
===================================================================
RCS file: /home/cvs/src/sys/net80211/ieee80211_input.c,v
diff -u -p -r1.260 ieee80211_input.c
--- sys/net80211/ieee80211_input.c      19 Mar 2026 16:50:32 -0000      1.260
+++ sys/net80211/ieee80211_input.c      25 Mar 2026 16:14:30 -0000
@@ -1623,7 +1623,7 @@ ieee80211_recv_probe_resp(struct ieee802
 {
        struct ieee80211_node *ni;
        const struct ieee80211_frame *wh;
-       const u_int8_t *frm, *efrm;
+       const u_int8_t *frm, *efrm, *csa, *xcsa;
        const u_int8_t *tstamp, *ssid, *rates, *xrates, *edcaie, *wmmie, *tim;
        const u_int8_t *rsnie, *wpaie, *htcaps, *htop, *vhtcaps, *vhtop, 
*hecaps, *heop;
        u_int16_t capinfo, bintval;
@@ -1666,7 +1666,7 @@ ieee80211_recv_probe_resp(struct ieee802
        capinfo = LE_READ_2(frm); frm += 2;
 
        ssid = rates = xrates = edcaie = wmmie = rsnie = wpaie = tim = NULL;
-       htcaps = htop = vhtcaps = vhtop = hecaps = heop = NULL;
+       htcaps = htop = vhtcaps = vhtop = hecaps = heop = csa = xcsa = NULL;
        if (rxi->rxi_chan)
                bchan = rxi->rxi_chan;
        else
@@ -1702,6 +1702,20 @@ ieee80211_recv_probe_resp(struct ieee802
                        }
                        erp = frm[2];
                        break;
+               case IEEE80211_ELEMID_CSA:
+                       if (frm[1] < 3) {
+                               ic->ic_stats.is_rx_elem_toosmall++;
+                               break;
+                       }
+                       csa = frm;
+                       break;
+               case IEEE80211_ELEMID_XCSA:
+                       if (frm[1] < 4) {
+                               ic->ic_stats.is_rx_elem_toosmall++;
+                               break;
+                       }
+                       xcsa = frm;
+                       break;
                case IEEE80211_ELEMID_RSN:
                        rsnie = frm;
                        break;
@@ -1826,6 +1840,9 @@ ieee80211_recv_probe_resp(struct ieee802
 #endif
 
        ni->ni_chan = &ic->ic_channels[chan];
+       ni->ni_flags &= ~IEEE80211_NODE_CSA;
+       if (csa != NULL || xcsa != NULL)
+               ni->ni_flags |= IEEE80211_NODE_CSA;
 
        if (htcaps)
                ieee80211_setup_htcaps(ni, htcaps + 2, htcaps[1]);
Index: sys/net80211/ieee80211_ioctl.h
===================================================================
RCS file: /home/cvs/src/sys/net80211/ieee80211_ioctl.h,v
diff -u -p -r1.44 ieee80211_ioctl.h
--- sys/net80211/ieee80211_ioctl.h      22 Mar 2025 07:24:08 -0000      1.44
+++ sys/net80211/ieee80211_ioctl.h      25 Mar 2026 16:23:29 -0000
@@ -385,9 +385,10 @@ struct ieee80211_nodereq {
 #define IEEE80211_NODEREQ_ASSOCFAIL_BSSID      0x20
 #define IEEE80211_NODEREQ_ASSOCFAIL_WPA_PROTO  0x40
 #define IEEE80211_NODEREQ_ASSOCFAIL_WPA_KEY    0x80
+#define IEEE80211_NODEREQ_ASSOCFAIL_CSA                0x100
 #define IEEE80211_NODEREQ_ASSOCFAIL_BITS       \
        "\20\1!CHAN\2!IBSS\3!PRIVACY\4!BASICRATE\5!ESSID\6!BSSID\7!WPAPROTO" \
-       "\10!WPAKEY"
+       "\10!WPAKEY\11!CSA"
 
 /* get the entire node cache */
 struct ieee80211_nodereq_all {
Index: sys/net80211/ieee80211_node.c
===================================================================
RCS file: /home/cvs/src/sys/net80211/ieee80211_node.c,v
diff -u -p -r1.211 ieee80211_node.c
--- sys/net80211/ieee80211_node.c       19 Mar 2026 16:50:32 -0000      1.211
+++ sys/net80211/ieee80211_node.c       25 Mar 2026 16:14:30 -0000
@@ -1135,6 +1135,8 @@ ieee80211_match_bss(struct ieee80211com 
        if ((ic->ic_flags & IEEE80211_F_DESBSSID) &&
            !IEEE80211_ADDR_EQ(ic->ic_des_bssid, ni->ni_bssid))
                fail |= IEEE80211_NODE_ASSOCFAIL_BSSID;
+       if (ni->ni_flags & IEEE80211_NODE_CSA)
+               fail |= IEEE80211_NODE_ASSOCFAIL_CSA;
 
        if (ic->ic_flags & IEEE80211_F_RSNON) {
                /*
Index: sys/net80211/ieee80211_node.h
===================================================================
RCS file: /home/cvs/src/sys/net80211/ieee80211_node.h,v
diff -u -p -r1.99 ieee80211_node.h
--- sys/net80211/ieee80211_node.h       19 Mar 2026 16:50:32 -0000      1.99
+++ sys/net80211/ieee80211_node.h       25 Mar 2026 16:14:30 -0000
@@ -413,6 +413,7 @@ struct ieee80211_node {
 #define IEEE80211_NODE_ASSOCFAIL_BSSID         0x20
 #define IEEE80211_NODE_ASSOCFAIL_WPA_PROTO     0x40
 #define IEEE80211_NODE_ASSOCFAIL_WPA_KEY       0x80
+#define IEEE80211_NODE_ASSOCFAIL_CSA           0x100
 
        int                     ni_inact;       /* inactivity mark count */
        int                     ni_txrate;      /* index to ni_rates[] */
@@ -444,6 +445,7 @@ struct ieee80211_node {
 #define IEEE80211_NODE_VHT_SGI160      0x100000 /* SGI on 160 MHz negotiated 
*/ 
 #define IEEE80211_NODE_HE              0x200000 /* HE negotiated */
 #define IEEE80211_NODE_HECAP           0x400000 /* claims to support HE */
+#define IEEE80211_NODE_CSA             0x800000 /* channel switch announced */
 
        /* If not NULL, this function gets called when ni_refcnt hits zero. */
        void                    (*ni_unref_cb)(struct ieee80211com *,


-- 
wbr, Kirill

Reply via email to