18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci#ifndef B43legacy_DMA_H_ 38c2ecf20Sopenharmony_ci#define B43legacy_DMA_H_ 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ci#include <linux/list.h> 68c2ecf20Sopenharmony_ci#include <linux/spinlock.h> 78c2ecf20Sopenharmony_ci#include <linux/workqueue.h> 88c2ecf20Sopenharmony_ci#include <linux/linkage.h> 98c2ecf20Sopenharmony_ci#include <linux/atomic.h> 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci#include "b43legacy.h" 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ci/* DMA-Interrupt reasons. */ 158c2ecf20Sopenharmony_ci#define B43legacy_DMAIRQ_FATALMASK ((1 << 10) | (1 << 11) | (1 << 12) \ 168c2ecf20Sopenharmony_ci | (1 << 14) | (1 << 15)) 178c2ecf20Sopenharmony_ci#define B43legacy_DMAIRQ_NONFATALMASK (1 << 13) 188c2ecf20Sopenharmony_ci#define B43legacy_DMAIRQ_RX_DONE (1 << 16) 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci/*** 32-bit DMA Engine. ***/ 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ci/* 32-bit DMA controller registers. */ 248c2ecf20Sopenharmony_ci#define B43legacy_DMA32_TXCTL 0x00 258c2ecf20Sopenharmony_ci#define B43legacy_DMA32_TXENABLE 0x00000001 268c2ecf20Sopenharmony_ci#define B43legacy_DMA32_TXSUSPEND 0x00000002 278c2ecf20Sopenharmony_ci#define B43legacy_DMA32_TXLOOPBACK 0x00000004 288c2ecf20Sopenharmony_ci#define B43legacy_DMA32_TXFLUSH 0x00000010 298c2ecf20Sopenharmony_ci#define B43legacy_DMA32_TXADDREXT_MASK 0x00030000 308c2ecf20Sopenharmony_ci#define B43legacy_DMA32_TXADDREXT_SHIFT 16 318c2ecf20Sopenharmony_ci#define B43legacy_DMA32_TXRING 0x04 328c2ecf20Sopenharmony_ci#define B43legacy_DMA32_TXINDEX 0x08 338c2ecf20Sopenharmony_ci#define B43legacy_DMA32_TXSTATUS 0x0C 348c2ecf20Sopenharmony_ci#define B43legacy_DMA32_TXDPTR 0x00000FFF 358c2ecf20Sopenharmony_ci#define B43legacy_DMA32_TXSTATE 0x0000F000 368c2ecf20Sopenharmony_ci#define B43legacy_DMA32_TXSTAT_DISABLED 0x00000000 378c2ecf20Sopenharmony_ci#define B43legacy_DMA32_TXSTAT_ACTIVE 0x00001000 388c2ecf20Sopenharmony_ci#define B43legacy_DMA32_TXSTAT_IDLEWAIT 0x00002000 398c2ecf20Sopenharmony_ci#define B43legacy_DMA32_TXSTAT_STOPPED 0x00003000 408c2ecf20Sopenharmony_ci#define B43legacy_DMA32_TXSTAT_SUSP 0x00004000 418c2ecf20Sopenharmony_ci#define B43legacy_DMA32_TXERROR 0x000F0000 428c2ecf20Sopenharmony_ci#define B43legacy_DMA32_TXERR_NOERR 0x00000000 438c2ecf20Sopenharmony_ci#define B43legacy_DMA32_TXERR_PROT 0x00010000 448c2ecf20Sopenharmony_ci#define B43legacy_DMA32_TXERR_UNDERRUN 0x00020000 458c2ecf20Sopenharmony_ci#define B43legacy_DMA32_TXERR_BUFREAD 0x00030000 468c2ecf20Sopenharmony_ci#define B43legacy_DMA32_TXERR_DESCREAD 0x00040000 478c2ecf20Sopenharmony_ci#define B43legacy_DMA32_TXACTIVE 0xFFF00000 488c2ecf20Sopenharmony_ci#define B43legacy_DMA32_RXCTL 0x10 498c2ecf20Sopenharmony_ci#define B43legacy_DMA32_RXENABLE 0x00000001 508c2ecf20Sopenharmony_ci#define B43legacy_DMA32_RXFROFF_MASK 0x000000FE 518c2ecf20Sopenharmony_ci#define B43legacy_DMA32_RXFROFF_SHIFT 1 528c2ecf20Sopenharmony_ci#define B43legacy_DMA32_RXDIRECTFIFO 0x00000100 538c2ecf20Sopenharmony_ci#define B43legacy_DMA32_RXADDREXT_MASK 0x00030000 548c2ecf20Sopenharmony_ci#define B43legacy_DMA32_RXADDREXT_SHIFT 16 558c2ecf20Sopenharmony_ci#define B43legacy_DMA32_RXRING 0x14 568c2ecf20Sopenharmony_ci#define B43legacy_DMA32_RXINDEX 0x18 578c2ecf20Sopenharmony_ci#define B43legacy_DMA32_RXSTATUS 0x1C 588c2ecf20Sopenharmony_ci#define B43legacy_DMA32_RXDPTR 0x00000FFF 598c2ecf20Sopenharmony_ci#define B43legacy_DMA32_RXSTATE 0x0000F000 608c2ecf20Sopenharmony_ci#define B43legacy_DMA32_RXSTAT_DISABLED 0x00000000 618c2ecf20Sopenharmony_ci#define B43legacy_DMA32_RXSTAT_ACTIVE 0x00001000 628c2ecf20Sopenharmony_ci#define B43legacy_DMA32_RXSTAT_IDLEWAIT 0x00002000 638c2ecf20Sopenharmony_ci#define B43legacy_DMA32_RXSTAT_STOPPED 0x00003000 648c2ecf20Sopenharmony_ci#define B43legacy_DMA32_RXERROR 0x000F0000 658c2ecf20Sopenharmony_ci#define B43legacy_DMA32_RXERR_NOERR 0x00000000 668c2ecf20Sopenharmony_ci#define B43legacy_DMA32_RXERR_PROT 0x00010000 678c2ecf20Sopenharmony_ci#define B43legacy_DMA32_RXERR_OVERFLOW 0x00020000 688c2ecf20Sopenharmony_ci#define B43legacy_DMA32_RXERR_BUFWRITE 0x00030000 698c2ecf20Sopenharmony_ci#define B43legacy_DMA32_RXERR_DESCREAD 0x00040000 708c2ecf20Sopenharmony_ci#define B43legacy_DMA32_RXACTIVE 0xFFF00000 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci/* 32-bit DMA descriptor. */ 738c2ecf20Sopenharmony_cistruct b43legacy_dmadesc32 { 748c2ecf20Sopenharmony_ci __le32 control; 758c2ecf20Sopenharmony_ci __le32 address; 768c2ecf20Sopenharmony_ci} __packed; 778c2ecf20Sopenharmony_ci#define B43legacy_DMA32_DCTL_BYTECNT 0x00001FFF 788c2ecf20Sopenharmony_ci#define B43legacy_DMA32_DCTL_ADDREXT_MASK 0x00030000 798c2ecf20Sopenharmony_ci#define B43legacy_DMA32_DCTL_ADDREXT_SHIFT 16 808c2ecf20Sopenharmony_ci#define B43legacy_DMA32_DCTL_DTABLEEND 0x10000000 818c2ecf20Sopenharmony_ci#define B43legacy_DMA32_DCTL_IRQ 0x20000000 828c2ecf20Sopenharmony_ci#define B43legacy_DMA32_DCTL_FRAMEEND 0x40000000 838c2ecf20Sopenharmony_ci#define B43legacy_DMA32_DCTL_FRAMESTART 0x80000000 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ci/* Misc DMA constants */ 878c2ecf20Sopenharmony_ci#define B43legacy_DMA_RINGMEMSIZE PAGE_SIZE 888c2ecf20Sopenharmony_ci#define B43legacy_DMA0_RX_FRAMEOFFSET 30 898c2ecf20Sopenharmony_ci#define B43legacy_DMA3_RX_FRAMEOFFSET 0 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_ci/* DMA engine tuning knobs */ 938c2ecf20Sopenharmony_ci#define B43legacy_TXRING_SLOTS 128 948c2ecf20Sopenharmony_ci#define B43legacy_RXRING_SLOTS 64 958c2ecf20Sopenharmony_ci#define B43legacy_DMA0_RX_BUFFERSIZE (2304 + 100) 968c2ecf20Sopenharmony_ci#define B43legacy_DMA3_RX_BUFFERSIZE 16 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_ci 998c2ecf20Sopenharmony_ci 1008c2ecf20Sopenharmony_ci#ifdef CONFIG_B43LEGACY_DMA 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_cistruct sk_buff; 1048c2ecf20Sopenharmony_cistruct b43legacy_private; 1058c2ecf20Sopenharmony_cistruct b43legacy_txstatus; 1068c2ecf20Sopenharmony_ci 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_cistruct b43legacy_dmadesc_meta { 1098c2ecf20Sopenharmony_ci /* The kernel DMA-able buffer. */ 1108c2ecf20Sopenharmony_ci struct sk_buff *skb; 1118c2ecf20Sopenharmony_ci /* DMA base bus-address of the descriptor buffer. */ 1128c2ecf20Sopenharmony_ci dma_addr_t dmaaddr; 1138c2ecf20Sopenharmony_ci /* ieee80211 TX status. Only used once per 802.11 frag. */ 1148c2ecf20Sopenharmony_ci bool is_last_fragment; 1158c2ecf20Sopenharmony_ci}; 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_cienum b43legacy_dmatype { 1188c2ecf20Sopenharmony_ci B43legacy_DMA_30BIT = 30, 1198c2ecf20Sopenharmony_ci B43legacy_DMA_32BIT = 32, 1208c2ecf20Sopenharmony_ci}; 1218c2ecf20Sopenharmony_ci 1228c2ecf20Sopenharmony_cistruct b43legacy_dmaring { 1238c2ecf20Sopenharmony_ci /* Kernel virtual base address of the ring memory. */ 1248c2ecf20Sopenharmony_ci void *descbase; 1258c2ecf20Sopenharmony_ci /* Meta data about all descriptors. */ 1268c2ecf20Sopenharmony_ci struct b43legacy_dmadesc_meta *meta; 1278c2ecf20Sopenharmony_ci /* Cache of TX headers for each slot. 1288c2ecf20Sopenharmony_ci * This is to avoid an allocation on each TX. 1298c2ecf20Sopenharmony_ci * This is NULL for an RX ring. 1308c2ecf20Sopenharmony_ci */ 1318c2ecf20Sopenharmony_ci u8 *txhdr_cache; 1328c2ecf20Sopenharmony_ci /* (Unadjusted) DMA base bus-address of the ring memory. */ 1338c2ecf20Sopenharmony_ci dma_addr_t dmabase; 1348c2ecf20Sopenharmony_ci /* Number of descriptor slots in the ring. */ 1358c2ecf20Sopenharmony_ci int nr_slots; 1368c2ecf20Sopenharmony_ci /* Number of used descriptor slots. */ 1378c2ecf20Sopenharmony_ci int used_slots; 1388c2ecf20Sopenharmony_ci /* Currently used slot in the ring. */ 1398c2ecf20Sopenharmony_ci int current_slot; 1408c2ecf20Sopenharmony_ci /* Frameoffset in octets. */ 1418c2ecf20Sopenharmony_ci u32 frameoffset; 1428c2ecf20Sopenharmony_ci /* Descriptor buffer size. */ 1438c2ecf20Sopenharmony_ci u16 rx_buffersize; 1448c2ecf20Sopenharmony_ci /* The MMIO base register of the DMA controller. */ 1458c2ecf20Sopenharmony_ci u16 mmio_base; 1468c2ecf20Sopenharmony_ci /* DMA controller index number (0-5). */ 1478c2ecf20Sopenharmony_ci int index; 1488c2ecf20Sopenharmony_ci /* Boolean. Is this a TX ring? */ 1498c2ecf20Sopenharmony_ci bool tx; 1508c2ecf20Sopenharmony_ci /* The type of DMA engine used. */ 1518c2ecf20Sopenharmony_ci enum b43legacy_dmatype type; 1528c2ecf20Sopenharmony_ci /* Boolean. Is this ring stopped at ieee80211 level? */ 1538c2ecf20Sopenharmony_ci bool stopped; 1548c2ecf20Sopenharmony_ci /* The QOS priority assigned to this ring. Only used for TX rings. 1558c2ecf20Sopenharmony_ci * This is the mac80211 "queue" value. */ 1568c2ecf20Sopenharmony_ci u8 queue_prio; 1578c2ecf20Sopenharmony_ci struct b43legacy_wldev *dev; 1588c2ecf20Sopenharmony_ci#ifdef CONFIG_B43LEGACY_DEBUG 1598c2ecf20Sopenharmony_ci /* Maximum number of used slots. */ 1608c2ecf20Sopenharmony_ci int max_used_slots; 1618c2ecf20Sopenharmony_ci /* Last time we injected a ring overflow. */ 1628c2ecf20Sopenharmony_ci unsigned long last_injected_overflow; 1638c2ecf20Sopenharmony_ci#endif /* CONFIG_B43LEGACY_DEBUG*/ 1648c2ecf20Sopenharmony_ci}; 1658c2ecf20Sopenharmony_ci 1668c2ecf20Sopenharmony_ci 1678c2ecf20Sopenharmony_cistatic inline 1688c2ecf20Sopenharmony_ciu32 b43legacy_dma_read(struct b43legacy_dmaring *ring, 1698c2ecf20Sopenharmony_ci u16 offset) 1708c2ecf20Sopenharmony_ci{ 1718c2ecf20Sopenharmony_ci return b43legacy_read32(ring->dev, ring->mmio_base + offset); 1728c2ecf20Sopenharmony_ci} 1738c2ecf20Sopenharmony_ci 1748c2ecf20Sopenharmony_cistatic inline 1758c2ecf20Sopenharmony_civoid b43legacy_dma_write(struct b43legacy_dmaring *ring, 1768c2ecf20Sopenharmony_ci u16 offset, u32 value) 1778c2ecf20Sopenharmony_ci{ 1788c2ecf20Sopenharmony_ci b43legacy_write32(ring->dev, ring->mmio_base + offset, value); 1798c2ecf20Sopenharmony_ci} 1808c2ecf20Sopenharmony_ci 1818c2ecf20Sopenharmony_ci 1828c2ecf20Sopenharmony_ciint b43legacy_dma_init(struct b43legacy_wldev *dev); 1838c2ecf20Sopenharmony_civoid b43legacy_dma_free(struct b43legacy_wldev *dev); 1848c2ecf20Sopenharmony_ci 1858c2ecf20Sopenharmony_civoid b43legacy_dma_tx_suspend(struct b43legacy_wldev *dev); 1868c2ecf20Sopenharmony_civoid b43legacy_dma_tx_resume(struct b43legacy_wldev *dev); 1878c2ecf20Sopenharmony_ci 1888c2ecf20Sopenharmony_ciint b43legacy_dma_tx(struct b43legacy_wldev *dev, 1898c2ecf20Sopenharmony_ci struct sk_buff *skb); 1908c2ecf20Sopenharmony_civoid b43legacy_dma_handle_txstatus(struct b43legacy_wldev *dev, 1918c2ecf20Sopenharmony_ci const struct b43legacy_txstatus *status); 1928c2ecf20Sopenharmony_ci 1938c2ecf20Sopenharmony_civoid b43legacy_dma_rx(struct b43legacy_dmaring *ring); 1948c2ecf20Sopenharmony_ci 1958c2ecf20Sopenharmony_ci#else /* CONFIG_B43LEGACY_DMA */ 1968c2ecf20Sopenharmony_ci 1978c2ecf20Sopenharmony_ci 1988c2ecf20Sopenharmony_cistatic inline 1998c2ecf20Sopenharmony_ciint b43legacy_dma_init(struct b43legacy_wldev *dev) 2008c2ecf20Sopenharmony_ci{ 2018c2ecf20Sopenharmony_ci return 0; 2028c2ecf20Sopenharmony_ci} 2038c2ecf20Sopenharmony_cistatic inline 2048c2ecf20Sopenharmony_civoid b43legacy_dma_free(struct b43legacy_wldev *dev) 2058c2ecf20Sopenharmony_ci{ 2068c2ecf20Sopenharmony_ci} 2078c2ecf20Sopenharmony_cistatic inline 2088c2ecf20Sopenharmony_ciint b43legacy_dma_tx(struct b43legacy_wldev *dev, 2098c2ecf20Sopenharmony_ci struct sk_buff *skb) 2108c2ecf20Sopenharmony_ci{ 2118c2ecf20Sopenharmony_ci return 0; 2128c2ecf20Sopenharmony_ci} 2138c2ecf20Sopenharmony_cistatic inline 2148c2ecf20Sopenharmony_civoid b43legacy_dma_handle_txstatus(struct b43legacy_wldev *dev, 2158c2ecf20Sopenharmony_ci const struct b43legacy_txstatus *status) 2168c2ecf20Sopenharmony_ci{ 2178c2ecf20Sopenharmony_ci} 2188c2ecf20Sopenharmony_cistatic inline 2198c2ecf20Sopenharmony_civoid b43legacy_dma_rx(struct b43legacy_dmaring *ring) 2208c2ecf20Sopenharmony_ci{ 2218c2ecf20Sopenharmony_ci} 2228c2ecf20Sopenharmony_cistatic inline 2238c2ecf20Sopenharmony_civoid b43legacy_dma_tx_suspend(struct b43legacy_wldev *dev) 2248c2ecf20Sopenharmony_ci{ 2258c2ecf20Sopenharmony_ci} 2268c2ecf20Sopenharmony_cistatic inline 2278c2ecf20Sopenharmony_civoid b43legacy_dma_tx_resume(struct b43legacy_wldev *dev) 2288c2ecf20Sopenharmony_ci{ 2298c2ecf20Sopenharmony_ci} 2308c2ecf20Sopenharmony_ci 2318c2ecf20Sopenharmony_ci#endif /* CONFIG_B43LEGACY_DMA */ 2328c2ecf20Sopenharmony_ci#endif /* B43legacy_DMA_H_ */ 233