Commit 33eb14f1 authored by Felix Fietkau's avatar Felix Fietkau
Browse files

wifi: mt76: mt7915: use mac80211 .sta_state op

Allows adding stations before assoc, though they are not passed to the
firmware yet at that point.

Link: https://patch.msgid.link/20240827093011.18621-12-nbd@nbd.name


Signed-off-by: default avatarFelix Fietkau <nbd@nbd.name>
parent 17b0f68a
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -347,6 +347,7 @@ struct mt76_wcid {
	u8 hw_key_idx2;

	u8 sta:1;
	u8 sta_disabled:1;
	u8 amsdu:1;
	u8 phy_idx:2;
	u8 link_id:4;
+1 −1
Original line number Diff line number Diff line
@@ -283,7 +283,7 @@ __mt76_connac_mcu_alloc_sta_req(struct mt76_dev *dev, struct mt76_vif *mvif,
	};
	struct sk_buff *skb;

	if (wcid && !wcid->sta)
	if (wcid && !wcid->sta && !wcid->sta_disabled)
		hdr.muar_idx = 0xe;

	mt76_connac_mcu_get_wlan_idx(dev, wcid, &hdr.wlan_idx_lo,
+65 −40
Original line number Diff line number Diff line
@@ -274,7 +274,7 @@ static int mt7915_add_interface(struct ieee80211_hw *hw,
	memset(&mvif->cap, -1, sizeof(mvif->cap));

	mt7915_mcu_add_bss_info(phy, vif, true);
	mt7915_mcu_add_sta(dev, vif, NULL, true);
	mt7915_mcu_add_sta(dev, vif, NULL, CONN_STATE_PORT_SECURE, true);
	rcu_assign_pointer(dev->mt76.wcid[idx], &mvif->sta.wcid);

out:
@@ -293,7 +293,7 @@ static void mt7915_remove_interface(struct ieee80211_hw *hw,
	int idx = msta->wcid.idx;

	mt7915_mcu_add_bss_info(phy, vif, false);
	mt7915_mcu_add_sta(dev, vif, NULL, false);
	mt7915_mcu_add_sta(dev, vif, NULL, CONN_STATE_DISCONNECT, false);
	mt76_wcid_mask_clear(dev->mt76.wcid_mask, mvif->sta.wcid.idx);

	mutex_lock(&dev->mt76.mutex);
@@ -366,6 +366,9 @@ static int mt7915_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
	int idx = key->keyidx;
	int err = 0;

	if (sta && !wcid->sta)
		return -EOPNOTSUPP;

	/* The hardware does not support per-STA RX GTK, fallback
	 * to software mode for these.
	 */
@@ -623,7 +626,7 @@ static void mt7915_bss_info_changed(struct ieee80211_hw *hw,
	if (set_bss_info == 1)
		mt7915_mcu_add_bss_info(phy, vif, true);
	if (set_sta == 1)
		mt7915_mcu_add_sta(dev, vif, NULL, true);
		mt7915_mcu_add_sta(dev, vif, NULL, CONN_STATE_PORT_SECURE, false);

	if (changed & BSS_CHANGED_ERP_CTS_PROT)
		mt7915_mac_enable_rtscts(dev, vif, info->use_cts_prot);
@@ -658,7 +661,7 @@ static void mt7915_bss_info_changed(struct ieee80211_hw *hw,
	if (set_bss_info == 0)
		mt7915_mcu_add_bss_info(phy, vif, false);
	if (set_sta == 0)
		mt7915_mcu_add_sta(dev, vif, NULL, false);
		mt7915_mcu_add_sta(dev, vif, NULL, CONN_STATE_DISCONNECT, false);

	mutex_unlock(&dev->mt76.mutex);
}
@@ -696,7 +699,7 @@ mt7915_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
	err = mt7915_mcu_add_bss_info(phy, vif, true);
	if (err)
		goto out;
	err = mt7915_mcu_add_sta(dev, vif, NULL, true);
	err = mt7915_mcu_add_sta(dev, vif, NULL, CONN_STATE_PORT_SECURE, false);
out:
	mutex_unlock(&dev->mt76.mutex);

@@ -710,7 +713,7 @@ mt7915_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
	struct mt7915_dev *dev = mt7915_hw_dev(hw);

	mutex_lock(&dev->mt76.mutex);
	mt7915_mcu_add_sta(dev, vif, NULL, false);
	mt7915_mcu_add_sta(dev, vif, NULL, CONN_STATE_DISCONNECT, false);
	mutex_unlock(&dev->mt76.mutex);
}

@@ -733,8 +736,7 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
	struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
	struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
	bool ext_phy = mvif->phy != &dev->phy;
	int ret, idx;
	u32 addr;
	int idx;

	idx = mt76_wcid_alloc(dev->mt76.wcid_mask, MT7915_WTBL_STA);
	if (idx < 0)
@@ -743,25 +745,61 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
	INIT_LIST_HEAD(&msta->rc_list);
	INIT_LIST_HEAD(&msta->wcid.poll_list);
	msta->vif = mvif;
	msta->wcid.sta = 1;
	msta->wcid.sta_disabled = 1;
	msta->wcid.idx = idx;
	msta->wcid.phy_idx = ext_phy;
	msta->wcid.tx_info |= MT_WCID_TX_INFO_SET;
	msta->jiffies = jiffies;

	ewma_avg_signal_init(&msta->avg_ack_signal);

	mt7915_mac_wtbl_update(dev, idx,
			       MT_WTBL_UPDATE_ADM_COUNT_CLEAR);
	mt7915_mcu_add_sta(dev, vif, sta, CONN_STATE_DISCONNECT, true);

	return 0;
}

int mt7915_mac_sta_event(struct mt76_dev *mdev, struct ieee80211_vif *vif,
			 struct ieee80211_sta *sta, enum mt76_sta_event ev)
{
	struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76);
	struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
	int i, ret;
	u32 addr;

	ret = mt7915_mcu_add_sta(dev, vif, sta, true);
	switch (ev) {
	case MT76_STA_EVENT_ASSOC:
		ret = mt7915_mcu_add_sta(dev, vif, sta, CONN_STATE_CONNECT, true);
		if (ret)
			return ret;

		addr = mt7915_mac_wtbl_lmac_addr(dev, msta->wcid.idx, 30);
		mt76_rmw_field(dev, addr, GENMASK(7, 0), 0xa0);

	return mt7915_mcu_add_rate_ctrl(dev, vif, sta, false);
		ret = mt7915_mcu_add_rate_ctrl(dev, vif, sta, false);
		if (ret)
			return ret;

		msta->wcid.tx_info |= MT_WCID_TX_INFO_SET;
		msta->wcid.sta = 1;
		msta->wcid.sta_disabled = 0;

		return 0;

	case MT76_STA_EVENT_AUTHORIZE:
		return mt7915_mcu_add_sta(dev, vif, sta, CONN_STATE_PORT_SECURE, false);

	case MT76_STA_EVENT_DISASSOC:
		for (i = 0; i < ARRAY_SIZE(msta->twt.flow); i++)
			mt7915_mac_twt_teardown_flow(dev, msta, i);

		mt7915_mcu_add_sta(dev, vif, sta, CONN_STATE_DISCONNECT, false);
		msta->wcid.sta_disabled = 1;
		msta->wcid.sta = 0;
		return 0;
	}

	return 0;
}

void mt7915_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
@@ -769,16 +807,10 @@ void mt7915_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
{
	struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76);
	struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
	int i;

	mt7915_mcu_add_sta(dev, vif, sta, false);

	mt7915_mac_wtbl_update(dev, msta->wcid.idx,
			       MT_WTBL_UPDATE_ADM_COUNT_CLEAR);

	for (i = 0; i < ARRAY_SIZE(msta->twt.flow); i++)
		mt7915_mac_twt_teardown_flow(dev, msta, i);

	spin_lock_bh(&mdev->sta_poll_lock);
	if (!list_empty(&msta->wcid.poll_list))
		list_del_init(&msta->wcid.poll_list);
@@ -885,22 +917,6 @@ mt7915_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
	return ret;
}

static int
mt7915_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
	       struct ieee80211_sta *sta)
{
	return mt76_sta_state(hw, vif, sta, IEEE80211_STA_NOTEXIST,
			      IEEE80211_STA_NONE);
}

static int
mt7915_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
		  struct ieee80211_sta *sta)
{
	return mt76_sta_state(hw, vif, sta, IEEE80211_STA_NONE,
			      IEEE80211_STA_NOTEXIST);
}

static int
mt7915_get_stats(struct ieee80211_hw *hw,
		 struct ieee80211_low_level_stats *stats)
@@ -1154,6 +1170,10 @@ static void mt7915_sta_rc_update(struct ieee80211_hw *hw,
{
	struct mt7915_phy *phy = mt7915_hw_phy(hw);
	struct mt7915_dev *dev = phy->dev;
	struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;

	if (!msta->wcid.sta)
		return;

	mt7915_sta_rc_work(&changed, sta);
	ieee80211_queue_work(hw, &dev->rc_work);
@@ -1197,6 +1217,9 @@ static void mt7915_sta_set_4addr(struct ieee80211_hw *hw,
	else
		clear_bit(MT_WCID_FLAG_4ADDR, &msta->wcid.flags);

	if (!msta->wcid.sta)
		return;

	mt76_connac_mcu_wtbl_update_hdr_trans(&dev->mt76, vif, sta);
}

@@ -1213,6 +1236,9 @@ static void mt7915_sta_set_decap_offload(struct ieee80211_hw *hw,
	else
		clear_bit(MT_WCID_FLAG_HDR_TRANS, &msta->wcid.flags);

	if (!msta->wcid.sta)
		return;

	mt76_connac_mcu_wtbl_update_hdr_trans(&dev->mt76, vif, sta);
}

@@ -1666,8 +1692,7 @@ const struct ieee80211_ops mt7915_ops = {
	.bss_info_changed = mt7915_bss_info_changed,
	.start_ap = mt7915_start_ap,
	.stop_ap = mt7915_stop_ap,
	.sta_add = mt7915_sta_add,
	.sta_remove = mt7915_sta_remove,
	.sta_state = mt76_sta_state,
	.sta_pre_rcu_remove = mt76_sta_pre_rcu_remove,
	.sta_rc_update = mt7915_sta_rc_update,
	.set_key = mt7915_set_key,
+13 −13
Original line number Diff line number Diff line
@@ -1657,13 +1657,12 @@ mt7915_mcu_add_group(struct mt7915_dev *dev, struct ieee80211_vif *vif,
}

int mt7915_mcu_add_sta(struct mt7915_dev *dev, struct ieee80211_vif *vif,
		       struct ieee80211_sta *sta, bool enable)
		       struct ieee80211_sta *sta, int conn_state, bool newly)
{
	struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
	struct ieee80211_link_sta *link_sta;
	struct mt7915_sta *msta;
	struct sk_buff *skb;
	int conn_state;
	int ret;

	msta = sta ? (struct mt7915_sta *)sta->drv_priv : &mvif->sta;
@@ -1675,14 +1674,10 @@ int mt7915_mcu_add_sta(struct mt7915_dev *dev, struct ieee80211_vif *vif,
		return PTR_ERR(skb);

	/* starec basic */
	conn_state = enable ? CONN_STATE_PORT_SECURE : CONN_STATE_DISCONNECT;
	mt76_connac_mcu_sta_basic_tlv(&dev->mt76, skb, vif, link_sta, conn_state,
				      !rcu_access_pointer(dev->mt76.wcid[msta->wcid.idx]));
	if (!enable)
		goto out;

	mt76_connac_mcu_sta_basic_tlv(&dev->mt76, skb, vif, link_sta,
				      conn_state, newly);
	/* tag order is in accordance with firmware dependency. */
	if (sta) {
	if (sta && conn_state != CONN_STATE_DISCONNECT) {
		/* starec bfer */
		mt7915_mcu_sta_bfer_tlv(dev, skb, vif, sta);
		/* starec ht */
@@ -1693,11 +1688,16 @@ int mt7915_mcu_add_sta(struct mt7915_dev *dev, struct ieee80211_vif *vif,
		mt76_connac_mcu_sta_uapsd(skb, vif, sta);
	}

	if (newly || conn_state != CONN_STATE_DISCONNECT) {
		ret = mt7915_mcu_sta_wtbl_tlv(dev, skb, vif, sta);
		if (ret) {
			dev_kfree_skb(skb);
			return ret;
		}
	}

	if (conn_state == CONN_STATE_DISCONNECT)
		goto out;

	if (sta) {
		/* starec amsdu */
+1 −0
Original line number Diff line number Diff line
@@ -927,6 +927,7 @@ struct mt7915_dev *mt7915_mmio_probe(struct device *pdev,
		.rx_check = mt7915_rx_check,
		.rx_poll_complete = mt7915_rx_poll_complete,
		.sta_add = mt7915_mac_sta_add,
		.sta_event = mt7915_mac_sta_event,
		.sta_remove = mt7915_mac_sta_remove,
		.update_survey = mt7915_update_channel,
		.set_channel = mt7915_set_channel,
Loading