Commit e151d71e authored by Felix Fietkau's avatar Felix Fietkau
Browse files

mt76: mt7915: add encap offload for 4-address mode stations



Enable MWDS mode in firmware as well and fix txp->rept_wds_wcid for wcid >= 255

Signed-off-by: default avatarFelix Fietkau <nbd@nbd.name>
parent 55f7c9b0
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -185,6 +185,7 @@ struct mt76_queue_ops {
enum mt76_wcid_flags {
	MT_WCID_FLAG_CHECK_PS,
	MT_WCID_FLAG_PS,
	MT_WCID_FLAG_4ADDR,
};

#define MT76_N_WCIDS 288
+5 −2
Original line number Diff line number Diff line
@@ -799,7 +799,7 @@ int mt7915_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
	tx_info->buf[1].skip_unmap = true;
	tx_info->nbuf = MT_CT_DMA_BUF_NUM;

	txp->flags = cpu_to_le16(MT_CT_INFO_APPLY_TXD);
	txp->flags = cpu_to_le16(MT_CT_INFO_APPLY_TXD | MT_CT_INFO_FROM_HOST);

	if (!key)
		txp->flags |= cpu_to_le16(MT_CT_INFO_NONE_CIPHER_FRAME);
@@ -824,7 +824,10 @@ int mt7915_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
		return id;

	txp->token = cpu_to_le16(id);
	txp->rept_wds_wcid = 0xff;
	if (test_bit(MT_WCID_FLAG_4ADDR, &wcid->flags))
		txp->rept_wds_wcid = cpu_to_le16(wcid->idx);
	else
		txp->rept_wds_wcid = cpu_to_le16(0x3ff);
	tx_info->skb = DMA_DUMMY_DATA;

	return 0;
+2 −2
Original line number Diff line number Diff line
@@ -160,6 +160,7 @@ enum tx_mcu_port_q_idx {
#define MT_CT_INFO_MGMT_FRAME		BIT(2)
#define MT_CT_INFO_NONE_CIPHER_FRAME	BIT(3)
#define MT_CT_INFO_HSR2_TX		BIT(4)
#define MT_CT_INFO_FROM_HOST		BIT(7)

#define MT_TXD_SIZE			(8 * 4)

@@ -255,8 +256,7 @@ struct mt7915_txp {
	__le16 flags;
	__le16 token;
	u8 bss_idx;
	u8 rept_wds_wcid;
	u8 rsv;
	__le16 rept_wds_wcid;
	u8 nbuf;
	__le32 buf[MT_TXP_MAX_BUF_NUM];
	__le16 len[MT_TXP_MAX_BUF_NUM];
+19 −0
Original line number Diff line number Diff line
@@ -173,6 +173,8 @@ static int mt7915_add_interface(struct ieee80211_hw *hw,
		mtxq->wcid = &mvif->sta.wcid;
	}

	vif->offload_flags |= IEEE80211_OFFLOAD_ENCAP_4ADDR;

out:
	mutex_unlock(&dev->mt76.mutex);

@@ -804,6 +806,22 @@ mt7915_sta_rc_update(struct ieee80211_hw *hw,
	ieee80211_queue_work(hw, &dev->rc_work);
}

static void mt7915_sta_set_4addr(struct ieee80211_hw *hw,
				 struct ieee80211_vif *vif,
				 struct ieee80211_sta *sta,
				 bool enabled)
{
	struct mt7915_dev *dev = mt7915_hw_dev(hw);
	struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;

	if (enabled)
		set_bit(MT_WCID_FLAG_4ADDR, &msta->wcid.flags);
	else
		clear_bit(MT_WCID_FLAG_4ADDR, &msta->wcid.flags);

	mt7915_mcu_sta_update_hdr_trans(dev, vif, sta);
}

const struct ieee80211_ops mt7915_ops = {
	.tx = mt7915_tx,
	.start = mt7915_start,
@@ -835,6 +853,7 @@ const struct ieee80211_ops mt7915_ops = {
	.set_antenna = mt7915_set_antenna,
	.set_coverage_class = mt7915_set_coverage_class,
	.sta_statistics = mt7915_sta_statistics,
	.sta_set_4addr = mt7915_sta_set_4addr,
#ifdef CONFIG_MAC80211_DEBUGFS
	.sta_add_debugfs = mt7915_sta_add_debugfs,
#endif
+46 −1
Original line number Diff line number Diff line
@@ -276,6 +276,9 @@ static int __mt7915_mcu_msg_send(struct mt7915_dev *dev, struct sk_buff *skb,
			mcu_txd->set_query = MCU_Q_SET;
	}

	if (cmd == MCU_EXT_CMD_MWDS_SUPPORT)
		mcu_txd->s2d_index = MCU_S2D_H2C;
	else
		mcu_txd->s2d_index = MCU_S2D_H2N;
	WARN_ON(cmd == MCU_EXT_CMD_EFUSE_ACCESS &&
		mcu_txd->set_query != MCU_Q_QUERY);
@@ -1693,6 +1696,7 @@ mt7915_mcu_wtbl_hdr_trans_tlv(struct sk_buff *skb, struct ieee80211_vif *vif,
			      struct ieee80211_sta *sta,
			      void *sta_wtbl, void *wtbl_tlv)
{
	struct mt7915_sta *msta;
	struct wtbl_hdr_trans *htr = NULL;
	struct tlv *tlv;

@@ -1704,6 +1708,33 @@ mt7915_mcu_wtbl_hdr_trans_tlv(struct sk_buff *skb, struct ieee80211_vif *vif,
		htr->to_ds = true;
	else
		htr->from_ds = true;

	if (!sta)
		return;

	msta = (struct mt7915_sta *)sta->drv_priv;
	if (test_bit(MT_WCID_FLAG_4ADDR, &msta->wcid.flags)) {
		htr->to_ds = true;
		htr->from_ds = true;
	}
}

int mt7915_mcu_sta_update_hdr_trans(struct mt7915_dev *dev,
				    struct ieee80211_vif *vif,
				    struct ieee80211_sta *sta)
{
	struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
	struct wtbl_req_hdr *wtbl_hdr;
	struct sk_buff *skb;

	skb = mt76_mcu_msg_alloc(&dev->mt76, NULL, MT7915_WTBL_UPDATE_MAX_SIZE);
	if (!skb)
		return -ENOMEM;

	wtbl_hdr = mt7915_mcu_alloc_wtbl_req(dev, msta, WTBL_SET, NULL, &skb);
	mt7915_mcu_wtbl_hdr_trans_tlv(skb, vif, sta, NULL, wtbl_hdr);

	return __mt76_mcu_skb_send_msg(&dev->mt76, skb, MCU_EXT_CMD_WTBL_UPDATE, true);
}

int mt7915_mcu_add_smps(struct mt7915_dev *dev, struct ieee80211_vif *vif,
@@ -2867,6 +2898,19 @@ int mt7915_mcu_fw_dbg_ctrl(struct mt7915_dev *dev, u32 module, u8 level)
				   &data, sizeof(data), false);
}

static int mt7915_mcu_set_mwds(struct mt7915_dev *dev, bool enabled)
{
	struct {
		u8 enable;
		u8 _rsv[3];
	} __packed req = {
		.enable = enabled
	};

	return __mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_MWDS_SUPPORT,
				   &req, sizeof(req), false);
}

int mt7915_mcu_init(struct mt7915_dev *dev)
{
	static const struct mt76_mcu_ops mt7915_mcu_ops = {
@@ -2889,6 +2933,7 @@ int mt7915_mcu_init(struct mt7915_dev *dev)

	set_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state);
	mt7915_mcu_fw_log_2_host(dev, 0);
	mt7915_mcu_set_mwds(dev, 1);

	return 0;
}
Loading