diff options
| author | Dmitry Torokhov <[email protected]> | 2023-08-30 16:06:38 -0700 | 
|---|---|---|
| committer | Dmitry Torokhov <[email protected]> | 2023-08-30 16:06:38 -0700 | 
| commit | 1ac731c529cd4d6adbce134754b51ff7d822b145 (patch) | |
| tree | 143ab3f35ca5f3b69f583c84e6964b17139c2ec1 /drivers/net/wireless/mediatek/mt76/mt7996/mcu.c | |
| parent | 07b4c950f27bef0362dc6ad7ee713aab61d58149 (diff) | |
| parent | 54116d442e001e1b6bd482122043b1870998a1f3 (diff) | |
Merge branch 'next' into for-linus
Prepare input updates for 6.6 merge window.
Diffstat (limited to 'drivers/net/wireless/mediatek/mt76/mt7996/mcu.c')
| -rw-r--r-- | drivers/net/wireless/mediatek/mt76/mt7996/mcu.c | 222 | 
1 files changed, 63 insertions, 159 deletions
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c index dbe30832fd88..88e2f9d0e513 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c @@ -422,7 +422,8 @@ mt7996_mcu_ie_countdown(struct mt7996_dev *dev, struct sk_buff *skb)  	if (hdr->band && dev->mt76.phys[hdr->band])  		mphy = dev->mt76.phys[hdr->band]; -	tail = skb->data + le16_to_cpu(rxd->len); +	tail = skb->data + skb->len; +	data += sizeof(struct header);  	while (data + sizeof(struct tlv) < tail && le16_to_cpu(tlv->len)) {  		switch (le16_to_cpu(tlv->tag)) {  		case UNI_EVENT_IE_COUNTDOWN_CSA: @@ -596,25 +597,24 @@ mt7996_mcu_bss_he_tlv(struct sk_buff *skb, struct ieee80211_vif *vif,  }  static void -mt7996_mcu_bss_bmc_tlv(struct sk_buff *skb, struct mt7996_phy *phy) +mt7996_mcu_bss_bmc_tlv(struct sk_buff *skb, struct ieee80211_vif *vif, +		       struct mt7996_phy *phy)  { +	struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;  	struct bss_rate_tlv *bmc;  	struct cfg80211_chan_def *chandef = &phy->mt76->chandef;  	enum nl80211_band band = chandef->chan->band;  	struct tlv *tlv; +	u8 idx = mvif->mcast_rates_idx ? +		 mvif->mcast_rates_idx : mvif->basic_rates_idx;  	tlv = mt7996_mcu_add_uni_tlv(skb, UNI_BSS_INFO_RATE, sizeof(*bmc));  	bmc = (struct bss_rate_tlv *)tlv; -	if (band == NL80211_BAND_2GHZ) { -		bmc->short_preamble = true; -	} else { -		bmc->bc_trans = cpu_to_le16(0x8080); -		bmc->mc_trans = cpu_to_le16(0x8080); -		bmc->bc_fixed_rate = 1; -		bmc->mc_fixed_rate = 1; -		bmc->short_preamble = 1; -	} + +	bmc->short_preamble = (band == NL80211_BAND_2GHZ); +	bmc->bc_fixed_rate = idx; +	bmc->mc_fixed_rate = idx;  }  static void @@ -822,7 +822,7 @@ int mt7996_mcu_add_bss_info(struct mt7996_phy *phy,  	if (enable) {  		mt7996_mcu_bss_rfch_tlv(skb, vif, phy); -		mt7996_mcu_bss_bmc_tlv(skb, phy); +		mt7996_mcu_bss_bmc_tlv(skb, vif, phy);  		mt7996_mcu_bss_ra_tlv(skb, vif, phy);  		mt7996_mcu_bss_txcmd_tlv(skb, true); @@ -1022,6 +1022,7 @@ mt7996_mcu_sta_amsdu_tlv(struct mt7996_dev *dev, struct sk_buff *skb,  	struct tlv *tlv;  	if (vif->type != NL80211_IFTYPE_STATION && +	    vif->type != NL80211_IFTYPE_MESH_POINT &&  	    vif->type != NL80211_IFTYPE_AP)  		return; @@ -1053,7 +1054,6 @@ static inline bool  mt7996_is_ebf_supported(struct mt7996_phy *phy, struct ieee80211_vif *vif,  			struct ieee80211_sta *sta, bool bfee)  { -	struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;  	int sts = hweight16(phy->mt76->chainmask);  	if (vif->type != NL80211_IFTYPE_STATION && @@ -1068,10 +1068,10 @@ mt7996_is_ebf_supported(struct mt7996_phy *phy, struct ieee80211_vif *vif,  		struct ieee80211_eht_cap_elem_fixed *pe = &pc->eht_cap_elem;  		if (bfee) -			return mvif->cap.eht_su_ebfee && +			return vif->bss_conf.eht_su_beamformee &&  			       EHT_PHY(CAP0_SU_BEAMFORMEE, pe->phy_cap_info[0]);  		else -			return mvif->cap.eht_su_ebfer && +			return vif->bss_conf.eht_su_beamformer &&  			       EHT_PHY(CAP0_SU_BEAMFORMER, pe->phy_cap_info[0]);  	} @@ -1079,10 +1079,10 @@ mt7996_is_ebf_supported(struct mt7996_phy *phy, struct ieee80211_vif *vif,  		struct ieee80211_he_cap_elem *pe = &sta->deflink.he_cap.he_cap_elem;  		if (bfee) -			return mvif->cap.he_su_ebfee && +			return vif->bss_conf.he_su_beamformee &&  			       HE_PHY(CAP3_SU_BEAMFORMER, pe->phy_cap_info[3]);  		else -			return mvif->cap.he_su_ebfer && +			return vif->bss_conf.he_su_beamformer &&  			       HE_PHY(CAP4_SU_BEAMFORMEE, pe->phy_cap_info[4]);  	} @@ -1090,10 +1090,10 @@ mt7996_is_ebf_supported(struct mt7996_phy *phy, struct ieee80211_vif *vif,  		u32 cap = sta->deflink.vht_cap.cap;  		if (bfee) -			return mvif->cap.vht_su_ebfee && +			return vif->bss_conf.vht_su_beamformee &&  			       (cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE);  		else -			return mvif->cap.vht_su_ebfer && +			return vif->bss_conf.vht_su_beamformer &&  			       (cap & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE);  	} @@ -1471,6 +1471,12 @@ mt7996_mcu_sta_hdr_trans_tlv(struct mt7996_dev *dev, struct sk_buff *skb,  		hdr_trans->to_ds = true;  		hdr_trans->from_ds = true;  	} + +	if (vif->type == NL80211_IFTYPE_MESH_POINT) { +		hdr_trans->to_ds = true; +		hdr_trans->from_ds = true; +		hdr_trans->mesh = true; +	}  }  static enum mcu_mmps_mode @@ -1572,7 +1578,7 @@ mt7996_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7996_dev *dev,  			cap |= STA_CAP_TX_STBC;  		if (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_RX_STBC)  			cap |= STA_CAP_RX_STBC; -		if (mvif->cap.ht_ldpc && +		if (vif->bss_conf.ht_ldpc &&  		    (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_LDPC_CODING))  			cap |= STA_CAP_LDPC; @@ -1598,7 +1604,7 @@ mt7996_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7996_dev *dev,  			cap |= STA_CAP_VHT_TX_STBC;  		if (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_RXSTBC_1)  			cap |= STA_CAP_VHT_RX_STBC; -		if (mvif->cap.vht_ldpc && +		if (vif->bss_conf.vht_ldpc &&  		    (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC))  			cap |= STA_CAP_VHT_LDPC; @@ -1694,8 +1700,8 @@ int mt7996_mcu_add_sta(struct mt7996_dev *dev, struct ieee80211_vif *vif,  		return PTR_ERR(skb);  	/* starec basic */ -	mt76_connac_mcu_sta_basic_tlv(skb, vif, sta, enable, -			!rcu_access_pointer(dev->mt76.wcid[msta->wcid.idx])); +	mt76_connac_mcu_sta_basic_tlv(&dev->mt76, skb, vif, sta, enable, +				      !rcu_access_pointer(dev->mt76.wcid[msta->wcid.idx]));  	if (!enable)  		goto out; @@ -1906,105 +1912,10 @@ mt7996_mcu_beacon_cont(struct mt7996_dev *dev, struct ieee80211_vif *vif,  	}  	buf = (u8 *)bcn + sizeof(*bcn) - MAX_BEACON_SIZE; -	mt7996_mac_write_txwi(dev, (__le32 *)buf, skb, wcid, 0, NULL, +	mt7996_mac_write_txwi(dev, (__le32 *)buf, skb, wcid, NULL, 0, 0,  			      BSS_CHANGED_BEACON); -	memcpy(buf + MT_TXD_SIZE, skb->data, skb->len); -} -static void -mt7996_mcu_beacon_check_caps(struct mt7996_phy *phy, struct ieee80211_vif *vif, -			     struct sk_buff *skb) -{ -	struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; -	struct mt7996_vif_cap *vc = &mvif->cap; -	const struct ieee80211_eht_cap_elem_fixed *eht; -	const struct ieee80211_he_cap_elem *he; -	const struct ieee80211_vht_cap *vht; -	const struct ieee80211_ht_cap *ht; -	struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; -	const u8 *ie; -	u32 len, bc; - -	/* Check missing configuration options to allow AP mode in mac80211 -	 * to remain in sync with hostapd settings, and get a subset of -	 * beacon and hardware capabilities. -	 */ -	if (WARN_ON_ONCE(skb->len <= (mgmt->u.beacon.variable - skb->data))) -		return; - -	memset(vc, 0, sizeof(*vc)); - -	len = skb->len - (mgmt->u.beacon.variable - skb->data); - -	ie = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, mgmt->u.beacon.variable, -			      len); -	if (ie && ie[1] >= sizeof(*ht)) { -		ht = (void *)(ie + 2); -		vc->ht_ldpc |= !!(le16_to_cpu(ht->cap_info) & -				  IEEE80211_HT_CAP_LDPC_CODING); -	} - -	ie = cfg80211_find_ie(WLAN_EID_VHT_CAPABILITY, mgmt->u.beacon.variable, -			      len); -	if (ie && ie[1] >= sizeof(*vht)) { -		u32 pc = phy->mt76->sband_5g.sband.vht_cap.cap; - -		vht = (void *)(ie + 2); -		bc = le32_to_cpu(vht->vht_cap_info); - -		vc->vht_ldpc |= !!(bc & IEEE80211_VHT_CAP_RXLDPC); -		vc->vht_su_ebfer = -			(bc & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE) && -			(pc & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE); -		vc->vht_su_ebfee = -			(bc & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE) && -			(pc & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE); -		vc->vht_mu_ebfer = -			(bc & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE) && -			(pc & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE); -		vc->vht_mu_ebfee = -			(bc & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE) && -			(pc & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE); -	} - -	ie = cfg80211_find_ext_ie(WLAN_EID_EXT_HE_CAPABILITY, -				  mgmt->u.beacon.variable, len); -	if (ie && ie[1] >= sizeof(*he) + 1) { -		const struct ieee80211_sta_he_cap *pc = -			mt76_connac_get_he_phy_cap(phy->mt76, vif); -		const struct ieee80211_he_cap_elem *pe = &pc->he_cap_elem; - -		he = (void *)(ie + 3); - -		vc->he_ldpc = -			HE_PHY(CAP1_LDPC_CODING_IN_PAYLOAD, pe->phy_cap_info[1]); -		vc->he_su_ebfer = -			HE_PHY(CAP3_SU_BEAMFORMER, he->phy_cap_info[3]) && -			HE_PHY(CAP3_SU_BEAMFORMER, pe->phy_cap_info[3]); -		vc->he_su_ebfee = -			HE_PHY(CAP4_SU_BEAMFORMEE, he->phy_cap_info[4]) && -			HE_PHY(CAP4_SU_BEAMFORMEE, pe->phy_cap_info[4]); -		vc->he_mu_ebfer = -			HE_PHY(CAP4_MU_BEAMFORMER, he->phy_cap_info[4]) && -			HE_PHY(CAP4_MU_BEAMFORMER, pe->phy_cap_info[4]); -	} - -	ie = cfg80211_find_ext_ie(WLAN_EID_EXT_EHT_CAPABILITY, -				  mgmt->u.beacon.variable, len); -	if (ie && ie[1] >= sizeof(*eht) + 1) { -		const struct ieee80211_sta_eht_cap *pc = -			mt76_connac_get_eht_phy_cap(phy->mt76, vif); -		const struct ieee80211_eht_cap_elem_fixed *pe = &pc->eht_cap_elem; - -		eht = (void *)(ie + 3); - -		vc->eht_su_ebfer = -			EHT_PHY(CAP0_SU_BEAMFORMER, eht->phy_cap_info[0]) && -			EHT_PHY(CAP0_SU_BEAMFORMER, pe->phy_cap_info[0]); -		vc->eht_su_ebfee = -			EHT_PHY(CAP0_SU_BEAMFORMEE, eht->phy_cap_info[0]) && -			EHT_PHY(CAP0_SU_BEAMFORMEE, pe->phy_cap_info[0]); -	} +	memcpy(buf + MT_TXD_SIZE, skb->data, skb->len);  }  int mt7996_mcu_add_beacon(struct ieee80211_hw *hw, @@ -2045,8 +1956,6 @@ int mt7996_mcu_add_beacon(struct ieee80211_hw *hw,  	info = IEEE80211_SKB_CB(skb);  	info->hw_queue |= FIELD_PREP(MT_TX_HW_QUEUE_PHY, phy->mt76->band_idx); -	mt7996_mcu_beacon_check_caps(phy, vif, skb); -  	mt7996_mcu_beacon_cont(dev, vif, rskb, skb, bcn, &offs);  	/* TODO: subtag - 11v MBSSID */  	mt7996_mcu_beacon_cntdwn(vif, rskb, skb, &offs); @@ -2115,8 +2024,7 @@ int mt7996_mcu_beacon_inband_discov(struct mt7996_dev *dev,  	buf = (u8 *)tlv + sizeof(*discov) - MAX_INBAND_FRAME_SIZE; -	mt7996_mac_write_txwi(dev, (__le32 *)buf, skb, wcid, 0, NULL, -			      changed); +	mt7996_mac_write_txwi(dev, (__le32 *)buf, skb, wcid, NULL, 0, 0, changed);  	memcpy(buf + MT_TXD_SIZE, skb->data, skb->len); @@ -2523,17 +2431,10 @@ mt7996_mcu_init_rx_airtime(struct mt7996_dev *dev)  				     MCU_WM_UNI_CMD(VOW), true);  } -int mt7996_mcu_init(struct mt7996_dev *dev) +int mt7996_mcu_init_firmware(struct mt7996_dev *dev)  { -	static const struct mt76_mcu_ops mt7996_mcu_ops = { -		.headroom = sizeof(struct mt76_connac2_mcu_txd), /* reuse */ -		.mcu_skb_send_msg = mt7996_mcu_send_message, -		.mcu_parse_response = mt7996_mcu_parse_response, -	};  	int ret; -	dev->mt76.mcu_ops = &mt7996_mcu_ops; -  	/* force firmware operation mode into normal state,  	 * which should be set before firmware download stage.  	 */ @@ -2574,6 +2475,19 @@ int mt7996_mcu_init(struct mt7996_dev *dev)  				 MCU_WA_PARAM_RED, 0, 0);  } +int mt7996_mcu_init(struct mt7996_dev *dev) +{ +	static const struct mt76_mcu_ops mt7996_mcu_ops = { +		.headroom = sizeof(struct mt76_connac2_mcu_txd), /* reuse */ +		.mcu_skb_send_msg = mt7996_mcu_send_message, +		.mcu_parse_response = mt7996_mcu_parse_response, +	}; + +	dev->mt76.mcu_ops = &mt7996_mcu_ops; + +	return mt7996_mcu_init_firmware(dev); +} +  void mt7996_mcu_exit(struct mt7996_dev *dev)  {  	mt7996_mcu_restart(&dev->mt76); @@ -3133,7 +3047,7 @@ int mt7996_mcu_get_chip_config(struct mt7996_dev *dev, u32 *cap)  			break;  		default:  			break; -		}; +		}  		buf += le16_to_cpu(tlv->len);  	} @@ -3576,32 +3490,6 @@ int mt7996_mcu_twt_agrt_update(struct mt7996_dev *dev,  				 &req, sizeof(req), true);  } -void mt7996_mcu_set_pm(void *priv, u8 *mac, struct ieee80211_vif *vif) -{ -#define EXIT_PM_STATE	0 -#define ENTER_PM_STATE	1 -	struct ieee80211_hw *hw = priv; -	struct mt7996_dev *dev = mt7996_hw_dev(hw); -	struct mt7996_phy *phy = mt7996_hw_phy(hw); -	struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; -	struct bss_power_save *ps; -	struct sk_buff *skb; -	struct tlv *tlv; -	bool running = test_bit(MT76_STATE_RUNNING, &phy->mt76->state); - -	skb = __mt7996_mcu_alloc_bss_req(&dev->mt76, &mvif->mt76, -					 MT7996_BSS_UPDATE_MAX_SIZE); -	if (IS_ERR(skb)) -		return; - -	tlv = mt7996_mcu_add_uni_tlv(skb, UNI_BSS_INFO_PS, sizeof(*ps)); -	ps = (struct bss_power_save *)tlv; -	ps->profile = running ? EXIT_PM_STATE : ENTER_PM_STATE; - -	mt76_mcu_skb_send_msg(&dev->mt76, skb, -			      MCU_WMWA_UNI_CMD(BSS_INFO_UPDATE), true); -} -  int mt7996_mcu_set_rts_thresh(struct mt7996_phy *phy, u32 val)  {  	struct { @@ -3733,6 +3621,22 @@ int mt7996_mcu_rf_regval(struct mt7996_dev *dev, u32 regidx, u32 *val, bool set)  	return 0;  } +int mt7996_mcu_trigger_assert(struct mt7996_dev *dev) +{ +	struct { +		__le16 tag; +		__le16 len; +		u8 enable; +		u8 rsv[3]; +	} __packed req = { +		.len = cpu_to_le16(sizeof(req) - 4), +		.enable = true, +	}; + +	return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(ASSERT_DUMP), +				 &req, sizeof(req), false); +} +  int mt7996_mcu_set_rro(struct mt7996_dev *dev, u16 tag, u8 val)  {  	struct {  |