Path: blob/main/sys/contrib/dev/broadcom/brcm80211/brcmsmac/dma.h
178665 views
/*1* Copyright (c) 2010 Broadcom Corporation2*3* Permission to use, copy, modify, and/or distribute this software for any4* purpose with or without fee is hereby granted, provided that the above5* copyright notice and this permission notice appear in all copies.6*7* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES8* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF9* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY10* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES11* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION12* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN13* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.14*/1516#ifndef _BRCM_DMA_H_17#define _BRCM_DMA_H_1819#include <linux/delay.h>20#include <linux/skbuff.h>21#include "types.h" /* forward structure declarations */2223/* map/unmap direction */24#define DMA_TX 1 /* TX direction for DMA */25#define DMA_RX 2 /* RX direction for DMA */2627/* DMA structure:28* support two DMA engines: 32 bits address or 64 bit addressing29* basic DMA register set is per channel(transmit or receive)30* a pair of channels is defined for convenience31*/3233/* 32 bits addressing */3435struct dma32diag { /* diag access */36u32 fifoaddr; /* diag address */37u32 fifodatalow; /* low 32bits of data */38u32 fifodatahigh; /* high 32bits of data */39u32 pad; /* reserved */40};4142/* 64 bits addressing */4344/* dma registers per channel(xmt or rcv) */45struct dma64regs {46u32 control; /* enable, et al */47u32 ptr; /* last descriptor posted to chip */48u32 addrlow; /* desc ring base address low 32-bits (8K aligned) */49u32 addrhigh; /* desc ring base address bits 63:32 (8K aligned) */50u32 status0; /* current descriptor, xmt state */51u32 status1; /* active descriptor, xmt error */52};5354/* range param for dma_getnexttxp() and dma_txreclaim */55enum txd_range {56DMA_RANGE_ALL = 1,57DMA_RANGE_TRANSMITTED,58DMA_RANGE_TRANSFERED59};6061/*62* Exported data structure (read-only)63*/64/* export structure */65struct dma_pub {66uint txavail; /* # free tx descriptors */67uint dmactrlflags; /* dma control flags */6869/* rx error counters */70uint rxgiants; /* rx giant frames */71uint rxnobuf; /* rx out of dma descriptors */72/* tx error counters */73uint txnobuf; /* tx out of dma descriptors */74};7576extern struct dma_pub *dma_attach(char *name, struct brcms_c_info *wlc,77uint txregbase, uint rxregbase,78uint ntxd, uint nrxd,79uint rxbufsize, int rxextheadroom,80uint nrxpost, uint rxoffset);8182void dma_rxinit(struct dma_pub *pub);83int dma_rx(struct dma_pub *pub, struct sk_buff_head *skb_list);84bool dma_rxfill(struct dma_pub *pub);85bool dma_rxreset(struct dma_pub *pub);86bool dma_txreset(struct dma_pub *pub);87void dma_txinit(struct dma_pub *pub);88int dma_txfast(struct brcms_c_info *wlc, struct dma_pub *pub,89struct sk_buff *p0);90int dma_txpending(struct dma_pub *pub);91void dma_kick_tx(struct dma_pub *pub);92void dma_txsuspend(struct dma_pub *pub);93bool dma_txsuspended(struct dma_pub *pub);94void dma_txresume(struct dma_pub *pub);95void dma_txreclaim(struct dma_pub *pub, enum txd_range range);96void dma_rxreclaim(struct dma_pub *pub);97void dma_detach(struct dma_pub *pub);98unsigned long dma_getvar(struct dma_pub *pub, const char *name);99struct sk_buff *dma_getnexttxp(struct dma_pub *pub, enum txd_range range);100void dma_counterreset(struct dma_pub *pub);101102void dma_walk_packets(struct dma_pub *dmah, void (*callback_fnc)103(void *pkt, void *arg_a), void *arg_a);104105/*106* DMA(Bug) on bcm47xx chips seems to declare that the packet is ready, but107* the packet length is not updated yet (by DMA) on the expected time.108* Workaround is to hold processor till DMA updates the length, and stay off109* the bus to allow DMA update the length in buffer110*/111static inline void dma_spin_for_len(uint len, struct sk_buff *head)112{113#if defined(CONFIG_BCM47XX)114if (!len) {115while (!(len = *(u16 *) KSEG1ADDR(head->data)))116udelay(1);117118*(u16 *) (head->data) = cpu_to_le16((u16) len);119}120#endif /* defined(CONFIG_BCM47XX) */121}122123#endif /* _BRCM_DMA_H_ */124125126