view usr/src/uts/common/io/atge/atge.h @ 13768:ed21ea5d20cf

212 Atheros AR8132 / L1c Gigabit Ethernet Adapter Reviewed by: Garrett D'Amore <garrett@damore.org> Reviewed by: Milan Jurik <milan.jurik@xylab.cz> Approved by: Dan McDonald <danmcd@nexenta.com>
author Gary Mills <gary_mills@fastmail.fm>
date Fri, 10 Aug 2012 10:52:49 -0400
parents ac93462db6d7
children
line wrap: on
line source

/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright (c) 2012 Gary Mills
 *
 * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#ifndef _ATGE_H
#define	_ATGE_H

#ifdef __cplusplus
	extern "C" {
#endif

#include <sys/ethernet.h>
#include <sys/mac_provider.h>
#include "atge_l1e_reg.h"
#include "atge_l1c_reg.h"

#define	ATGE_PCI_REG_NUMBER	1

#define	ROUNDUP(x, a)		(((x) + (a) - 1) & ~((a) - 1))

/*
 * Flags.
 */
#define	ATGE_FLAG_PCIE		0x0001
#define	ATGE_FIXED_TYPE		0x0002
#define	ATGE_MSI_TYPE		0x0004
#define	ATGE_MSIX_TYPE		0x0008
#define	ATGE_FLAG_FASTETHER	0x0010
#define	ATGE_FLAG_JUMBO		0x0020
#define	ATGE_MII_CHECK		0x0040
#define	ATGE_FLAG_ASPM_MON	0x0080
#define	ATGE_FLAG_CMB_BUG	0x0100
#define	ATGE_FLAG_SMB_BUG	0x0200
#define	ATGE_FLAG_APS		0x1000

#define	ATGE_CHIP_L1_DEV_ID	0x1048
#define	ATGE_CHIP_L2_DEV_ID	0x2048
#define	ATGE_CHIP_L1E_DEV_ID	0x1026
#define	ATGE_CHIP_L1CG_DEV_ID	0x1063
#define	ATGE_CHIP_L1CF_DEV_ID	0x1062
#define	ATGE_CHIP_AR8151V1_DEV_ID	0x1073
#define	ATGE_CHIP_AR8151V2_DEV_ID	0x1083
#define	ATGE_CHIP_AR8152V1_DEV_ID	0x2060
#define	ATGE_CHIP_AR8152V2_DEV_ID	0x2062

#define	ATGE_PROMISC		0x001
#define	ATGE_ALL_MULTICST	0x002

/*
 * Timer for one second interval.
 */
#define	ATGE_TIMER_INTERVAL	(1000 * 1000 * 1000)

/*
 * Chip state.
 */
#define	ATGE_CHIP_INITIALIZED	0x0001
#define	ATGE_CHIP_RUNNING	0x0002
#define	ATGE_CHIP_STOPPED	0x0004
#define	ATGE_CHIP_SUSPENDED	0x0008

#define	ETHER_CRC_LEN		0x4

/*
 * Descriptor increment and decrment operation.
 */
#define	ATGE_INC_SLOT(x, y)	\
	((x) = ((x) + 1) % (y))

#define	ATGE_DEC_SLOT(x, y)	\
	(x = ((x + y - 1) % y))

/*
 * I/O instructions
 */
#define	OUTB(atge, p, v)  \
	ddi_put8((atge)->atge_io_handle, \
		(void *)((caddr_t)((atge)->atge_io_regs) + (p)), v)

#define	OUTW(atge, p, v)  \
	ddi_put16((atge)->atge_io_handle, \
		(void *)((caddr_t)((atge)->atge_io_regs) + (p)), v)

#define	OUTL(atge, p, v)  \
	ddi_put32((atge)->atge_io_handle, \
		(void *)((caddr_t)((atge)->atge_io_regs) + (p)), v)

#define	INB(atge, p)      \
	ddi_get8((atge)->atge_io_handle, \
		(void *)(((caddr_t)(atge)->atge_io_regs) + (p)))
#define	INW(atge, p)      \
	ddi_get16((atge)->atge_io_handle, \
		(void *)(((caddr_t)(atge)->atge_io_regs) + (p)))

#define	INL(atge, p)      \
	ddi_get32((atge)->atge_io_handle, \
		(void *)(((caddr_t)(atge)->atge_io_regs) + (p)))

#define	FLUSH(atge, reg) \
	(void) INL(atge, reg)

#define	OUTL_OR(atge, reg, v) \
	OUTL(atge, reg, (INL(atge, reg) | v))

#define	OUTL_AND(atge, reg, v) \
	OUTL(atge, reg, (INL(atge, reg) & v))

/*
 * Descriptor and other endianess aware access.
 */
#define	ATGE_PUT64(dma, addr, v) \
	ddi_put64(dma->acchdl, (addr), (v))

#define	ATGE_PUT32(dma, addr, v) \
	ddi_put32(dma->acchdl, (addr), (v))

#define	ATGE_GET32(dma, addr) \
	ddi_get32(dma->acchdl, (addr))

#define	ATGE_GET64(dma, addr) \
	ddi_get64(dma->acchdl, (addr))

#define	DMA_SYNC(dma, s, l, d)	\
	(void) ddi_dma_sync(dma->hdl, (off_t)(s), (l), d)


#define	ATGE_ADDR_LO(x)		((uint64_t)(x) & 0xFFFFFFFF)
#define	ATGE_ADDR_HI(x)		((uint64_t)(x) >> 32)


/*
 * General purpose macros.
 */
#define	ATGE_MODEL(atgep)	atgep->atge_model
#define	ATGE_VID(atgep)		atgep->atge_vid
#define	ATGE_DID(atgep)		atgep->atge_did

/*
 * Different type of chip models.
 */
typedef	enum {
	ATGE_CHIP_L1 = 1,
	ATGE_CHIP_L2,
	ATGE_CHIP_L1E,
	ATGE_CHIP_L1C,
} atge_model_t;

typedef	struct	atge_cards {
	uint16_t	vendor_id;	/* PCI vendor id */
	uint16_t	device_id;	/* PCI device id */
	char		*cardname;	/* Description of the card */
	atge_model_t	model;		/* Model of the card */
} atge_cards_t;

/*
 * Number of Descriptors for TX and RX Ring.
 */
#define	ATGE_TX_NUM_DESC	256
#define	ATGE_RX_NUM_DESC	256

/*
 * DMA Handle for all DMA work.
 */
typedef	struct	atge_dma_data {
	ddi_dma_handle_t	hdl;
	ddi_acc_handle_t	acchdl;
	ddi_dma_cookie_t	cookie;
	caddr_t			addr;
	size_t			len;
	uint_t			count;
} atge_dma_t;

struct	atge;

/*
 * Structure for ring data (TX/RX).
 */
typedef	struct	atge_ring {
	struct	atge	*r_atge;
	atge_dma_t	**r_buf_tbl;
	atge_dma_t	*r_desc_ring;
	int		r_ndesc;
	int		r_consumer;
	int		r_producer;
	int		r_avail_desc;
} atge_ring_t;

/*
 * L1E specific private data.
 */
typedef	struct	atge_l1e_data {
	atge_dma_t	**atge_l1e_rx_page;
	atge_dma_t	*atge_l1e_rx_cmb;
	int		atge_l1e_pagesize;
	int		atge_l1e_rx_curp;
	uint16_t	atge_l1e_rx_seqno;
	uint32_t	atge_l1e_proc_max;
	uint32_t	atge_l1e_rx_page_cons;
	uint32_t	atge_l1e_rx_page_prods[L1E_RX_PAGES];
} atge_l1e_data_t;

/*
 * L1 specific private data.
 */
typedef	struct	atge_l1_data {
	atge_ring_t		*atge_rx_ring;
	atge_dma_t		*atge_l1_cmb;
	atge_dma_t		*atge_l1_rr;
	atge_dma_t		*atge_l1_smb;
	int			atge_l1_rr_consumers;
	uint32_t		atge_l1_intr_status;
	uint32_t		atge_l1_rx_prod_cons;
	uint32_t		atge_l1_tx_prod_cons;
} atge_l1_data_t;

/*
 * L1C specific private data.
 */
typedef	struct	atge_l1c_data {
	atge_ring_t		*atge_rx_ring;
	atge_dma_t		*atge_l1c_cmb;
	atge_dma_t		*atge_l1c_rr;
	atge_dma_t		*atge_l1c_smb;
	int			atge_l1c_rr_consumers;
	uint32_t		atge_l1c_intr_status;
	uint32_t		atge_l1c_rx_prod_cons;
	uint32_t		atge_l1c_tx_prod_cons;
} atge_l1c_data_t;

/*
 * TX descriptor table is same with L1, L1E and L2E chips.
 */
#pragma pack(1)
typedef struct  atge_tx_desc {
	uint64_t	addr;
	uint32_t	len;
	uint32_t	flags;
} atge_tx_desc_t;
#pragma pack()

#define	ATGE_TX_RING_CNT		256
#define	ATGE_TX_RING_SZ	\
	(sizeof (struct atge_tx_desc) * ATGE_TX_RING_CNT)

/*
 * Private instance data structure (per-instance soft-state).
 */
typedef	struct	atge {
	/*
	 * Lock for the TX ring, RX ring and interrupt. In order to align
	 * these locks at 8-byte boundary, we have kept it at the beginning
	 * of atge_t.
	 */
	kmutex_t		atge_tx_lock;
	kmutex_t		atge_rx_lock;
	kmutex_t		atge_intr_lock;
	kmutex_t		atge_mii_lock;
	kmutex_t		atge_mbox_lock;

	/*
	 * Instance number and devinfo pointer.
	 */
	int			atge_unit;
	dev_info_t		*atge_dip;
	char			atge_name[8];
	atge_model_t		atge_model;
	uint16_t		atge_vid;
	uint16_t		atge_did;
	int			atge_chip_rev;
	uint8_t			atge_revid;

	/*
	 * Mac handle.
	 */
	mac_handle_t		atge_mh;

	/*
	 * MII layer handle.
	 */
	mii_handle_t		atge_mii;
	link_state_t		atge_link_state;

	/*
	 * Config Space Handle.
	 */
	ddi_acc_handle_t	atge_conf_handle;

	/*
	 * IO registers mapped by DDI.
	 */
	ddi_acc_handle_t	atge_io_handle;
	caddr_t			atge_io_regs;
	uint_t			atge_intrs;

	/*
	 * Interrupt management structures.
	 */
	ddi_intr_handle_t	*atge_intr_handle;
	int			atge_intr_types;
	int			atge_intr_cnt;
	uint_t			atge_intr_pri;
	int			atge_intr_size;
	int			atge_intr_cap;

	/*
	 * Common structures.
	 */
	atge_ring_t		*atge_tx_ring;
	int			atge_tx_resched;
	int			atge_mtu;
	int			atge_int_mod;
	int			atge_int_rx_mod; /* L1C */
	int			atge_int_tx_mod; /* L1C */
	int			atge_max_frame_size;


	/*
	 * Ethernet addresses.
	 */
	ether_addr_t		atge_ether_addr;
	ether_addr_t		atge_dev_addr;
	uint64_t		atge_mchash;
	uint32_t		atge_mchash_ref_cnt[64];

	/*
	 * PHY register.
	 */
	int			atge_phyaddr;

	/*
	 * Flags.
	 */
	int			atge_flags;
	uint32_t		atge_dma_rd_burst;
	uint32_t		atge_dma_wr_burst;
	int			atge_filter_flags;
	int			atge_chip_state;

	/*
	 * Private data for the chip.
	 */
	void			*atge_private_data;

	/*
	 * Buffer length.
	 */
	int			atge_rx_buf_len;
	int			atge_tx_buf_len;

	/*
	 * Common stats.
	 */
	void			*atge_hw_stats;
	uint64_t		atge_ipackets;
	uint64_t		atge_opackets;
	uint64_t		atge_rbytes;
	uint64_t		atge_obytes;
	uint64_t		atge_brdcstxmt;
	uint64_t		atge_multixmt;
	uint64_t		atge_brdcstrcv;
	uint64_t		atge_multircv;
	unsigned		atge_norcvbuf;
	unsigned		atge_errrcv;
	unsigned		atge_errxmt;
	unsigned		atge_missed;
	unsigned		atge_underflow;
	unsigned		atge_overflow;
	unsigned		atge_align_errors;
	unsigned		atge_fcs_errors;
	unsigned		atge_carrier_errors;
	unsigned		atge_collisions;
	unsigned		atge_ex_collisions;
	unsigned		atge_tx_late_collisions;
	unsigned		atge_defer_xmts;
	unsigned		atge_first_collisions;
	unsigned		atge_multi_collisions;
	unsigned		atge_sqe_errors;
	unsigned		atge_macxmt_errors;
	unsigned		atge_macrcv_errors;
	unsigned		atge_toolong_errors;
	unsigned		atge_runt;
	unsigned		atge_jabber;
	unsigned		atge_noxmtbuf;
} atge_t;

/*
 * extern functions.
 */
extern	void	atge_error(dev_info_t *, char *, ...);

/*
 * Debugging Support.
 */
#ifdef	DEBUG
#define	ATGE_DB(arg)	atge_debug_func arg
#else
#define	ATGE_DB(arg)
#endif

extern	int	atge_debug;
extern	void	atge_debug_func(char *, ...);
extern	atge_dma_t	*atge_alloc_a_dma_blk(atge_t *, ddi_dma_attr_t *,
    int, int);
extern	void	atge_free_a_dma_blk(atge_dma_t *);
extern	atge_dma_t *atge_buf_alloc(atge_t *, size_t, int);
extern	void	atge_buf_free(atge_dma_t *);
extern	mblk_t *atge_get_mblk(int);
extern	void	atge_device_restart(atge_t *);
extern	int	atge_alloc_buffers(atge_ring_t *, size_t, size_t, int);
extern	void	atge_free_buffers(atge_ring_t *, size_t);
extern	void	atge_stop_timer(atge_t *);
extern	void	atge_start_timer(atge_t *);
extern	void	atge_mii_write(void *, uint8_t, uint8_t, uint16_t);
extern	uint16_t	atge_mii_read(void *, uint8_t, uint8_t);
extern	void	atge_device_stop(atge_t *);
extern	void	atge_tx_reclaim(atge_t *, int);


#ifdef __cplusplus
}
#endif

#endif	/* _ATGE_H */