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_WR_H__
0036 #define __CSIO_WR_H__
0037 
0038 #include <linux/cache.h>
0039 
0040 #include "csio_defs.h"
0041 #include "t4fw_api.h"
0042 #include "t4fw_api_stor.h"
0043 
0044 /*
0045  * SGE register field values.
0046  */
0047 #define X_INGPCIEBOUNDARY_32B       0
0048 #define X_INGPCIEBOUNDARY_64B       1
0049 #define X_INGPCIEBOUNDARY_128B      2
0050 #define X_INGPCIEBOUNDARY_256B      3
0051 #define X_INGPCIEBOUNDARY_512B      4
0052 #define X_INGPCIEBOUNDARY_1024B     5
0053 #define X_INGPCIEBOUNDARY_2048B     6
0054 #define X_INGPCIEBOUNDARY_4096B     7
0055 
0056 /* GTS register */
0057 #define X_TIMERREG_COUNTER0     0
0058 #define X_TIMERREG_COUNTER1     1
0059 #define X_TIMERREG_COUNTER2     2
0060 #define X_TIMERREG_COUNTER3     3
0061 #define X_TIMERREG_COUNTER4     4
0062 #define X_TIMERREG_COUNTER5     5
0063 #define X_TIMERREG_RESTART_COUNTER  6
0064 #define X_TIMERREG_UPDATE_CIDX      7
0065 
0066 /*
0067  * Egress Context field values
0068  */
0069 #define X_FETCHBURSTMIN_16B     0
0070 #define X_FETCHBURSTMIN_32B     1
0071 #define X_FETCHBURSTMIN_64B     2
0072 #define X_FETCHBURSTMIN_128B        3
0073 
0074 #define X_FETCHBURSTMAX_64B     0
0075 #define X_FETCHBURSTMAX_128B        1
0076 #define X_FETCHBURSTMAX_256B        2
0077 #define X_FETCHBURSTMAX_512B        3
0078 
0079 #define X_HOSTFCMODE_NONE       0
0080 #define X_HOSTFCMODE_INGRESS_QUEUE  1
0081 #define X_HOSTFCMODE_STATUS_PAGE    2
0082 #define X_HOSTFCMODE_BOTH       3
0083 
0084 /*
0085  * Ingress Context field values
0086  */
0087 #define X_UPDATESCHEDULING_TIMER    0
0088 #define X_UPDATESCHEDULING_COUNTER_OPTTIMER 1
0089 
0090 #define X_UPDATEDELIVERY_NONE       0
0091 #define X_UPDATEDELIVERY_INTERRUPT  1
0092 #define X_UPDATEDELIVERY_STATUS_PAGE    2
0093 #define X_UPDATEDELIVERY_BOTH       3
0094 
0095 #define X_INTERRUPTDESTINATION_PCIE 0
0096 #define X_INTERRUPTDESTINATION_IQ   1
0097 
0098 #define X_RSPD_TYPE_FLBUF       0
0099 #define X_RSPD_TYPE_CPL         1
0100 #define X_RSPD_TYPE_INTR        2
0101 
0102 /* WR status is at the same position as retval in a CMD header */
0103 #define csio_wr_status(_wr)     \
0104         (FW_CMD_RETVAL_G(ntohl(((struct fw_cmd_hdr *)(_wr))->lo)))
0105 
0106 struct csio_hw;
0107 
0108 extern int csio_intr_coalesce_cnt;
0109 extern int csio_intr_coalesce_time;
0110 
0111 /* Ingress queue params */
0112 struct csio_iq_params {
0113 
0114     uint8_t     iq_start:1;
0115     uint8_t     iq_stop:1;
0116     uint8_t     pfn:3;
0117 
0118     uint8_t     vfn;
0119 
0120     uint16_t    physiqid;
0121     uint16_t    iqid;
0122 
0123     uint16_t    fl0id;
0124     uint16_t    fl1id;
0125 
0126     uint8_t     viid;
0127 
0128     uint8_t     type;
0129     uint8_t     iqasynch;
0130     uint8_t     reserved4;
0131 
0132     uint8_t     iqandst;
0133     uint8_t     iqanus;
0134     uint8_t     iqanud;
0135 
0136     uint16_t    iqandstindex;
0137 
0138     uint8_t     iqdroprss;
0139     uint8_t     iqpciech;
0140     uint8_t     iqdcaen;
0141 
0142     uint8_t     iqdcacpu;
0143     uint8_t     iqintcntthresh;
0144     uint8_t     iqo;
0145 
0146     uint8_t     iqcprio;
0147     uint8_t     iqesize;
0148 
0149     uint16_t    iqsize;
0150 
0151     uint64_t    iqaddr;
0152 
0153     uint8_t     iqflintiqhsen;
0154     uint8_t     reserved5;
0155     uint8_t     iqflintcongen;
0156     uint8_t     iqflintcngchmap;
0157 
0158     uint32_t    reserved6;
0159 
0160     uint8_t     fl0hostfcmode;
0161     uint8_t     fl0cprio;
0162     uint8_t     fl0paden;
0163     uint8_t     fl0packen;
0164     uint8_t     fl0congen;
0165     uint8_t     fl0dcaen;
0166 
0167     uint8_t     fl0dcacpu;
0168     uint8_t     fl0fbmin;
0169 
0170     uint8_t     fl0fbmax;
0171     uint8_t     fl0cidxfthresho;
0172     uint8_t     fl0cidxfthresh;
0173 
0174     uint16_t    fl0size;
0175 
0176     uint64_t    fl0addr;
0177 
0178     uint64_t    reserved7;
0179 
0180     uint8_t     fl1hostfcmode;
0181     uint8_t     fl1cprio;
0182     uint8_t     fl1paden;
0183     uint8_t     fl1packen;
0184     uint8_t     fl1congen;
0185     uint8_t     fl1dcaen;
0186 
0187     uint8_t     fl1dcacpu;
0188     uint8_t     fl1fbmin;
0189 
0190     uint8_t     fl1fbmax;
0191     uint8_t     fl1cidxfthresho;
0192     uint8_t     fl1cidxfthresh;
0193 
0194     uint16_t    fl1size;
0195 
0196     uint64_t    fl1addr;
0197 };
0198 
0199 /* Egress queue params */
0200 struct csio_eq_params {
0201 
0202     uint8_t     pfn;
0203     uint8_t     vfn;
0204 
0205     uint8_t     eqstart:1;
0206     uint8_t     eqstop:1;
0207 
0208     uint16_t        physeqid;
0209     uint32_t    eqid;
0210 
0211     uint8_t     hostfcmode:2;
0212     uint8_t     cprio:1;
0213     uint8_t     pciechn:3;
0214 
0215     uint16_t    iqid;
0216 
0217     uint8_t     dcaen:1;
0218     uint8_t     dcacpu:5;
0219 
0220     uint8_t     fbmin:3;
0221     uint8_t     fbmax:3;
0222 
0223     uint8_t     cidxfthresho:1;
0224     uint8_t     cidxfthresh:3;
0225 
0226     uint16_t    eqsize;
0227 
0228     uint64_t    eqaddr;
0229 };
0230 
0231 struct csio_dma_buf {
0232     struct list_head    list;
0233     void            *vaddr;     /* Virtual address */
0234     dma_addr_t      paddr;      /* Physical address */
0235     uint32_t        len;        /* Buffer size */
0236 };
0237 
0238 /* Generic I/O request structure */
0239 struct csio_ioreq {
0240     struct csio_sm      sm;     /* SM, List
0241                          * should be the first member
0242                          */
0243     int         iq_idx;     /* Ingress queue index */
0244     int         eq_idx;     /* Egress queue index */
0245     uint32_t        nsge;       /* Number of SG elements */
0246     uint32_t        tmo;        /* Driver timeout */
0247     uint32_t        datadir;    /* Data direction */
0248     struct csio_dma_buf dma_buf;    /* Req/resp DMA buffers */
0249     uint16_t        wr_status;  /* WR completion status */
0250     int16_t         drv_status; /* Driver internal status */
0251     struct csio_lnode   *lnode;     /* Owner lnode */
0252     struct csio_rnode   *rnode;     /* Src/destination rnode */
0253     void (*io_cbfn) (struct csio_hw *, struct csio_ioreq *);
0254                         /* completion callback */
0255     void            *scratch1;  /* Scratch area 1.
0256                          */
0257     void            *scratch2;  /* Scratch area 2. */
0258     struct list_head    gen_list;   /* Any list associated with
0259                          * this ioreq.
0260                          */
0261     uint64_t        fw_handle;  /* Unique handle passed
0262                          * to FW
0263                          */
0264     uint8_t         dcopy;      /* Data copy required */
0265     uint8_t         reserved1;
0266     uint16_t        reserved2;
0267     struct completion   cmplobj;    /* ioreq completion object */
0268 } ____cacheline_aligned_in_smp;
0269 
0270 /*
0271  * Egress status page for egress cidx updates
0272  */
0273 struct csio_qstatus_page {
0274     __be32 qid;
0275     __be16 cidx;
0276     __be16 pidx;
0277 };
0278 
0279 
0280 enum {
0281     CSIO_MAX_FLBUF_PER_IQWR = 4,
0282     CSIO_QCREDIT_SZ  = 64,          /* pidx/cidx increments
0283                          * in bytes
0284                          */
0285     CSIO_MAX_QID = 0xFFFF,
0286     CSIO_MAX_IQ = 128,
0287 
0288     CSIO_SGE_NTIMERS = 6,
0289     CSIO_SGE_NCOUNTERS = 4,
0290     CSIO_SGE_FL_SIZE_REGS = 16,
0291 };
0292 
0293 /* Defines for type */
0294 enum {
0295     CSIO_EGRESS = 1,
0296     CSIO_INGRESS    = 2,
0297     CSIO_FREELIST   = 3,
0298 };
0299 
0300 /*
0301  * Structure for footer (last 2 flits) of Ingress Queue Entry.
0302  */
0303 struct csio_iqwr_footer {
0304     __be32          hdrbuflen_pidx;
0305     __be32          pldbuflen_qid;
0306     union {
0307         u8      type_gen;
0308         __be64      last_flit;
0309     } u;
0310 };
0311 
0312 #define IQWRF_NEWBUF        (1 << 31)
0313 #define IQWRF_LEN_GET(x)    (((x) >> 0) & 0x7fffffffU)
0314 #define IQWRF_GEN_SHIFT     7
0315 #define IQWRF_TYPE_GET(x)   (((x) >> 4) & 0x3U)
0316 
0317 
0318 /*
0319  * WR pair:
0320  * ========
0321  * A WR can start towards the end of a queue, and then continue at the
0322  * beginning, since the queue is considered to be circular. This will
0323  * require a pair of address/len to be passed back to the caller -
0324  * hence the Work request pair structure.
0325  */
0326 struct csio_wr_pair {
0327     void            *addr1;
0328     uint32_t        size1;
0329     void            *addr2;
0330     uint32_t        size2;
0331 };
0332 
0333 /*
0334  * The following structure is used by ingress processing to return the
0335  * free list buffers to consumers.
0336  */
0337 struct csio_fl_dma_buf {
0338     struct csio_dma_buf flbufs[CSIO_MAX_FLBUF_PER_IQWR];
0339                         /* Freelist DMA buffers */
0340     int         offset;     /* Offset within the
0341                          * first FL buf.
0342                          */
0343     uint32_t        totlen;     /* Total length */
0344     uint8_t         defer_free; /* Free of buffer can
0345                          * deferred
0346                          */
0347 };
0348 
0349 /* Data-types */
0350 typedef void (*iq_handler_t)(struct csio_hw *, void *, uint32_t,
0351                  struct csio_fl_dma_buf *, void *);
0352 
0353 struct csio_iq {
0354     uint16_t        iqid;       /* Queue ID */
0355     uint16_t        physiqid;   /* Physical Queue ID */
0356     uint16_t        genbit;     /* Generation bit,
0357                          * initially set to 1
0358                          */
0359     int         flq_idx;    /* Freelist queue index */
0360     iq_handler_t        iq_intx_handler; /* IQ INTx handler routine */
0361 };
0362 
0363 struct csio_eq {
0364     uint16_t        eqid;       /* Qid */
0365     uint16_t        physeqid;   /* Physical Queue ID */
0366     uint8_t         wrap[512];  /* Temp area for q-wrap around*/
0367 };
0368 
0369 struct csio_fl {
0370     uint16_t        flid;       /* Qid */
0371     uint16_t        packen;     /* Packing enabled? */
0372     int         offset;     /* Offset within FL buf */
0373     int         sreg;       /* Size register */
0374     struct csio_dma_buf *bufs;      /* Free list buffer ptr array
0375                          * indexed using flq->cidx/pidx
0376                          */
0377 };
0378 
0379 struct csio_qstats {
0380     uint32_t    n_tot_reqs;     /* Total no. of Requests */
0381     uint32_t    n_tot_rsps;     /* Total no. of responses */
0382     uint32_t    n_qwrap;        /* Queue wraps */
0383     uint32_t    n_eq_wr_split;      /* Number of split EQ WRs */
0384     uint32_t    n_qentry;       /* Queue entry */
0385     uint32_t    n_qempty;       /* Queue empty */
0386     uint32_t    n_qfull;        /* Queue fulls */
0387     uint32_t    n_rsp_unknown;      /* Unknown response type */
0388     uint32_t    n_stray_comp;       /* Stray completion intr */
0389     uint32_t    n_flq_refill;       /* Number of FL refills */
0390 };
0391 
0392 /* Queue metadata */
0393 struct csio_q {
0394     uint16_t        type;       /* Type: Ingress/Egress/FL */
0395     uint16_t        pidx;       /* producer index */
0396     uint16_t        cidx;       /* consumer index */
0397     uint16_t        inc_idx;    /* Incremental index */
0398     uint32_t        wr_sz;      /* Size of all WRs in this q
0399                          * if fixed
0400                          */
0401     void            *vstart;    /* Base virtual address
0402                          * of queue
0403                          */
0404     void            *vwrap;     /* Virtual end address to
0405                          * wrap around at
0406                          */
0407     uint32_t        credits;    /* Size of queue in credits */
0408     void            *owner;     /* Owner */
0409     union {                 /* Queue contexts */
0410         struct csio_iq  iq;
0411         struct csio_eq  eq;
0412         struct csio_fl  fl;
0413     } un;
0414 
0415     dma_addr_t      pstart;     /* Base physical address of
0416                          * queue
0417                          */
0418     uint32_t        portid;     /* PCIE Channel */
0419     uint32_t        size;       /* Size of queue in bytes */
0420     struct csio_qstats  stats;      /* Statistics */
0421 } ____cacheline_aligned_in_smp;
0422 
0423 struct csio_sge {
0424     uint32_t    csio_fl_align;      /* Calculated and cached
0425                          * for fast path
0426                          */
0427     uint32_t    sge_control;        /* padding, boundaries,
0428                          * lengths, etc.
0429                          */
0430     uint32_t    sge_host_page_size; /* Host page size */
0431     uint32_t    sge_fl_buf_size[CSIO_SGE_FL_SIZE_REGS];
0432                         /* free list buffer sizes */
0433     uint16_t    timer_val[CSIO_SGE_NTIMERS];
0434     uint8_t     counter_val[CSIO_SGE_NCOUNTERS];
0435 };
0436 
0437 /* Work request module */
0438 struct csio_wrm {
0439     int         num_q;      /* Number of queues */
0440     struct csio_q       **q_arr;    /* Array of queue pointers
0441                          * allocated dynamically
0442                          * based on configured values
0443                          */
0444     uint32_t        fw_iq_start;    /* Start ID of IQ for this fn*/
0445     uint32_t        fw_eq_start;    /* Start ID of EQ for this fn*/
0446     struct csio_q       *intr_map[CSIO_MAX_IQ];
0447                         /* IQ-id to IQ map table. */
0448     int         free_qidx;  /* queue idx of free queue */
0449     struct csio_sge     sge;        /* SGE params */
0450 };
0451 
0452 #define csio_get_q(__hw, __idx)     ((__hw)->wrm.q_arr[__idx])
0453 #define csio_q_type(__hw, __idx)    ((__hw)->wrm.q_arr[(__idx)]->type)
0454 #define csio_q_pidx(__hw, __idx)    ((__hw)->wrm.q_arr[(__idx)]->pidx)
0455 #define csio_q_cidx(__hw, __idx)    ((__hw)->wrm.q_arr[(__idx)]->cidx)
0456 #define csio_q_inc_idx(__hw, __idx) ((__hw)->wrm.q_arr[(__idx)]->inc_idx)
0457 #define csio_q_vstart(__hw, __idx)  ((__hw)->wrm.q_arr[(__idx)]->vstart)
0458 #define csio_q_pstart(__hw, __idx)  ((__hw)->wrm.q_arr[(__idx)]->pstart)
0459 #define csio_q_size(__hw, __idx)    ((__hw)->wrm.q_arr[(__idx)]->size)
0460 #define csio_q_credits(__hw, __idx) ((__hw)->wrm.q_arr[(__idx)]->credits)
0461 #define csio_q_portid(__hw, __idx)  ((__hw)->wrm.q_arr[(__idx)]->portid)
0462 #define csio_q_wr_sz(__hw, __idx)   ((__hw)->wrm.q_arr[(__idx)]->wr_sz)
0463 #define csio_q_iqid(__hw, __idx)    ((__hw)->wrm.q_arr[(__idx)]->un.iq.iqid)
0464 #define csio_q_physiqid(__hw, __idx)                    \
0465                 ((__hw)->wrm.q_arr[(__idx)]->un.iq.physiqid)
0466 #define csio_q_iq_flq_idx(__hw, __idx)                  \
0467                 ((__hw)->wrm.q_arr[(__idx)]->un.iq.flq_idx)
0468 #define csio_q_eqid(__hw, __idx)    ((__hw)->wrm.q_arr[(__idx)]->un.eq.eqid)
0469 #define csio_q_flid(__hw, __idx)    ((__hw)->wrm.q_arr[(__idx)]->un.fl.flid)
0470 
0471 #define csio_q_physeqid(__hw, __idx)                    \
0472                 ((__hw)->wrm.q_arr[(__idx)]->un.eq.physeqid)
0473 #define csio_iq_has_fl(__iq)        ((__iq)->un.iq.flq_idx != -1)
0474 
0475 #define csio_q_iq_to_flid(__hw, __iq_idx)               \
0476     csio_q_flid((__hw), (__hw)->wrm.q_arr[(__iq_qidx)]->un.iq.flq_idx)
0477 #define csio_q_set_intr_map(__hw, __iq_idx, __rel_iq_id)        \
0478         (__hw)->wrm.intr_map[__rel_iq_id] = csio_get_q(__hw, __iq_idx)
0479 #define csio_q_eq_wrap(__hw, __idx) ((__hw)->wrm.q_arr[(__idx)]->un.eq.wrap)
0480 
0481 struct csio_mb;
0482 
0483 int csio_wr_alloc_q(struct csio_hw *, uint32_t, uint32_t,
0484             uint16_t, void *, uint32_t, int, iq_handler_t);
0485 int csio_wr_iq_create(struct csio_hw *, void *, int,
0486                 uint32_t, uint8_t, bool,
0487                 void (*)(struct csio_hw *, struct csio_mb *));
0488 int csio_wr_eq_create(struct csio_hw *, void *, int, int, uint8_t,
0489                 void (*)(struct csio_hw *, struct csio_mb *));
0490 int csio_wr_destroy_queues(struct csio_hw *, bool cmd);
0491 
0492 
0493 int csio_wr_get(struct csio_hw *, int, uint32_t,
0494               struct csio_wr_pair *);
0495 void csio_wr_copy_to_wrp(void *, struct csio_wr_pair *, uint32_t, uint32_t);
0496 int csio_wr_issue(struct csio_hw *, int, bool);
0497 int csio_wr_process_iq(struct csio_hw *, struct csio_q *,
0498                  void (*)(struct csio_hw *, void *,
0499                       uint32_t, struct csio_fl_dma_buf *,
0500                       void *),
0501                  void *);
0502 int csio_wr_process_iq_idx(struct csio_hw *, int,
0503                  void (*)(struct csio_hw *, void *,
0504                       uint32_t, struct csio_fl_dma_buf *,
0505                       void *),
0506                  void *);
0507 
0508 void csio_wr_sge_init(struct csio_hw *);
0509 int csio_wrm_init(struct csio_wrm *, struct csio_hw *);
0510 void csio_wrm_exit(struct csio_wrm *, struct csio_hw *);
0511 
0512 #endif /* ifndef __CSIO_WR_H__ */