Merge remote-tracking branch 'origin/master'
[unleashed/lotheac.git] / usr / src / uts / common / io / dmfe / dmfe_impl.h
blob888e1e95143bcb6e876b7872569ca02a4b702718
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #ifndef _SYS_DMFE_IMPL_H
27 #define _SYS_DMFE_IMPL_H
29 #include <sys/types.h>
30 #include <sys/stream.h>
31 #include <sys/strsun.h>
32 #include <sys/stat.h>
33 #include <sys/pci.h>
34 #include <sys/note.h>
35 #include <sys/modctl.h>
36 #include <sys/kstat.h>
37 #include <sys/ethernet.h>
38 #include <sys/devops.h>
39 #include <sys/debug.h>
40 #include <sys/conf.h>
42 #include <sys/vlan.h>
44 #include <sys/dditypes.h>
45 #include <sys/ddi.h>
46 #include <sys/sunddi.h>
48 #include <sys/mii.h>
49 #include <sys/mac_provider.h>
50 #include <sys/mac_ether.h>
51 #include "dmfe.h"
53 #define DMFE_MAX_PKT_SIZE (VLAN_TAGSZ + ETHERMAX + ETHERFCSL)
56 #define DRIVER_NAME "dmfe"
59 * Describes the identity of a specific chip
61 typedef struct {
62 uint16_t vendor;
63 uint16_t device;
64 uint8_t revision;
65 uint8_t spare;
66 } chip_id_t;
69 * Describes the state of a descriptor ring
71 * NOTE: n_free and next_busy are only used for the Tx descriptors
72 * and are not valid on the receive side.
74 typedef struct {
75 uint32_t n_desc; /* # of descriptors */
76 uint32_t n_free; /* # of free descriptors */
77 uint32_t next_free; /* next index to use/check */
78 uint32_t next_busy; /* next index to reclaim */
79 } desc_state_t;
82 * Describes one chunk of allocated DMA-able memory
84 typedef struct {
85 ddi_dma_handle_t dma_hdl;
86 ddi_acc_handle_t acc_hdl;
87 size_t alength; /* allocated size */
88 caddr_t mem_va; /* CPU VA of memory */
89 uint32_t spare1;
90 uint32_t mem_dvma; /* DVMA addr of memory */
91 caddr_t setup_va;
92 uint32_t spare2;
93 uint32_t setup_dvma;
94 int spare3;
95 int ncookies;
96 } dma_area_t;
99 * Indexes into the driver-specific kstats, divided into:
101 * cyclic activity
102 * reasons for waking the factotum
103 * the factotum's activities
105 enum {
106 KS_CYCLIC_RUN,
108 KS_INTERRUPT,
109 KS_TX_STALL,
110 KS_CHIP_ERROR,
112 KS_FACTOTUM_RUN,
113 KS_RECOVERY,
115 KS_DRV_COUNT
119 * Actual state of the DM9102A chip
121 enum chip_state {
122 CHIP_ERROR = -1, /* error, need reset */
123 CHIP_UNKNOWN, /* Initial state only */
124 CHIP_RESET, /* reset, need init */
125 CHIP_STOPPED, /* Tx/Rx stopped */
126 CHIP_TX_ONLY, /* Tx (re)started */
127 CHIP_TX_RX, /* Tx & Rx (re)started */
128 CHIP_RUNNING /* with interrupts */
132 * Required state according to MAC
134 enum mac_state {
135 DMFE_MAC_UNKNOWN,
136 DMFE_MAC_RESET,
137 DMFE_MAC_STOPPED,
138 DMFE_MAC_STARTED
142 * (Internal) return values from ioctl subroutines
144 enum ioc_reply {
145 IOC_INVAL = -1, /* bad, NAK with EINVAL */
146 IOC_DONE, /* OK, reply sent */
147 IOC_REPLY, /* OK, just send reply */
148 IOC_ACK, /* OK, just send ACK */
149 IOC_RESTART, /* OK, restart & reply */
150 IOC_RESTART_ACK /* OK, restart & ACK */
154 * Per-instance soft-state structure
156 typedef struct dmfe {
158 * These fields are set by attach() and unchanged thereafter ...
160 dev_info_t *devinfo; /* device instance */
161 mac_handle_t mh; /* MAC instance data */
162 mii_handle_t mii; /* MII handle */
163 ddi_acc_handle_t io_handle; /* DDI I/O handle */
164 caddr_t io_reg; /* mapped registers */
165 boolean_t suspended;
167 uint32_t debug; /* per-instance debug */
168 uint32_t progress; /* attach tracking */
169 chip_id_t chipid;
170 uint8_t vendor_addr[ETHERADDRL];
171 char ifname[12]; /* "dmfeXXXX" */
173 dma_area_t tx_desc; /* transmit descriptors */
174 dma_area_t tx_buff; /* transmit buffers */
175 dma_area_t rx_desc; /* receive descriptors */
176 dma_area_t rx_buff; /* receive buffers */
178 ddi_periodic_t cycid; /* periodical callback */
179 ddi_softintr_t factotum_id; /* identity of factotum */
180 ddi_iblock_cookie_t iblk;
183 * Locks:
185 * <milock> is used only by the MII (PHY) level code, to ensure
186 * exclusive access during the bit-twiddling needed to send
187 * signals along the MII serial bus. These operations are
188 * --S--L--O--W-- so we keep this lock separate, so that
189 * faster operations (e.g. interrupts) aren't delayed by
190 * waiting for it.
192 * <oplock> is a general "outer" lock, protecting most r/w data
193 * and chip state. It is also acquired by the interrupt
194 * handler.
196 * <rxlock> is used to protect the Rx-side buffers, descriptors,
197 * and statistics during a single call to dmfe_getp().
198 * This is called from inside the interrupt handler, but
199 * <oplock> is not held across this call.
201 * <txlock> is an "inner" lock, and protects only the Tx-side
202 * data below and in the ring buffers/descriptors. The
203 * Tx-side code uses only this lock, avoiding contention
204 * with the receive-side code.
206 * Any of the locks can be acquired singly, but where multiple
207 * locks are acquired, they *must* be in the order:
209 * milock >>> oplock >>> rxlock >>> txlock.
211 * *None* of these locks may be held across calls out to the
212 * MAC routines mac_rx() or mac_tx_notify(); MAC locks must
213 * be regarded as *outermost* locks in all cases, as they will
214 * already be held before calling the ioctl() or get_stats()
215 * entry points - which then have to acquire multiple locks, in
216 * the order described here.
218 kmutex_t milock[1];
219 kmutex_t oplock[1];
220 kmutex_t rxlock[1];
221 kmutex_t txlock[1];
224 * DMFE Extended kstats, protected by <oplock>
226 kstat_t *ksp_drv;
227 kstat_named_t *knp_drv;
230 * GLD statistics; the prefix tells which lock each is protected by.
233 uint64_t rx_stats_ipackets;
234 uint64_t rx_stats_multi;
235 uint64_t rx_stats_bcast;
236 uint64_t rx_stats_ierrors;
237 uint64_t rx_stats_norcvbuf;
238 uint64_t rx_stats_rbytes;
239 uint64_t rx_stats_missed;
240 uint64_t rx_stats_align;
241 uint64_t rx_stats_fcs;
242 uint64_t rx_stats_toolong;
243 uint64_t rx_stats_macrcv_errors;
244 uint64_t rx_stats_overflow;
245 uint64_t rx_stats_short;
247 uint64_t tx_stats_oerrors;
248 uint64_t tx_stats_opackets;
249 uint64_t tx_stats_multi;
250 uint64_t tx_stats_bcast;
251 uint64_t tx_stats_obytes;
252 uint64_t tx_stats_collisions;
253 uint64_t tx_stats_nocarrier;
254 uint64_t tx_stats_xmtlatecoll;
255 uint64_t tx_stats_excoll;
256 uint64_t tx_stats_macxmt_errors;
257 uint64_t tx_stats_jabber;
258 uint64_t tx_stats_defer;
259 uint64_t tx_stats_first_coll;
260 uint64_t tx_stats_multi_coll;
261 uint64_t tx_stats_underflow;
264 * These two sets of desciptors are manipulated during
265 * packet receive/transmit respectively.
267 desc_state_t rx; /* describes Rx ring */
268 desc_state_t tx; /* describes Tx ring */
271 * Miscellaneous Tx-side variables (protected by txlock)
273 uint32_t tx_pending_tix; /* tix since reclaim */
274 uint8_t *tx_mcast; /* bitmask: pkt is mcast */
275 uint8_t *tx_bcast; /* bitmask: pkt is bcast */
278 * Miscellaneous operating variables (protected by oplock)
280 uint16_t factotum_flag; /* callback pending */
281 uint16_t need_setup; /* send-setup pending */
282 uint32_t opmode; /* operating mode shadow */
283 uint32_t imask; /* interrupt mask shadow */
284 enum mac_state mac_state; /* RESET/STOPPED/STARTED */
285 enum chip_state chip_state; /* see above */
288 * Current Ethernet address & multicast map ...
290 uint8_t curr_addr[ETHERADDRL];
291 uint8_t mcast_refs[MCASTBUF_SIZE];
292 boolean_t addr_set;
295 * Guard element used to check data integrity
297 uint64_t dmfe_guard;
298 } dmfe_t;
301 * 'Progress' bit flags ...
303 #define PROGRESS_CONFIG 0x0001 /* config space initialised */
304 #define PROGRESS_MUTEX 0x0002 /* mutexes initialized */
305 #define PROGRESS_REGS 0x0004 /* registers mapped */
306 #define PROGRESS_BUFS 0x0008 /* buffers allocated */
307 #define PROGRESS_SOFTINT 0x0010 /* softint registered */
308 #define PROGRESS_HWINT 0x0020 /* h/w interrupt registered */
311 * Sync a DMA area described by a dma_area_t
313 #define DMA_SYNC(descp, flag) ((void) ddi_dma_sync((descp)->dma_hdl, \
314 0, (descp)->alength, flag))
317 * Next value of a cyclic index
319 #define NEXT(index, limit) ((index)+1 < (limit) ? (index)+1 : 0);
322 * Copy an ethernet address
324 #define ethaddr_copy(src, dst) bcopy((src), (dst), ETHERADDRL)
327 * Get/set/increment a (64-bit) driver-private kstat
329 #define DRV_KS_GET(dmfep, id) \
330 (((dmfep)->knp_drv) ? ((dmfep)->knp_drv)[id].value.ui64 : 0)
332 #define DRV_KS_SET(dmfep, id, val) \
333 do { \
334 if ((dmfep)->knp_drv) \
335 ((dmfep)->knp_drv)[id].value.ui64 = (val); \
336 _NOTE(CONSTANTCONDITION) \
337 } while (0)
339 #define DRV_KS_INC(dmfep, id) \
340 do { \
341 if ((dmfep)->knp_drv) \
342 ((dmfep)->knp_drv)[id].value.ui64 += 1; \
343 _NOTE(CONSTANTCONDITION) \
344 } while (0)
347 #define DMFE_GUARD 0x1919603003090218
350 * Inter-source-file linkage ...
353 /* dmfe_log.c */
354 void dmfe_warning(dmfe_t *dmfep, const char *fmt, ...);
355 void dmfe_error(dmfe_t *dmfep, const char *fmt, ...);
356 void dmfe_notice(dmfe_t *dmfep, const char *fmt, ...);
357 void dmfe_log(dmfe_t *dmfep, const char *fmt, ...);
358 void dmfe_log_init(void);
359 void dmfe_log_fini(void);
361 /* dmfe_main.c */
362 uint32_t dmfe_chip_get32(dmfe_t *dmfep, off_t offset);
363 void dmfe_chip_put32(dmfe_t *dmfep, off_t offset, uint32_t value);
365 /* dmfe_mii.c */
366 void dmfe_read_eeprom(dmfe_t *dmfep, uint16_t addr, uint8_t *ptr, int cnt);
367 boolean_t dmfe_init_phy(dmfe_t *dmfep);
369 #endif /* _SYS_DMFE_IMPL_H */