Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * This file is part of the Chelsio FCoE driver for Linux.
0003  *
0004  * Copyright (c) 2008-2012 Chelsio Communications, Inc. All rights reserved.
0005  *
0006  * This software is available to you under a choice of one of two
0007  * licenses.  You may choose to be licensed under the terms of the GNU
0008  * General Public License (GPL) Version 2, available from the file
0009  * COPYING in the main directory of this source tree, or the
0010  * OpenIB.org BSD license below:
0011  *
0012  *     Redistribution and use in source and binary forms, with or
0013  *     without modification, are permitted provided that the following
0014  *     conditions are met:
0015  *
0016  *      - Redistributions of source code must retain the above
0017  *        copyright notice, this list of conditions and the following
0018  *        disclaimer.
0019  *
0020  *      - Redistributions in binary form must reproduce the above
0021  *        copyright notice, this list of conditions and the following
0022  *        disclaimer in the documentation and/or other materials
0023  *        provided with the distribution.
0024  *
0025  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
0026  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
0027  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
0028  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
0029  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
0030  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
0031  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
0032  * SOFTWARE.
0033  */
0034 
0035 #ifndef __CSIO_HW_H__
0036 #define __CSIO_HW_H__
0037 
0038 #include <linux/kernel.h>
0039 #include <linux/pci.h>
0040 #include <linux/device.h>
0041 #include <linux/workqueue.h>
0042 #include <linux/compiler.h>
0043 #include <linux/cdev.h>
0044 #include <linux/list.h>
0045 #include <linux/mempool.h>
0046 #include <linux/io.h>
0047 #include <linux/spinlock_types.h>
0048 #include <scsi/scsi_device.h>
0049 #include <scsi/scsi_transport_fc.h>
0050 
0051 #include "t4_hw.h"
0052 #include "csio_hw_chip.h"
0053 #include "csio_wr.h"
0054 #include "csio_mb.h"
0055 #include "csio_scsi.h"
0056 #include "csio_defs.h"
0057 #include "t4_regs.h"
0058 #include "t4_msg.h"
0059 
0060 /*
0061  * An error value used by host. Should not clash with FW defined return values.
0062  */
0063 #define FW_HOSTERROR            255
0064 
0065 #define CSIO_HW_NAME        "Chelsio FCoE Adapter"
0066 #define CSIO_MAX_PFN        8
0067 #define CSIO_MAX_PPORTS     4
0068 
0069 #define CSIO_MAX_LUN        0xFFFF
0070 #define CSIO_MAX_QUEUE      2048
0071 #define CSIO_MAX_CMD_PER_LUN    32
0072 #define CSIO_MAX_DDP_BUF_SIZE   (1024 * 1024)
0073 #define CSIO_MAX_SECTOR_SIZE    128
0074 #define CSIO_MIN_T6_FW      0x01102D00  /* FW 1.16.45.0 */
0075 
0076 /* Interrupts */
0077 #define CSIO_EXTRA_MSI_IQS  2   /* Extra iqs for INTX/MSI mode
0078                      * (Forward intr iq + fw iq) */
0079 #define CSIO_EXTRA_VECS     2   /* non-data + FW evt */
0080 #define CSIO_MAX_SCSI_CPU   128
0081 #define CSIO_MAX_SCSI_QSETS (CSIO_MAX_SCSI_CPU * CSIO_MAX_PPORTS)
0082 #define CSIO_MAX_MSIX_VECS  (CSIO_MAX_SCSI_QSETS + CSIO_EXTRA_VECS)
0083 
0084 /* Queues */
0085 enum {
0086     CSIO_INTR_WRSIZE = 128,
0087     CSIO_INTR_IQSIZE = ((CSIO_MAX_MSIX_VECS + 1) * CSIO_INTR_WRSIZE),
0088     CSIO_FWEVT_WRSIZE = 128,
0089     CSIO_FWEVT_IQLEN = 128,
0090     CSIO_FWEVT_FLBUFS = 64,
0091     CSIO_FWEVT_IQSIZE = (CSIO_FWEVT_WRSIZE * CSIO_FWEVT_IQLEN),
0092     CSIO_HW_NIQ = 1,
0093     CSIO_HW_NFLQ = 1,
0094     CSIO_HW_NEQ = 1,
0095     CSIO_HW_NINTXQ = 1,
0096 };
0097 
0098 struct csio_msix_entries {
0099     void        *dev_id;    /* Priv object associated w/ this msix*/
0100     char        desc[24];   /* Description of this vector */
0101 };
0102 
0103 struct csio_scsi_qset {
0104     int     iq_idx;     /* Ingress index */
0105     int     eq_idx;     /* Egress index */
0106     uint32_t    intr_idx;   /* MSIX Vector index */
0107 };
0108 
0109 struct csio_scsi_cpu_info {
0110     int16_t max_cpus;
0111 };
0112 
0113 extern int csio_dbg_level;
0114 extern unsigned int csio_port_mask;
0115 extern int csio_msi;
0116 
0117 #define CSIO_VENDOR_ID              0x1425
0118 #define CSIO_ASIC_DEVID_PROTO_MASK      0xFF00
0119 #define CSIO_ASIC_DEVID_TYPE_MASK       0x00FF
0120 
0121 #define CSIO_GLBL_INTR_MASK (CIM_F | MPS_F | PL_F | PCIE_F | MC_F | \
0122                  EDC0_F | EDC1_F | LE_F | TP_F | MA_F | \
0123                  PM_TX_F | PM_RX_F | ULP_RX_F | \
0124                  CPL_SWITCH_F | SGE_F | ULP_TX_F | SF_F)
0125 
0126 /*
0127  * Hard parameters used to initialize the card in the absence of a
0128  * configuration file.
0129  */
0130 enum {
0131     /* General */
0132     CSIO_SGE_DBFIFO_INT_THRESH  = 10,
0133 
0134     CSIO_SGE_RX_DMA_OFFSET      = 2,
0135 
0136     CSIO_SGE_FLBUF_SIZE1        = 65536,
0137     CSIO_SGE_FLBUF_SIZE2        = 1536,
0138     CSIO_SGE_FLBUF_SIZE3        = 9024,
0139     CSIO_SGE_FLBUF_SIZE4        = 9216,
0140     CSIO_SGE_FLBUF_SIZE5        = 2048,
0141     CSIO_SGE_FLBUF_SIZE6        = 128,
0142     CSIO_SGE_FLBUF_SIZE7        = 8192,
0143     CSIO_SGE_FLBUF_SIZE8        = 16384,
0144 
0145     CSIO_SGE_TIMER_VAL_0        = 5,
0146     CSIO_SGE_TIMER_VAL_1        = 10,
0147     CSIO_SGE_TIMER_VAL_2        = 20,
0148     CSIO_SGE_TIMER_VAL_3        = 50,
0149     CSIO_SGE_TIMER_VAL_4        = 100,
0150     CSIO_SGE_TIMER_VAL_5        = 200,
0151 
0152     CSIO_SGE_INT_CNT_VAL_0      = 1,
0153     CSIO_SGE_INT_CNT_VAL_1      = 4,
0154     CSIO_SGE_INT_CNT_VAL_2      = 8,
0155     CSIO_SGE_INT_CNT_VAL_3      = 16,
0156 };
0157 
0158 /* Slowpath events */
0159 enum csio_evt {
0160     CSIO_EVT_FW  = 0,   /* FW event */
0161     CSIO_EVT_MBX,       /* MBX event */
0162     CSIO_EVT_SCN,       /* State change notification */
0163     CSIO_EVT_DEV_LOSS,  /* Device loss event */
0164     CSIO_EVT_MAX,       /* Max supported event */
0165 };
0166 
0167 #define CSIO_EVT_MSG_SIZE   512
0168 #define CSIO_EVTQ_SIZE      512
0169 
0170 /* Event msg  */
0171 struct csio_evt_msg {
0172     struct list_head    list;   /* evt queue*/
0173     enum csio_evt       type;
0174     uint8_t         data[CSIO_EVT_MSG_SIZE];
0175 };
0176 
0177 enum {
0178     SERNUM_LEN     = 16,    /* Serial # length */
0179     EC_LEN         = 16,    /* E/C length */
0180     ID_LEN         = 16,    /* ID length */
0181 };
0182 
0183 enum {
0184     SF_SIZE = SF_SEC_SIZE * 16,   /* serial flash size */
0185 };
0186 
0187 /* serial flash and firmware constants */
0188 enum {
0189     SF_ATTEMPTS = 10,             /* max retries for SF operations */
0190 
0191     /* flash command opcodes */
0192     SF_PROG_PAGE    = 2,          /* program page */
0193     SF_WR_DISABLE   = 4,          /* disable writes */
0194     SF_RD_STATUS    = 5,          /* read status register */
0195     SF_WR_ENABLE    = 6,          /* enable writes */
0196     SF_RD_DATA_FAST = 0xb,        /* read flash */
0197     SF_RD_ID    = 0x9f,       /* read ID */
0198     SF_ERASE_SECTOR = 0xd8,       /* erase sector */
0199 };
0200 
0201 /* Management module */
0202 enum {
0203     CSIO_MGMT_EQ_WRSIZE = 512,
0204     CSIO_MGMT_IQ_WRSIZE = 128,
0205     CSIO_MGMT_EQLEN = 64,
0206     CSIO_MGMT_IQLEN = 64,
0207 };
0208 
0209 #define CSIO_MGMT_EQSIZE    (CSIO_MGMT_EQLEN * CSIO_MGMT_EQ_WRSIZE)
0210 #define CSIO_MGMT_IQSIZE    (CSIO_MGMT_IQLEN * CSIO_MGMT_IQ_WRSIZE)
0211 
0212 /* mgmt module stats */
0213 struct csio_mgmtm_stats {
0214     uint32_t    n_abort_req;        /* Total abort request */
0215     uint32_t    n_abort_rsp;        /* Total abort response */
0216     uint32_t    n_close_req;        /* Total close request */
0217     uint32_t    n_close_rsp;        /* Total close response */
0218     uint32_t    n_err;          /* Total Errors */
0219     uint32_t    n_drop;         /* Total request dropped */
0220     uint32_t    n_active;       /* Count of active_q */
0221     uint32_t    n_cbfn;         /* Count of cbfn_q */
0222 };
0223 
0224 /* MGMT module */
0225 struct csio_mgmtm {
0226     struct  csio_hw     *hw;        /* Pointer to HW moduel */
0227     int         eq_idx;     /* Egress queue index */
0228     int         iq_idx;     /* Ingress queue index */
0229     int         msi_vec;    /* MSI vector */
0230     struct list_head    active_q;   /* Outstanding ELS/CT */
0231     struct list_head    abort_q;    /* Outstanding abort req */
0232     struct list_head    cbfn_q;     /* Completion queue */
0233     struct list_head    mgmt_req_freelist; /* Free poll of reqs */
0234                         /* ELSCT request freelist*/
0235     struct timer_list   mgmt_timer; /* MGMT timer */
0236     struct csio_mgmtm_stats stats;      /* ELS/CT stats */
0237 };
0238 
0239 struct csio_adap_desc {
0240     char model_no[16];
0241     char description[32];
0242 };
0243 
0244 struct pci_params {
0245     uint16_t   vendor_id;
0246     uint16_t   device_id;
0247     int        vpd_cap_addr;
0248     uint16_t   speed;
0249     uint8_t    width;
0250 };
0251 
0252 /* User configurable hw parameters */
0253 struct csio_hw_params {
0254     uint32_t        sf_size;        /* serial flash
0255                              * size in bytes
0256                              */
0257     uint32_t        sf_nsec;        /* # of flash sectors */
0258     struct pci_params   pci;
0259     uint32_t        log_level;      /* Module-level for
0260                              * debug log.
0261                              */
0262 };
0263 
0264 struct csio_vpd {
0265     uint32_t cclk;
0266     uint8_t ec[EC_LEN + 1];
0267     uint8_t sn[SERNUM_LEN + 1];
0268     uint8_t id[ID_LEN + 1];
0269 };
0270 
0271 /* Firmware Port Capabilities types. */
0272 
0273 typedef u16 fw_port_cap16_t;    /* 16-bit Port Capabilities integral value */
0274 typedef u32 fw_port_cap32_t;    /* 32-bit Port Capabilities integral value */
0275 
0276 enum fw_caps {
0277     FW_CAPS_UNKNOWN = 0,    /* 0'ed out initial state */
0278     FW_CAPS16       = 1,    /* old Firmware: 16-bit Port Capabilities */
0279     FW_CAPS32       = 2,    /* new Firmware: 32-bit Port Capabilities */
0280 };
0281 
0282 enum cc_pause {
0283     PAUSE_RX      = 1 << 0,
0284     PAUSE_TX      = 1 << 1,
0285     PAUSE_AUTONEG = 1 << 2
0286 };
0287 
0288 enum cc_fec {
0289     FEC_AUTO    = 1 << 0,  /* IEEE 802.3 "automatic" */
0290     FEC_RS      = 1 << 1,  /* Reed-Solomon */
0291     FEC_BASER_RS    = 1 << 2   /* BaseR/Reed-Solomon */
0292 };
0293 
0294 struct link_config {
0295     fw_port_cap32_t pcaps;      /* link capabilities */
0296     fw_port_cap32_t def_acaps;  /* default advertised capabilities */
0297     fw_port_cap32_t acaps;      /* advertised capabilities */
0298     fw_port_cap32_t lpacaps;    /* peer advertised capabilities */
0299 
0300     fw_port_cap32_t speed_caps; /* speed(s) user has requested */
0301     unsigned int   speed;       /* actual link speed (Mb/s) */
0302 
0303     enum cc_pause  requested_fc;    /* flow control user has requested */
0304     enum cc_pause  fc;      /* actual link flow control */
0305 
0306     enum cc_fec    requested_fec;   /* Forward Error Correction: */
0307     enum cc_fec    fec;     /* requested and actual in use */
0308 
0309     unsigned char  autoneg;     /* autonegotiating? */
0310 
0311     unsigned char  link_ok;     /* link up? */
0312     unsigned char  link_down_rc;    /* link down reason */
0313 };
0314 
0315 #define FW_LEN16(fw_struct) FW_CMD_LEN16_V(sizeof(fw_struct) / 16)
0316 
0317 #define ADVERT_MASK (FW_PORT_CAP32_SPEED_V(FW_PORT_CAP32_SPEED_M) | \
0318              FW_PORT_CAP32_ANEG)
0319 
0320 /* Enable or disable autonegotiation. */
0321 #define AUTONEG_DISABLE 0x00
0322 #define AUTONEG_ENABLE  0x01
0323 
0324 struct csio_pport {
0325     uint16_t    pcap;
0326     uint16_t    acap;
0327     uint8_t     portid;
0328     uint8_t     link_status;
0329     uint16_t    link_speed;
0330     uint8_t     mac[6];
0331     uint8_t     mod_type;
0332     uint8_t     rsvd1;
0333     uint8_t     rsvd2;
0334     uint8_t     rsvd3;
0335     struct link_config link_cfg;
0336 };
0337 
0338 /* fcoe resource information */
0339 struct csio_fcoe_res_info {
0340     uint16_t    e_d_tov;
0341     uint16_t    r_a_tov_seq;
0342     uint16_t    r_a_tov_els;
0343     uint16_t    r_r_tov;
0344     uint32_t    max_xchgs;
0345     uint32_t    max_ssns;
0346     uint32_t    used_xchgs;
0347     uint32_t    used_ssns;
0348     uint32_t    max_fcfs;
0349     uint32_t    max_vnps;
0350     uint32_t    used_fcfs;
0351     uint32_t    used_vnps;
0352 };
0353 
0354 /* HW State machine Events */
0355 enum csio_hw_ev {
0356     CSIO_HWE_CFG = (uint32_t)1, /* Starts off the State machine */
0357     CSIO_HWE_INIT,           /* Config done, start Init      */
0358     CSIO_HWE_INIT_DONE,      /* Init Mailboxes sent, HW ready */
0359     CSIO_HWE_FATAL,      /* Fatal error during initialization */
0360     CSIO_HWE_PCIERR_DETECTED,/* PCI error recovery detetced */
0361     CSIO_HWE_PCIERR_SLOT_RESET, /* Slot reset after PCI recoviery */
0362     CSIO_HWE_PCIERR_RESUME,  /* Resume after PCI error recovery */
0363     CSIO_HWE_QUIESCED,   /* HBA quiesced */
0364     CSIO_HWE_HBA_RESET,      /* HBA reset requested */
0365     CSIO_HWE_HBA_RESET_DONE, /* HBA reset completed */
0366     CSIO_HWE_FW_DLOAD,       /* FW download requested */
0367     CSIO_HWE_PCI_REMOVE,     /* PCI de-instantiation */
0368     CSIO_HWE_SUSPEND,        /* HW suspend for Online(hot) replacement */
0369     CSIO_HWE_RESUME,         /* HW resume for Online(hot) replacement */
0370     CSIO_HWE_MAX,        /* Max HW event */
0371 };
0372 
0373 /* hw stats */
0374 struct csio_hw_stats {
0375     uint32_t    n_evt_activeq;  /* Number of event in active Q */
0376     uint32_t    n_evt_freeq;    /* Number of event in free Q */
0377     uint32_t    n_evt_drop; /* Number of event droped */
0378     uint32_t    n_evt_unexp;    /* Number of unexpected events */
0379     uint32_t    n_pcich_offline;/* Number of pci channel offline */
0380     uint32_t    n_lnlkup_miss;  /* Number of lnode lookup miss */
0381     uint32_t    n_cpl_fw6_msg;  /* Number of cpl fw6 message*/
0382     uint32_t    n_cpl_fw6_pld;  /* Number of cpl fw6 payload*/
0383     uint32_t    n_cpl_unexp;    /* Number of unexpected cpl */
0384     uint32_t    n_mbint_unexp;  /* Number of unexpected mbox */
0385                     /* interrupt */
0386     uint32_t    n_plint_unexp;  /* Number of unexpected PL */
0387                     /* interrupt */
0388     uint32_t    n_plint_cnt;    /* Number of PL interrupt */
0389     uint32_t    n_int_stray;    /* Number of stray interrupt */
0390     uint32_t    n_err;      /* Number of hw errors */
0391     uint32_t    n_err_fatal;    /* Number of fatal errors */
0392     uint32_t    n_err_nomem;    /* Number of memory alloc failure */
0393     uint32_t    n_err_io;   /* Number of IO failure */
0394     enum csio_hw_ev n_evt_sm[CSIO_HWE_MAX]; /* Number of sm events */
0395     uint64_t    n_reset_start;  /* Start time after the reset */
0396     uint32_t    rsvd1;
0397 };
0398 
0399 /* Defines for hw->flags */
0400 #define CSIO_HWF_MASTER         0x00000001  /* This is the Master
0401                              * function for the
0402                              * card.
0403                              */
0404 #define CSIO_HWF_HW_INTR_ENABLED    0x00000002  /* Are HW Interrupt
0405                              * enable bit set?
0406                              */
0407 #define CSIO_HWF_FWEVT_PENDING      0x00000004  /* FW events pending */
0408 #define CSIO_HWF_Q_MEM_ALLOCED      0x00000008  /* Queues have been
0409                              * allocated memory.
0410                              */
0411 #define CSIO_HWF_Q_FW_ALLOCED       0x00000010  /* Queues have been
0412                              * allocated in FW.
0413                              */
0414 #define CSIO_HWF_VPD_VALID      0x00000020  /* Valid VPD copied */
0415 #define CSIO_HWF_DEVID_CACHED       0X00000040  /* PCI vendor & device
0416                              * id cached */
0417 #define CSIO_HWF_FWEVT_STOP     0x00000080  /* Stop processing
0418                              * FW events
0419                              */
0420 #define CSIO_HWF_USING_SOFT_PARAMS  0x00000100      /* Using FW config
0421                              * params
0422                              */
0423 #define CSIO_HWF_HOST_INTR_ENABLED  0x00000200  /* Are host interrupts
0424                              * enabled?
0425                              */
0426 #define CSIO_HWF_ROOT_NO_RELAXED_ORDERING 0x00000400    /* Is PCIe relaxed
0427                              * ordering enabled
0428                              */
0429 
0430 #define csio_is_hw_intr_enabled(__hw)   \
0431                 ((__hw)->flags & CSIO_HWF_HW_INTR_ENABLED)
0432 #define csio_is_host_intr_enabled(__hw) \
0433                 ((__hw)->flags & CSIO_HWF_HOST_INTR_ENABLED)
0434 #define csio_is_hw_master(__hw)     ((__hw)->flags & CSIO_HWF_MASTER)
0435 #define csio_is_valid_vpd(__hw)     ((__hw)->flags & CSIO_HWF_VPD_VALID)
0436 #define csio_is_dev_id_cached(__hw) ((__hw)->flags & CSIO_HWF_DEVID_CACHED)
0437 #define csio_valid_vpd_copied(__hw) ((__hw)->flags |= CSIO_HWF_VPD_VALID)
0438 #define csio_dev_id_cached(__hw)    ((__hw)->flags |= CSIO_HWF_DEVID_CACHED)
0439 
0440 /* Defines for intr_mode */
0441 enum csio_intr_mode {
0442     CSIO_IM_NONE = 0,
0443     CSIO_IM_INTX = 1,
0444     CSIO_IM_MSI  = 2,
0445     CSIO_IM_MSIX = 3,
0446 };
0447 
0448 /* Master HW structure: One per function */
0449 struct csio_hw {
0450     struct csio_sm      sm;         /* State machine: should
0451                              * be the 1st member.
0452                              */
0453     spinlock_t      lock;           /* Lock for hw */
0454 
0455     struct csio_scsim   scsim;          /* SCSI module*/
0456     struct csio_wrm     wrm;            /* Work request module*/
0457     struct pci_dev      *pdev;          /* PCI device */
0458 
0459     void __iomem        *regstart;      /* Virtual address of
0460                              * register map
0461                              */
0462     /* SCSI queue sets */
0463     uint32_t        num_sqsets;     /* Number of SCSI
0464                              * queue sets */
0465     uint32_t        num_scsi_msix_cpus; /* Number of CPUs that
0466                              * will be used
0467                              * for ingress
0468                              * processing.
0469                              */
0470 
0471     struct csio_scsi_qset   sqset[CSIO_MAX_PPORTS][CSIO_MAX_SCSI_CPU];
0472     struct csio_scsi_cpu_info scsi_cpu_info[CSIO_MAX_PPORTS];
0473 
0474     uint32_t        evtflag;        /* Event flag  */
0475     uint32_t        flags;          /* HW flags */
0476 
0477     struct csio_mgmtm   mgmtm;          /* management module */
0478     struct csio_mbm     mbm;            /* Mailbox module */
0479 
0480     /* Lnodes */
0481     uint32_t        num_lns;        /* Number of lnodes */
0482     struct csio_lnode   *rln;           /* Root lnode */
0483     struct list_head    sln_head;       /* Sibling node list
0484                              * list
0485                              */
0486     int         intr_iq_idx;        /* Forward interrupt
0487                              * queue.
0488                              */
0489     int         fwevt_iq_idx;       /* FW evt queue */
0490     struct work_struct  evtq_work;      /* Worker thread for
0491                              * HW events.
0492                              */
0493     struct list_head    evt_free_q;     /* freelist of evt
0494                              * elements
0495                              */
0496     struct list_head    evt_active_q;       /* active evt queue*/
0497 
0498     /* board related info */
0499     char            name[32];
0500     char            hw_ver[16];
0501     char            model_desc[32];
0502     char            drv_version[32];
0503     char            fwrev_str[32];
0504     uint32_t        optrom_ver;
0505     uint32_t        fwrev;
0506     uint32_t        tp_vers;
0507     char            chip_ver;
0508     uint16_t        chip_id;        /* Tells T4/T5 chip */
0509     enum csio_dev_state fw_state;
0510     struct csio_vpd     vpd;
0511 
0512     uint8_t         pfn;            /* Physical Function
0513                              * number
0514                              */
0515     uint32_t        port_vec;       /* Port vector */
0516     uint8_t         num_pports;     /* Number of physical
0517                              * ports.
0518                              */
0519     uint8_t         rst_retries;        /* Reset retries */
0520     uint8_t         cur_evt;        /* current s/m evt */
0521     uint8_t         prev_evt;       /* Previous s/m evt */
0522     uint32_t        dev_num;        /* device number */
0523     struct csio_pport   pport[CSIO_MAX_PPORTS]; /* Ports (XGMACs) */
0524     struct csio_hw_params   params;         /* Hw parameters */
0525 
0526     struct dma_pool     *scsi_dma_pool;     /* DMA pool for SCSI */
0527     mempool_t       *mb_mempool;        /* Mailbox memory pool*/
0528     mempool_t       *rnode_mempool;     /* rnode memory pool */
0529 
0530     /* Interrupt */
0531     enum csio_intr_mode intr_mode;      /* INTx, MSI, MSIX */
0532     uint32_t        fwevt_intr_idx;     /* FW evt MSIX/interrupt
0533                              * index
0534                              */
0535     uint32_t        nondata_intr_idx;   /* nondata MSIX/intr
0536                              * idx
0537                              */
0538 
0539     uint8_t         cfg_neq;        /* FW configured no of
0540                              * egress queues
0541                              */
0542     uint8_t         cfg_niq;        /* FW configured no of
0543                              * iq queues.
0544                              */
0545 
0546     struct csio_fcoe_res_info  fres_info;       /* Fcoe resource info */
0547     struct csio_hw_chip_ops *chip_ops;      /* T4/T5 Chip specific
0548                              * Operations
0549                              */
0550 
0551     /* MSIX vectors */
0552     struct csio_msix_entries msix_entries[CSIO_MAX_MSIX_VECS];
0553 
0554     struct dentry       *debugfs_root;      /* Debug FS */
0555     struct csio_hw_stats    stats;          /* Hw statistics */
0556 };
0557 
0558 /* Register access macros */
0559 #define csio_reg(_b, _r)        ((_b) + (_r))
0560 
0561 #define csio_rd_reg8(_h, _r)        readb(csio_reg((_h)->regstart, (_r)))
0562 #define csio_rd_reg16(_h, _r)       readw(csio_reg((_h)->regstart, (_r)))
0563 #define csio_rd_reg32(_h, _r)       readl(csio_reg((_h)->regstart, (_r)))
0564 #define csio_rd_reg64(_h, _r)       readq(csio_reg((_h)->regstart, (_r)))
0565 
0566 #define csio_wr_reg8(_h, _v, _r)    writeb((_v), \
0567                         csio_reg((_h)->regstart, (_r)))
0568 #define csio_wr_reg16(_h, _v, _r)   writew((_v), \
0569                         csio_reg((_h)->regstart, (_r)))
0570 #define csio_wr_reg32(_h, _v, _r)   writel((_v), \
0571                         csio_reg((_h)->regstart, (_r)))
0572 #define csio_wr_reg64(_h, _v, _r)   writeq((_v), \
0573                         csio_reg((_h)->regstart, (_r)))
0574 
0575 void csio_set_reg_field(struct csio_hw *, uint32_t, uint32_t, uint32_t);
0576 
0577 /* Core clocks <==> uSecs */
0578 static inline uint32_t
0579 csio_core_ticks_to_us(struct csio_hw *hw, uint32_t ticks)
0580 {
0581     /* add Core Clock / 2 to round ticks to nearest uS */
0582     return (ticks * 1000 + hw->vpd.cclk/2) / hw->vpd.cclk;
0583 }
0584 
0585 static inline uint32_t
0586 csio_us_to_core_ticks(struct csio_hw *hw, uint32_t us)
0587 {
0588     return (us * hw->vpd.cclk) / 1000;
0589 }
0590 
0591 /* Easy access macros */
0592 #define csio_hw_to_wrm(hw)      ((struct csio_wrm *)(&(hw)->wrm))
0593 #define csio_hw_to_mbm(hw)      ((struct csio_mbm *)(&(hw)->mbm))
0594 #define csio_hw_to_scsim(hw)        ((struct csio_scsim *)(&(hw)->scsim))
0595 #define csio_hw_to_mgmtm(hw)        ((struct csio_mgmtm *)(&(hw)->mgmtm))
0596 
0597 #define CSIO_PCI_BUS(hw)        ((hw)->pdev->bus->number)
0598 #define CSIO_PCI_DEV(hw)        (PCI_SLOT((hw)->pdev->devfn))
0599 #define CSIO_PCI_FUNC(hw)       (PCI_FUNC((hw)->pdev->devfn))
0600 
0601 #define csio_set_fwevt_intr_idx(_h, _i)     ((_h)->fwevt_intr_idx = (_i))
0602 #define csio_get_fwevt_intr_idx(_h)     ((_h)->fwevt_intr_idx)
0603 #define csio_set_nondata_intr_idx(_h, _i)   ((_h)->nondata_intr_idx = (_i))
0604 #define csio_get_nondata_intr_idx(_h)       ((_h)->nondata_intr_idx)
0605 
0606 /* Printing/logging */
0607 #define CSIO_DEVID(__dev)       ((__dev)->dev_num)
0608 #define CSIO_DEVID_LO(__dev)        (CSIO_DEVID((__dev)) & 0xFFFF)
0609 #define CSIO_DEVID_HI(__dev)        ((CSIO_DEVID((__dev)) >> 16) & 0xFFFF)
0610 
0611 #define csio_info(__hw, __fmt, ...)                 \
0612             dev_info(&(__hw)->pdev->dev, __fmt, ##__VA_ARGS__)
0613 
0614 #define csio_fatal(__hw, __fmt, ...)                    \
0615             dev_crit(&(__hw)->pdev->dev, __fmt, ##__VA_ARGS__)
0616 
0617 #define csio_err(__hw, __fmt, ...)                  \
0618             dev_err(&(__hw)->pdev->dev, __fmt, ##__VA_ARGS__)
0619 
0620 #define csio_warn(__hw, __fmt, ...)                 \
0621             dev_warn(&(__hw)->pdev->dev, __fmt, ##__VA_ARGS__)
0622 
0623 #ifdef __CSIO_DEBUG__
0624 #define csio_dbg(__hw, __fmt, ...)                  \
0625             csio_info((__hw), __fmt, ##__VA_ARGS__);
0626 #else
0627 #define csio_dbg(__hw, __fmt, ...)
0628 #endif
0629 
0630 int csio_hw_wait_op_done_val(struct csio_hw *, int, uint32_t, int,
0631                  int, int, uint32_t *);
0632 void csio_hw_tp_wr_bits_indirect(struct csio_hw *, unsigned int,
0633                  unsigned int, unsigned int);
0634 int csio_mgmt_req_lookup(struct csio_mgmtm *, struct csio_ioreq *);
0635 void csio_hw_intr_disable(struct csio_hw *);
0636 int csio_hw_slow_intr_handler(struct csio_hw *);
0637 int csio_handle_intr_status(struct csio_hw *, unsigned int,
0638                 const struct intr_info *);
0639 
0640 fw_port_cap32_t fwcap_to_fwspeed(fw_port_cap32_t acaps);
0641 fw_port_cap32_t fwcaps16_to_caps32(fw_port_cap16_t caps16);
0642 fw_port_cap16_t fwcaps32_to_caps16(fw_port_cap32_t caps32);
0643 fw_port_cap32_t lstatus_to_fwcap(u32 lstatus);
0644 
0645 int csio_hw_start(struct csio_hw *);
0646 int csio_hw_stop(struct csio_hw *);
0647 int csio_hw_reset(struct csio_hw *);
0648 int csio_is_hw_ready(struct csio_hw *);
0649 int csio_is_hw_removing(struct csio_hw *);
0650 
0651 int csio_fwevtq_handler(struct csio_hw *);
0652 void csio_evtq_worker(struct work_struct *);
0653 int csio_enqueue_evt(struct csio_hw *, enum csio_evt, void *, uint16_t);
0654 void csio_evtq_flush(struct csio_hw *hw);
0655 
0656 int csio_request_irqs(struct csio_hw *);
0657 void csio_intr_enable(struct csio_hw *);
0658 void csio_intr_disable(struct csio_hw *, bool);
0659 void csio_hw_fatal_err(struct csio_hw *);
0660 
0661 struct csio_lnode *csio_lnode_alloc(struct csio_hw *);
0662 int csio_config_queues(struct csio_hw *);
0663 
0664 int csio_hw_init(struct csio_hw *);
0665 void csio_hw_exit(struct csio_hw *);
0666 #endif /* ifndef __CSIO_HW_H__ */