Commit 0880d408 authored by Lorenzo Bianconi's avatar Lorenzo Bianconi Committed by Felix Fietkau
Browse files

mt76: connac: move mt76_connac2_reverse_frag0_hdr_trans in mt76-connac module



mt76_connac2_reverse_frag0_hdr_trans routine is shared between mt7921
and mt7915e drivers.

Signed-off-by: default avatarLorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: default avatarFelix Fietkau <nbd@nbd.name>
parent f71662de
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -256,5 +256,7 @@ bool mt76_connac2_mac_add_txs_skb(struct mt76_dev *dev, struct mt76_wcid *wcid,
void mt76_connac2_mac_decode_he_radiotap(struct mt76_dev *dev,
					 struct sk_buff *skb,
					 __le32 *rxv, u32 mode);
int mt76_connac2_reverse_frag0_hdr_trans(struct ieee80211_vif *vif,
					 struct sk_buff *skb, u16 hdr_offset);

#endif /* __MT76_CONNAC_H */
+86 −0
Original line number Diff line number Diff line
@@ -164,6 +164,92 @@ enum {

#define MT_TXS4_TIMESTAMP		GENMASK(31, 0)

/* RXD DW1 */
#define MT_RXD1_NORMAL_WLAN_IDX		GENMASK(9, 0)
#define MT_RXD1_NORMAL_GROUP_1		BIT(11)
#define MT_RXD1_NORMAL_GROUP_2		BIT(12)
#define MT_RXD1_NORMAL_GROUP_3		BIT(13)
#define MT_RXD1_NORMAL_GROUP_4		BIT(14)
#define MT_RXD1_NORMAL_GROUP_5		BIT(15)
#define MT_RXD1_NORMAL_SEC_MODE		GENMASK(20, 16)
#define MT_RXD1_NORMAL_KEY_ID		GENMASK(22, 21)
#define MT_RXD1_NORMAL_CM		BIT(23)
#define MT_RXD1_NORMAL_CLM		BIT(24)
#define MT_RXD1_NORMAL_ICV_ERR		BIT(25)
#define MT_RXD1_NORMAL_TKIP_MIC_ERR	BIT(26)
#define MT_RXD1_NORMAL_FCS_ERR		BIT(27)
#define MT_RXD1_NORMAL_BAND_IDX		BIT(28)
#define MT_RXD1_NORMAL_SPP_EN		BIT(29)
#define MT_RXD1_NORMAL_ADD_OM		BIT(30)
#define MT_RXD1_NORMAL_SEC_DONE		BIT(31)

/* RXD DW2 */
#define MT_RXD2_NORMAL_BSSID		GENMASK(5, 0)
#define MT_RXD2_NORMAL_CO_ANT		BIT(6)
#define MT_RXD2_NORMAL_BF_CQI		BIT(7)
#define MT_RXD2_NORMAL_MAC_HDR_LEN	GENMASK(12, 8)
#define MT_RXD2_NORMAL_HDR_TRANS	BIT(13)
#define MT_RXD2_NORMAL_HDR_OFFSET	GENMASK(15, 14)
#define MT_RXD2_NORMAL_TID		GENMASK(19, 16)
#define MT_RXD2_NORMAL_MU_BAR		BIT(21)
#define MT_RXD2_NORMAL_SW_BIT		BIT(22)
#define MT_RXD2_NORMAL_AMSDU_ERR	BIT(23)
#define MT_RXD2_NORMAL_MAX_LEN_ERROR	BIT(24)
#define MT_RXD2_NORMAL_HDR_TRANS_ERROR	BIT(25)
#define MT_RXD2_NORMAL_INT_FRAME	BIT(26)
#define MT_RXD2_NORMAL_FRAG		BIT(27)
#define MT_RXD2_NORMAL_NULL_FRAME	BIT(28)
#define MT_RXD2_NORMAL_NDATA		BIT(29)
#define MT_RXD2_NORMAL_NON_AMPDU	BIT(30)
#define MT_RXD2_NORMAL_BF_REPORT	BIT(31)

/* RXD DW4 */
#define MT_RXD4_NORMAL_PAYLOAD_FORMAT	GENMASK(1, 0)
#define MT_RXD4_FIRST_AMSDU_FRAME	GENMASK(1, 0)
#define MT_RXD4_MID_AMSDU_FRAME		BIT(1)
#define MT_RXD4_LAST_AMSDU_FRAME	BIT(0)
#define MT_RXD4_NORMAL_PATTERN_DROP	BIT(9)
#define MT_RXD4_NORMAL_CLS		BIT(10)
#define MT_RXD4_NORMAL_OFLD		GENMASK(12, 11)
#define MT_RXD4_NORMAL_MAGIC_PKT	BIT(13)
#define MT_RXD4_NORMAL_WOL		GENMASK(18, 14)
#define MT_RXD4_NORMAL_CLS_BITMAP	GENMASK(28, 19)
#define MT_RXD3_NORMAL_PF_MODE		BIT(29)
#define MT_RXD3_NORMAL_PF_STS		GENMASK(31, 30)

#define MT_RXV_HDR_BAND_IDX		BIT(24)

/* RXD DW3 */
#define MT_RXD3_NORMAL_RXV_SEQ		GENMASK(7, 0)
#define MT_RXD3_NORMAL_CH_FREQ		GENMASK(15, 8)
#define MT_RXD3_NORMAL_ADDR_TYPE	GENMASK(17, 16)
#define MT_RXD3_NORMAL_U2M		BIT(0)
#define MT_RXD3_NORMAL_HTC_VLD		BIT(0)
#define MT_RXD3_NORMAL_TSF_COMPARE_LOSS	BIT(19)
#define MT_RXD3_NORMAL_BEACON_MC	BIT(20)
#define MT_RXD3_NORMAL_BEACON_UC	BIT(21)
#define MT_RXD3_NORMAL_AMSDU		BIT(22)
#define MT_RXD3_NORMAL_MESH		BIT(23)
#define MT_RXD3_NORMAL_MHCP		BIT(24)
#define MT_RXD3_NORMAL_NO_INFO_WB	BIT(25)
#define MT_RXD3_NORMAL_DISABLE_RX_HDR_TRANS	BIT(26)
#define MT_RXD3_NORMAL_POWER_SAVE_STAT	BIT(27)
#define MT_RXD3_NORMAL_MORE		BIT(28)
#define MT_RXD3_NORMAL_UNWANT		BIT(29)
#define MT_RXD3_NORMAL_RX_DROP		BIT(30)
#define MT_RXD3_NORMAL_VLAN2ETH		BIT(31)

/* RXD GROUP4 */
#define MT_RXD6_FRAME_CONTROL		GENMASK(15, 0)
#define MT_RXD6_TA_LO			GENMASK(31, 16)

#define MT_RXD7_TA_HI			GENMASK(31, 0)

#define MT_RXD8_SEQ_CTRL		GENMASK(15, 0)
#define MT_RXD8_QOS_CTL			GENMASK(31, 16)

#define MT_RXD9_HT_CONTROL		GENMASK(31, 0)

/* P-RXV DW0 */
#define MT_PRXV_TX_RATE			GENMASK(6, 0)
#define MT_PRXV_TX_DCM			BIT(4)
+76 −0
Original line number Diff line number Diff line
@@ -708,3 +708,79 @@ void mt76_connac2_mac_decode_he_radiotap(struct mt76_dev *dev,
	}
}
EXPORT_SYMBOL_GPL(mt76_connac2_mac_decode_he_radiotap);

/* The HW does not translate the mac header to 802.3 for mesh point */
int mt76_connac2_reverse_frag0_hdr_trans(struct ieee80211_vif *vif,
					 struct sk_buff *skb, u16 hdr_offset)
{
	struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb;
	struct ethhdr *eth_hdr = (struct ethhdr *)(skb->data + hdr_offset);
	__le32 *rxd = (__le32 *)skb->data;
	struct ieee80211_sta *sta;
	struct ieee80211_hdr hdr;
	u16 frame_control;

	if (le32_get_bits(rxd[3], MT_RXD3_NORMAL_ADDR_TYPE) !=
	    MT_RXD3_NORMAL_U2M)
		return -EINVAL;

	if (!(le32_to_cpu(rxd[1]) & MT_RXD1_NORMAL_GROUP_4))
		return -EINVAL;

	sta = container_of((void *)status->wcid, struct ieee80211_sta, drv_priv);

	/* store the info from RXD and ethhdr to avoid being overridden */
	frame_control = le32_get_bits(rxd[6], MT_RXD6_FRAME_CONTROL);
	hdr.frame_control = cpu_to_le16(frame_control);
	hdr.seq_ctrl = cpu_to_le16(le32_get_bits(rxd[8], MT_RXD8_SEQ_CTRL));
	hdr.duration_id = 0;

	ether_addr_copy(hdr.addr1, vif->addr);
	ether_addr_copy(hdr.addr2, sta->addr);
	switch (frame_control & (IEEE80211_FCTL_TODS |
				 IEEE80211_FCTL_FROMDS)) {
	case 0:
		ether_addr_copy(hdr.addr3, vif->bss_conf.bssid);
		break;
	case IEEE80211_FCTL_FROMDS:
		ether_addr_copy(hdr.addr3, eth_hdr->h_source);
		break;
	case IEEE80211_FCTL_TODS:
		ether_addr_copy(hdr.addr3, eth_hdr->h_dest);
		break;
	case IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS:
		ether_addr_copy(hdr.addr3, eth_hdr->h_dest);
		ether_addr_copy(hdr.addr4, eth_hdr->h_source);
		break;
	default:
		break;
	}

	skb_pull(skb, hdr_offset + sizeof(struct ethhdr) - 2);
	if (eth_hdr->h_proto == cpu_to_be16(ETH_P_AARP) ||
	    eth_hdr->h_proto == cpu_to_be16(ETH_P_IPX))
		ether_addr_copy(skb_push(skb, ETH_ALEN), bridge_tunnel_header);
	else if (be16_to_cpu(eth_hdr->h_proto) >= ETH_P_802_3_MIN)
		ether_addr_copy(skb_push(skb, ETH_ALEN), rfc1042_header);
	else
		skb_pull(skb, 2);

	if (ieee80211_has_order(hdr.frame_control))
		memcpy(skb_push(skb, IEEE80211_HT_CTL_LEN), &rxd[9],
		       IEEE80211_HT_CTL_LEN);
	if (ieee80211_is_data_qos(hdr.frame_control)) {
		__le16 qos_ctrl;

		qos_ctrl = cpu_to_le16(le32_get_bits(rxd[8], MT_RXD8_QOS_CTL));
		memcpy(skb_push(skb, IEEE80211_QOS_CTL_LEN), &qos_ctrl,
		       IEEE80211_QOS_CTL_LEN);
	}

	if (ieee80211_has_a4(hdr.frame_control))
		memcpy(skb_push(skb, sizeof(hdr)), &hdr, sizeof(hdr));
	else
		memcpy(skb_push(skb, sizeof(hdr) - 6), &hdr, sizeof(hdr) - 6);

	return 0;
}
EXPORT_SYMBOL_GPL(mt76_connac2_reverse_frag0_hdr_trans);
+13 −84
Original line number Diff line number Diff line
@@ -176,7 +176,7 @@ static void mt7915_mac_sta_poll(struct mt7915_dev *dev)
		/*
		 * We don't support reading GI info from txs packets.
		 * For accurate tx status reporting and AQL improvement,
		 * we need to make sure that flags match so polling GI
		  we need to make sure that flags match so polling GI
		 * from per-sta counters directly.
		 */
		rate = &msta->wcid.rate;
@@ -214,86 +214,6 @@ static void mt7915_mac_sta_poll(struct mt7915_dev *dev)
	rcu_read_unlock();
}

/* The HW does not translate the mac header to 802.3 for mesh point */
static int mt7915_reverse_frag0_hdr_trans(struct sk_buff *skb, u16 hdr_gap)
{
	struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb;
	struct ethhdr *eth_hdr = (struct ethhdr *)(skb->data + hdr_gap);
	struct mt7915_sta *msta = (struct mt7915_sta *)status->wcid;
	__le32 *rxd = (__le32 *)skb->data;
	struct ieee80211_sta *sta;
	struct ieee80211_vif *vif;
	struct ieee80211_hdr hdr;
	u16 frame_control;

	if (le32_get_bits(rxd[3], MT_RXD3_NORMAL_ADDR_TYPE) !=
	    MT_RXD3_NORMAL_U2M)
		return -EINVAL;

	if (!(le32_to_cpu(rxd[1]) & MT_RXD1_NORMAL_GROUP_4))
		return -EINVAL;

	if (!msta || !msta->vif)
		return -EINVAL;

	sta = container_of((void *)msta, struct ieee80211_sta, drv_priv);
	vif = container_of((void *)msta->vif, struct ieee80211_vif, drv_priv);

	/* store the info from RXD and ethhdr to avoid being overridden */
	frame_control = le32_get_bits(rxd[6], MT_RXD6_FRAME_CONTROL);
	hdr.frame_control = cpu_to_le16(frame_control);
	hdr.seq_ctrl = cpu_to_le16(le32_get_bits(rxd[8], MT_RXD8_SEQ_CTRL));
	hdr.duration_id = 0;

	ether_addr_copy(hdr.addr1, vif->addr);
	ether_addr_copy(hdr.addr2, sta->addr);
	switch (frame_control & (IEEE80211_FCTL_TODS |
				 IEEE80211_FCTL_FROMDS)) {
	case 0:
		ether_addr_copy(hdr.addr3, vif->bss_conf.bssid);
		break;
	case IEEE80211_FCTL_FROMDS:
		ether_addr_copy(hdr.addr3, eth_hdr->h_source);
		break;
	case IEEE80211_FCTL_TODS:
		ether_addr_copy(hdr.addr3, eth_hdr->h_dest);
		break;
	case IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS:
		ether_addr_copy(hdr.addr3, eth_hdr->h_dest);
		ether_addr_copy(hdr.addr4, eth_hdr->h_source);
		break;
	default:
		break;
	}

	skb_pull(skb, hdr_gap + sizeof(struct ethhdr) - 2);
	if (eth_hdr->h_proto == cpu_to_be16(ETH_P_AARP) ||
	    eth_hdr->h_proto == cpu_to_be16(ETH_P_IPX))
		ether_addr_copy(skb_push(skb, ETH_ALEN), bridge_tunnel_header);
	else if (be16_to_cpu(eth_hdr->h_proto) >= ETH_P_802_3_MIN)
		ether_addr_copy(skb_push(skb, ETH_ALEN), rfc1042_header);
	else
		skb_pull(skb, 2);

	if (ieee80211_has_order(hdr.frame_control))
		memcpy(skb_push(skb, IEEE80211_HT_CTL_LEN), &rxd[9],
		       IEEE80211_HT_CTL_LEN);
	if (ieee80211_is_data_qos(hdr.frame_control)) {
		__le16 qos_ctrl;

		qos_ctrl = cpu_to_le16(le32_get_bits(rxd[8], MT_RXD8_QOS_CTL));
		memcpy(skb_push(skb, IEEE80211_QOS_CTL_LEN), &qos_ctrl,
		       IEEE80211_QOS_CTL_LEN);
	}

	if (ieee80211_has_a4(hdr.frame_control))
		memcpy(skb_push(skb, sizeof(hdr)), &hdr, sizeof(hdr));
	else
		memcpy(skb_push(skb, sizeof(hdr) - 6), &hdr, sizeof(hdr) - 6);

	return 0;
}

static int
mt7915_mac_fill_rx_rate(struct mt7915_dev *dev,
			struct mt76_rx_status *status,
@@ -414,6 +334,7 @@ mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb)
	bool unicast, insert_ccmp_hdr = false;
	u8 remove_pad, amsdu_info;
	u8 mode = 0, qos_ctl = 0;
	struct mt7915_sta *msta;
	bool hdr_trans;
	u16 hdr_gap;
	u16 seq_ctrl = 0;
@@ -450,8 +371,6 @@ mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb)
	status->wcid = mt7915_rx_get_wcid(dev, idx, unicast);

	if (status->wcid) {
		struct mt7915_sta *msta;

		msta = container_of(status->wcid, struct mt7915_sta, wcid);
		spin_lock_bh(&dev->sta_poll_lock);
		if (list_empty(&msta->poll_list))
@@ -605,8 +524,18 @@ mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb)

	hdr_gap = (u8 *)rxd - skb->data + 2 * remove_pad;
	if (hdr_trans && ieee80211_has_morefrags(fc)) {
		if (mt7915_reverse_frag0_hdr_trans(skb, hdr_gap))
		struct ieee80211_vif *vif;
		int err;

		if (!msta || !msta->vif)
			return -EINVAL;

		vif = container_of((void *)msta->vif, struct ieee80211_vif,
				   drv_priv);
		err = mt76_connac2_reverse_frag0_hdr_trans(vif, skb, hdr_gap);
		if (err)
			return err;

		hdr_trans = false;
	} else {
		int pad_start = 0;
+0 −87
Original line number Diff line number Diff line
@@ -29,93 +29,6 @@ enum rx_pkt_type {
	PKT_TYPE_TXRX_NOTIFY_V0 = 0x18,
};

/* RXD DW1 */
#define MT_RXD1_NORMAL_WLAN_IDX		GENMASK(9, 0)
#define MT_RXD1_NORMAL_GROUP_1		BIT(11)
#define MT_RXD1_NORMAL_GROUP_2		BIT(12)
#define MT_RXD1_NORMAL_GROUP_3		BIT(13)
#define MT_RXD1_NORMAL_GROUP_4		BIT(14)
#define MT_RXD1_NORMAL_GROUP_5		BIT(15)
#define MT_RXD1_NORMAL_SEC_MODE		GENMASK(20, 16)
#define MT_RXD1_NORMAL_KEY_ID		GENMASK(22, 21)
#define MT_RXD1_NORMAL_CM		BIT(23)
#define MT_RXD1_NORMAL_CLM		BIT(24)
#define MT_RXD1_NORMAL_ICV_ERR		BIT(25)
#define MT_RXD1_NORMAL_TKIP_MIC_ERR	BIT(26)
#define MT_RXD1_NORMAL_FCS_ERR		BIT(27)
#define MT_RXD1_NORMAL_BAND_IDX		BIT(28)
#define MT_RXD1_NORMAL_SPP_EN		BIT(29)
#define MT_RXD1_NORMAL_ADD_OM		BIT(30)
#define MT_RXD1_NORMAL_SEC_DONE		BIT(31)

/* RXD DW2 */
#define MT_RXD2_NORMAL_BSSID		GENMASK(5, 0)
#define MT_RXD2_NORMAL_CO_ANT		BIT(6)
#define MT_RXD2_NORMAL_BF_CQI		BIT(7)
#define MT_RXD2_NORMAL_MAC_HDR_LEN	GENMASK(12, 8)
#define MT_RXD2_NORMAL_HDR_TRANS	BIT(13)
#define MT_RXD2_NORMAL_HDR_OFFSET	GENMASK(15, 14)
#define MT_RXD2_NORMAL_TID		GENMASK(19, 16)
#define MT_RXD2_NORMAL_MU_BAR		BIT(21)
#define MT_RXD2_NORMAL_SW_BIT		BIT(22)
#define MT_RXD2_NORMAL_AMSDU_ERR	BIT(23)
#define MT_RXD2_NORMAL_MAX_LEN_ERROR	BIT(24)
#define MT_RXD2_NORMAL_HDR_TRANS_ERROR	BIT(25)
#define MT_RXD2_NORMAL_INT_FRAME	BIT(26)
#define MT_RXD2_NORMAL_FRAG		BIT(27)
#define MT_RXD2_NORMAL_NULL_FRAME	BIT(28)
#define MT_RXD2_NORMAL_NDATA		BIT(29)
#define MT_RXD2_NORMAL_NON_AMPDU	BIT(30)
#define MT_RXD2_NORMAL_BF_REPORT	BIT(31)

/* RXD DW3 */
#define MT_RXD3_NORMAL_RXV_SEQ		GENMASK(7, 0)
#define MT_RXD3_NORMAL_CH_FREQ		GENMASK(15, 8)
#define MT_RXD3_NORMAL_ADDR_TYPE	GENMASK(17, 16)
#define MT_RXD3_NORMAL_U2M		BIT(0)
#define MT_RXD3_NORMAL_HTC_VLD		BIT(0)
#define MT_RXD3_NORMAL_TSF_COMPARE_LOSS	BIT(19)
#define MT_RXD3_NORMAL_BEACON_MC	BIT(20)
#define MT_RXD3_NORMAL_BEACON_UC	BIT(21)
#define MT_RXD3_NORMAL_AMSDU		BIT(22)
#define MT_RXD3_NORMAL_MESH		BIT(23)
#define MT_RXD3_NORMAL_MHCP		BIT(24)
#define MT_RXD3_NORMAL_NO_INFO_WB	BIT(25)
#define MT_RXD3_NORMAL_DISABLE_RX_HDR_TRANS	BIT(26)
#define MT_RXD3_NORMAL_POWER_SAVE_STAT	BIT(27)
#define MT_RXD3_NORMAL_MORE		BIT(28)
#define MT_RXD3_NORMAL_UNWANT		BIT(29)
#define MT_RXD3_NORMAL_RX_DROP		BIT(30)
#define MT_RXD3_NORMAL_VLAN2ETH		BIT(31)

/* RXD DW4 */
#define MT_RXD4_NORMAL_PAYLOAD_FORMAT	GENMASK(1, 0)
#define MT_RXD4_FIRST_AMSDU_FRAME	GENMASK(1, 0)
#define MT_RXD4_MID_AMSDU_FRAME		BIT(1)
#define MT_RXD4_LAST_AMSDU_FRAME	BIT(0)

#define MT_RXD4_NORMAL_PATTERN_DROP	BIT(9)
#define MT_RXD4_NORMAL_CLS		BIT(10)
#define MT_RXD4_NORMAL_OFLD		GENMASK(12, 11)
#define MT_RXD4_NORMAL_MAGIC_PKT	BIT(13)
#define MT_RXD4_NORMAL_WOL		GENMASK(18, 14)
#define MT_RXD4_NORMAL_CLS_BITMAP	GENMASK(28, 19)
#define MT_RXD3_NORMAL_PF_MODE		BIT(29)
#define MT_RXD3_NORMAL_PF_STS		GENMASK(31, 30)

#define MT_RXV_HDR_BAND_IDX		BIT(24)

/* RXD GROUP4 */
#define MT_RXD6_FRAME_CONTROL		GENMASK(15, 0)
#define MT_RXD6_TA_LO			GENMASK(31, 16)

#define MT_RXD7_TA_HI			GENMASK(31, 0)

#define MT_RXD8_SEQ_CTRL		GENMASK(15, 0)
#define MT_RXD8_QOS_CTL			GENMASK(31, 16)

#define MT_RXD9_HT_CONTROL		GENMASK(31, 0)

enum tx_port_idx {
	MT_TX_PORT_IDX_LMAC,
	MT_TX_PORT_IDX_MCU
Loading