Home | History | Annotate | Download | only in dmfe
      1 /*
      2  * CDDL HEADER START
      3  *
      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.
      7  *
      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.
     12  *
     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]
     18  *
     19  * CDDL HEADER END
     20  */
     21 /*
     22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
     23  * Use is subject to license terms.
     24  */
     25 
     26 #ifndef _SYS_DMFE_IMPL_H
     27 #define	_SYS_DMFE_IMPL_H
     28 
     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>
     41 
     42 #include <sys/vlan.h>
     43 
     44 #include <sys/dditypes.h>
     45 #include <sys/ddi.h>
     46 #include <sys/sunddi.h>
     47 
     48 #include <sys/mii.h>
     49 #include <sys/mac_provider.h>
     50 #include <sys/mac_ether.h>
     51 #include "dmfe.h"
     52 
     53 #define	DMFE_MAX_PKT_SIZE	(VLAN_TAGSZ + ETHERMAX + ETHERFCSL)
     54 
     55 
     56 #define	DRIVER_NAME		"dmfe"
     57 
     58 /*
     59  * Describes the identity of a specific chip
     60  */
     61 typedef struct {
     62 	uint16_t		vendor;
     63 	uint16_t		device;
     64 	uint8_t			revision;
     65 	uint8_t			spare;
     66 } chip_id_t;
     67 
     68 /*
     69  * Describes the state of a descriptor ring
     70  *
     71  * NOTE: n_free and next_busy are only used for the Tx descriptors
     72  * and are not valid on the receive side.
     73  */
     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;
     80 
     81 /*
     82  * Describes one chunk of allocated DMA-able memory
     83  */
     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;
     97 
     98 /*
     99  * Indexes into the driver-specific kstats, divided into:
    100  *
    101  *	cyclic activity
    102  *	reasons for waking the factotum
    103  *	the factotum's activities
    104  */
    105 enum {
    106 	KS_CYCLIC_RUN,
    107 
    108 	KS_INTERRUPT,
    109 	KS_TX_STALL,
    110 	KS_CHIP_ERROR,
    111 
    112 	KS_FACTOTUM_RUN,
    113 	KS_RECOVERY,
    114 
    115 	KS_DRV_COUNT
    116 };
    117 
    118 /*
    119  * Actual state of the DM9102A chip
    120  */
    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	*/
    129 };
    130 
    131 /*
    132  * Required state according to MAC
    133  */
    134 enum mac_state {
    135 	DMFE_MAC_UNKNOWN,
    136 	DMFE_MAC_RESET,
    137 	DMFE_MAC_STOPPED,
    138 	DMFE_MAC_STARTED
    139 };
    140 
    141 /*
    142  * (Internal) return values from ioctl subroutines
    143  */
    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	*/
    151 };
    152 
    153 /*
    154  * Per-instance soft-state structure
    155  */
    156 typedef struct dmfe {
    157 	/*
    158 	 * These fields are set by attach() and unchanged thereafter ...
    159 	 */
    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;
    166 
    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"		*/
    172 
    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	*/
    177 
    178 	ddi_periodic_t		cycid;		/* periodical callback 	*/
    179 	ddi_softintr_t		factotum_id;	/* identity of factotum	*/
    180 	ddi_iblock_cookie_t	iblk;
    181 
    182 	/*
    183 	 * Locks:
    184 	 *
    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.
    191 	 *
    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.
    195 	 *
    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.
    200 	 *
    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.
    205 	 *
    206 	 * Any of the locks can be acquired singly, but where multiple
    207 	 * locks are acquired, they *must* be in the order:
    208 	 *
    209 	 *	milock >>> oplock >>> rxlock >>> txlock.
    210 	 *
    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.
    217 	 */
    218 	kmutex_t		milock[1];
    219 	kmutex_t		oplock[1];
    220 	kmutex_t		rxlock[1];
    221 	kmutex_t		txlock[1];
    222 
    223 	/*
    224 	 * DMFE Extended kstats, protected by <oplock>
    225 	 */
    226 	kstat_t			*ksp_drv;
    227 	kstat_named_t		*knp_drv;
    228 
    229 	/*
    230 	 * GLD statistics; the prefix tells which lock each is protected by.
    231 	 */
    232 
    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;
    246 
    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;
    262 
    263 	/*
    264 	 * These two sets of desciptors are manipulated during
    265 	 * packet receive/transmit respectively.
    266 	 */
    267 	desc_state_t		rx;		/* describes Rx ring	*/
    268 	desc_state_t		tx;		/* describes Tx ring	*/
    269 
    270 	/*
    271 	 * Miscellaneous Tx-side variables (protected by txlock)
    272 	 */
    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 */
    276 
    277 	/*
    278 	 * Miscellaneous operating variables (protected by oplock)
    279 	 */
    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		 */
    286 
    287 	/*
    288 	 * Current Ethernet address & multicast map ...
    289 	 */
    290 	uint8_t			curr_addr[ETHERADDRL];
    291 	uint8_t			mcast_refs[MCASTBUF_SIZE];
    292 	boolean_t		addr_set;
    293 
    294 	/*
    295 	 * Guard element used to check data integrity
    296 	 */
    297 	uint64_t		dmfe_guard;
    298 } dmfe_t;
    299 
    300 /*
    301  * 'Progress' bit flags ...
    302  */
    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	*/
    309 
    310 /*
    311  * Sync a DMA area described by a dma_area_t
    312  */
    313 #define	DMA_SYNC(descp, flag)	((void) ddi_dma_sync((descp)->dma_hdl,	\
    314 					0, (descp)->alength, flag))
    315 
    316 /*
    317  * Next value of a cyclic index
    318  */
    319 #define	NEXT(index, limit)	((index)+1 < (limit) ? (index)+1 : 0);
    320 
    321 /*
    322  * Copy an ethernet address
    323  */
    324 #define	ethaddr_copy(src, dst)	bcopy((src), (dst), ETHERADDRL)
    325 
    326 /*
    327  * Get/set/increment a (64-bit) driver-private kstat
    328  */
    329 #define	DRV_KS_GET(dmfep, id)						\
    330 	(((dmfep)->knp_drv) ? ((dmfep)->knp_drv)[id].value.ui64 : 0)
    331 
    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)
    338 
    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)
    345 
    346 
    347 #define	DMFE_GUARD		0x1919603003090218
    348 
    349 /*
    350  * Inter-source-file linkage ...
    351  */
    352 
    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);
    360 
    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);
    364 
    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);
    368 
    369 #endif	/* _SYS_DMFE_IMPL_H */
    370