162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci#ifndef B43legacy_DMA_H_
362306a36Sopenharmony_ci#define B43legacy_DMA_H_
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci#include <linux/list.h>
662306a36Sopenharmony_ci#include <linux/spinlock.h>
762306a36Sopenharmony_ci#include <linux/workqueue.h>
862306a36Sopenharmony_ci#include <linux/linkage.h>
962306a36Sopenharmony_ci#include <linux/atomic.h>
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#include "b43legacy.h"
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci/* DMA-Interrupt reasons. */
1562306a36Sopenharmony_ci#define B43legacy_DMAIRQ_FATALMASK	((1 << 10) | (1 << 11) | (1 << 12) \
1662306a36Sopenharmony_ci					 | (1 << 14) | (1 << 15))
1762306a36Sopenharmony_ci#define B43legacy_DMAIRQ_NONFATALMASK	(1 << 13)
1862306a36Sopenharmony_ci#define B43legacy_DMAIRQ_RX_DONE		(1 << 16)
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci/*** 32-bit DMA Engine. ***/
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ci/* 32-bit DMA controller registers. */
2462306a36Sopenharmony_ci#define B43legacy_DMA32_TXCTL				0x00
2562306a36Sopenharmony_ci#define		B43legacy_DMA32_TXENABLE		0x00000001
2662306a36Sopenharmony_ci#define		B43legacy_DMA32_TXSUSPEND		0x00000002
2762306a36Sopenharmony_ci#define		B43legacy_DMA32_TXLOOPBACK		0x00000004
2862306a36Sopenharmony_ci#define		B43legacy_DMA32_TXFLUSH			0x00000010
2962306a36Sopenharmony_ci#define		B43legacy_DMA32_TXADDREXT_MASK		0x00030000
3062306a36Sopenharmony_ci#define		B43legacy_DMA32_TXADDREXT_SHIFT		16
3162306a36Sopenharmony_ci#define B43legacy_DMA32_TXRING				0x04
3262306a36Sopenharmony_ci#define B43legacy_DMA32_TXINDEX				0x08
3362306a36Sopenharmony_ci#define B43legacy_DMA32_TXSTATUS			0x0C
3462306a36Sopenharmony_ci#define		B43legacy_DMA32_TXDPTR			0x00000FFF
3562306a36Sopenharmony_ci#define		B43legacy_DMA32_TXSTATE			0x0000F000
3662306a36Sopenharmony_ci#define			B43legacy_DMA32_TXSTAT_DISABLED	0x00000000
3762306a36Sopenharmony_ci#define			B43legacy_DMA32_TXSTAT_ACTIVE	0x00001000
3862306a36Sopenharmony_ci#define			B43legacy_DMA32_TXSTAT_IDLEWAIT	0x00002000
3962306a36Sopenharmony_ci#define			B43legacy_DMA32_TXSTAT_STOPPED	0x00003000
4062306a36Sopenharmony_ci#define			B43legacy_DMA32_TXSTAT_SUSP	0x00004000
4162306a36Sopenharmony_ci#define		B43legacy_DMA32_TXERROR			0x000F0000
4262306a36Sopenharmony_ci#define			B43legacy_DMA32_TXERR_NOERR	0x00000000
4362306a36Sopenharmony_ci#define			B43legacy_DMA32_TXERR_PROT	0x00010000
4462306a36Sopenharmony_ci#define			B43legacy_DMA32_TXERR_UNDERRUN	0x00020000
4562306a36Sopenharmony_ci#define			B43legacy_DMA32_TXERR_BUFREAD	0x00030000
4662306a36Sopenharmony_ci#define			B43legacy_DMA32_TXERR_DESCREAD	0x00040000
4762306a36Sopenharmony_ci#define		B43legacy_DMA32_TXACTIVE		0xFFF00000
4862306a36Sopenharmony_ci#define B43legacy_DMA32_RXCTL				0x10
4962306a36Sopenharmony_ci#define		B43legacy_DMA32_RXENABLE		0x00000001
5062306a36Sopenharmony_ci#define		B43legacy_DMA32_RXFROFF_MASK		0x000000FE
5162306a36Sopenharmony_ci#define		B43legacy_DMA32_RXFROFF_SHIFT		1
5262306a36Sopenharmony_ci#define		B43legacy_DMA32_RXDIRECTFIFO		0x00000100
5362306a36Sopenharmony_ci#define		B43legacy_DMA32_RXADDREXT_MASK		0x00030000
5462306a36Sopenharmony_ci#define		B43legacy_DMA32_RXADDREXT_SHIFT		16
5562306a36Sopenharmony_ci#define B43legacy_DMA32_RXRING				0x14
5662306a36Sopenharmony_ci#define B43legacy_DMA32_RXINDEX				0x18
5762306a36Sopenharmony_ci#define B43legacy_DMA32_RXSTATUS			0x1C
5862306a36Sopenharmony_ci#define		B43legacy_DMA32_RXDPTR			0x00000FFF
5962306a36Sopenharmony_ci#define		B43legacy_DMA32_RXSTATE			0x0000F000
6062306a36Sopenharmony_ci#define			B43legacy_DMA32_RXSTAT_DISABLED	0x00000000
6162306a36Sopenharmony_ci#define			B43legacy_DMA32_RXSTAT_ACTIVE	0x00001000
6262306a36Sopenharmony_ci#define			B43legacy_DMA32_RXSTAT_IDLEWAIT	0x00002000
6362306a36Sopenharmony_ci#define			B43legacy_DMA32_RXSTAT_STOPPED	0x00003000
6462306a36Sopenharmony_ci#define		B43legacy_DMA32_RXERROR			0x000F0000
6562306a36Sopenharmony_ci#define			B43legacy_DMA32_RXERR_NOERR	0x00000000
6662306a36Sopenharmony_ci#define			B43legacy_DMA32_RXERR_PROT	0x00010000
6762306a36Sopenharmony_ci#define			B43legacy_DMA32_RXERR_OVERFLOW	0x00020000
6862306a36Sopenharmony_ci#define			B43legacy_DMA32_RXERR_BUFWRITE	0x00030000
6962306a36Sopenharmony_ci#define			B43legacy_DMA32_RXERR_DESCREAD	0x00040000
7062306a36Sopenharmony_ci#define		B43legacy_DMA32_RXACTIVE		0xFFF00000
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_ci/* 32-bit DMA descriptor. */
7362306a36Sopenharmony_cistruct b43legacy_dmadesc32 {
7462306a36Sopenharmony_ci	__le32 control;
7562306a36Sopenharmony_ci	__le32 address;
7662306a36Sopenharmony_ci} __packed;
7762306a36Sopenharmony_ci#define B43legacy_DMA32_DCTL_BYTECNT		0x00001FFF
7862306a36Sopenharmony_ci#define B43legacy_DMA32_DCTL_ADDREXT_MASK	0x00030000
7962306a36Sopenharmony_ci#define B43legacy_DMA32_DCTL_ADDREXT_SHIFT	16
8062306a36Sopenharmony_ci#define B43legacy_DMA32_DCTL_DTABLEEND		0x10000000
8162306a36Sopenharmony_ci#define B43legacy_DMA32_DCTL_IRQ		0x20000000
8262306a36Sopenharmony_ci#define B43legacy_DMA32_DCTL_FRAMEEND		0x40000000
8362306a36Sopenharmony_ci#define B43legacy_DMA32_DCTL_FRAMESTART		0x80000000
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ci/* Misc DMA constants */
8762306a36Sopenharmony_ci#define B43legacy_DMA_RINGMEMSIZE	PAGE_SIZE
8862306a36Sopenharmony_ci#define B43legacy_DMA0_RX_FRAMEOFFSET	30
8962306a36Sopenharmony_ci#define B43legacy_DMA3_RX_FRAMEOFFSET	0
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_ci
9262306a36Sopenharmony_ci/* DMA engine tuning knobs */
9362306a36Sopenharmony_ci#define B43legacy_TXRING_SLOTS		128
9462306a36Sopenharmony_ci#define B43legacy_RXRING_SLOTS		64
9562306a36Sopenharmony_ci#define B43legacy_DMA0_RX_BUFFERSIZE	(2304 + 100)
9662306a36Sopenharmony_ci#define B43legacy_DMA3_RX_BUFFERSIZE	16
9762306a36Sopenharmony_ci
9862306a36Sopenharmony_ci
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_ci#ifdef CONFIG_B43LEGACY_DMA
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_cistruct sk_buff;
10462306a36Sopenharmony_cistruct b43legacy_private;
10562306a36Sopenharmony_cistruct b43legacy_txstatus;
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_ci
10862306a36Sopenharmony_cistruct b43legacy_dmadesc_meta {
10962306a36Sopenharmony_ci	/* The kernel DMA-able buffer. */
11062306a36Sopenharmony_ci	struct sk_buff *skb;
11162306a36Sopenharmony_ci	/* DMA base bus-address of the descriptor buffer. */
11262306a36Sopenharmony_ci	dma_addr_t dmaaddr;
11362306a36Sopenharmony_ci	/* ieee80211 TX status. Only used once per 802.11 frag. */
11462306a36Sopenharmony_ci	bool is_last_fragment;
11562306a36Sopenharmony_ci};
11662306a36Sopenharmony_ci
11762306a36Sopenharmony_cienum b43legacy_dmatype {
11862306a36Sopenharmony_ci	B43legacy_DMA_30BIT = 30,
11962306a36Sopenharmony_ci	B43legacy_DMA_32BIT = 32,
12062306a36Sopenharmony_ci};
12162306a36Sopenharmony_ci
12262306a36Sopenharmony_cistruct b43legacy_dmaring {
12362306a36Sopenharmony_ci	/* Kernel virtual base address of the ring memory. */
12462306a36Sopenharmony_ci	void *descbase;
12562306a36Sopenharmony_ci	/* Meta data about all descriptors. */
12662306a36Sopenharmony_ci	struct b43legacy_dmadesc_meta *meta;
12762306a36Sopenharmony_ci	/* Cache of TX headers for each slot.
12862306a36Sopenharmony_ci	 * This is to avoid an allocation on each TX.
12962306a36Sopenharmony_ci	 * This is NULL for an RX ring.
13062306a36Sopenharmony_ci	 */
13162306a36Sopenharmony_ci	u8 *txhdr_cache;
13262306a36Sopenharmony_ci	/* (Unadjusted) DMA base bus-address of the ring memory. */
13362306a36Sopenharmony_ci	dma_addr_t dmabase;
13462306a36Sopenharmony_ci	/* Number of descriptor slots in the ring. */
13562306a36Sopenharmony_ci	int nr_slots;
13662306a36Sopenharmony_ci	/* Number of used descriptor slots. */
13762306a36Sopenharmony_ci	int used_slots;
13862306a36Sopenharmony_ci	/* Currently used slot in the ring. */
13962306a36Sopenharmony_ci	int current_slot;
14062306a36Sopenharmony_ci	/* Frameoffset in octets. */
14162306a36Sopenharmony_ci	u32 frameoffset;
14262306a36Sopenharmony_ci	/* Descriptor buffer size. */
14362306a36Sopenharmony_ci	u16 rx_buffersize;
14462306a36Sopenharmony_ci	/* The MMIO base register of the DMA controller. */
14562306a36Sopenharmony_ci	u16 mmio_base;
14662306a36Sopenharmony_ci	/* DMA controller index number (0-5). */
14762306a36Sopenharmony_ci	int index;
14862306a36Sopenharmony_ci	/* Boolean. Is this a TX ring? */
14962306a36Sopenharmony_ci	bool tx;
15062306a36Sopenharmony_ci	/* The type of DMA engine used. */
15162306a36Sopenharmony_ci	enum b43legacy_dmatype type;
15262306a36Sopenharmony_ci	/* Boolean. Is this ring stopped at ieee80211 level? */
15362306a36Sopenharmony_ci	bool stopped;
15462306a36Sopenharmony_ci	/* The QOS priority assigned to this ring. Only used for TX rings.
15562306a36Sopenharmony_ci	 * This is the mac80211 "queue" value. */
15662306a36Sopenharmony_ci	u8 queue_prio;
15762306a36Sopenharmony_ci	struct b43legacy_wldev *dev;
15862306a36Sopenharmony_ci#ifdef CONFIG_B43LEGACY_DEBUG
15962306a36Sopenharmony_ci	/* Maximum number of used slots. */
16062306a36Sopenharmony_ci	int max_used_slots;
16162306a36Sopenharmony_ci	/* Last time we injected a ring overflow. */
16262306a36Sopenharmony_ci	unsigned long last_injected_overflow;
16362306a36Sopenharmony_ci#endif /* CONFIG_B43LEGACY_DEBUG*/
16462306a36Sopenharmony_ci};
16562306a36Sopenharmony_ci
16662306a36Sopenharmony_ci
16762306a36Sopenharmony_cistatic inline
16862306a36Sopenharmony_ciu32 b43legacy_dma_read(struct b43legacy_dmaring *ring,
16962306a36Sopenharmony_ci		       u16 offset)
17062306a36Sopenharmony_ci{
17162306a36Sopenharmony_ci	return b43legacy_read32(ring->dev, ring->mmio_base + offset);
17262306a36Sopenharmony_ci}
17362306a36Sopenharmony_ci
17462306a36Sopenharmony_cistatic inline
17562306a36Sopenharmony_civoid b43legacy_dma_write(struct b43legacy_dmaring *ring,
17662306a36Sopenharmony_ci			 u16 offset, u32 value)
17762306a36Sopenharmony_ci{
17862306a36Sopenharmony_ci	b43legacy_write32(ring->dev, ring->mmio_base + offset, value);
17962306a36Sopenharmony_ci}
18062306a36Sopenharmony_ci
18162306a36Sopenharmony_ci
18262306a36Sopenharmony_ciint b43legacy_dma_init(struct b43legacy_wldev *dev);
18362306a36Sopenharmony_civoid b43legacy_dma_free(struct b43legacy_wldev *dev);
18462306a36Sopenharmony_ci
18562306a36Sopenharmony_civoid b43legacy_dma_tx_suspend(struct b43legacy_wldev *dev);
18662306a36Sopenharmony_civoid b43legacy_dma_tx_resume(struct b43legacy_wldev *dev);
18762306a36Sopenharmony_ci
18862306a36Sopenharmony_ciint b43legacy_dma_tx(struct b43legacy_wldev *dev,
18962306a36Sopenharmony_ci		     struct sk_buff *skb);
19062306a36Sopenharmony_civoid b43legacy_dma_handle_txstatus(struct b43legacy_wldev *dev,
19162306a36Sopenharmony_ci				   const struct b43legacy_txstatus *status);
19262306a36Sopenharmony_ci
19362306a36Sopenharmony_civoid b43legacy_dma_rx(struct b43legacy_dmaring *ring);
19462306a36Sopenharmony_ci
19562306a36Sopenharmony_ci#else /* CONFIG_B43LEGACY_DMA */
19662306a36Sopenharmony_ci
19762306a36Sopenharmony_ci
19862306a36Sopenharmony_cistatic inline
19962306a36Sopenharmony_ciint b43legacy_dma_init(struct b43legacy_wldev *dev)
20062306a36Sopenharmony_ci{
20162306a36Sopenharmony_ci	return 0;
20262306a36Sopenharmony_ci}
20362306a36Sopenharmony_cistatic inline
20462306a36Sopenharmony_civoid b43legacy_dma_free(struct b43legacy_wldev *dev)
20562306a36Sopenharmony_ci{
20662306a36Sopenharmony_ci}
20762306a36Sopenharmony_cistatic inline
20862306a36Sopenharmony_ciint b43legacy_dma_tx(struct b43legacy_wldev *dev,
20962306a36Sopenharmony_ci		     struct sk_buff *skb)
21062306a36Sopenharmony_ci{
21162306a36Sopenharmony_ci	return 0;
21262306a36Sopenharmony_ci}
21362306a36Sopenharmony_cistatic inline
21462306a36Sopenharmony_civoid b43legacy_dma_handle_txstatus(struct b43legacy_wldev *dev,
21562306a36Sopenharmony_ci				   const struct b43legacy_txstatus *status)
21662306a36Sopenharmony_ci{
21762306a36Sopenharmony_ci}
21862306a36Sopenharmony_cistatic inline
21962306a36Sopenharmony_civoid b43legacy_dma_rx(struct b43legacy_dmaring *ring)
22062306a36Sopenharmony_ci{
22162306a36Sopenharmony_ci}
22262306a36Sopenharmony_cistatic inline
22362306a36Sopenharmony_civoid b43legacy_dma_tx_suspend(struct b43legacy_wldev *dev)
22462306a36Sopenharmony_ci{
22562306a36Sopenharmony_ci}
22662306a36Sopenharmony_cistatic inline
22762306a36Sopenharmony_civoid b43legacy_dma_tx_resume(struct b43legacy_wldev *dev)
22862306a36Sopenharmony_ci{
22962306a36Sopenharmony_ci}
23062306a36Sopenharmony_ci
23162306a36Sopenharmony_ci#endif /* CONFIG_B43LEGACY_DMA */
23262306a36Sopenharmony_ci#endif /* B43legacy_DMA_H_ */
233