git: 9efd215411bb - main - rtwn: create a new HAL routine for enabling STA mode beacon processing

From: Adrian Chadd <adrian_at_FreeBSD.org>
Date: Fri, 20 Dec 2024 20:41:03 UTC
The branch main has been updated by adrian:

URL: https://cgit.FreeBSD.org/src/commit/?id=9efd215411bb5ead2bc0ab208b4c19e46da0d2c9

commit 9efd215411bb5ead2bc0ab208b4c19e46da0d2c9
Author:     Adrian Chadd <adrian@FreeBSD.org>
AuthorDate: 2024-12-13 03:26:31 +0000
Commit:     Adrian Chadd <adrian@FreeBSD.org>
CommitDate: 2024-12-20 20:40:19 +0000

    rtwn: create a new HAL routine for enabling STA mode beacon processing
    
    For some NICs (notably the rtl8192cu that I'm working on) the
    firmware rate adaptation requires beacon processing to be enabled.
    
    Instead of making assumptions in the if_rtwn beacon routines (and
    honestly all of that should be in the HAL too), create a HAL method
    for enabling/disabling beacon processing specifically in STA mode.
    
    Since this isn't necessarily required for all NICs (notably the RTL8188E
    NICs, where some will do firmware rate control and some will require
    driver rate control), only enable it for the RTL8192CU and RT8192EU.
    
    The RTL8188E and RTL8812/RTL8821 just have no-op routines for now.
    
    Locally tested:
    
    * RTL8192CU, STA mode
    
    Differential Revision:  https://reviews.freebsd.org/D48066
    Reviewed by:    bz
---
 sys/dev/rtwn/if_rtwn.c                   |  3 +++
 sys/dev/rtwn/if_rtwnvar.h                |  4 ++++
 sys/dev/rtwn/rtl8188e/pci/r88ee_attach.c |  1 +
 sys/dev/rtwn/rtl8188e/r88e.h             |  1 +
 sys/dev/rtwn/rtl8188e/r88e_beacon.c      | 12 ++++++++++++
 sys/dev/rtwn/rtl8188e/usb/r88eu_attach.c |  1 +
 sys/dev/rtwn/rtl8192c/pci/r92ce_attach.c |  1 +
 sys/dev/rtwn/rtl8192c/r92c.h             |  1 +
 sys/dev/rtwn/rtl8192c/r92c_beacon.c      | 20 ++++++++++++++++++++
 sys/dev/rtwn/rtl8192c/usb/r92cu_attach.c |  1 +
 sys/dev/rtwn/rtl8192e/usb/r92eu_attach.c |  1 +
 sys/dev/rtwn/rtl8812a/r12a.h             |  1 +
 sys/dev/rtwn/rtl8812a/r12a_beacon.c      |  9 +++++++++
 sys/dev/rtwn/rtl8812a/usb/r12au_attach.c |  1 +
 sys/dev/rtwn/rtl8821a/usb/r21au_attach.c |  1 +
 15 files changed, 58 insertions(+)

diff --git a/sys/dev/rtwn/if_rtwn.c b/sys/dev/rtwn/if_rtwn.c
index 3b286d9adba9..46fa8e2de840 100644
--- a/sys/dev/rtwn/if_rtwn.c
+++ b/sys/dev/rtwn/if_rtwn.c
@@ -968,6 +968,8 @@ rtwn_tsf_sync_enable(struct rtwn_softc *sc, struct ieee80211vap *vap)
 		/* Enable TSF synchronization. */
 		rtwn_setbits_1(sc, R92C_BCN_CTRL(uvp->id),
 		    R92C_BCN_CTRL_DIS_TSF_UDT0, 0);
+		/* Enable TSF beacon handling, needed for RA */
+		rtwn_sta_beacon_enable(sc, uvp->id, true);
 		break;
 	case IEEE80211_M_IBSS:
 		ieee80211_runtask(ic, &uvp->tsf_sync_adhoc_task);
@@ -1109,6 +1111,7 @@ rtwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
 
 		/* Disable TSF synchronization / beaconing. */
 		rtwn_beacon_enable(sc, uvp->id, 0);
+		rtwn_sta_beacon_enable(sc, uvp->id, false);
 		rtwn_setbits_1(sc, R92C_BCN_CTRL(uvp->id),
 		    0, R92C_BCN_CTRL_DIS_TSF_UDT0);
 
diff --git a/sys/dev/rtwn/if_rtwnvar.h b/sys/dev/rtwn/if_rtwnvar.h
index 3f14c05eb79d..8c52ad7ff482 100644
--- a/sys/dev/rtwn/if_rtwnvar.h
+++ b/sys/dev/rtwn/if_rtwnvar.h
@@ -329,6 +329,8 @@ struct rtwn_softc {
 	uint8_t		(*sc_rx_radiotap_flags)(const void *);
 	void		(*sc_beacon_init)(struct rtwn_softc *, void *, int);
 	void		(*sc_beacon_enable)(struct rtwn_softc *, int, int);
+	void		(*sc_sta_beacon_enable)(struct rtwn_softc *, int,
+			    bool);
 	void		(*sc_beacon_set_rate)(void *, int);
 	void		(*sc_beacon_select)(struct rtwn_softc *, int);
 	void		(*sc_set_chan)(struct rtwn_softc *,
@@ -564,6 +566,8 @@ void	rtwn_suspend(struct rtwn_softc *);
 	(((_sc)->sc_beacon_init)((_sc), (_buf), (_id)))
 #define rtwn_beacon_enable(_sc, _id, _enable) \
 	(((_sc)->sc_beacon_enable)((_sc), (_id), (_enable)))
+#define rtwn_sta_beacon_enable(_sc, _id, _enable) \
+	(((_sc)->sc_sta_beacon_enable)((_sc), (_id), (_enable)))
 #define rtwn_beacon_set_rate(_sc, _buf, _is5ghz) \
 	(((_sc)->sc_beacon_set_rate)((_buf), (_is5ghz)))
 #define rtwn_beacon_select(_sc, _id) \
diff --git a/sys/dev/rtwn/rtl8188e/pci/r88ee_attach.c b/sys/dev/rtwn/rtl8188e/pci/r88ee_attach.c
index d8c0a98e43a3..5bcd4a81b50d 100644
--- a/sys/dev/rtwn/rtl8188e/pci/r88ee_attach.c
+++ b/sys/dev/rtwn/rtl8188e/pci/r88ee_attach.c
@@ -177,6 +177,7 @@ r88ee_attach(struct rtwn_pci_softc *pc)
 #endif
 	sc->sc_beacon_init		= r92c_beacon_init;
 	sc->sc_beacon_enable		= r88e_beacon_enable;
+	sc->sc_sta_beacon_enable	= r88e_sta_beacon_enable;
 	sc->sc_beacon_set_rate		= rtwn_nop_void_int;
 	sc->sc_beacon_select		= rtwn_nop_softc_int;
 	sc->sc_temp_measure		= r88e_temp_measure;
diff --git a/sys/dev/rtwn/rtl8188e/r88e.h b/sys/dev/rtwn/rtl8188e/r88e.h
index 33c6fa3432f5..488e6ea79d3f 100644
--- a/sys/dev/rtwn/rtl8188e/r88e.h
+++ b/sys/dev/rtwn/rtl8188e/r88e.h
@@ -39,6 +39,7 @@
  */
 /* r88e_beacon.c */
 void	r88e_beacon_enable(struct rtwn_softc *, int, int);
+void	r88e_sta_beacon_enable(struct rtwn_softc *, int, bool);
 
 /* r88e_calib.c */
 void	r88e_iq_calib(struct rtwn_softc *);
diff --git a/sys/dev/rtwn/rtl8188e/r88e_beacon.c b/sys/dev/rtwn/rtl8188e/r88e_beacon.c
index 941e41151b59..74b23359e1a3 100644
--- a/sys/dev/rtwn/rtl8188e/r88e_beacon.c
+++ b/sys/dev/rtwn/rtl8188e/r88e_beacon.c
@@ -43,6 +43,9 @@
 #include <dev/rtwn/rtl8188e/r88e.h>
 #include <dev/rtwn/rtl8188e/r88e_reg.h>
 
+/*
+ * Enable/disable beaconing in AP/IBSS/Mesh modes.
+ */
 void
 r88e_beacon_enable(struct rtwn_softc *sc, int id, int enable)
 {
@@ -57,3 +60,12 @@ r88e_beacon_enable(struct rtwn_softc *sc, int id, int enable)
 		    R92C_BCN_CTRL_EN_BCN, 0);
 	}
 }
+
+/*
+ * There's no firmware rate control, beacon processing isn't
+ * needed in STA mode.
+ */
+void
+r88e_sta_beacon_enable(struct rtwn_softc *sc, int id, bool enable)
+{
+}
diff --git a/sys/dev/rtwn/rtl8188e/usb/r88eu_attach.c b/sys/dev/rtwn/rtl8188e/usb/r88eu_attach.c
index 752761415bce..2d4713e92bd2 100644
--- a/sys/dev/rtwn/rtl8188e/usb/r88eu_attach.c
+++ b/sys/dev/rtwn/rtl8188e/usb/r88eu_attach.c
@@ -170,6 +170,7 @@ r88eu_attach(struct rtwn_usb_softc *uc)
 #endif
 	sc->sc_beacon_init		= r92c_beacon_init;
 	sc->sc_beacon_enable		= r88e_beacon_enable;
+	sc->sc_sta_beacon_enable	= r88e_sta_beacon_enable;
 	sc->sc_beacon_set_rate		= rtwn_nop_void_int;
 	sc->sc_beacon_select		= rtwn_nop_softc_int;
 	sc->sc_temp_measure		= r88e_temp_measure;
diff --git a/sys/dev/rtwn/rtl8192c/pci/r92ce_attach.c b/sys/dev/rtwn/rtl8192c/pci/r92ce_attach.c
index ddb9fa9ae8c1..ef18edceabc2 100644
--- a/sys/dev/rtwn/rtl8192c/pci/r92ce_attach.c
+++ b/sys/dev/rtwn/rtl8192c/pci/r92ce_attach.c
@@ -207,6 +207,7 @@ r92ce_attach(struct rtwn_pci_softc *pc)
 #endif
 	sc->sc_beacon_init		= r92c_beacon_init;
 	sc->sc_beacon_enable		= r92c_beacon_enable;
+	sc->sc_sta_beacon_enable	= r92c_sta_beacon_enable;
 	sc->sc_beacon_set_rate		= rtwn_nop_void_int;
 	sc->sc_beacon_select		= rtwn_nop_softc_int;
 	sc->sc_temp_measure		= r92c_temp_measure;
diff --git a/sys/dev/rtwn/rtl8192c/r92c.h b/sys/dev/rtwn/rtl8192c/r92c.h
index c602f314825a..a7091be66f64 100644
--- a/sys/dev/rtwn/rtl8192c/r92c.h
+++ b/sys/dev/rtwn/rtl8192c/r92c.h
@@ -46,6 +46,7 @@ void	r92c_read_chipid_vendor(struct rtwn_softc *, uint32_t);
 /* r92c_beacon.c */
 void	r92c_beacon_init(struct rtwn_softc *, void *, int);
 void	r92c_beacon_enable(struct rtwn_softc *, int, int);
+void	r92c_sta_beacon_enable(struct rtwn_softc *, int, bool);
 
 /* r92c_calib.c */
 void	r92c_iq_calib(struct rtwn_softc *);
diff --git a/sys/dev/rtwn/rtl8192c/r92c_beacon.c b/sys/dev/rtwn/rtl8192c/r92c_beacon.c
index 9e4cdb5f1399..8084d5b69438 100644
--- a/sys/dev/rtwn/rtl8192c/r92c_beacon.c
+++ b/sys/dev/rtwn/rtl8192c/r92c_beacon.c
@@ -69,6 +69,9 @@ r92c_beacon_init(struct rtwn_softc *sc, void *buf, int id)
 	txd->txdw5 |= htole32(SM(R92C_TXDW5_DATARATE, RTWN_RIDX_CCK1));
 }
 
+/*
+ * Enable/disable beacon generation in AP/IBSS/mesh modes.
+ */
 void
 r92c_beacon_enable(struct rtwn_softc *sc, int id, int enable)
 {
@@ -81,3 +84,20 @@ r92c_beacon_enable(struct rtwn_softc *sc, int id, int enable)
 		    R92C_BCN_CTRL_EN_BCN, 0);
 	}
 }
+
+/*
+ * Enable/disable beacon processing in STA mode.
+ *
+ * This is required for firmware rate control.
+ */
+void
+r92c_sta_beacon_enable(struct rtwn_softc *sc, int id, bool enable)
+{
+	if (enable) {
+		rtwn_setbits_1(sc, R92C_BCN_CTRL(id),
+		    0, R92C_BCN_CTRL_EN_BCN);
+	} else {
+		rtwn_setbits_1(sc, R92C_BCN_CTRL(id),
+		    R92C_BCN_CTRL_EN_BCN, 0);
+	}
+}
diff --git a/sys/dev/rtwn/rtl8192c/usb/r92cu_attach.c b/sys/dev/rtwn/rtl8192c/usb/r92cu_attach.c
index 8e9c4987a359..cd350c7fcd8a 100644
--- a/sys/dev/rtwn/rtl8192c/usb/r92cu_attach.c
+++ b/sys/dev/rtwn/rtl8192c/usb/r92cu_attach.c
@@ -199,6 +199,7 @@ r92cu_attach(struct rtwn_usb_softc *uc)
 #endif
 	sc->sc_beacon_init		= r92c_beacon_init;
 	sc->sc_beacon_enable		= r92c_beacon_enable;
+	sc->sc_sta_beacon_enable	= r92c_sta_beacon_enable;
 	sc->sc_beacon_set_rate		= rtwn_nop_void_int;
 	sc->sc_beacon_select		= rtwn_nop_softc_int;
 	sc->sc_temp_measure		= r92c_temp_measure;
diff --git a/sys/dev/rtwn/rtl8192e/usb/r92eu_attach.c b/sys/dev/rtwn/rtl8192e/usb/r92eu_attach.c
index 35ff5cb65853..a11a6bb79c5d 100644
--- a/sys/dev/rtwn/rtl8192e/usb/r92eu_attach.c
+++ b/sys/dev/rtwn/rtl8192e/usb/r92eu_attach.c
@@ -150,6 +150,7 @@ r92eu_attach(struct rtwn_usb_softc *uc)
 #endif
 	sc->sc_beacon_init		= r12a_beacon_init;
 	sc->sc_beacon_enable		= r92c_beacon_enable;
+	sc->sc_sta_beacon_enable	= r92c_sta_beacon_enable;
 	sc->sc_beacon_set_rate		= rtwn_nop_void_int;
 	sc->sc_beacon_select		= r21a_beacon_select;
 	sc->sc_temp_measure		= r88e_temp_measure;
diff --git a/sys/dev/rtwn/rtl8812a/r12a.h b/sys/dev/rtwn/rtl8812a/r12a.h
index 19dbd1569e6d..8bf1464b9525 100644
--- a/sys/dev/rtwn/rtl8812a/r12a.h
+++ b/sys/dev/rtwn/rtl8812a/r12a.h
@@ -60,6 +60,7 @@ void	r12a_detach_private(struct rtwn_softc *);
 /* r12a_beacon.c */
 void	r12a_beacon_init(struct rtwn_softc *, void *, int);
 void	r12a_beacon_set_rate(void *, int);
+void	r12a_sta_beacon_enable(struct rtwn_softc *, int, bool);
 
 /* r12a_calib.c */
 void	r12a_save_bb_afe_vals(struct rtwn_softc *, uint32_t[],
diff --git a/sys/dev/rtwn/rtl8812a/r12a_beacon.c b/sys/dev/rtwn/rtl8812a/r12a_beacon.c
index b4458d60a0fa..93b4e25a50ed 100644
--- a/sys/dev/rtwn/rtl8812a/r12a_beacon.c
+++ b/sys/dev/rtwn/rtl8812a/r12a_beacon.c
@@ -91,3 +91,12 @@ r12a_beacon_set_rate(void *buf, int is5ghz)
 	} else
 		txd->txdw4 = htole32(SM(R12A_TXDW4_DATARATE, RTWN_RIDX_CCK1));
 }
+
+/*
+ * For now (no rate control) don't change the beacon configuration
+ * in STA mode.
+ */
+void
+r12a_sta_beacon_enable(struct rtwn_softc *sc, int id, bool enable)
+{
+}
diff --git a/sys/dev/rtwn/rtl8812a/usb/r12au_attach.c b/sys/dev/rtwn/rtl8812a/usb/r12au_attach.c
index 4b86461b2f25..84bfcfbda0e8 100644
--- a/sys/dev/rtwn/rtl8812a/usb/r12au_attach.c
+++ b/sys/dev/rtwn/rtl8812a/usb/r12au_attach.c
@@ -237,6 +237,7 @@ r12au_attach(struct rtwn_usb_softc *uc)
 #endif
 	sc->sc_beacon_init		= r12a_beacon_init;
 	sc->sc_beacon_enable		= r92c_beacon_enable;
+	sc->sc_sta_beacon_enable	= r12a_sta_beacon_enable;
 	sc->sc_beacon_set_rate		= r12a_beacon_set_rate;
 	sc->sc_beacon_select		= rtwn_nop_softc_int;
 	sc->sc_temp_measure		= r88e_temp_measure;
diff --git a/sys/dev/rtwn/rtl8821a/usb/r21au_attach.c b/sys/dev/rtwn/rtl8821a/usb/r21au_attach.c
index 75d8f3669c12..9f0e2c950a1e 100644
--- a/sys/dev/rtwn/rtl8821a/usb/r21au_attach.c
+++ b/sys/dev/rtwn/rtl8821a/usb/r21au_attach.c
@@ -223,6 +223,7 @@ r21au_attach(struct rtwn_usb_softc *uc)
 #endif
 	sc->sc_beacon_init		= r21a_beacon_init;
 	sc->sc_beacon_enable		= r92c_beacon_enable;
+	sc->sc_sta_beacon_enable	= r12a_sta_beacon_enable;
 	sc->sc_beacon_set_rate		= r12a_beacon_set_rate;
 	sc->sc_beacon_select		= r21a_beacon_select;
 	sc->sc_temp_measure		= r88e_temp_measure;