Blame view

kernel/linux-rt-4.4.41/drivers/net/wireless/brcm80211/brcmsmac/dma.h 4.12 KB
5113f6f70   김현기   kernel add
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
  /*
   * Copyright (c) 2010 Broadcom Corporation
   *
   * Permission to use, copy, modify, and/or distribute this software for any
   * purpose with or without fee is hereby granted, provided that the above
   * copyright notice and this permission notice appear in all copies.
   *
   * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
   * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
   * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
   * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
   * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   */
  
  #ifndef	_BRCM_DMA_H_
  #define	_BRCM_DMA_H_
  
  #include <linux/delay.h>
  #include <linux/skbuff.h>
  #include "types.h"		/* forward structure declarations */
  
  /* map/unmap direction */
  #define	DMA_TX	1		/* TX direction for DMA */
  #define	DMA_RX	2		/* RX direction for DMA */
  
  /* DMA structure:
   *  support two DMA engines: 32 bits address or 64 bit addressing
   *  basic DMA register set is per channel(transmit or receive)
   *  a pair of channels is defined for convenience
   */
  
  /* 32 bits addressing */
  
  struct dma32diag {	/* diag access */
  	u32 fifoaddr;	/* diag address */
  	u32 fifodatalow;	/* low 32bits of data */
  	u32 fifodatahigh;	/* high 32bits of data */
  	u32 pad;		/* reserved */
  };
  
  /* 64 bits addressing */
  
  /* dma registers per channel(xmt or rcv) */
  struct dma64regs {
  	u32 control;	/* enable, et al */
  	u32 ptr;	/* last descriptor posted to chip */
  	u32 addrlow;	/* desc ring base address low 32-bits (8K aligned) */
  	u32 addrhigh;	/* desc ring base address bits 63:32 (8K aligned) */
  	u32 status0;	/* current descriptor, xmt state */
  	u32 status1;	/* active descriptor, xmt error */
  };
  
  /* range param for dma_getnexttxp() and dma_txreclaim */
  enum txd_range {
  	DMA_RANGE_ALL = 1,
  	DMA_RANGE_TRANSMITTED,
  	DMA_RANGE_TRANSFERED
  };
  
  /*
   * Exported data structure (read-only)
   */
  /* export structure */
  struct dma_pub {
  	uint txavail;		/* # free tx descriptors */
  	uint dmactrlflags;	/* dma control flags */
  
  	/* rx error counters */
  	uint rxgiants;		/* rx giant frames */
  	uint rxnobuf;		/* rx out of dma descriptors */
  	/* tx error counters */
  	uint txnobuf;		/* tx out of dma descriptors */
  };
  
  extern struct dma_pub *dma_attach(char *name, struct brcms_c_info *wlc,
  				  uint txregbase, uint rxregbase,
  				  uint ntxd, uint nrxd,
  				  uint rxbufsize, int rxextheadroom,
  				  uint nrxpost, uint rxoffset);
  
  void dma_rxinit(struct dma_pub *pub);
  int dma_rx(struct dma_pub *pub, struct sk_buff_head *skb_list);
  bool dma_rxfill(struct dma_pub *pub);
  bool dma_rxreset(struct dma_pub *pub);
  bool dma_txreset(struct dma_pub *pub);
  void dma_txinit(struct dma_pub *pub);
  int dma_txfast(struct brcms_c_info *wlc, struct dma_pub *pub,
  	       struct sk_buff *p0);
  void dma_txflush(struct dma_pub *pub);
  int dma_txpending(struct dma_pub *pub);
  void dma_kick_tx(struct dma_pub *pub);
  void dma_txsuspend(struct dma_pub *pub);
  bool dma_txsuspended(struct dma_pub *pub);
  void dma_txresume(struct dma_pub *pub);
  void dma_txreclaim(struct dma_pub *pub, enum txd_range range);
  void dma_rxreclaim(struct dma_pub *pub);
  void dma_detach(struct dma_pub *pub);
  unsigned long dma_getvar(struct dma_pub *pub, const char *name);
  struct sk_buff *dma_getnexttxp(struct dma_pub *pub, enum txd_range range);
  void dma_counterreset(struct dma_pub *pub);
  
  void dma_walk_packets(struct dma_pub *dmah, void (*callback_fnc)
  		      (void *pkt, void *arg_a), void *arg_a);
  
  /*
   * DMA(Bug) on bcm47xx chips seems to declare that the packet is ready, but
   * the packet length is not updated yet (by DMA) on the expected time.
   * Workaround is to hold processor till DMA updates the length, and stay off
   * the bus to allow DMA update the length in buffer
   */
  static inline void dma_spin_for_len(uint len, struct sk_buff *head)
  {
  #if defined(CONFIG_BCM47XX)
  	if (!len) {
  		while (!(len = *(u16 *) KSEG1ADDR(head->data)))
  			udelay(1);
  
  		*(u16 *) (head->data) = cpu_to_le16((u16) len);
  	}
  #endif				/* defined(CONFIG_BCM47XX) */
  }
  
  #endif				/* _BRCM_DMA_H_ */