The branch main has been updated by adrian:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=378eeae502e2d556733d20edaac8dc1ac5573d6d

commit 378eeae502e2d556733d20edaac8dc1ac5573d6d
Author:     Adrian Chadd <adr...@freebsd.org>
AuthorDate: 2025-01-12 23:58:58 +0000
Commit:     Adrian Chadd <adr...@freebsd.org>
CommitDate: 2025-02-26 19:29:39 +0000

    net80211: convert ni_txrate to a struct, with extra rate information
    
    * create struct ieee80211_node_txrate, which represents both
      the existing legacy / HT rates, and makes space for VHT rates
    
    * convert the ieee80211_node_* routines that manipulate the txrate
      field to use the new format
    
    * return OFDM6 for now if a VHT rate is set but the driver calls
      ieee80211_node_get_txrate_dot11rate().  It SHOULD be the lowest
      available rate - which for 11b will be a CCK rate, for
      turbo/half/quarter will be different rates! - but this is just
      for development.
    
    This should be a no-op for existing drivers and rate control, as
    everything now uses the accessor functions instead of directly
    accessing ni->ni_txrate.
    
    Locally tested:
    
    * RTL8821AU, STA mode (5GHz VHT/40)
    
    Differential Revision:  https://reviews.freebsd.org/D48604
    Reviewed by:    bz, thj
---
 sys/net80211/ieee80211_ddb.c  |  5 ++-
 sys/net80211/ieee80211_node.c | 94 ++++++++++++++++++++++++++++++++++++++-----
 sys/net80211/ieee80211_node.h | 21 +++++++++-
 3 files changed, 108 insertions(+), 12 deletions(-)

diff --git a/sys/net80211/ieee80211_ddb.c b/sys/net80211/ieee80211_ddb.c
index 05b370eafa38..5dbb20dfe8e0 100644
--- a/sys/net80211/ieee80211_ddb.c
+++ b/sys/net80211/ieee80211_ddb.c
@@ -306,8 +306,9 @@ _db_show_sta(const struct ieee80211_node *ni)
                if (ni->ni_rx_ampdu[i].rxa_flags)
                        _db_show_rxampdu("\t", i, &ni->ni_rx_ampdu[i]);
 
-       db_printf("\tinact %u inact_reload %u txrate %u\n",
-               ni->ni_inact, ni->ni_inact_reload, ni->ni_txrate);
+       db_printf("\tinact %u inact_reload %u txrate type %d rate %u\n",
+               ni->ni_inact, ni->ni_inact_reload, ni->ni_txrate.type,
+               ni->ni_txrate.dot11rate);
 #ifdef IEEE80211_SUPPORT_MESH
        _db_show_ssid("\tmeshid ", 0, ni->ni_meshidlen, ni->ni_meshid);
        db_printf(" mlstate %b mllid 0x%x mlpid 0x%x mlrcnt %u mltval %u\n",
diff --git a/sys/net80211/ieee80211_node.c b/sys/net80211/ieee80211_node.c
index f5b05ed769c9..01f7c8904237 100644
--- a/sys/net80211/ieee80211_node.c
+++ b/sys/net80211/ieee80211_node.c
@@ -2667,8 +2667,10 @@ ieee80211_dump_node(struct ieee80211_node_table *nt 
__unused,
                ni->ni_esslen, ni->ni_essid,
                (ni->ni_chan != IEEE80211_CHAN_ANYC) ? ni->ni_chan->ic_freq : 0,
                (ni->ni_chan != IEEE80211_CHAN_ANYC) ? ni->ni_chan->ic_flags : 
0);
-       printf("\tinact %u inact_reload %u txrate %u\n",
-               ni->ni_inact, ni->ni_inact_reload, ni->ni_txrate);
+       printf("\tinact %u inact_reload %u txrate type %d dot11rate %u\n",
+               ni->ni_inact, ni->ni_inact_reload,
+               ni->ni_txrate.type,
+               ni->ni_txrate.dot11rate);
        printf("\thtcap %x htparam %x htctlchan %u ht2ndchan %u\n",
                ni->ni_htcap, ni->ni_htparam,
                ni->ni_htctlchan, ni->ni_ht2ndchan);
@@ -3138,19 +3140,73 @@ ieee80211_getsignal(struct ieee80211vap *vap, int8_t 
*rssi, int8_t *noise)
                *rssi = ieee80211_getrssi(vap);
 }
 
+/**
+ * @brief return a dot11rate / ratecode representing the current transmit rate
+ *
+ * This is the API call for legacy / 802.11n drivers and rate control APIs
+ * which expect a dot11rate / ratecode representation for legacy and HT MCS
+ * rates.
+ *
+ * Drivers which support VHT should not use this API, as it will log an error
+ * and return a low rate if a VHT rate is selected.
+ *
+ * @param ni           the ieee80211_node to return the transmit rate for
+ * @returns            the dot11rate / ratecode for legacy/MCS, or the
+ *                     lowest available dot11rate if it's VHT (and shouldn't
+ *                     have been called.)
+ */
 uint8_t
 ieee80211_node_get_txrate_dot11rate(struct ieee80211_node *ni)
 {
-       return (ni->ni_txrate);
+       switch (ni->ni_txrate.type) {
+       case IEEE80211_NODE_TXRATE_LEGACY:
+       case IEEE80211_NODE_TXRATE_HT:
+               return (ni->ni_txrate.dot11rate);
+               break;
+       case IEEE80211_NODE_TXRATE_VHT:
+       default:
+               printf("%s: called for VHT / unknown rate (type %d)!\n",
+                   __func__, ni->ni_txrate.type);
+               return (12);            /* OFDM6 for now */
+       }
 }
 
+/**
+ * @brief set the dot11rate / ratecode representing the current transmit rate
+ *
+ * This is the API call for legacy / 802.11n drivers and rate control APIs
+ * which expect a dot11rate / ratecode representation for legacy and HT MCS
+ * rates.
+ *
+ * @param ni           the ieee80211_node to return the transmit rate for
+ * @param dot11rate    the dot11rate rate code to use
+ */
 void
 ieee80211_node_set_txrate_dot11rate(struct ieee80211_node *ni,
     uint8_t dot11Rate)
 {
-       ni->ni_txrate = dot11Rate;
+       if (dot11Rate & IEEE80211_RATE_MCS) {
+               ni->ni_txrate.type = IEEE80211_NODE_TXRATE_HT;
+               ni->ni_txrate.mcs = dot11Rate & IEEE80211_RATE_VAL;
+               ni->ni_txrate.nss = 0;
+               ni->ni_txrate.dot11rate = dot11Rate;
+       } else {
+               ni->ni_txrate.type = IEEE80211_NODE_TXRATE_LEGACY;
+               ni->ni_txrate.mcs = ni->ni_txrate.nss = 0;
+               ni->ni_txrate.dot11rate = dot11Rate;
+       }
 }
 
+/**
+ * @brief set the dot11rate / ratecode representing the current HT transmit 
rate
+ *
+ * This is the API call for 802.11n drivers and rate control APIs
+ * which expect a dot11rate / ratecode representation for legacy and HT MCS
+ * rates.  It expects an MCS rate code from 0 .. 76.
+ *
+ * @param ni           the ieee80211_node to return the transmit rate for
+ * @param mcs          the MCS rate to select
+ */
 void
 ieee80211_node_set_txrate_ht_mcsrate(struct ieee80211_node *ni,
     uint8_t mcs)
@@ -3160,7 +3216,11 @@ ieee80211_node_set_txrate_ht_mcsrate(struct 
ieee80211_node *ni,
                ic_printf(ni->ni_ic, "%s: invalid MCS (%d)\n", __func__, mcs);
                return;
        }
-       ni->ni_txrate = IEEE80211_RATE_MCS | mcs;
+
+       ni->ni_txrate.type = IEEE80211_NODE_TXRATE_HT;
+       ni->ni_txrate.mcs = mcs;
+       ni->ni_txrate.nss = 0;
+       ni->ni_txrate.dot11rate = IEEE80211_RATE_MCS | mcs;
 }
 
 
@@ -3177,10 +3237,26 @@ ieee80211_node_get_txrate_kbit(struct ieee80211_node 
*ni)
 {
        uint32_t mbps;
 
-       if (ni->ni_txrate & IEEE80211_RATE_MCS) {
-               const struct ieee80211_mcs_rates *mcs =
-                   &ieee80211_htrates[ni->ni_txrate & ~IEEE80211_RATE_MCS];
+       /*
+        * TODO: only handle legacy/HT rates, VHT will need
+        * to use other logic.
+        */
+       switch (ni->ni_txrate.type) {
+       case IEEE80211_NODE_TXRATE_LEGACY:
+       case IEEE80211_NODE_TXRATE_HT:
+               break;
+       case IEEE80211_NODE_TXRATE_VHT:
+       default:
+               printf("%s: called for VHT / unknown rate (type %d)!\n",
+                   __func__, ni->ni_txrate.type);
+               return (0);
+       }
 
+       /* Legacy / MCS rates */
+       if (ni->ni_txrate.dot11rate & IEEE80211_RATE_MCS) {
+               const struct ieee80211_mcs_rates *mcs =
+                   &ieee80211_htrates[ni->ni_txrate.dot11rate &
+                   ~IEEE80211_RATE_MCS];
                if (IEEE80211_IS_CHAN_HT40(ni->ni_chan)) {
                        /* Note: these are in 1/2Mbit/s units */
                        if (ni->ni_flags & IEEE80211_NODE_SGI40)
@@ -3195,7 +3271,7 @@ ieee80211_node_get_txrate_kbit(struct ieee80211_node *ni)
                }
        } else
                /* Note: CCK/OFDM dot11rate entries are in 1/2Mbit/s units */
-               mbps = ni->ni_txrate;
+               mbps = ni->ni_txrate.dot11rate;
 
        /*
         * Note; 'mbps' in 1/2 Mbit/s units so *500 to make it in kbit/s units.
diff --git a/sys/net80211/ieee80211_node.h b/sys/net80211/ieee80211_node.h
index 722f3d54a00b..859b8b0288a1 100644
--- a/sys/net80211/ieee80211_node.h
+++ b/sys/net80211/ieee80211_node.h
@@ -139,6 +139,20 @@ ieee80211_ni_chw_to_str(enum ieee80211_sta_rx_bw bw)
        }
 }
 
+enum ieee80211_node_txrate_type {
+       IEEE80211_NODE_TXRATE_UNDEFINED         = 0,
+       IEEE80211_NODE_TXRATE_LEGACY            = 1, /* CCK/OFDM, HT for now */
+       IEEE80211_NODE_TXRATE_HT                = 2, /* HT */
+       IEEE80211_NODE_TXRATE_VHT               = 3, /* VHT */
+};
+
+struct ieee80211_node_txrate {
+       enum ieee80211_node_txrate_type type;
+       uint8_t         nss;            /* VHT - number of spatial streams */
+       uint8_t         mcs;            /* HT/VHT - MCS */
+       uint8_t         dot11rate;      /* Legacy/HT - dot11rate / ratecode */
+};
+
 /*
  * Node specific information.  Note that drivers are expected
  * to derive from this structure to add device-specific per-node
@@ -275,7 +289,7 @@ struct ieee80211_node {
        /* others */
        short                   ni_inact;       /* inactivity mark count */
        short                   ni_inact_reload;/* inactivity reload value */
-       int                     ni_txrate;      /* legacy rate/MCS */
+       struct ieee80211_node_txrate    ni_txrate;      /* current transmit 
rate */
        struct ieee80211_psq    ni_psq;         /* power save queue */
        struct ieee80211_nodestats ni_stats;    /* per-node statistics */
 
@@ -499,6 +513,11 @@ void       ieee80211_node_leave(struct ieee80211_node *);
 int8_t ieee80211_getrssi(struct ieee80211vap *);
 void   ieee80211_getsignal(struct ieee80211vap *, int8_t *, int8_t *);
 
+/*
+ * Node transmit rate specific manipulation.
+ *
+ * This should eventually be refactored into its own type.
+ */
 uint8_t        ieee80211_node_get_txrate_dot11rate(struct ieee80211_node *);
 void   ieee80211_node_set_txrate_dot11rate(struct ieee80211_node *, uint8_t);
 void   ieee80211_node_set_txrate_ht_mcsrate(struct ieee80211_node *, uint8_t);

Reply via email to