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
This commit is contained in:
Adrian Chadd 2024-12-12 19:26:31 -08:00
parent 1fc7922f9f
commit 9efd215411
15 changed files with 58 additions and 0 deletions

View file

@ -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);

View file

@ -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) \

View file

@ -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;

View file

@ -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 *);

View file

@ -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)
{
}

View file

@ -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;

View file

@ -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;

View file

@ -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 *);

View file

@ -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);
}
}

View file

@ -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;

View file

@ -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;

View file

@ -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[],

View file

@ -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)
{
}

View file

@ -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;

View file

@ -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;