From 9efd215411bb5ead2bc0ab208b4c19e46da0d2c9 Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Thu, 12 Dec 2024 19:26:31 -0800 Subject: [PATCH] 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 3b286d9adba..46fa8e2de84 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 3f14c05eb79..8c52ad7ff48 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 d8c0a98e43a..5bcd4a81b50 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 33c6fa3432f..488e6ea79d3 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 941e41151b5..74b23359e1a 100644 --- a/sys/dev/rtwn/rtl8188e/r88e_beacon.c +++ b/sys/dev/rtwn/rtl8188e/r88e_beacon.c @@ -43,6 +43,9 @@ #include #include +/* + * 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 752761415bc..2d4713e92bd 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 ddb9fa9ae8c..ef18edceabc 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 c602f314825..a7091be66f6 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 9e4cdb5f139..8084d5b6943 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 8e9c4987a35..cd350c7fcd8 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 35ff5cb6585..a11a6bb79c5 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 19dbd1569e6..8bf1464b952 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 b4458d60a0f..93b4e25a50e 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 4b86461b2f2..84bfcfbda0e 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 75d8f3669c1..9f0e2c950a1 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;