162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (C) 2014 Felix Fietkau <nbd@openwrt.org>
462306a36Sopenharmony_ci * Copyright (C) 2015 Jakub Kicinski <kubakici@wp.pl>
562306a36Sopenharmony_ci */
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci#ifndef __MT7601U_DMA_H
862306a36Sopenharmony_ci#define __MT7601U_DMA_H
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#include <asm/unaligned.h>
1162306a36Sopenharmony_ci#include <linux/skbuff.h>
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci#define MT_DMA_HDR_LEN			4
1462306a36Sopenharmony_ci#define MT_RX_INFO_LEN			4
1562306a36Sopenharmony_ci#define MT_FCE_INFO_LEN			4
1662306a36Sopenharmony_ci#define MT_DMA_HDRS			(MT_DMA_HDR_LEN + MT_RX_INFO_LEN)
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci/* Common Tx DMA descriptor fields */
1962306a36Sopenharmony_ci#define MT_TXD_INFO_LEN			GENMASK(15, 0)
2062306a36Sopenharmony_ci#define MT_TXD_INFO_D_PORT		GENMASK(29, 27)
2162306a36Sopenharmony_ci#define MT_TXD_INFO_TYPE		GENMASK(31, 30)
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_cienum mt76_msg_port {
2462306a36Sopenharmony_ci	WLAN_PORT,
2562306a36Sopenharmony_ci	CPU_RX_PORT,
2662306a36Sopenharmony_ci	CPU_TX_PORT,
2762306a36Sopenharmony_ci	HOST_PORT,
2862306a36Sopenharmony_ci	VIRTUAL_CPU_RX_PORT,
2962306a36Sopenharmony_ci	VIRTUAL_CPU_TX_PORT,
3062306a36Sopenharmony_ci	DISCARD,
3162306a36Sopenharmony_ci};
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_cienum mt76_info_type {
3462306a36Sopenharmony_ci	DMA_PACKET,
3562306a36Sopenharmony_ci	DMA_COMMAND,
3662306a36Sopenharmony_ci};
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ci/* Tx DMA packet specific flags */
3962306a36Sopenharmony_ci#define MT_TXD_PKT_INFO_NEXT_VLD	BIT(16)
4062306a36Sopenharmony_ci#define MT_TXD_PKT_INFO_TX_BURST	BIT(17)
4162306a36Sopenharmony_ci#define MT_TXD_PKT_INFO_80211		BIT(19)
4262306a36Sopenharmony_ci#define MT_TXD_PKT_INFO_TSO		BIT(20)
4362306a36Sopenharmony_ci#define MT_TXD_PKT_INFO_CSO		BIT(21)
4462306a36Sopenharmony_ci#define MT_TXD_PKT_INFO_WIV		BIT(24)
4562306a36Sopenharmony_ci#define MT_TXD_PKT_INFO_QSEL		GENMASK(26, 25)
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_cienum mt76_qsel {
4862306a36Sopenharmony_ci	MT_QSEL_MGMT,
4962306a36Sopenharmony_ci	MT_QSEL_HCCA,
5062306a36Sopenharmony_ci	MT_QSEL_EDCA,
5162306a36Sopenharmony_ci	MT_QSEL_EDCA_2,
5262306a36Sopenharmony_ci};
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_ci/* Tx DMA MCU command specific flags */
5562306a36Sopenharmony_ci#define MT_TXD_CMD_INFO_SEQ		GENMASK(19, 16)
5662306a36Sopenharmony_ci#define MT_TXD_CMD_INFO_TYPE		GENMASK(26, 20)
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_cistatic inline int mt7601u_dma_skb_wrap(struct sk_buff *skb,
5962306a36Sopenharmony_ci				       enum mt76_msg_port d_port,
6062306a36Sopenharmony_ci				       enum mt76_info_type type, u32 flags)
6162306a36Sopenharmony_ci{
6262306a36Sopenharmony_ci	u32 info;
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_ci	/* Buffer layout:
6562306a36Sopenharmony_ci	 *	|   4B   | xfer len |      pad       |  4B  |
6662306a36Sopenharmony_ci	 *	| TXINFO | pkt/cmd  | zero pad to 4B | zero |
6762306a36Sopenharmony_ci	 *
6862306a36Sopenharmony_ci	 * length field of TXINFO should be set to 'xfer len'.
6962306a36Sopenharmony_ci	 */
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ci	info = flags |
7262306a36Sopenharmony_ci		FIELD_PREP(MT_TXD_INFO_LEN, round_up(skb->len, 4)) |
7362306a36Sopenharmony_ci		FIELD_PREP(MT_TXD_INFO_D_PORT, d_port) |
7462306a36Sopenharmony_ci		FIELD_PREP(MT_TXD_INFO_TYPE, type);
7562306a36Sopenharmony_ci
7662306a36Sopenharmony_ci	put_unaligned_le32(info, skb_push(skb, sizeof(info)));
7762306a36Sopenharmony_ci	return skb_put_padto(skb, round_up(skb->len, 4) + 4);
7862306a36Sopenharmony_ci}
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_cistatic inline int
8162306a36Sopenharmony_cimt7601u_dma_skb_wrap_pkt(struct sk_buff *skb, enum mt76_qsel qsel, u32 flags)
8262306a36Sopenharmony_ci{
8362306a36Sopenharmony_ci	flags |= FIELD_PREP(MT_TXD_PKT_INFO_QSEL, qsel);
8462306a36Sopenharmony_ci	return mt7601u_dma_skb_wrap(skb, WLAN_PORT, DMA_PACKET, flags);
8562306a36Sopenharmony_ci}
8662306a36Sopenharmony_ci
8762306a36Sopenharmony_ci/* Common Rx DMA descriptor fields */
8862306a36Sopenharmony_ci#define MT_RXD_INFO_LEN			GENMASK(13, 0)
8962306a36Sopenharmony_ci#define MT_RXD_INFO_PCIE_INTR		BIT(24)
9062306a36Sopenharmony_ci#define MT_RXD_INFO_QSEL		GENMASK(26, 25)
9162306a36Sopenharmony_ci#define MT_RXD_INFO_PORT		GENMASK(29, 27)
9262306a36Sopenharmony_ci#define MT_RXD_INFO_TYPE		GENMASK(31, 30)
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_ci/* Rx DMA packet specific flags */
9562306a36Sopenharmony_ci#define MT_RXD_PKT_INFO_UDP_ERR		BIT(16)
9662306a36Sopenharmony_ci#define MT_RXD_PKT_INFO_TCP_ERR		BIT(17)
9762306a36Sopenharmony_ci#define MT_RXD_PKT_INFO_IP_ERR		BIT(18)
9862306a36Sopenharmony_ci#define MT_RXD_PKT_INFO_PKT_80211	BIT(19)
9962306a36Sopenharmony_ci#define MT_RXD_PKT_INFO_L3L4_DONE	BIT(20)
10062306a36Sopenharmony_ci#define MT_RXD_PKT_INFO_MAC_LEN		GENMASK(23, 21)
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_ci/* Rx DMA MCU command specific flags */
10362306a36Sopenharmony_ci#define MT_RXD_CMD_INFO_SELF_GEN	BIT(15)
10462306a36Sopenharmony_ci#define MT_RXD_CMD_INFO_CMD_SEQ		GENMASK(19, 16)
10562306a36Sopenharmony_ci#define MT_RXD_CMD_INFO_EVT_TYPE	GENMASK(23, 20)
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_cienum mt76_evt_type {
10862306a36Sopenharmony_ci	CMD_DONE,
10962306a36Sopenharmony_ci	CMD_ERROR,
11062306a36Sopenharmony_ci	CMD_RETRY,
11162306a36Sopenharmony_ci	EVENT_PWR_RSP,
11262306a36Sopenharmony_ci	EVENT_WOW_RSP,
11362306a36Sopenharmony_ci	EVENT_CARRIER_DETECT_RSP,
11462306a36Sopenharmony_ci	EVENT_DFS_DETECT_RSP,
11562306a36Sopenharmony_ci};
11662306a36Sopenharmony_ci
11762306a36Sopenharmony_ci#endif
118