summaryrefslogtreecommitdiff
path: root/sys/dev/pci/if_bgevar.h
blob: fdf66f1be46fa5d3c6c499de375fb7f31da9f707 (plain)
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
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
/*	$NetBSD: if_bgevar.h,v 1.41 2023/02/21 22:13:02 andvar Exp $	*/
/*
 * Copyright (c) 2001 Wind River Systems
 * Copyright (c) 1997, 1998, 1999, 2001
 *	Bill Paul <wpaul@windriver.com>.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by Bill Paul.
 * 4. Neither the name of the author nor the names of any co-contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 *
 * $FreeBSD: if_bgereg.h,v 1.1.2.7 2002/11/02 18:17:55 mp Exp $
 */

/*
 * BCM570x memory map. The internal memory layout varies somewhat
 * depending on whether or not we have external SSRAM attached.
 * The BCM5700 can have up to 16MB of external memory. The BCM5701
 * is apparently not designed to use external SSRAM. The mappings
 * up to the first 4 send rings are the same for both internal and
 * external memory configurations. Note that mini RX ring space is
 * only available with external SSRAM configurations, which means
 * the mini RX ring is not supported on the BCM5701.
 *
 * The NIC's memory can be accessed by the host in one of 3 ways:
 *
 * 1) Indirect register access. The MEMWIN_BASEADDR and MEMWIN_DATA
 *    registers in PCI config space can be used to read any 32-bit
 *    address within the NIC's memory.
 *
 * 2) Memory window access. The MEMWIN_BASEADDR register in PCI config
 *    space can be used in conjunction with the memory window in the
 *    device register space at offset 0x8000 to read any 32K chunk
 *    of NIC memory.
 *
 * 3) Flat mode. If the 'flat mode' bit in the PCI state register is
 *    set, the device I/O mapping consumes 32MB of host address space,
 *    allowing all of the registers and internal NIC memory to be
 *    accessed directly. NIC memory addresses are offset by 0x01000000.
 *    Flat mode consumes so much host address space that it is not
 *    recommended.
 */

#ifndef _DEV_PCI_IF_BGEVAR_H_
#define _DEV_PCI_IF_BGEVAR_H_

#include <sys/bus.h>
#include <sys/rndsource.h>
#include <sys/time.h>

#include <net/if_ether.h>

#include <dev/pci/pcivar.h>

#define BGE_HOSTADDR(x, y)						      \
	do {								      \
		(x).bge_addr_lo = BUS_ADDR_LO32(y);			      \
		if (sizeof (bus_addr_t) == 8)				      \
			(x).bge_addr_hi = BUS_ADDR_HI32(y);		      \
		else							      \
			(x).bge_addr_hi = 0;				      \
	} while(0)

#define RCB_WRITE_4(sc, rcb, offset, val)				      \
	bus_space_write_4(sc->bge_btag, sc->bge_bhandle,		      \
			  rcb + offsetof(struct bge_rcb, offset), val)

/*
 * Other utility macros.
 */
#define BGE_INC(x, y)	(x) = (x + 1) % y

/*
 * Register access macros. The Tigon always uses memory mapped register
 * accesses and all registers must be accessed with 32 bit operations.
 */

#define CSR_WRITE_4(sc, reg, val)					      \
	bus_space_write_4(sc->bge_btag, sc->bge_bhandle, reg, val)

#define CSR_READ_4(sc, reg)						      \
	bus_space_read_4(sc->bge_btag, sc->bge_bhandle, reg)

#define CSR_WRITE_4_FLUSH(sc, reg, val)					      \
	do {								      \
		CSR_WRITE_4(sc, reg, val);				      \
		CSR_READ_4(sc, reg);					      \
	} while (0)

#define BGE_SETBIT(sc, reg, x)						      \
	CSR_WRITE_4(sc, reg, (CSR_READ_4(sc, reg) | (x)))
#define BGE_SETBIT_FLUSH(sc, reg, x)					      \
	do {								      \
		BGE_SETBIT(sc, reg, x);					      \
		CSR_READ_4(sc, reg);					      \
	} while (0)
#define BGE_CLRBIT(sc, reg, x)						      \
	CSR_WRITE_4(sc, reg, (CSR_READ_4(sc, reg) & ~(x)))
#define BGE_CLRBIT_FLUSH(sc, reg, x)					      \
	do {								      \
		BGE_CLRBIT(sc, reg, x);					      \
		CSR_READ_4(sc, reg);					      \
	} while (0)

/* BAR2 APE register access macros. */
#define	APE_WRITE_4(sc, reg, val)					      \
	bus_space_write_4(sc->bge_apetag, sc->bge_apehandle, reg, val)

#define	APE_READ_4(sc, reg)						      \
	bus_space_read_4(sc->bge_apetag, sc->bge_apehandle, reg)

#define	APE_WRITE_4_FLUSH(sc, reg, val)					      \
	do {								      \
		APE_WRITE_4(sc, reg, val);				      \
		APE_READ_4(sc, reg);					      \
	} while (0)

#define	APE_SETBIT(sc, reg, x)						      \
	APE_WRITE_4(sc, reg, (APE_READ_4(sc, reg) | (x)))
#define	APE_CLRBIT(sc, reg, x)						      \
	APE_WRITE_4(sc, reg, (APE_READ_4(sc, reg) & ~(x)))

#define PCI_SETBIT(pc, tag, reg, x)					      \
	pci_conf_write(pc, tag, reg, (pci_conf_read(pc, tag, reg) | (x)))
#define PCI_CLRBIT(pc, tag, reg, x)					      \
	pci_conf_write(pc, tag, reg, (pci_conf_read(pc, tag, reg) & ~(x)))

/*
 * Memory management stuff. Note: the SSLOTS, MSLOTS and JSLOTS
 * values are tuneable. They control the actual amount of buffers
 * allocated for the standard, mini and jumbo receive rings.
 */

#define BGE_SSLOTS	256
#define BGE_MSLOTS	256
#define BGE_JSLOTS	384

#define BGE_JRAWLEN	(BGE_JUMBO_FRAMELEN + ETHER_ALIGN)
#define BGE_JLEN	(BGE_JRAWLEN + (sizeof(uint64_t) - 		      \
			    (BGE_JRAWLEN % sizeof(uint64_t))))
#define BGE_JPAGESZ 	PAGE_SIZE
#define BGE_RESID 	(BGE_JPAGESZ - (BGE_JLEN * BGE_JSLOTS) % BGE_JPAGESZ)
#define BGE_JMEM 	((BGE_JLEN * BGE_JSLOTS) + BGE_RESID)

/*
 * Ring structures. Most of these reside in host memory and we tell
 * the NIC where they are via the ring control blocks. The exceptions
 * are the tx and command rings, which live in NIC memory and which
 * we access via the shared memory window.
 */
struct bge_ring_data {
	struct bge_rx_bd	bge_rx_std_ring[BGE_STD_RX_RING_CNT];
	struct bge_rx_bd	bge_rx_jumbo_ring[BGE_JUMBO_RX_RING_CNT];
	struct bge_rx_bd	bge_rx_return_ring[BGE_RETURN_RING_CNT];
	struct bge_tx_bd	bge_tx_ring[BGE_TX_RING_CNT];
	struct bge_status_block	bge_status_block;
	struct bge_tx_desc	*bge_tx_ring_nic;/* pointer to shared mem */
	struct bge_cmd_desc	*bge_cmd_ring;	/* pointer to shared mem */
	struct bge_gib		bge_info;
};

#define BGE_RING_DMA_ADDR(sc, offset)					      \
	((sc)->bge_ring_map->dm_segs[0].ds_addr +			      \
	offsetof(struct bge_ring_data, offset))

/*
 * Number of DMA segments in a TxCB. Note that this is carefully
 * chosen to make the total struct size an even power of two. It's
 * critical that no TxCB be split across a page boundary since
 * no attempt is made to allocate physically contiguous memory.
 *
 */
#if 0	/* pre-TSO values */
#define BGE_TXDMA_MAX	ETHER_MAX_LEN_JUMBO
#ifdef _LP64
#define BGE_NTXSEG	30
#else
#define BGE_NTXSEG	31
#endif
#else	/* TSO values */
#define BGE_TXDMA_MAX	(round_page(IP_MAXPACKET))	/* for TSO */
#ifdef _LP64
#define BGE_NTXSEG	120	/* XXX just a guess */
#else
#define BGE_NTXSEG	124	/* XXX just a guess */
#endif
#endif	/* TSO values */

#define	BGE_STATUS_BLK_SZ	sizeof (struct bge_status_block)

/*
 * Mbuf pointers. We need these to keep track of the virtual addresses
 * of our mbuf chains since we can only convert from physical to virtual,
 * not the other way around.
 */
struct bge_chain_data {
	struct mbuf		*bge_tx_chain[BGE_TX_RING_CNT];
	struct mbuf		*bge_rx_std_chain[BGE_STD_RX_RING_CNT];
	struct mbuf		*bge_rx_jumbo_chain[BGE_JUMBO_RX_RING_CNT];
	bus_dmamap_t		bge_rx_std_map[BGE_STD_RX_RING_CNT];
	bus_dmamap_t		bge_rx_jumbo_map;
	bus_dma_segment_t	bge_rx_jumbo_seg;
	/* Stick the jumbo mem management stuff here too. */
	void *			bge_jslots[BGE_JSLOTS];
	void *			bge_jumbo_buf;
};

#define BGE_JUMBO_DMA_ADDR(sc, m) \
	((sc)->bge_cdata.bge_rx_jumbo_map->dm_segs[0].ds_addr + \
	 (mtod((m), char *) - (char *)(sc)->bge_cdata.bge_jumbo_buf))

struct bge_type {
	uint16_t		bge_vid;
	uint16_t		bge_did;
	char			*bge_name;
};

#define BGE_TIMEOUT		100000
#define BGE_TXCONS_UNSET		0xFFFF	/* impossible value */

struct bge_jpool_entry {
	int				slot;
	SLIST_ENTRY(bge_jpool_entry)	jpool_entries;
};

struct bge_bcom_hack {
	int			reg;
	int			val;
};

struct txdmamap_pool_entry {
	bus_dmamap_t dmamap;
	bus_dmamap_t dmamap32;
	bool is_dma32;
	SLIST_ENTRY(txdmamap_pool_entry) link;
};

#define	ASF_ENABLE		1
#define	ASF_NEW_HANDSHAKE	2
#define	ASF_STACKUP		4

struct bge_softc {
	device_t		bge_dev;
	struct ethercom		ethercom;	/* interface info */
	bus_space_handle_t	bge_bhandle;
	bus_space_tag_t		bge_btag;
	bus_size_t		bge_bsize;
	bus_space_handle_t	bge_apehandle;
	bus_space_tag_t		bge_apetag;
	bus_size_t		bge_apesize;
	void			*bge_intrhand;
	pci_intr_handle_t	*bge_pihp;
	pci_chipset_tag_t	sc_pc;
	pcitag_t		sc_pcitag;

	struct pci_attach_args	bge_pa;
	struct mii_data		bge_mii;
	struct ifmedia		bge_ifmedia;	/* media info */
	uint32_t		bge_return_ring_cnt;
	uint32_t		bge_tx_prodidx;
	bus_dma_tag_t		bge_dmatag;
	bus_dma_tag_t		bge_dmatag32;
	bool			bge_dma64;
	uint32_t		bge_pcixcap;
	uint32_t		bge_pciecap;
	uint16_t		bge_mps;
	int			bge_expmrq;
	uint32_t		bge_lasttag;
	uint32_t		bge_mfw_flags;  /* Management F/W flags */
#define	BGE_MFW_ON_RXCPU	__BIT(0)
#define	BGE_MFW_ON_APE		__BIT(1)
#define	BGE_MFW_TYPE_NCSI	__BIT(2)
#define	BGE_MFW_TYPE_DASH	__BIT(3)
	int			bge_phy_ape_lock;
	int			bge_phy_addr;
	uint32_t		bge_chipid;
	uint8_t			bge_asf_mode;
	uint8_t			bge_asf_count;
	struct bge_ring_data	*bge_rdata;	/* rings */
	struct bge_chain_data	bge_cdata;	/* mbufs */
	bus_dmamap_t		bge_ring_map;
	bus_dma_segment_t	bge_ring_seg;
	int			bge_ring_rseg;
	uint16_t		bge_tx_saved_considx;
	uint16_t		bge_rx_saved_considx;
	uint16_t		bge_std;	/* current std ring head */
	uint16_t		bge_std_cnt;
	uint16_t		bge_jumbo;	/* current jumbo ring head */
	SLIST_HEAD(__bge_jfreehead, bge_jpool_entry)	bge_jfree_listhead;
	SLIST_HEAD(__bge_jinusehead, bge_jpool_entry)	bge_jinuse_listhead;
	uint32_t		bge_stat_ticks;
	uint32_t		bge_rx_coal_ticks;
	uint32_t		bge_tx_coal_ticks;
	uint32_t		bge_rx_max_coal_bds;
	uint32_t		bge_tx_max_coal_bds;
	uint32_t		bge_sts;
#define BGE_STS_LINK		__BIT(0)	/* MAC link status */
#define BGE_STS_LINK_EVT	__BIT(1)	/* pending link event */
#define BGE_STS_AUTOPOLL	__BIT(2)	/* PHY auto-polling  */
#define BGE_STS_BIT(sc, x)	((sc)->bge_sts & (x))
#define BGE_STS_SETBIT(sc, x)	((sc)->bge_sts |= (x))
#define BGE_STS_CLRBIT(sc, x)	((sc)->bge_sts &= ~(x))
	u_short			bge_if_flags;
	uint32_t		bge_flags;
	uint32_t		bge_phy_flags;
	int			bge_flowflags;
	time_t			bge_tx_lastsent;
	bool			bge_stopping;
	bool			bge_txrx_stopping;
	bool			bge_tx_sending;

#ifdef BGE_EVENT_COUNTERS
	/*
	 * Event counters.
	 */
	struct evcnt bge_ev_intr;	/* interrupts */
	struct evcnt bge_ev_intr_spurious;  /* spurious intr. (tagged status)*/
	struct evcnt bge_ev_intr_spurious2; /* spurious interrupts */
	struct evcnt bge_ev_tx_xoff;	/* send PAUSE(len>0) packets */
	struct evcnt bge_ev_tx_xon;	/* send PAUSE(len=0) packets */
	struct evcnt bge_ev_rx_xoff;	/* receive PAUSE(len>0) packets */
	struct evcnt bge_ev_rx_xon;	/* receive PAUSE(len=0) packets */
	struct evcnt bge_ev_rx_macctl;	/* receive MAC control packets */
	struct evcnt bge_ev_xoffentered;/* XOFF state entered */
#endif /* BGE_EVENT_COUNTERS */
	uint64_t		bge_if_collisions;
	int			bge_txcnt;
	struct callout		bge_timeout;
	bool			bge_pending_rxintr_change;
	bool			bge_detaching;
	SLIST_HEAD(, txdmamap_pool_entry) txdma_list;
	struct txdmamap_pool_entry *txdma[BGE_TX_RING_CNT];

	struct sysctllog	*bge_log;

	krndsource_t	rnd_source;	/* random source */

	kmutex_t *sc_core_lock;		/* lock for softc operations */
	kmutex_t *sc_intr_lock;		/* lock for interrupt operations */
	struct workqueue *sc_reset_wq;
	struct work sc_reset_work;
	volatile unsigned sc_reset_pending;

	bool sc_trigger_reset;
};

#endif /* _DEV_PCI_IF_BGEVAR_H_ */