From: Johannes Berg <johannes.berg@xxxxxxxxx> Handle the operating mode notification action frame. When the supported streams change, let the driver and rate control algorithm know. INCOMPLETE - need to handle bandwidth changes Signed-off-by: Johannes Berg <johannes.berg@xxxxxxxxx> --- include/net/mac80211.h | 3 +++ net/mac80211/rx.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 5bc6459..66a8b0a 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -2072,11 +2072,14 @@ enum ieee80211_frame_release_type { * @IEEE80211_RC_SUPP_RATES_CHANGED: The supported rate set of this peer * changed (in IBSS mode) due to discovering more information about * the peer. + * @IEEE80211_RC_NSS_CHANGED: N_SS (number of spatial streams) was changed + * by the peer, using an operating mode notification */ enum ieee80211_rate_control_changed { IEEE80211_RC_BW_CHANGED = BIT(0), IEEE80211_RC_SMPS_CHANGED = BIT(1), IEEE80211_RC_SUPP_RATES_CHANGED = BIT(2), + IEEE80211_RC_NSS_CHANGED = BIT(3), }; /** diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 580704e..e863190 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -2397,6 +2397,48 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) } break; + case WLAN_CATEGORY_VHT: + if (sdata->vif.type != NL80211_IFTYPE_STATION && + sdata->vif.type != NL80211_IFTYPE_MESH_POINT && + sdata->vif.type != NL80211_IFTYPE_AP_VLAN && + sdata->vif.type != NL80211_IFTYPE_AP && + sdata->vif.type != NL80211_IFTYPE_ADHOC) + break; + + /* verify action code and one more byte (opmode) are present */ + if (len < IEEE80211_MIN_ACTION_SIZE + 2) + goto invalid; + + switch (mgmt->u.action.u.vht_opmode_notif.action_code) { + case WLAN_VHT_ACTION_OPMODE_NOTIF: { + struct ieee80211_supported_band *sband; + u8 opmode = mgmt->u.action.u.vht_opmode_notif.operating_mode; + u8 nss; + + /* ignore - no support for BF yet */ + if (opmode & IEEE80211_VHT_OPMODE_RX_NSS_TYPE_BF) + goto handled; + + nss = opmode & IEEE80211_VHT_OPMODE_RX_NSS_MASK; + nss >>= IEEE80211_VHT_OPMODE_RX_NSS_SHIFT; + + /* if no change do nothing */ + if (rx->sta->sta.rx_nss == nss) + goto handled; + rx->sta->sta.rx_nss = nss; + + /* TODO: handle bandwidth */ + + sband = rx->local->hw.wiphy->bands[status->band]; + + rate_control_rate_update(local, sband, rx->sta, + IEEE80211_RC_NSS_CHANGED); + goto handled; + } + default: + goto invalid; + } + break; case WLAN_CATEGORY_BACK: if (sdata->vif.type != NL80211_IFTYPE_STATION && sdata->vif.type != NL80211_IFTYPE_MESH_POINT && -- 1.8.0 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html