root/usr/src/uts/common/io/atge/atge.h
/*
 * 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 */