The branch main has been updated by adrian:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=1c746222c2ef25d2caa7578217ce92b637a1ee3d

commit 1c746222c2ef25d2caa7578217ce92b637a1ee3d
Author:     Adrian Chadd <adr...@freebsd.org>
AuthorDate: 2025-01-13 05:17:36 +0000
Commit:     Adrian Chadd <adr...@freebsd.org>
CommitDate: 2025-02-26 19:30:23 +0000

    net80211: Implement ieee80211_setup_vht_rates()
    
    Implement ieee80211_setup_vht_rates() - calculate the intersection between
    the peers advertised RX VHT MCS map and the vap's configured TX map.
    
    Whilst here, remove the unused vhtcap/vhtinfo fields; they're
    already populated in the ieee80211_node before ieee80211_setup_vht_rates()
    is called.
    
    Differential Revision:  https://reviews.freebsd.org/D48607
    Reviewed by:    bz
---
 sys/net80211/ieee80211_ddb.c  |  4 +--
 sys/net80211/ieee80211_node.c |  7 ++---
 sys/net80211/ieee80211_node.h |  4 +--
 sys/net80211/ieee80211_sta.c  |  2 +-
 sys/net80211/ieee80211_vht.c  | 61 +++++++++++++++++++++++++++++++++++++++----
 sys/net80211/ieee80211_vht.h  |  3 +--
 6 files changed, 64 insertions(+), 17 deletions(-)

diff --git a/sys/net80211/ieee80211_ddb.c b/sys/net80211/ieee80211_ddb.c
index 5dbb20dfe8e0..3c57b03ddc65 100644
--- a/sys/net80211/ieee80211_ddb.c
+++ b/sys/net80211/ieee80211_ddb.c
@@ -317,9 +317,9 @@ _db_show_sta(const struct ieee80211_node *ni)
 #endif
 
        /* VHT state */
-       db_printf("\tvhtcap %b vht_basicmcs %#06x vht_pad2 %#06x\n",
+       db_printf("\tvhtcap %b vht_basicmcs %#06x vht_tx_map %#06x\n",
            ni->ni_vhtcap, IEEE80211_VHTCAP_BITS,
-           ni->ni_vht_basicmcs, ni->ni_vht_pad2);
+           ni->ni_vht_basicmcs, ni->ni_vht_tx_map);
        db_printf("\tvht_mcsinfo: { rx_mcs_map %#06x rx_highest %#06x "
            "tx_mcs_map %#06x tx_highest %#06x }\n",
            ni->ni_vht_mcsinfo.rx_mcs_map, ni->ni_vht_mcsinfo.rx_highest,
diff --git a/sys/net80211/ieee80211_node.c b/sys/net80211/ieee80211_node.c
index c781280d5e8a..5a239bbd30f6 100644
--- a/sys/net80211/ieee80211_node.c
+++ b/sys/net80211/ieee80211_node.c
@@ -1044,8 +1044,7 @@ ieee80211_sta_join(struct ieee80211vap *vap, struct 
ieee80211_channel *chan,
                        ieee80211_vht_updateparams(ni,
                            ni->ni_ies.vhtcap_ie,
                            ni->ni_ies.vhtopmode_ie);
-                       ieee80211_setup_vht_rates(ni, ni->ni_ies.vhtcap_ie,
-                           ni->ni_ies.vhtopmode_ie);
+                       ieee80211_setup_vht_rates(ni);
                        do_ht = 1;
                }
        }
@@ -1874,9 +1873,7 @@ ieee80211_init_neighbor(struct ieee80211_node *ni,
                                ieee80211_vht_updateparams(ni,
                                    ni->ni_ies.vhtcap_ie,
                                    ni->ni_ies.vhtopmode_ie);
-                               ieee80211_setup_vht_rates(ni,
-                                   ni->ni_ies.vhtcap_ie,
-                                   ni->ni_ies.vhtopmode_ie);
+                               ieee80211_setup_vht_rates(ni);
                        }
                }
 
diff --git a/sys/net80211/ieee80211_node.h b/sys/net80211/ieee80211_node.h
index bb14c8c4bb42..969d8e563fa9 100644
--- a/sys/net80211/ieee80211_node.h
+++ b/sys/net80211/ieee80211_node.h
@@ -274,8 +274,8 @@ struct ieee80211_node {
 
        /* VHT state */
        uint32_t                ni_vhtcap;
-       uint16_t                ni_vht_basicmcs;
-       uint16_t                ni_vht_pad2;
+       uint16_t                ni_vht_basicmcs;        /* Basic VHT MCS bitmap 
from IE */
+       uint16_t                ni_vht_tx_map;          /* Negotiated MCS TX 
map with peer */
        struct ieee80211_vht_mcs_info   ni_vht_mcsinfo;
        uint8_t                 ni_vht_chan1;   /* 20/40/80/160 - VHT chan1 */
        uint8_t                 ni_vht_chan2;   /* 80+80 - VHT chan2 */
diff --git a/sys/net80211/ieee80211_sta.c b/sys/net80211/ieee80211_sta.c
index 96603f339710..48d56d0ad217 100644
--- a/sys/net80211/ieee80211_sta.c
+++ b/sys/net80211/ieee80211_sta.c
@@ -1875,7 +1875,7 @@ sta_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, 
int subtype,
                                } else {
                                        ieee80211_vht_node_init(ni);
                                        ieee80211_vht_updateparams(ni, vhtcap, 
vhtopmode);
-                                       ieee80211_setup_vht_rates(ni, vhtcap, 
vhtopmode);
+                                       ieee80211_setup_vht_rates(ni);
                                }
                        }
 
diff --git a/sys/net80211/ieee80211_vht.c b/sys/net80211/ieee80211_vht.c
index 82879f90c67b..e704e0cbd176 100644
--- a/sys/net80211/ieee80211_vht.c
+++ b/sys/net80211/ieee80211_vht.c
@@ -284,14 +284,65 @@ ieee80211_vht_updateparams(struct ieee80211_node *ni,
        return (0);
 }
 
+/**
+ * @brief calculate the supported MCS rates for this node
+ *
+ * This is called once a node has finished association /
+ * joined a BSS.  The vhtcap / vhtop IEs are from the
+ * peer.  The transmit rate tables need to be combined
+ * together to setup the list of available rates.
+ *
+ * This must be called after the ieee80211_node VHT fields
+ * have been parsed / populated by either ieee80211_vht_updateparams() or
+ * ieee80211_parse_vhtcap(),
+ *
+ * This does not take into account the channel bandwidth,
+ * which (a) may change during operation, and (b) depends
+ * upon packet to packet rate transmission selection.
+ * There are various rate combinations which are not
+ * available in various channel widths and those will
+ * need to be masked off separately.
+ *
+ * (See 802.11-2020 21.5 Parameters for VHT-MCSs for the
+ * tables and supported rates.)
+ *
+ * ALSO: i need to do some filtering based on the HT set too.
+ * (That should be done here too, and in the negotiation, sigh.)
+ * (See 802.11-2016 10.7.12.3 Additional rate selection constraints
+ * for VHT PPDUs)
+ *
+ * @param ni   struct ieee80211_node to configure
+ */
 void
-ieee80211_setup_vht_rates(struct ieee80211_node *ni,
-    const uint8_t *vhtcap_ie,
-    const uint8_t *vhtop_ie)
+ieee80211_setup_vht_rates(struct ieee80211_node *ni)
 {
+       struct ieee80211vap *vap = ni->ni_vap;
+       uint32_t val, val1, val2;
+       uint16_t tx_mcs_map = 0;
+       int i;
 
-       //printf("%s: called\n", __func__);
-       /* XXX TODO */
+       /*
+        * Merge our tx_mcs_map with the peer rx_mcs_map to determine what
+        * can be actually transmitted to the peer.
+        */
+
+       for (i = 0; i < 8; i++) {
+               /*
+                * Merge the two together; remember that 0..2 is in order
+                * of increasing MCS support, but 3 equals
+                * IEEE80211_VHT_MCS_NOT_SUPPORTED so must "win".
+                */
+               val1 = (vap->iv_vht_cap.supp_mcs.tx_mcs_map >> (i*2)) & 0x3;
+               val2 = (ni->ni_vht_mcsinfo.rx_mcs_map >> (i*2)) & 0x3;
+               val = MIN(val1, val2);
+               if (val1 == IEEE80211_VHT_MCS_NOT_SUPPORTED ||
+                   val2 == IEEE80211_VHT_MCS_NOT_SUPPORTED)
+                       val = IEEE80211_VHT_MCS_NOT_SUPPORTED;
+               tx_mcs_map |= (val << (i*2));
+       }
+
+       /* Store the TX MCS map somewhere in the node that can be used */
+       ni->ni_vht_tx_map = tx_mcs_map;
 }
 
 void
diff --git a/sys/net80211/ieee80211_vht.h b/sys/net80211/ieee80211_vht.h
index bcb61020c5a1..a61804a43059 100644
--- a/sys/net80211/ieee80211_vht.h
+++ b/sys/net80211/ieee80211_vht.h
@@ -40,8 +40,7 @@ void  ieee80211_parse_vhtcap(struct ieee80211_node *, const 
uint8_t *);
 
 int    ieee80211_vht_updateparams(struct ieee80211_node *,
            const uint8_t *, const uint8_t *);
-void   ieee80211_setup_vht_rates(struct ieee80211_node *,
-           const uint8_t *, const uint8_t *);
+void   ieee80211_setup_vht_rates(struct ieee80211_node *);
 
 void   ieee80211_vht_timeout(struct ieee80211vap *vap);
 

Reply via email to