root/usr/src/uts/common/io/bnx/bnx.h
/*
 * Copyright 2014-2017 Cavium, Inc.
 * The contents of this file are subject to the terms of the Common Development
 * and Distribution License, v.1,  (the "License").
 *
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the License at available
 * at http://opensource.org/licenses/CDDL-1.0
 *
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 2019, Joyent, Inc.
 */

#ifndef _BNX_H
#define _BNX_H

#ifdef __cplusplus
extern "C" {
#endif

#include <sys/types.h>
#include <sys/stream.h>
#include <sys/stropts.h>
#include <sys/errno.h>
#include <sys/cred.h>
#include <sys/poll.h>
#include <sys/modctl.h>
#ifdef __10u7
#include <sys/mac.h>
#else
#include <sys/mac_provider.h>
#endif
#include <sys/stat.h>
#include <sys/ddi.h>
#include <sys/sunddi.h>
#include <sys/pattr.h>
#include <sys/sysmacros.h>
#include <sys/ethernet.h>
#include <sys/strsun.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <inet/common.h>
#include <inet/ip.h>
#include <inet/ip_if.h>
#include <sys/strsubr.h>
#include <sys/pci.h>
#include <sys/kstat.h>



#include "listq.h"
#include "lm5706.h"
#include "54xx_reg.h"

#define BNX_MAGIC       0x0feedead
#define BNX_STR_SIZE    32

#ifdef __sparc
#define BNX_DMA_ALIGNMENT       0x2000UL
#else
#define BNX_DMA_ALIGNMENT       0x1000UL
#endif

#define BNX_MAX_SGL_ENTRIES             16
#define BNX_MIN_BYTES_PER_FRAGMENT      32

#define FW_VER_WITH_UNLOAD_POWER_DOWN   0x01090003


extern ddi_device_acc_attr_t bnxAccessAttribBAR;
extern ddi_device_acc_attr_t bnxAccessAttribBUF;
extern ddi_dma_attr_t bnx_std_dma_attrib;


typedef struct _bnx_memreq_t {
        void   * addr;
        size_t   size;
} bnx_memreq_t;



/*
 * Transmit queue info structure holds information regarding transmit resources.
 * This consists of two list, one is a free list of transmit packets and another
 * a list of pending packets (packets posted to ASIC for transmit). Upon
 * receiving transmit complete notification from the asic, the message blocks
 * are freed and and packet structure is moved to the free list.
 */

typedef struct _um_xmit_qinfo {
        ddi_dma_handle_t        dcpyhndl;
        ddi_acc_handle_t        dcpyahdl;
        caddr_t                 dcpyvirt;
        lm_u64_t                dcpyphys;
        size_t                  dcpyhard;

        /* Packet descriptor memory. */
        u32_t                   desc_cnt;
        bnx_memreq_t            desc_mem;

        /* Low resource water marks. */
        u32_t                   thresh_pdwm;

        /* Free queue mutex */
        kmutex_t                free_mutex;

        /* Packet descriptors that are free for use. */
        s_list_t                free_tx_desc;

        /* Packet descriptors that have been setup and are awaiting xmit. */
        s_list_t                tx_resc_que;
} um_xmit_qinfo;



/*
 * Receive queue is mostly managed by the LM (lm_dev->rx_info.chain[]).
 * During initialization, UM allocates receive buffers and prepares the
 * rx descriptions to posts the receive buffers.
 */
typedef struct _um_recv_qinfo {
        volatile boolean_t processing;

        /* For packet descriptors that do not have rx buffers assigned. */
        s_list_t buffq;

        /* For packet descriptors waiting to be sent up. */
        s_list_t waitq;
} um_recv_qinfo;


typedef struct _os_param {
        u32_t active_resc_flag;
#define DRV_RESOURCE_PCICFG_MAPPED      0x0001
#define DRV_RESOURCE_MAP_REGS           0x0002
#define DRV_RESOURCE_INTR_1             0x0004
#define DRV_RESOURCE_MUTEX              0x0008
#define DRV_RESOURCE_HDWR_REGISTER      0x0020
#define DRV_RESOURCE_GLD_REGISTER       0x0040
#define DRV_RESOURCE_KSTAT              0x0080
#define DRV_RESOURCE_TIMER              0x0100
#define DRV_RESOURCE_MINOR_NODE         0x0200
#define DRV_LINK_TIMEOUT_CB             0x0400

        dev_info_t *dip;

        ddi_acc_handle_t pci_cfg_handle;
        ddi_acc_handle_t reg_acc_handle;

        mac_handle_t macp;
        mac_resource_handle_t rx_resc_handle[NUM_RX_CHAIN];
        caddr_t regs_addr;

        kmutex_t  gld_mutex;
        krwlock_t gld_snd_mutex;
        kmutex_t  xmit_mutex;
        kmutex_t  rcv_mutex;
        kmutex_t  phy_mutex;
        kmutex_t  ind_mutex;

        /*
         * Following are generic DMA handles used for the following -
         * 1. Status _ Statistic DMA memory
         * 2. TXBD queue
         * 3. RXBD queue
         */
#define BNX_MAX_PHYS_MEMREQS   32
        u32_t dma_handles_used;
        void *dma_virt[BNX_MAX_PHYS_MEMREQS];
        ddi_dma_handle_t dma_handle[BNX_MAX_PHYS_MEMREQS];
        ddi_acc_handle_t dma_acc_handle[BNX_MAX_PHYS_MEMREQS];

        ddi_dma_handle_t *status_block_dma_hdl;

} os_param_t;




/*
 * Following structure hosts attributes related to the device, like media type,
 * transmit/receive descriptor queue information, last status index
 * processed/acknowledged, etc'
 */

typedef struct _dev_param {

        u32_t mtu;

        lm_rx_mask_t rx_filter_mask;
        lm_offload_t enabled_oflds;

        /*
         * This is the last value of 'status_idx' processed and acknowledged
         * by the driver. This value is compared with current value in the
         * status block to determine if new status block was generated by
         * host coalesce block.
         */
        u32_t processed_status_idx;

        u32_t fw_ver;

        boolean_t isfiber;

    boolean_t disableMsix;

    lm_status_t indLink;
    lm_medium_t indMedium;
} device_param_t;


typedef struct _bnx_ndd_lnk_tbl_t {
        const char **label;
        const boolean_t *value;
} bnx_ndd_lnk_tbl_t;


/* NDD parameters related structure members. */
typedef struct _bnx_ndd_t {
        caddr_t ndd_data;

        bnx_ndd_lnk_tbl_t lnktbl[3];

        int link_speed;
        boolean_t link_duplex;
        boolean_t link_tx_pause;
        boolean_t link_rx_pause;
} bnx_ndd_t;


typedef struct _bnx_lnk_cfg_t {
        boolean_t link_autoneg;
        boolean_t param_2500fdx;
        boolean_t param_1000fdx;
        boolean_t param_1000hdx;
        boolean_t param_100fdx;
        boolean_t param_100hdx;
        boolean_t param_10fdx;
        boolean_t param_10hdx;
        boolean_t param_tx_pause;
        boolean_t param_rx_pause;
} bnx_lnk_cfg_t;



typedef struct _bnx_phy_cfg_t {
        bnx_lnk_cfg_t lnkcfg;

        boolean_t flow_autoneg;
        boolean_t wirespeed;
} bnx_phy_cfg_t;



typedef struct _um_device {
        /* Lower Module device structure should be the first element */
        struct _lm_device_t lm_dev;

        u32_t magic;

        ddi_intr_handle_t *pIntrBlock;
        u32_t intrPriority;
        int intrType;

        volatile boolean_t intr_enabled;
        kmutex_t intr_mutex;
        uint32_t intr_count;
        uint32_t intr_no_change;
        uint32_t intr_in_disabled;

        volatile boolean_t timer_enabled;
        kmutex_t tmr_mutex;
        timeout_id_t tmrtid;
        unsigned int timer_link_check_interval;
        unsigned int timer_link_check_counter;
        unsigned int timer_link_check_interval2;
        unsigned int timer_link_check_counter2;

        volatile boolean_t dev_start;
        volatile boolean_t link_updates_ok;

        os_param_t os_param;
        device_param_t dev_var;

        u32_t tx_copy_threshold;

        u32_t no_tx_credits;
#define BNX_TX_RESOURCES_NO_CREDIT      0x01
#define BNX_TX_RESOURCES_NO_DESC        0x02
/* Unable to allocate DMA resources. (e.g. bind error) */
#define BNX_TX_RESOURCES_NO_OS_DMA_RES  0x08
#define BNX_TX_RESOURCES_TOO_MANY_FRAGS 0x10

        um_xmit_qinfo txq[NUM_TX_CHAIN];
#define _TX_QINFO(pdev, chain)  (pdev->txq[chain])
#define _TXQ_FREE_DESC(pdev, chain) (pdev->txq[chain].free_tx_desc)
#define _TXQ_RESC_DESC(pdev, chain) (pdev->txq[chain].tx_resc_que)

        u32_t rx_copy_threshold;
        uint32_t recv_discards;

        um_recv_qinfo rxq[NUM_RX_CHAIN];
#define _RX_QINFO(pdev, chain)  (pdev->rxq[chain])

        bnx_ndd_t nddcfg;

        bnx_phy_cfg_t hwinit;
        bnx_phy_cfg_t curcfg;
        bnx_lnk_cfg_t remote;

        char dev_name[BNX_STR_SIZE];
        int instance;
        char version[BNX_STR_SIZE];
        char versionFW[BNX_STR_SIZE];
        char chipName[BNX_STR_SIZE];
        char intrAlloc[BNX_STR_SIZE];
        u64_t intrFired;

        kstat_t *kstats;
        kmutex_t kstatMutex;

#define BNX_MAX_MEMREQS 2
        unsigned int memcnt;
        bnx_memreq_t memreq[BNX_MAX_MEMREQS];
} um_device_t;



/*
 * Following structure defines the packet descriptor as seen by the UM module.
 * This is used to map  buffers to lm_packet on xmit path and receive path.
 */

typedef struct _um_txpacket_t {
        /* Must be the first entry in this structure. */
        struct _lm_packet_t lm_pkt;

        mblk_t                  *mp;

        ddi_dma_handle_t        *cpyhdl;
        caddr_t                 cpymem;
        lm_u64_t                cpyphy;
        off_t                   cpyoff;

        u32_t                   num_handles;
        ddi_dma_handle_t        dma_handle[BNX_MAX_SGL_ENTRIES];

        lm_frag_list_t          frag_list;
        lm_frag_t               frag_list_buffer[BNX_MAX_SGL_ENTRIES];
} um_txpacket_t;



#define BNX_RECV_MAX_FRAGS 1
typedef struct _um_rxpacket_t {
        /* Must be the first entry in this structure. */
        struct _lm_packet_t lmpacket;

        ddi_dma_handle_t    dma_handle;
        ddi_acc_handle_t    dma_acc_handle;
} um_rxpacket_t;


#define VLAN_TPID               0x8100u
#define VLAN_TAGSZ              4
#define VLAN_TAG_SIZE           4
#define VLAN_VID_MAX    4094    /* 4095 is reserved */


typedef struct ether_vlan_header vlan_hdr_t;
#define DRV_EXTRACT_VLAN_TPID(vhdrp)    htons(vhdrp->ether_tpid)
#define DRV_EXTRACT_VLAN_TCI(vhdrp)     htons(vhdrp->ether_tci)
#define DRV_SET_VLAN_TPID(vhdrp, tpid)  vhdrp->ether_tpid = htons(tpid)
#define DRV_SET_VLAN_TCI(vhdrp, vtag)   vhdrp->ether_tci = htons(vtag)





/*
 *
 *                      'ndd' Get/Set IOCTL Definition
 *
 */


/*
 * (Internal) return values from ioctl subroutines
 */
enum ioc_reply {
        IOC_INVAL = -1,                 /* bad, NAK with EINVAL */
        IOC_DONE,                       /* OK, reply sent */
        IOC_ACK,                        /* OK, just send ACK */
        IOC_REPLY,                      /* OK, just send reply */
        IOC_RESTART_ACK,                /* OK, restart & ACK */
        IOC_RESTART_REPLY               /* OK, restart & reply */
};

/*
 *                      Function Prototypes
 *
 */

ddi_dma_handle_t *bnx_find_dma_hdl(um_device_t * const umdevice,
    const void * const virtaddr);

void um_send_driver_pulse(um_device_t *udevp);

int bnx_find_mchash_collision(lm_mc_table_t *mc_table,
    const u8_t *const mc_addr);

void bnx_update_phy(um_device_t *pdev);


boolean_t bnx_kstat_init(um_device_t *pUM);
void bnx_kstat_fini(um_device_t *pUM);

#ifdef __cplusplus
}
#endif

#endif /* _BNX_H */