From c6f5f0fe759db17f5585e7443eab23b24e859e8f Mon Sep 17 00:00:00 2001
From: Sabeeh Khan <sabeeh-khan@ti.com>
Date: Fri, 23 Aug 2024 10:28:30 -0500
Subject: [PATCH] backport k5.10

---
 arch/arm64/configs/defconfig          |  5 ++
 drivers/net/wireless/ti/cc33xx/acx.c  |  6 +--
 drivers/net/wireless/ti/cc33xx/cmd.c  | 19 +++----
 drivers/net/wireless/ti/cc33xx/main.c | 71 +++++++++++++--------------
 net/mac80211/mlme.c                   | 17 +++++--
 5 files changed, 64 insertions(+), 54 deletions(-)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 2d61efddb10b..b13939481477 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -1092,3 +1092,8 @@ CONFIG_DEBUG_KERNEL=y
 # CONFIG_DEBUG_PREEMPT is not set
 # CONFIG_FTRACE is not set
 CONFIG_MEMTEST=y
+CONFIG_WLCORE=n
+CONFIG_WLCORE_SDIO=n
+CONFIG_WL18XX=n
+CONFIG_CC33XX=m
+CONFIG_CC33XX_SDIO=m
diff --git a/drivers/net/wireless/ti/cc33xx/acx.c b/drivers/net/wireless/ti/cc33xx/acx.c
index e1577ad7cdc6..a89acb037401 100644
--- a/drivers/net/wireless/ti/cc33xx/acx.c
+++ b/drivers/net/wireless/ti/cc33xx/acx.c
@@ -350,9 +350,9 @@ int cc33xx_assoc_info_cfg(struct cc33xx *wl, struct cc33xx_vif *wlvif,
 	cfg->nontransmitted = wlvif->nontransmitted;
 	cfg->bssid_index = wlvif->bssid_index;
 	cfg->bssid_indicator = wlvif->bssid_indicator;
-	cfg->ht_supported = sta->deflink.ht_cap.ht_supported;
-	cfg->vht_supported = sta->deflink.vht_cap.vht_supported;
-	cfg->has_he = sta->deflink.he_cap.has_he;
+	cfg->ht_supported = sta->ht_cap.ht_supported;
+	cfg->vht_supported = sta->vht_cap.vht_supported;
+	cfg->has_he = sta->he_cap.has_he;
 	memcpy(cfg->transmitter_bssid, wlvif->transmitter_bssid, ETH_ALEN);
 	ret = cc33xx_cmd_configure(wl, ASSOC_INFO_CFG, cfg, sizeof(*cfg));
 	if (ret < 0) {
diff --git a/drivers/net/wireless/ti/cc33xx/cmd.c b/drivers/net/wireless/ti/cc33xx/cmd.c
index c4403504548b..8c80c8632b4a 100644
--- a/drivers/net/wireless/ti/cc33xx/cmd.c
+++ b/drivers/net/wireless/ti/cc33xx/cmd.c
@@ -391,6 +391,7 @@ static u8 check_is_dfs_channel(struct cc33xx *wl,
 						enum nl80211_band rate_band, u8 channel)
 {
 	struct ieee80211_supported_band *band;
+	int i;
 	u8 is_dfs = 0;
 
 	if (rate_band != NL80211_BAND_5GHZ)
@@ -400,7 +401,7 @@ static u8 check_is_dfs_channel(struct cc33xx *wl,
 
 	band = wl->hw->wiphy->bands[NL80211_BAND_5GHZ];
 
-	for (int i = 0; i < band->n_channels; i++)
+	for (i = 0; i < band->n_channels; i++)
 	{
 		if (band->channels[i].hw_value == channel)
 		{
@@ -1453,11 +1454,11 @@ int cc33xx_cmd_add_peer(struct cc33xx *wl, struct cc33xx_vif *wlvif,
 		}
 	}
 
-	sta_rates = sta->deflink.supp_rates[wlvif->band];
-	if (sta->deflink.ht_cap.ht_supported) {
+	sta_rates = sta->supp_rates[wlvif->band];
+	if (sta->ht_cap.ht_supported) {
 		sta_rates |=
-			(sta->deflink.ht_cap.mcs.rx_mask[0] << HW_HT_RATES_OFFSET) |
-			(sta->deflink.ht_cap.mcs.rx_mask[1] << HW_MIMO_RATES_OFFSET);
+			(sta->ht_cap.mcs.rx_mask[0] << HW_HT_RATES_OFFSET) |
+			(sta->ht_cap.mcs.rx_mask[1] << HW_MIMO_RATES_OFFSET);
 	}
 
 	cmd->supported_rates =
@@ -1474,14 +1475,14 @@ int cc33xx_cmd_add_peer(struct cc33xx *wl, struct cc33xx_vif *wlvif,
 	cc33xx_debug(DEBUG_CMD, "new peer rates=0x%x queues=0x%x",
 		     cmd->supported_rates, sta->uapsd_queues);
 			
-	if(sta->deflink.ht_cap.ht_supported)
+	if(sta->ht_cap.ht_supported)
 	{
-		cmd->ht_capabilities = cpu_to_le32(sta->deflink.ht_cap.cap);
+		cmd->ht_capabilities = cpu_to_le32(sta->ht_cap.cap);
 		cmd->ht_capabilities |= cpu_to_le32(CC33XX_HT_CAP_HT_OPERATION);
-		cmd->ampdu_params = sta->deflink.ht_cap.ampdu_factor | sta->deflink.ht_cap.ampdu_density;
+		cmd->ampdu_params = sta->ht_cap.ampdu_factor | sta->ht_cap.ampdu_density;
 	}
 
-	cmd->has_he= sta->deflink.he_cap.has_he;
+	cmd->has_he= sta->he_cap.has_he;
 	cmd->mfp = sta->mfp;
 	ret = cc33xx_cmd_send(wl, CMD_ADD_PEER, cmd, sizeof(*cmd), 0);
 	if (ret < 0) {
diff --git a/drivers/net/wireless/ti/cc33xx/main.c b/drivers/net/wireless/ti/cc33xx/main.c
index 37f7f53ffb17..770b25b6dc43 100644
--- a/drivers/net/wireless/ti/cc33xx/main.c
+++ b/drivers/net/wireless/ti/cc33xx/main.c
@@ -311,7 +311,7 @@ static struct ieee80211_sband_iftype_data iftype_data_2ghz[] = {{
 			IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
 			IEEE80211_HE_MAC_CAP3_RX_CTRL_FRAME_TO_MULTIBSS,
 		.mac_cap_info[4] =
-			IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU |
+			IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU |
 			IEEE80211_HE_MAC_CAP4_NDP_FB_REP |
 			IEEE80211_HE_MAC_CAP4_MULTI_TID_AGG_TX_QOS_B39,
 		.mac_cap_info[5] =
@@ -336,8 +336,8 @@ static struct ieee80211_sband_iftype_data iftype_data_2ghz[] = {{
 		.phy_cap_info[6] =
 			IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_42_SU  |
 			IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_75_MU  |
-			IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMING_FB  |
-			IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMING_PARTIAL_BW_FB |
+			IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMER_FB  |
+			IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMER_FB |
 			IEEE80211_HE_PHY_CAP6_TRIG_CQI_FB |
 			IEEE80211_HE_PHY_CAP6_PARTIAL_BW_EXT_RANGE,
 		.phy_cap_info[7] =
@@ -350,8 +350,7 @@ static struct ieee80211_sband_iftype_data iftype_data_2ghz[] = {{
 			IEEE80211_HE_PHY_CAP9_NON_TRIGGERED_CQI_FEEDBACK |
 			IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_COMP_SIGB |
 			IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_NON_COMP_SIGB |				
-			(IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_16US << 
-			 IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_POS),
+			IEEE80211_HE_PHY_CAP9_NOMIMAL_PKT_PADDING_16US,
 		},
 		/*
 		* Set default Tx/Rx HE MCS NSS Support field.
@@ -479,7 +478,7 @@ static struct ieee80211_sband_iftype_data iftype_data_5ghz[] = {{
 			IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
 			IEEE80211_HE_MAC_CAP3_RX_CTRL_FRAME_TO_MULTIBSS,
 		.mac_cap_info[4] =
-			IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU |
+			IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU |
 			IEEE80211_HE_MAC_CAP4_NDP_FB_REP |
 			IEEE80211_HE_MAC_CAP4_MULTI_TID_AGG_TX_QOS_B39,
 		.mac_cap_info[5] =
@@ -504,8 +503,8 @@ static struct ieee80211_sband_iftype_data iftype_data_5ghz[] = {{
 		.phy_cap_info[6] =
 			IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_42_SU  |
 			IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_75_MU  |
-			IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMING_FB  |
-			IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMING_PARTIAL_BW_FB |
+			IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMER_FB  |
+			IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMER_FB |
 			IEEE80211_HE_PHY_CAP6_TRIG_CQI_FB |
 			IEEE80211_HE_PHY_CAP6_PARTIAL_BW_EXT_RANGE,
 		.phy_cap_info[7] =
@@ -518,8 +517,7 @@ static struct ieee80211_sband_iftype_data iftype_data_5ghz[] = {{
 			IEEE80211_HE_PHY_CAP9_NON_TRIGGERED_CQI_FEEDBACK |
 			IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_COMP_SIGB |
 			IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_NON_COMP_SIGB |			
-			(IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_16US <<
-			 IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_POS),
+			IEEE80211_HE_PHY_CAP9_NOMIMAL_PKT_PADDING_16US,
 		},
 		/*
 			* Set default Tx/Rx HE MCS NSS Support field.
@@ -2774,7 +2772,7 @@ static int wlcore_set_assoc(struct cc33xx *wl, struct cc33xx_vif *wlvif,
 {
 	int ret;
 
-	wlvif->aid = vif->cfg.aid;
+	wlvif->aid = bss_conf->aid;
 	wlvif->channel_type = cfg80211_get_chandef_type(&bss_conf->chandef);
 	wlvif->beacon_int = bss_conf->beacon_int;
 	wlvif->wmm_enabled = bss_conf->qos;
@@ -3627,7 +3625,7 @@ static int wlcore_set_beacon_template(struct cc33xx *wl,
 	struct cc33xx_vif *wlvif = cc33xx_vif_to_data(vif);
 	int ret;
 	int ieoffset = offsetof(struct ieee80211_mgmt, u.beacon.variable);
-	struct sk_buff *beacon = ieee80211_beacon_get(wl->hw, vif, 0);
+	struct sk_buff *beacon = ieee80211_beacon_get(wl->hw, vif);
 
 	struct cc33xx_cmd_set_beacon_info *cmd;
 
@@ -3782,7 +3780,7 @@ static int wlcore_set_bssid(struct cc33xx *wl, struct cc33xx_vif *wlvif,
 
 	cc33xx_debug(DEBUG_MAC80211, "changed_bssid: %pM, aid: %d, bcn_int: %d,"
 			" brates: 0x%x sta_rate_set: 0x%x, nontx: %d",
-			bss_conf->bssid, vif->cfg.aid, bss_conf->beacon_int,
+			bss_conf->bssid, bss_conf->aid, bss_conf->beacon_int,
 			bss_conf->basic_rates, sta_rate_set,
 			bss_conf->nontransmitted);
 
@@ -3868,7 +3866,7 @@ static void cc33xx_bss_info_changed_sta(struct cc33xx *wl,
 	}
 
 	if (changed & BSS_CHANGED_IBSS) {
-		if (vif->cfg.ibss_joined){
+		if (bss_conf->ibss_joined){
 			set_bit(WLVIF_FLAG_IBSS_JOINED, &wlvif->flags);
 			ibss_joined = true;
 		} else {
@@ -3892,7 +3890,7 @@ static void cc33xx_bss_info_changed_sta(struct cc33xx *wl,
 	}
 
 	if (changed & BSS_CHANGED_IDLE && !is_ibss)
-		cc33xx_sta_handle_idle(wl, wlvif, vif->cfg.idle);
+		cc33xx_sta_handle_idle(wl, wlvif, bss_conf->idle);
 
 	if (changed & BSS_CHANGED_CQM)
 		wlvif->rssi_thold = bss_conf->cqm_rssi_thold;
@@ -3901,17 +3899,17 @@ static void cc33xx_bss_info_changed_sta(struct cc33xx *wl,
 		rcu_read_lock();
 		sta = ieee80211_find_sta(vif, bss_conf->bssid);
 		if (sta) {
-			u8 *rx_mask = sta->deflink.ht_cap.mcs.rx_mask;
+			u8 *rx_mask = sta->ht_cap.mcs.rx_mask;
 
 			/* save the supp_rates of the ap */
-			sta_rate_set = sta->deflink.supp_rates[wlvif->band];
-			if (sta->deflink.ht_cap.ht_supported) {
+			sta_rate_set = sta->supp_rates[wlvif->band];
+			if (sta->ht_cap.ht_supported) {
 				sta_rate_set |=
 					(rx_mask[0] << HW_HT_RATES_OFFSET) |
 					(rx_mask[1] << HW_MIMO_RATES_OFFSET);
 			}
-			sta_ht_cap = sta->deflink.ht_cap;
-			sta_he_cap = sta->deflink.he_cap;
+			sta_ht_cap = sta->ht_cap;
+			sta_he_cap = sta->he_cap;
 			sta_exists = true;
 		}
 
@@ -3936,9 +3934,9 @@ static void cc33xx_bss_info_changed_sta(struct cc33xx *wl,
 
 	if (changed & BSS_CHANGED_IBSS) {
 		cc33xx_debug(DEBUG_ADHOC, "ibss_joined: %d",
-			     vif->cfg.ibss_joined);
+			     bss_conf->ibss_joined);
 
-		if (vif->cfg.ibss_joined) {
+		if (bss_conf->ibss_joined) {
 			u32 rates = bss_conf->basic_rates;
 			wlvif->basic_rate_set =
 				cc33xx_tx_enabled_rates_get(wl, rates,
@@ -3972,7 +3970,7 @@ static void cc33xx_bss_info_changed_sta(struct cc33xx *wl,
 	}
 
 	if (changed & BSS_CHANGED_ASSOC) {
-		if (vif->cfg.assoc) {
+		if (bss_conf->assoc) {
 			ret = wlcore_set_assoc(wl, wlvif, bss_conf,sta, vif,
  					       sta_rate_set);
 			if (ret < 0)
@@ -3985,9 +3983,9 @@ static void cc33xx_bss_info_changed_sta(struct cc33xx *wl,
 				struct cc33xx_vif *wlvif_itr;
 				u8 he_count = 0;
 
-				wlvif->sta_has_he = sta->deflink.he_cap.has_he;
+				wlvif->sta_has_he = sta->he_cap.has_he;
 
-				if (sta->deflink.he_cap.has_he)
+				if (sta->he_cap.has_he)
 					cc33xx_info("HE Enabled");		
 				else
 					cc33xx_info("HE Disabled");
@@ -4013,7 +4011,7 @@ static void cc33xx_bss_info_changed_sta(struct cc33xx *wl,
 	}
 
 	if (changed & BSS_CHANGED_PS) {
-		if ((vif->cfg.ps) &&
+		if ((bss_conf->ps) &&
 		    test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags) &&
 		    !test_bit(WLVIF_FLAG_IN_PS, &wlvif->flags)) {
 			int ps_mode;
@@ -4033,7 +4031,7 @@ static void cc33xx_bss_info_changed_sta(struct cc33xx *wl,
 			if (ret < 0)
 				cc33xx_warning("enter %s ps failed %d",
 					       ps_mode_str, ret);
-		} else if (!vif->cfg.ps && test_bit(WLVIF_FLAG_IN_PS,
+		} else if (!bss_conf->ps && test_bit(WLVIF_FLAG_IN_PS,
 						     &wlvif->flags)) {
 			cc33xx_debug(DEBUG_PSM, "auto ps disabled");
 
@@ -4074,11 +4072,11 @@ static void cc33xx_bss_info_changed_sta(struct cc33xx *wl,
 	/* Handle arp filtering. Done after join. */
 	if ((changed & BSS_CHANGED_ARP_FILTER) ||
 	    (!is_ibss && (changed & BSS_CHANGED_QOS))) {
-		__be32 addr = vif->cfg.arp_addr_list[0];
+		__be32 addr = bss_conf->arp_addr_list[0];
 		wlvif->sta.qos = bss_conf->qos;
 		WARN_ON(wlvif->bss_type != BSS_TYPE_STA_BSS);
 
-		if (vif->cfg.arp_addr_cnt == 1 && vif->cfg.assoc) {
+		if (bss_conf->arp_addr_cnt == 1 && bss_conf->assoc) {
 			wlvif->ip_addr = addr;
 			/*
 			 * The template should have been configured only upon
@@ -4105,7 +4103,7 @@ static void cc33xx_bss_info_changed_sta(struct cc33xx *wl,
 static void cc33xx_op_bss_info_changed(struct ieee80211_hw *hw,
 				       struct ieee80211_vif *vif,
 				       struct ieee80211_bss_conf *bss_conf,
-				       u64 changed)
+				       u32 changed)
 {
 	struct cc33xx *wl = hw->priv;
 	struct cc33xx_vif *wlvif = cc33xx_vif_to_data(vif);
@@ -4191,7 +4189,7 @@ static void cc33xx_op_change_chanctx(struct ieee80211_hw *hw,
 		struct ieee80211_vif *vif = cc33xx_wlvif_to_vif(wlvif);
 
 		rcu_read_lock();
-		if (rcu_access_pointer(vif->bss_conf.chanctx_conf) != ctx) {
+		if (rcu_access_pointer(vif->chanctx_conf) != ctx) {
 			rcu_read_unlock();
 			continue;
 		}
@@ -4213,7 +4211,6 @@ static void cc33xx_op_change_chanctx(struct ieee80211_hw *hw,
 
 static int cc33xx_op_assign_vif_chanctx(struct ieee80211_hw *hw,
 					struct ieee80211_vif *vif,
-					struct ieee80211_bss_conf *link_conf,
 					struct ieee80211_chanctx_conf *ctx)
 {
 	struct cc33xx *wl = hw->priv;
@@ -4255,7 +4252,6 @@ static int cc33xx_op_assign_vif_chanctx(struct ieee80211_hw *hw,
 
 static void cc33xx_op_unassign_vif_chanctx(struct ieee80211_hw *hw,
 					   struct ieee80211_vif *vif,
-					   struct ieee80211_bss_conf *link_conf,
 					   struct ieee80211_chanctx_conf *ctx)
 {
 	struct cc33xx *wl = hw->priv;
@@ -4361,8 +4357,7 @@ enum {
 };
 
 static int cc33xx_op_conf_tx(struct ieee80211_hw *hw,
-			     struct ieee80211_vif *vif, 
-			     unsigned int link_id, u16 queue,
+			     struct ieee80211_vif *vif, u16 queue,
 			     const struct ieee80211_tx_queue_params *params)
 {
 	struct cc33xx *wl = hw->priv;
@@ -5070,8 +5065,8 @@ static void cc33xx_op_sta_rc_update(struct ieee80211_hw *hw,
 		return;
 
 	/* this callback is atomic, so schedule a new work */
-	wlvif->rc_update_bw = sta->deflink.bandwidth;
-	memcpy(&wlvif->rc_ht_cap, &sta->deflink.ht_cap, sizeof(sta->deflink.ht_cap));
+	wlvif->rc_update_bw = sta->bandwidth;
+	memcpy(&wlvif->rc_ht_cap, &sta->ht_cap, sizeof(sta->ht_cap));
 	ieee80211_queue_work(hw, &wlvif->rc_update_work);
 }
 
@@ -5918,7 +5913,7 @@ int wlcore_probe(struct cc33xx *wl, struct platform_device *pdev)
 
 	if (pdev_data->family && pdev_data->family->nvs_name) {
 		nvs_name = pdev_data->family->nvs_name;
-		ret = request_firmware_nowait(THIS_MODULE, FW_ACTION_UEVENT,
+		ret = request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
 					      nvs_name, &pdev->dev, GFP_KERNEL,
 					      wl, wlcore_nvs_cb);
 		if (ret < 0) {
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index af36f0e19712..48ca23713563 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -224,10 +224,18 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata,
 	if (sta_ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) {
 		ieee80211_chandef_ht_oper(ht_oper, chandef);
 	} else {
-		/* 40 MHz (and 80 MHz) must be supported for VHT */
-		ret = IEEE80211_STA_DISABLE_VHT;
-		/* also mark 40 MHz disabled */
-		ret |= IEEE80211_STA_DISABLE_40MHZ;
+
+		/* 40 MHz (and 80 MHz) must be supported for 5GHZ VHT
+			unless peer allows operating mode notification. If so a 20MHz 
+			station can ask from peer to lower bandwidth. */
+		if (channel->band != NL80211_BAND_2GHZ){
+				ret = IEEE80211_STA_DISABLE_40MHZ;
+		}else{
+				ret = IEEE80211_STA_DISABLE_VHT;
+				/* also mark 40 MHz disabled */
+				ret |= IEEE80211_STA_DISABLE_40MHZ;
+		}
+
 		goto out;
 	}
 
@@ -765,6 +773,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
 			2 + 2 * sband->n_channels + /* supported channels */
 			2 + sizeof(struct ieee80211_ht_cap) + /* HT */
 			2 + sizeof(struct ieee80211_vht_cap) + /* VHT */
+			2 + sizeof(u8) + /* VHT operating mode notification elem */
 			2 + 1 + sizeof(struct ieee80211_he_cap_elem) + /* HE */
 				sizeof(struct ieee80211_he_mcs_nss_supp) +
 				IEEE80211_HE_PPE_THRES_MAX_LEN +
-- 
2.34.1

