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