/lib/firmware/carl9170fw/carlfw/include/dma.h is in linux-firmware 1.127.24.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 | /*
* carl9170 firmware - used by the ar9170 wireless device
*
* This module contains DMA descriptor related definitions.
*
* Copyright (c) 2000-2005 ZyDAS Technology Corporation
* Copyright (c) 2007-2009 Atheros Communications, Inc.
* Copyright 2009 Johannes Berg <johannes@sipsolutions.net>
* Copyright 2009-2011 Christian Lamparter <chunkeey@googlemail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef __CARL9170FW_DMA_H
#define __CARL9170FW_DMA_H
#include "config.h"
#include "types.h"
#include "compiler.h"
#include "hw.h"
#include "ieee80211.h"
#include "wlan.h"
struct dma_desc {
volatile uint16_t status; /* Descriptor status */
volatile uint16_t ctrl; /* Descriptor control */
volatile uint16_t dataSize; /* Data size */
volatile uint16_t totalLen; /* Total length */
struct dma_desc *lastAddr; /* Last address of this chain */
union {
uint8_t *_dataAddr; /* Data buffer address */
void *dataAddr;
} __packed;
struct dma_desc *nextAddr; /* Next TD address */
} __packed __aligned(4);
/* Up, Dn, 5x Tx, retry, Rx, [USB Int], (CAB), FW */
#define AR9170_TERMINATOR_NUMBER_B 10
#define AR9170_TERMINATOR_NUMBER_INT 1
#ifdef CONFIG_CARL9170FW_CAB_QUEUE
#define AR9170_TERMINATOR_NUMBER_CAB CARL9170_INTF_NUM
#else
#define AR9170_TERMINATOR_NUMBER_CAB 0
#endif /* CONFIG_CARL9170FW_CAB_QUEUE */
#define AR9170_TERMINATOR_NUMBER (AR9170_TERMINATOR_NUMBER_B + \
AR9170_TERMINATOR_NUMBER_INT + \
AR9170_TERMINATOR_NUMBER_CAB)
#define AR9170_BLOCK_SIZE (256 + 64)
#define AR9170_DESCRIPTOR_SIZE (sizeof(struct dma_desc))
struct ar9170_tx_ba_frame {
struct ar9170_tx_hwdesc hdr;
struct ieee80211_ba ba;
} __packed;
struct carl9170_tx_ba_superframe {
struct carl9170_tx_superdesc s;
struct ar9170_tx_ba_frame f;
} __packed;
struct ar9170_tx_null_frame {
struct ar9170_tx_hwdesc hdr;
struct ieee80211_hdr null;
} __packed;
struct carl9170_tx_null_superframe {
struct carl9170_tx_superdesc s;
struct ar9170_tx_null_frame f;
} __packed;
#define CARL9170_BA_BUFFER_LEN (__roundup(sizeof(struct carl9170_tx_ba_superframe), 16))
#define CARL9170_RSP_BUFFER_LEN AR9170_BLOCK_SIZE
struct carl9170_sram_reserved {
union {
uint32_t buf[CARL9170_BA_BUFFER_LEN / sizeof(uint32_t)];
struct carl9170_tx_ba_superframe ba;
} ba;
union {
uint32_t buf[CARL9170_MAX_CMD_LEN / sizeof(uint32_t)];
struct carl9170_cmd cmd;
#ifdef CONFIG_CARL9170FW_WOL
struct carl9170_tx_null_superframe null;
#endif /* CONFIG_CARL9170FW_WOL */
} cmd;
union {
uint32_t buf[CARL9170_RSP_BUFFER_LEN / sizeof(uint32_t)];
struct carl9170_rsp rsp;
} rsp;
union {
uint32_t buf[CARL9170_INTF_NUM][AR9170_MAC_BCN_LENGTH_MAX / sizeof(uint32_t)];
} bcn;
};
/*
* Memory layout in RAM:
*
* 0x100000 +--
* | terminator descriptors (dma_desc)
* | - Up (to USB host)
* | - Down (from USB host)
* | - TX (5x, to wifi)
* | - AMPDU TX retry
* | - RX (from wifi)
* | - CAB Queue
* | - FW cmd & req descriptor
* | - BlockAck descriptor
* | total: AR9170_TERMINATOR_NUMBER
* +--
* | block descriptors (dma_desc)
* | (AR9170_BLOCK_NUMBER)
* AR9170_BLOCK_BUFFER_BASE +-- align to multiple of 64
* | block buffers (AR9170_BLOCK_SIZE each)
* | (AR9170_BLOCK_NUMBER)
* approx. 0x117c00 +--
* | BA buffer (128 bytes)
* +--
* | CMD buffer (128 bytes)
* | - used as NULLFRAME buffer (128 bytes) for WOL
* +--
* | RSP buffer (320 bytes)
* +--
* | BEACON buffer (256 bytes)
* +--
* | unaccounted space / padding
* +--
* 0x18000
*/
#define CARL9170_SRAM_RESERVED (sizeof(struct carl9170_sram_reserved))
#define AR9170_FRAME_MEMORY_SIZE (AR9170_SRAM_SIZE - CARL9170_SRAM_RESERVED)
#define BLOCK_ALIGNMENT 64
#define NONBLOCK_DESCRIPTORS_SIZE \
(AR9170_DESCRIPTOR_SIZE * (AR9170_TERMINATOR_NUMBER))
#define NONBLOCK_DESCRIPTORS_SIZE_ALIGNED \
(ALIGN(NONBLOCK_DESCRIPTORS_SIZE, BLOCK_ALIGNMENT))
#define AR9170_BLOCK_NUMBER ((AR9170_FRAME_MEMORY_SIZE - NONBLOCK_DESCRIPTORS_SIZE_ALIGNED) / \
(AR9170_BLOCK_SIZE + AR9170_DESCRIPTOR_SIZE))
struct ar9170_data_block {
uint8_t data[AR9170_BLOCK_SIZE];
};
struct ar9170_dma_memory {
struct dma_desc terminator[AR9170_TERMINATOR_NUMBER];
struct dma_desc block[AR9170_BLOCK_NUMBER];
struct ar9170_data_block data[AR9170_BLOCK_NUMBER] __aligned(BLOCK_ALIGNMENT);
struct carl9170_sram_reserved reserved __aligned(BLOCK_ALIGNMENT);
};
extern struct ar9170_dma_memory dma_mem;
#define AR9170_DOWN_BLOCK_RATIO 2
#define AR9170_RX_BLOCK_RATIO 1
/* Tx 16*2 = 32 packets => 32*(5*320) */
#define AR9170_TX_BLOCK_NUMBER (AR9170_BLOCK_NUMBER * AR9170_DOWN_BLOCK_RATIO / \
(AR9170_RX_BLOCK_RATIO + AR9170_DOWN_BLOCK_RATIO))
#define AR9170_RX_BLOCK_NUMBER (AR9170_BLOCK_NUMBER - AR9170_TX_BLOCK_NUMBER)
/* Error code */
#define AR9170_ERR_FS_BIT 1
#define AR9170_ERR_LS_BIT 2
#define AR9170_ERR_OWN_BITS 3
#define AR9170_ERR_DATA_SIZE 4
#define AR9170_ERR_TOTAL_LEN 5
#define AR9170_ERR_DATA 6
#define AR9170_ERR_SEQ 7
#define AR9170_ERR_LEN 8
/* Status bits definitions */
/* Own bits definitions */
#define AR9170_OWN_BITS 0x3
#define AR9170_OWN_BITS_S 0
#define AR9170_OWN_BITS_SW 0x0
#define AR9170_OWN_BITS_HW 0x1
#define AR9170_OWN_BITS_SE 0x2
/* Control bits definitions */
#define AR9170_CTRL_TXFAIL 1
#define AR9170_CTRL_BAFAIL 2
#define AR9170_CTRL_FAIL (AR9170_CTRL_TXFAIL | AR9170_CTRL_BAFAIL)
/* First segament bit */
#define AR9170_CTRL_LS_BIT 0x100
/* Last segament bit */
#define AR9170_CTRL_FS_BIT 0x200
struct dma_queue {
struct dma_desc *head;
struct dma_desc *terminator;
};
#define DESC_PAYLOAD(a) ((void *)a->dataAddr)
#define DESC_PAYLOAD_OFF(a, offset) ((void *)((unsigned long)(a->_dataAddr) + offset))
struct dma_desc *dma_unlink_head(struct dma_queue *queue);
void dma_init_descriptors(void);
void dma_reclaim(struct dma_queue *q, struct dma_desc *desc);
void dma_put(struct dma_queue *q, struct dma_desc *desc);
static inline __inline bool is_terminator(struct dma_queue *q, struct dma_desc *desc)
{
return q->terminator == desc;
}
static inline __inline bool queue_empty(struct dma_queue *q)
{
return q->head == q->terminator;
}
/*
* Get a completed packet with # descriptors. Return the first
* descriptor and pointer the head directly by lastAddr->nextAddr
*/
static inline __inline struct dma_desc *dma_dequeue_bits(struct dma_queue *q,
uint16_t bits)
{
struct dma_desc *desc = NULL;
if ((q->head->status & AR9170_OWN_BITS) == bits)
desc = dma_unlink_head(q);
return desc;
}
static inline __inline struct dma_desc *dma_dequeue_not_bits(struct dma_queue *q,
uint16_t bits)
{
struct dma_desc *desc = NULL;
/* AR9170_OWN_BITS_HW will be filtered out here too. */
if ((q->head->status & AR9170_OWN_BITS) != bits)
desc = dma_unlink_head(q);
return desc;
}
#define for_each_desc_bits(desc, queue, bits) \
while ((desc = dma_dequeue_bits(queue, bits)))
#define for_each_desc_not_bits(desc, queue, bits) \
while ((desc = dma_dequeue_not_bits(queue, bits)))
#define for_each_desc(desc, queue) \
while ((desc = dma_unlink_head(queue)))
#define __for_each_desc_bits(desc, queue, bits) \
for (desc = (queue)->head; \
(desc != (queue)->terminator && \
(desc->status & AR9170_OWN_BITS) == bits); \
desc = desc->lastAddr->nextAddr)
#define __while_desc_bits(desc, queue, bits) \
for (desc = (queue)->head; \
(!queue_empty(queue) && \
(desc->status & AR9170_OWN_BITS) == bits); \
desc = (queue)->head)
#define __for_each_desc_continue(desc, queue) \
for (; desc != (queue)->terminator; \
desc = (desc)->lastAddr->nextAddr)
#define __for_each_desc(desc, queue) \
for (desc = (queue)->head; \
desc != (queue)->terminator; \
desc = (desc)->lastAddr->nextAddr)
#define __for_each_desc_safe(desc, tmp, queue) \
for (desc = (queue)->head, tmp = desc->lastAddr->nextAddr; \
desc != (queue)->terminator; \
desc = tmp, tmp = tmp->lastAddr->nextAddr)
#define __while_subdesc(desc, queue) \
for (desc = (queue)->head; \
desc != (queue)->terminator; \
desc = (desc)->nextAddr)
static inline __inline unsigned int queue_len(struct dma_queue *q)
{
struct dma_desc *desc;
unsigned int i = 0;
__while_subdesc(desc, q)
i++;
return i;
}
/*
* rearm a completed packet, so it will be processed agian.
*/
static inline __inline void dma_rearm(struct dma_desc *desc)
{
/* Set OWN bit to HW */
desc->status = ((desc->status & (~AR9170_OWN_BITS)) |
AR9170_OWN_BITS_HW);
}
static inline __inline void dma_fix_downqueue(struct dma_desc *desc)
{
desc->status = AR9170_OWN_BITS_HW;
desc->ctrl = 0;
desc->dataSize = 0;
desc->totalLen = AR9170_BLOCK_SIZE;
desc->lastAddr = desc;
}
static inline void __check_desc(void)
{
struct ar9170_dma_memory mem;
BUILD_BUG_ON(sizeof(struct ar9170_data_block) != AR9170_BLOCK_SIZE);
BUILD_BUG_ON(sizeof(struct dma_desc) != 20);
BUILD_BUG_ON(sizeof(mem) > AR9170_SRAM_SIZE);
BUILD_BUG_ON(offsetof(struct carl9170_sram_reserved, ba.buf) & (BLOCK_ALIGNMENT - 1));
BUILD_BUG_ON(offsetof(struct carl9170_sram_reserved, cmd.buf) & (BLOCK_ALIGNMENT - 1));
BUILD_BUG_ON(offsetof(struct carl9170_sram_reserved, rsp.buf) & (BLOCK_ALIGNMENT - 1));
BUILD_BUG_ON(offsetof(struct carl9170_sram_reserved, bcn.buf) & (BLOCK_ALIGNMENT - 1));
BUILD_BUG_ON(sizeof(struct carl9170_tx_null_superframe) > CARL9170_MAX_CMD_LEN);
}
#endif /* __CARL9170FW_DMA_H */
|