summaryrefslogtreecommitdiff
path: root/sys/dev/ic/rrunnervar.h
blob: e06c0e8d9f3b9b7299cc9b4b37349d46bcc4584f (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
/*	$NetBSD: rrunnervar.h,v 1.14 2012/10/27 17:18:22 chs Exp $	*/

/* Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
 * All rights reserved.
 *
 * This code contributed to The NetBSD Foundation by Kevin M. Lahey
 * of the Numerical Aerospace Simulation Facility, NASA Ames Research
 * Center.
 *
 * Partially based on a HIPPI driver written by Essential Communications
 * Corporation.  Thanks to Jason Thorpe, Matt Jacob, and Fred Templin
 * for invaluable advice and encouragement!
 *
 * 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.
 *
 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 THE FOUNDATION OR CONTRIBUTORS
 * 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.
 */

/* RoadRunner software status per interface */

struct rr_tuning {

	/* Performance tuning registers: */

	u_int32_t		rt_mode_and_status;
	u_int32_t		rt_conn_retry_count;
	u_int32_t		rt_conn_retry_timer;
	u_int32_t		rt_conn_timeout;
	u_int32_t		rt_stats_timer;
	u_int32_t		rt_interrupt_timer;
	u_int32_t		rt_tx_timeout;
	u_int32_t		rt_rx_timeout;

	/* DMA performance tuning registers: */

	u_int32_t		rt_pci_state;
	u_int32_t		rt_dma_write_state;
	u_int32_t		rt_dma_read_state;
	u_int32_t		rt_driver_param;
};



struct rr_eeprom {
	u_int32_t	ifr_offset;	/* initial offset in bytes */
	u_int32_t	ifr_length;	/* length in bytes to write */
	u_int32_t	*ifr_buffer;	/* data to be written */
};

#define EIOCGTUNE   1	/* retrieve tuning */
#define EIOCSTUNE   2	/* set tuning */
#define EIOCGEEPROM 3	/* get eeprom */
#define EIOCSEEPROM 4	/* set eeprom */
#define EIOCGSTATS  5	/* get statistics */
#define EIOCRESET   6   /* reset the card */

#ifdef _KERNEL

/* Per-ring information for the SNAP (network) receive ring */

struct esh_snap_ring_ctl {
	bus_dmamap_t ec_dma[RR_MAX_DESCR];
	struct mbuf *ec_m[RR_MAX_DESCR];
	struct mbuf *ec_cur_pkt;	/* current packet being processed */
	struct mbuf *ec_cur_mbuf;	/* current mbuf being processed */
	int ec_error;			/* encountered error? */
	u_int16_t ec_producer;		/* latest buffer driver produced */
	u_int16_t ec_consumer;		/* latest buffer runcode consumed */
	struct rr_descr *ec_descr;	/* array of descriptors for ring */
};

TAILQ_HEAD(esh_dmainfo_list, esh_dmainfo);

struct esh_dmainfo {
	u_int32_t ed_flags;
#define ESH_DI_BUSY	0x1
#define ESH_DI_READING	0x2
	bus_dmamap_t ed_dma;
	struct buf *ed_buf;
	int ed_read_len;
	int ed_error;
	TAILQ_ENTRY(esh_dmainfo) ed_list;
};

struct esh_send_ring_ctl {
	bus_dmamap_t ec_dma;		/* dmamap for data to transmit */
	int ec_offset;			/* offset in dmamap to send next */
	size_t ec_len;			/* total length of current buf */
	struct mbuf *ec_cur_mbuf;	/* current mbuf being processed */
	struct buf *ec_cur_buf;		/* current buf being processed */
	struct esh_dmainfo *ec_cur_dmainfo;
					/* current dmainfo being processed */
	struct bufq_state *ec_buf_queue;/* queue of bufs to send */
	int ec_error;			/* encountered error? */
	u_int16_t ec_producer;		/* latest buffer driver produced */
	u_int16_t ec_consumer;		/* latest buffer runcode consumed */
	struct rr_descr *ec_descr;	/* array of descriptors for ring */
	struct esh_dmainfo_list ec_di_queue;
};

struct esh_fp_ring_ctl {
	struct esh_dmainfo *ec_dmainfo[RR_MAX_DESCR];
	struct esh_dmainfo *ec_cur_dmainfo;
	int ec_offset;			/* offset of current buf */
	int ec_error;			/* encountered error? */
	int ec_seen_end;		/* seen the end of the buffer? */
	int ec_dmainfo_count;		/* dmainfo buffers in use count */
	u_int16_t ec_producer;		/* latest buffer driver produced */
	u_int16_t ec_consumer;		/* latest buffer runcode consumed */
	u_int32_t ec_read_len;		/* length of packet being read in */
	struct rr_descr *ec_descr;	/* array of descriptors for ring */
	struct esh_dmainfo_list ec_queue;
	u_int ec_ulp;			/* ULP for this ring */
	int ec_index;			/* index into list of active rings */
	bus_dmamap_t ec_dma;
	bus_dma_segment_t ec_dmaseg;
};


struct esh_softc {
	device_t		sc_dev;
	struct ifnet		sc_if;
	struct ifmedia		sc_media;

	volatile int		sc_flags;
#define ESH_FL_INITIALIZING	0x001
#define ESH_FL_INITIALIZED	0x002
#define ESH_FL_RUNCODE_UP	0x004
#define ESH_FL_LINK_UP		0x008
#define ESH_FL_SNAP_RING_UP	0x010
#define ESH_FL_FP_RING_UP	0x020
#define ESH_FL_EEPROM_BUSY	0x040
#define ESH_FL_FP_OPEN		0x080
#define ESH_FL_CRASHED		0x100
#define ESH_FL_CLOSING_SNAP	0x200

	void			*sc_ih;

	bus_space_tag_t		sc_iot;	     /* bus cookie      */
	bus_space_handle_t	sc_ioh;      /* bus i/o handle  */

	bus_dma_tag_t		sc_dmat;     /* dma tag */

	bus_dma_segment_t	sc_dmaseg;   /* segment holding the various
					        data structures in host memory
					        that are DMA'ed to the NIC */
	bus_dmamap_t		sc_dma;	     /* dma map for the segment */
	char 		        *sc_dma_addr; /* address in kernel of DMA mem */
	bus_size_t		sc_dma_size; /* size of dma-able region */

	u_int8_t	(*sc_bist_read)(struct esh_softc *);
	void		(*sc_bist_write)(struct esh_softc *, u_int8_t);

	/*
	 * Definitions for the various driver structures that sit in host
	 * memory and are read by the NIC via DMA:
	 */

	struct rr_gen_info	*sc_gen_info;	/* gen info block pointer */
	bus_addr_t		sc_gen_info_dma;

	struct rr_ring_ctl	*sc_recv_ring_table;
	bus_addr_t		sc_recv_ring_table_dma;

	struct rr_event		*sc_event_ring;
	bus_addr_t		sc_event_ring_dma;

	struct rr_descr		*sc_send_ring;
	struct rr2_descr	*sc2_send_ring;
	bus_addr_t		sc_send_ring_dma;

	struct rr_descr		*sc_snap_recv_ring;
	struct rr2_descr	*sc2_snap_recv_ring;
	bus_addr_t		sc_snap_recv_ring_dma;

	/*
	 * Control structures for the various rings that we definitely
	 * know we want to keep track of.
	 */

	struct esh_send_ring_ctl
				sc_send;
	struct esh_snap_ring_ctl
				sc_snap_recv;
	struct esh_fp_ring_ctl	*sc_fp_recv[RR_ULP_COUNT];
	struct esh_fp_ring_ctl	*sc_fp_recv_index[RR_MAX_RECV_RING];
	int			sc_event_consumer;
	int			sc_event_producer;
	int			sc_cmd_consumer;
	int			sc_cmd_producer;

	/*
	 * Various maintainance values we need
	 */

	int			sc_watchdog;

	/*
	 * Various hardware parameters we need to keep track of.
	 */

	u_int32_t		sc_sram_size;
	u_int32_t		sc_runcode_start;
	u_int32_t		sc_runcode_version;
	u_int32_t		sc_version; /* interface of runcode (1 or 2) */
	u_int16_t		sc_options; /* options in current RunCode */
	u_int			sc_max_rings;

	u_int32_t		sc_pci_latency;
	u_int32_t		sc_pci_lat_gnt;
	u_int32_t		sc_pci_cache_line;

	/* ULA assigned to hardware */

	u_int8_t		sc_ula[6];

	/* Tuning parameters */

	struct rr_tuning	sc_tune;

	/* Measure of how ugly this is. */

	u_int32_t		sc_misaligned_bufs;
	u_int32_t		sc_bad_lens;

	struct esh_dmainfo_list sc_dmainfo_freelist;
	u_int			sc_dmainfo_freelist_count;
	u_int			sc_fp_rings;
};

void	eshconfig(struct esh_softc *);
int	eshintr(void *);
#endif /* _KERNEL */

/* Define a few constants for future use */

#define ESH_MAX_NSEGS			512     /* room for 2MB of data */
#define ESH_STATS_TIMER_DEFAULT		1030900
	/* 1000000 usecs / 0.97 usecs/tick */

#define NEXT_EVENT(i)  (((i) + 1) & (RR_EVENT_RING_SIZE - 1))
#define NEXT_SEND(i)  (((i) + 1) & (RR_SEND_RING_SIZE - 1))
#define NEXT_RECV(i)  (((i) + 1) & (RR_SNAP_RECV_RING_SIZE - 1))

#define PREV_SEND(i)  (((i) + RR_SEND_RING_SIZE - 1) & (RR_SEND_RING_SIZE - 1))
#define PREV_RECV(i)  \
	(((i) + RR_SNAP_RECV_RING_SIZE - 1) & (RR_SNAP_RECV_RING_SIZE - 1))