Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src-draft/trunk]: src/sys/dev/usb run(4): optimize/fix beacon frame handling:



details:   https://anonhg.NetBSD.org/src-all/rev/e9741563445b
branches:  trunk
changeset: 375754:e9741563445b
user:      Martin Husemann <martin%NetBSD.org@localhost>
date:      Sun Feb 27 15:03:02 2022 +0100

description:
run(4): optimize/fix beacon frame handling:

 - keep a single mbuf per VAP for beacon handling
 - update the beacon contents whenever the stack thinks something
   important has changed
 - copy beacon data to the hardwares shared buffer whenever something
   did change

Actual sending of beacon frames is still autonomously done by the firmware.

diffstat:

 sys/dev/usb/if_run.c |  90 +++++++++++++++++++++++++++++++++++++++++----------
 1 files changed, 71 insertions(+), 19 deletions(-)

diffs (180 lines):

diff -r cd9687326430 -r e9741563445b sys/dev/usb/if_run.c
--- a/sys/dev/usb/if_run.c      Mon Feb 21 20:47:19 2022 +0100
+++ b/sys/dev/usb/if_run.c      Sun Feb 27 15:03:02 2022 +0100
@@ -411,7 +411,8 @@ static void         run_rt5390_set_chan(struct 
 static void            run_rt5592_set_chan(struct run_softc *, u_int);
 static int             run_set_chan(struct run_softc *,
                            struct ieee80211_channel *);
-static void            run_updateprot(struct run_softc *);
+static void            run_updateprot_cb(struct run_softc *, void *);
+static void            run_updateprot(struct ieee80211com *);
 static void            run_enable_tsf_sync(struct ieee80211vap *);
 static void            run_enable_mrr(struct run_softc *);
 static void            run_set_txpreamble(struct run_softc *);
@@ -437,7 +438,8 @@ static int                  run_adjust_freq_offset(
 static int             run_init(struct usbwifi *);
 static void            run_stop(struct usbwifi *);
 #ifndef IEEE80211_STA_ONLY
-static int             run_setup_beacon(struct ieee80211vap *);
+static void            run_update_beacon(struct ieee80211vap *, int);
+static void            run_update_beacon_cb(struct run_softc *, void*);
 #endif
 static void    run_get_radiocaps(struct ieee80211com *, int , int *,
                        struct ieee80211_channel []);
@@ -540,6 +542,7 @@ static const struct {
 struct run_vap {
        struct ieee80211vap vap;
        int (*newstate)(struct ieee80211vap *, enum ieee80211_state, int);
+       struct mbuf *beacon_mbuf;
 };
 
 static const struct usbwifi_ops run_ops = {
@@ -1787,7 +1790,7 @@ run_newstate(struct ieee80211vap *vap, e
 #ifndef IEEE80211_STA_ONLY
                if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
                    ic->ic_opmode == IEEE80211_M_IBSS)
-                       (void)run_setup_beacon(vap);
+                       run_update_beacon_cb(sc, &vap);
 #endif
                if (ic->ic_opmode == IEEE80211_M_STA) {
                        /* add BSS entry to the WCID table */
@@ -3547,7 +3550,7 @@ run_set_chan(struct run_softc *sc, struc
 }
 
 static void
-run_updateprot(struct run_softc *sc)
+run_updateprot_cb(struct run_softc *sc, void *dummy)
 {
        struct ieee80211com *ic = usbwifi_ic(&sc->sc_uw);
        uint32_t tmp;
@@ -3569,6 +3572,13 @@ run_updateprot(struct run_softc *sc)
        run_write(sc, RT2860_OFDM_PROT_CFG, tmp);
 }
 
+
+static void
+run_updateprot(struct ieee80211com *ic)
+{
+       run_do_async(ic->ic_softc, run_updateprot_cb, NULL, 0);
+}
+
 static void
 run_enable_tsf_sync(struct ieee80211vap *iv)
 {
@@ -4620,7 +4630,7 @@ run_init(struct usbwifi *uw)
        run_set_chan(sc, ic->ic_curchan);
 
        /* setup initial protection mode */
-       run_updateprot(sc);
+       run_updateprot_cb(sc, NULL);
 
        /* turn radio LED on */
        run_set_leds(sc, RT2860_LED_RADIO);
@@ -4681,22 +4691,25 @@ run_stop(struct usbwifi *uw)
 }
 
 #ifndef IEEE80211_STA_ONLY
-static int
-run_setup_beacon(struct ieee80211vap *iv)
+/* actually copy the beacon mbuf to the device - always in task context */
+static void
+run_update_beacon_cb(struct run_softc *sc, void *arg)
 {
-       struct ieee80211com *ic = iv->iv_ic;
-       struct run_softc *sc = ic->ic_softc;
+       struct run_vap *rvap = *(struct run_vap **)arg;
+       struct ieee80211com *ic = rvap->vap.iv_ic;
        struct rt2860_txwi txwi;
-       struct mbuf *m;
        uint16_t txwisize;
        int ridx;
 
-       if ((m = ieee80211_beacon_alloc(iv->iv_bss)) == NULL)
-               return ENOBUFS;
+       if (rvap->beacon_mbuf == NULL) {
+               rvap->beacon_mbuf = ieee80211_beacon_alloc(rvap->vap.iv_bss);
+               if (rvap->beacon_mbuf == NULL)
+                       return;
+       }
 
        memset(&txwi, 0, sizeof(txwi));
        txwi.wcid = 0xff;
-       txwi.len = htole16(m->m_pkthdr.len);
+       txwi.len = htole16(rvap->beacon_mbuf->m_pkthdr.len);
        /* send beacons at the lowest available rate */
        ridx = (ic->ic_curmode == IEEE80211_MODE_11A) ?
            RT2860_RIDX_OFDM6 : RT2860_RIDX_CCK1;
@@ -4711,12 +4724,44 @@ run_setup_beacon(struct ieee80211vap *iv
        run_write_region_1(sc, RT2860_BCN_BASE(0),
            (uint8_t *)&txwi, txwisize);
        run_write_region_1(sc, RT2860_BCN_BASE(0) + txwisize,
-           mtod(m, uint8_t *), (m->m_pkthdr.len + 1) & ~1);
-
-       m_freem(m);
-
-       return 0;
+           mtod(rvap->beacon_mbuf, uint8_t *),
+           (rvap->beacon_mbuf->m_pkthdr.len + 1) & ~1);
 }
+
+static void
+run_update_beacon(struct ieee80211vap *vap, int item)
+{
+       struct run_vap *rvp = (struct run_vap *)vap;
+       struct ieee80211com *ic = vap->iv_ic;
+       struct ieee80211_beacon_offsets *bo = &vap->iv_bcn_off;
+       struct ieee80211_node *ni = vap->iv_bss;
+       struct run_softc *sc = ic->ic_softc;
+       int mcast = 0;
+
+       switch (item) {
+       case IEEE80211_BEACON_ERP:
+               run_updateslot(ic);
+               break;
+       case IEEE80211_BEACON_HTINFO:
+               run_updateprot(ic);
+               break;
+       case IEEE80211_BEACON_TIM:
+               mcast = 1;
+               break;
+       default:
+               break;
+       }
+
+       setbit(bo->bo_flags, item);
+       if (rvp->beacon_mbuf == NULL) {
+               rvp->beacon_mbuf = ieee80211_beacon_alloc(ni);
+               if (rvp->beacon_mbuf == NULL)
+                       return;
+       }
+       ieee80211_beacon_update(ni, rvp->beacon_mbuf, mcast);
+       run_do_async(sc, run_update_beacon_cb, &vap, sizeof(vap));
+}
+
 #endif
 
 MODULE(MODULE_CLASS_DRIVER, if_run, NULL);
@@ -4804,6 +4849,11 @@ run_vap_create(struct ieee80211com *ic, 
        /* Override state transition machine. */
        rvap->newstate = rvap->vap.iv_newstate;
        rvap->vap.iv_newstate = run_newstate;
+       rvap->vap.iv_update_beacon = run_update_beacon;
+#ifdef RUN_HWCRYPTO
+       rvap->vap.iv_key_delete = run_key_delete;
+       rvap->vap.iv_key_set = run_key_set;
+#endif
 
        ieee80211_vap_attach(&rvap->vap, run_media_change,
             ieee80211_media_status, macaddr);
@@ -4816,8 +4866,10 @@ run_vap_create(struct ieee80211com *ic, 
 static void
 run_vap_delete(struct ieee80211vap *vap)
 {
+       struct run_vap *rvap = (struct run_vap *)vap;
        ieee80211_vap_detach(vap);
-       kmem_free(vap, sizeof(struct run_vap));
+       m_freem(rvap->beacon_mbuf);
+       kmem_free(rvap, sizeof(struct run_vap));
 }
 
 static void



Home | Main Index | Thread Index | Old Index