233 lines · c
1/* SPDX-License-Identifier: GPL-2.0 */2#ifndef B43legacy_DMA_H_3#define B43legacy_DMA_H_4 5#include <linux/list.h>6#include <linux/spinlock.h>7#include <linux/workqueue.h>8#include <linux/linkage.h>9#include <linux/atomic.h>10 11#include "b43legacy.h"12 13 14/* DMA-Interrupt reasons. */15#define B43legacy_DMAIRQ_FATALMASK ((1 << 10) | (1 << 11) | (1 << 12) \16 | (1 << 14) | (1 << 15))17#define B43legacy_DMAIRQ_NONFATALMASK (1 << 13)18#define B43legacy_DMAIRQ_RX_DONE (1 << 16)19 20 21/*** 32-bit DMA Engine. ***/22 23/* 32-bit DMA controller registers. */24#define B43legacy_DMA32_TXCTL 0x0025#define B43legacy_DMA32_TXENABLE 0x0000000126#define B43legacy_DMA32_TXSUSPEND 0x0000000227#define B43legacy_DMA32_TXLOOPBACK 0x0000000428#define B43legacy_DMA32_TXFLUSH 0x0000001029#define B43legacy_DMA32_TXADDREXT_MASK 0x0003000030#define B43legacy_DMA32_TXADDREXT_SHIFT 1631#define B43legacy_DMA32_TXRING 0x0432#define B43legacy_DMA32_TXINDEX 0x0833#define B43legacy_DMA32_TXSTATUS 0x0C34#define B43legacy_DMA32_TXDPTR 0x00000FFF35#define B43legacy_DMA32_TXSTATE 0x0000F00036#define B43legacy_DMA32_TXSTAT_DISABLED 0x0000000037#define B43legacy_DMA32_TXSTAT_ACTIVE 0x0000100038#define B43legacy_DMA32_TXSTAT_IDLEWAIT 0x0000200039#define B43legacy_DMA32_TXSTAT_STOPPED 0x0000300040#define B43legacy_DMA32_TXSTAT_SUSP 0x0000400041#define B43legacy_DMA32_TXERROR 0x000F000042#define B43legacy_DMA32_TXERR_NOERR 0x0000000043#define B43legacy_DMA32_TXERR_PROT 0x0001000044#define B43legacy_DMA32_TXERR_UNDERRUN 0x0002000045#define B43legacy_DMA32_TXERR_BUFREAD 0x0003000046#define B43legacy_DMA32_TXERR_DESCREAD 0x0004000047#define B43legacy_DMA32_TXACTIVE 0xFFF0000048#define B43legacy_DMA32_RXCTL 0x1049#define B43legacy_DMA32_RXENABLE 0x0000000150#define B43legacy_DMA32_RXFROFF_MASK 0x000000FE51#define B43legacy_DMA32_RXFROFF_SHIFT 152#define B43legacy_DMA32_RXDIRECTFIFO 0x0000010053#define B43legacy_DMA32_RXADDREXT_MASK 0x0003000054#define B43legacy_DMA32_RXADDREXT_SHIFT 1655#define B43legacy_DMA32_RXRING 0x1456#define B43legacy_DMA32_RXINDEX 0x1857#define B43legacy_DMA32_RXSTATUS 0x1C58#define B43legacy_DMA32_RXDPTR 0x00000FFF59#define B43legacy_DMA32_RXSTATE 0x0000F00060#define B43legacy_DMA32_RXSTAT_DISABLED 0x0000000061#define B43legacy_DMA32_RXSTAT_ACTIVE 0x0000100062#define B43legacy_DMA32_RXSTAT_IDLEWAIT 0x0000200063#define B43legacy_DMA32_RXSTAT_STOPPED 0x0000300064#define B43legacy_DMA32_RXERROR 0x000F000065#define B43legacy_DMA32_RXERR_NOERR 0x0000000066#define B43legacy_DMA32_RXERR_PROT 0x0001000067#define B43legacy_DMA32_RXERR_OVERFLOW 0x0002000068#define B43legacy_DMA32_RXERR_BUFWRITE 0x0003000069#define B43legacy_DMA32_RXERR_DESCREAD 0x0004000070#define B43legacy_DMA32_RXACTIVE 0xFFF0000071 72/* 32-bit DMA descriptor. */73struct b43legacy_dmadesc32 {74 __le32 control;75 __le32 address;76} __packed;77#define B43legacy_DMA32_DCTL_BYTECNT 0x00001FFF78#define B43legacy_DMA32_DCTL_ADDREXT_MASK 0x0003000079#define B43legacy_DMA32_DCTL_ADDREXT_SHIFT 1680#define B43legacy_DMA32_DCTL_DTABLEEND 0x1000000081#define B43legacy_DMA32_DCTL_IRQ 0x2000000082#define B43legacy_DMA32_DCTL_FRAMEEND 0x4000000083#define B43legacy_DMA32_DCTL_FRAMESTART 0x8000000084 85 86/* Misc DMA constants */87#define B43legacy_DMA_RINGMEMSIZE PAGE_SIZE88#define B43legacy_DMA0_RX_FRAMEOFFSET 3089#define B43legacy_DMA3_RX_FRAMEOFFSET 090 91 92/* DMA engine tuning knobs */93#define B43legacy_TXRING_SLOTS 12894#define B43legacy_RXRING_SLOTS 6495#define B43legacy_DMA0_RX_BUFFERSIZE (2304 + 100)96#define B43legacy_DMA3_RX_BUFFERSIZE 1697 98 99 100#ifdef CONFIG_B43LEGACY_DMA101 102 103struct sk_buff;104struct b43legacy_private;105struct b43legacy_txstatus;106 107 108struct b43legacy_dmadesc_meta {109 /* The kernel DMA-able buffer. */110 struct sk_buff *skb;111 /* DMA base bus-address of the descriptor buffer. */112 dma_addr_t dmaaddr;113 /* ieee80211 TX status. Only used once per 802.11 frag. */114 bool is_last_fragment;115};116 117enum b43legacy_dmatype {118 B43legacy_DMA_30BIT = 30,119 B43legacy_DMA_32BIT = 32,120};121 122struct b43legacy_dmaring {123 /* Kernel virtual base address of the ring memory. */124 void *descbase;125 /* Meta data about all descriptors. */126 struct b43legacy_dmadesc_meta *meta;127 /* Cache of TX headers for each slot.128 * This is to avoid an allocation on each TX.129 * This is NULL for an RX ring.130 */131 u8 *txhdr_cache;132 /* (Unadjusted) DMA base bus-address of the ring memory. */133 dma_addr_t dmabase;134 /* Number of descriptor slots in the ring. */135 int nr_slots;136 /* Number of used descriptor slots. */137 int used_slots;138 /* Currently used slot in the ring. */139 int current_slot;140 /* Frameoffset in octets. */141 u32 frameoffset;142 /* Descriptor buffer size. */143 u16 rx_buffersize;144 /* The MMIO base register of the DMA controller. */145 u16 mmio_base;146 /* DMA controller index number (0-5). */147 int index;148 /* Boolean. Is this a TX ring? */149 bool tx;150 /* The type of DMA engine used. */151 enum b43legacy_dmatype type;152 /* Boolean. Is this ring stopped at ieee80211 level? */153 bool stopped;154 /* The QOS priority assigned to this ring. Only used for TX rings.155 * This is the mac80211 "queue" value. */156 u8 queue_prio;157 struct b43legacy_wldev *dev;158#ifdef CONFIG_B43LEGACY_DEBUG159 /* Maximum number of used slots. */160 int max_used_slots;161 /* Last time we injected a ring overflow. */162 unsigned long last_injected_overflow;163#endif /* CONFIG_B43LEGACY_DEBUG*/164};165 166 167static inline168u32 b43legacy_dma_read(struct b43legacy_dmaring *ring,169 u16 offset)170{171 return b43legacy_read32(ring->dev, ring->mmio_base + offset);172}173 174static inline175void b43legacy_dma_write(struct b43legacy_dmaring *ring,176 u16 offset, u32 value)177{178 b43legacy_write32(ring->dev, ring->mmio_base + offset, value);179}180 181 182int b43legacy_dma_init(struct b43legacy_wldev *dev);183void b43legacy_dma_free(struct b43legacy_wldev *dev);184 185void b43legacy_dma_tx_suspend(struct b43legacy_wldev *dev);186void b43legacy_dma_tx_resume(struct b43legacy_wldev *dev);187 188int b43legacy_dma_tx(struct b43legacy_wldev *dev,189 struct sk_buff *skb);190void b43legacy_dma_handle_txstatus(struct b43legacy_wldev *dev,191 const struct b43legacy_txstatus *status);192 193void b43legacy_dma_rx(struct b43legacy_dmaring *ring);194 195#else /* CONFIG_B43LEGACY_DMA */196 197 198static inline199int b43legacy_dma_init(struct b43legacy_wldev *dev)200{201 return 0;202}203static inline204void b43legacy_dma_free(struct b43legacy_wldev *dev)205{206}207static inline208int b43legacy_dma_tx(struct b43legacy_wldev *dev,209 struct sk_buff *skb)210{211 return 0;212}213static inline214void b43legacy_dma_handle_txstatus(struct b43legacy_wldev *dev,215 const struct b43legacy_txstatus *status)216{217}218static inline219void b43legacy_dma_rx(struct b43legacy_dmaring *ring)220{221}222static inline223void b43legacy_dma_tx_suspend(struct b43legacy_wldev *dev)224{225}226static inline227void b43legacy_dma_tx_resume(struct b43legacy_wldev *dev)228{229}230 231#endif /* CONFIG_B43LEGACY_DMA */232#endif /* B43legacy_DMA_H_ */233