Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /* Copyright 2014 Cisco Systems, Inc.  All rights reserved. */
0003 
0004 #ifndef __SNIC_FWINT_H
0005 #define __SNIC_FWINT_H
0006 
0007 #define SNIC_CDB_LEN    32  /* SCSI CDB size 32, can be used for 16 bytes */
0008 #define LUN_ADDR_LEN    8
0009 
0010 /*
0011  * Command entry type
0012  */
0013 enum snic_io_type {
0014     /*
0015      * Initiator request types
0016      */
0017     SNIC_REQ_REPORT_TGTS = 0x2, /* Report Targets */
0018     SNIC_REQ_ICMND,         /* Initiator command for SCSI IO */
0019     SNIC_REQ_ITMF,          /* Initiator command for Task Mgmt */
0020     SNIC_REQ_HBA_RESET,     /* SNIC Reset */
0021     SNIC_REQ_EXCH_VER,      /* Exchange Version Information */
0022     SNIC_REQ_TGT_INFO,      /* Backend/Target Information */
0023     SNIC_REQ_BOOT_LUNS,
0024 
0025     /*
0026      * Response type
0027      */
0028     SNIC_RSP_REPORT_TGTS_CMPL = 0x12,/* Report Targets Completion */
0029     SNIC_RSP_ICMND_CMPL,        /* SCSI IO Completion */
0030     SNIC_RSP_ITMF_CMPL,     /* Task Management Completion */
0031     SNIC_RSP_HBA_RESET_CMPL,    /* SNIC Reset Completion */
0032     SNIC_RSP_EXCH_VER_CMPL,     /* Exchange Version Completion*/
0033     SNIC_RSP_BOOT_LUNS_CMPL,
0034 
0035     /*
0036      * Misc Request types
0037      */
0038     SNIC_MSG_ACK = 0x80,        /* Ack: snic_notify_msg */
0039     SNIC_MSG_ASYNC_EVNOTIFY,    /* Asynchronous Event Notification */
0040 }; /* end of enum snic_io_type */
0041 
0042 
0043 /*
0044  * Header status codes from firmware
0045  */
0046 enum snic_io_status {
0047     SNIC_STAT_IO_SUCCESS = 0,   /* request was successful */
0048 
0049     /*
0050      * If a request to the fw is rejected, the original request header
0051      * will be returned with the status set to one of the following:
0052      */
0053     SNIC_STAT_INVALID_HDR,  /* header contains invalid data */
0054     SNIC_STAT_OUT_OF_RES,   /* out of resources to complete request */
0055     SNIC_STAT_INVALID_PARM, /* some parameter in request is not valid */
0056     SNIC_STAT_REQ_NOT_SUP,  /* req type is not supported */
0057     SNIC_STAT_IO_NOT_FOUND, /* requested IO was not found */
0058 
0059     /*
0060      * Once a request is processed, the fw will usually return
0061      * a cmpl message type. In cases where errors occurred,
0062      * the header status would be filled in with one of the following:
0063      */
0064     SNIC_STAT_ABORTED,      /* req was aborted */
0065     SNIC_STAT_TIMEOUT,      /* req was timed out */
0066     SNIC_STAT_SGL_INVALID,      /* req was aborted due to sgl error */
0067     SNIC_STAT_DATA_CNT_MISMATCH,    /*recv/sent more/less data than expec */
0068     SNIC_STAT_FW_ERR,       /* req was terminated due to fw error */
0069     SNIC_STAT_ITMF_REJECT,      /* itmf req was rejected by target */
0070     SNIC_STAT_ITMF_FAIL,        /* itmf req was failed */
0071     SNIC_STAT_ITMF_INCORRECT_LUN,   /* itmf req has incorrect LUN id*/
0072     SNIC_STAT_CMND_REJECT,      /* req was invalid and rejected */
0073     SNIC_STAT_DEV_OFFLINE,      /* req sent to offline device */
0074     SNIC_STAT_NO_BOOTLUN,
0075     SNIC_STAT_SCSI_ERR,     /* SCSI error returned by Target. */
0076     SNIC_STAT_NOT_READY,        /* sNIC Subsystem is not ready */
0077     SNIC_STAT_FATAL_ERROR,      /* sNIC is in unrecoverable state */
0078 }; /* end of enum snic_io_status */
0079 
0080 /*
0081  * snic_io_hdr : host <--> firmware
0082  *
0083  * for any other message that will be queued to firmware should
0084  *  have the following request header
0085  */
0086 struct snic_io_hdr {
0087     __le32  hid;
0088     __le32  cmnd_id;    /* tag here */
0089     ulong   init_ctx;   /* initiator context */
0090     u8  type;       /* request/response type */
0091     u8  status;     /* header status entry */
0092     u8  protocol;   /* Protocol specific, may needed for RoCE*/
0093     u8  flags;
0094     __le16  sg_cnt;
0095     u16 resvd;
0096 };
0097 
0098 /* auxillary funciton for encoding the snic_io_hdr */
0099 static inline void
0100 snic_io_hdr_enc(struct snic_io_hdr *hdr, u8 typ, u8 status, u32 id, u32 hid,
0101         u16 sg_cnt, ulong ctx)
0102 {
0103     hdr->type = typ;
0104     hdr->status = status;
0105     hdr->protocol = 0;
0106     hdr->hid = cpu_to_le32(hid);
0107     hdr->cmnd_id = cpu_to_le32(id);
0108     hdr->sg_cnt = cpu_to_le16(sg_cnt);
0109     hdr->init_ctx = ctx;
0110     hdr->flags = 0;
0111 }
0112 
0113 /* auxillary funciton for decoding the snic_io_hdr */
0114 static inline void
0115 snic_io_hdr_dec(struct snic_io_hdr *hdr, u8 *typ, u8 *stat, u32 *cmnd_id,
0116         u32 *hid, ulong *ctx)
0117 {
0118     *typ = hdr->type;
0119     *stat = hdr->status;
0120     *hid = le32_to_cpu(hdr->hid);
0121     *cmnd_id = le32_to_cpu(hdr->cmnd_id);
0122     *ctx = hdr->init_ctx;
0123 }
0124 
0125 /*
0126  * snic_host_info: host -> firmware
0127  *
0128  * Used for sending host information to firmware, and request fw version
0129  */
0130 struct snic_exch_ver_req {
0131     __le32  drvr_ver;   /* for debugging, when fw dump captured */
0132     __le32  os_type;    /* for OS specific features */
0133 };
0134 
0135 /*
0136  * os_type flags
0137  * Bit 0-7 : OS information
0138  * Bit 8-31: Feature/Capability Information
0139  */
0140 #define SNIC_OS_LINUX   0x1
0141 #define SNIC_OS_WIN 0x2
0142 #define SNIC_OS_ESX 0x3
0143 
0144 /*
0145  * HBA Capabilities
0146  * Bit 1: Reserved.
0147  * Bit 2: Dynamic Discovery of LUNs.
0148  * Bit 3: Async event notifications on tgt online/offline events.
0149  * Bit 4: IO timeout support in FW.
0150  * Bit 5-31: Reserved.
0151  */
0152 #define SNIC_HBA_CAP_DDL    0x02    /* Supports Dynamic Discovery of LUNs */
0153 #define SNIC_HBA_CAP_AEN    0x04    /* Supports Async Event Noitifcation */
0154 #define SNIC_HBA_CAP_TMO    0x08    /* Supports IO timeout in FW */
0155 
0156 /*
0157  * snic_exch_ver_rsp : firmware -> host
0158  *
0159  * Used by firmware to send response to version request
0160  */
0161 struct snic_exch_ver_rsp {
0162     __le32  version;
0163     __le32  hid;
0164     __le32  max_concur_ios;     /* max concurrent ios */
0165     __le32  max_sgs_per_cmd;    /* max sgls per IO */
0166     __le32  max_io_sz;      /* max io size supported */
0167     __le32  hba_cap;        /* hba capabilities */
0168     __le32  max_tgts;       /* max tgts supported */
0169     __le16  io_timeout;     /* FW extended timeout */
0170     u16 rsvd;
0171 };
0172 
0173 
0174 /*
0175  * snic_report_tgts : host -> firmware request
0176  *
0177  * Used by the host to request list of targets
0178  */
0179 struct snic_report_tgts {
0180     __le16  sg_cnt;
0181     __le16  flags;      /* specific flags from fw */
0182     u8  _resvd[4];
0183     __le64  sg_addr;    /* Points to SGL */
0184     __le64  sense_addr;
0185 };
0186 
0187 enum snic_type {
0188     SNIC_NONE = 0x0,
0189     SNIC_DAS,
0190     SNIC_SAN,
0191 };
0192 
0193 
0194 /* Report Target Response */
0195 enum snic_tgt_type {
0196     SNIC_TGT_NONE = 0x0,
0197     SNIC_TGT_DAS,   /* DAS Target */
0198     SNIC_TGT_SAN,   /* SAN Target */
0199 };
0200 
0201 /* target id format */
0202 struct snic_tgt_id {
0203     __le32  tgt_id;     /* target id */
0204     __le16  tgt_type;   /* tgt type */
0205     __le16  vnic_id;    /* corresponding vnic id */
0206 };
0207 
0208 /*
0209  * snic_report_tgts_cmpl : firmware -> host response
0210  *
0211  * Used by firmware to send response to Report Targets request
0212  */
0213 struct snic_report_tgts_cmpl {
0214     __le32  tgt_cnt;    /* Number of Targets accessible */
0215     u32 _resvd;
0216 };
0217 
0218 /*
0219  * Command flags
0220  *
0221  * Bit 0: Read flags
0222  * Bit 1: Write flag
0223  * Bit 2: ESGL - sg/esg array contains extended sg
0224  *    ESGE - is a host buffer contains sg elements
0225  * Bit 3-4: Task Attributes
0226  *      00b - simple
0227  *      01b - head of queue
0228  *      10b - ordered
0229  * Bit 5-7: Priority - future use
0230  * Bit 8-15: Reserved
0231  */
0232 
0233 #define SNIC_ICMND_WR       0x01    /* write command */
0234 #define SNIC_ICMND_RD       0x02    /* read command */
0235 #define SNIC_ICMND_ESGL     0x04    /* SGE/ESGE array contains valid data*/
0236 
0237 /*
0238  * Priority/Task Attribute settings
0239  */
0240 #define SNIC_ICMND_TSK_SHIFT        2   /* task attr starts at bit 2 */
0241 #define SNIC_ICMND_TSK_MASK(x)      ((x>>SNIC_ICMND_TSK_SHIFT) & ~(0xffff))
0242 #define SNIC_ICMND_TSK_SIMPLE       0   /* simple task attr */
0243 #define SNIC_ICMND_TSK_HEAD_OF_QUEUE    1   /* head of qeuue task attr */
0244 #define SNIC_ICMND_TSK_ORDERED      2   /* ordered task attr */
0245 
0246 #define SNIC_ICMND_PRI_SHIFT        5   /* prio val starts at bit 5 */
0247 
0248 /*
0249  * snic_icmnd : host-> firmware request
0250  *
0251  * used for sending out an initiator SCSI 16/32-byte command
0252  */
0253 struct snic_icmnd {
0254     __le16  sg_cnt;     /* Number of SG Elements */
0255     __le16  flags;      /* flags */
0256     __le32  sense_len;  /* Sense buffer length */
0257     __le64  tgt_id;     /* Destination Target ID */
0258     __le64  lun_id;     /* Destination LUN ID */
0259     u8  cdb_len;
0260     u8  _resvd;
0261     __le16  time_out;   /* ms time for Res allocations fw to handle io*/
0262     __le32  data_len;   /* Total number of bytes to be transferred */
0263     u8  cdb[SNIC_CDB_LEN];
0264     __le64  sg_addr;    /* Points to SG List */
0265     __le64  sense_addr; /* Sense buffer address */
0266 };
0267 
0268 
0269 /* Response flags */
0270 /* Bit 0: Under run
0271  * Bit 1: Over Run
0272  * Bit 2-7: Reserved
0273  */
0274 #define SNIC_ICMND_CMPL_UNDR_RUN    0x01    /* resid under and valid */
0275 #define SNIC_ICMND_CMPL_OVER_RUN    0x02    /* resid over and valid */
0276 
0277 /*
0278  * snic_icmnd_cmpl: firmware -> host response
0279  *
0280  * Used for sending the host a response to an icmnd (initiator command)
0281  */
0282 struct snic_icmnd_cmpl {
0283     u8  scsi_status;    /* value as per SAM */
0284     u8  flags;
0285     __le16  sense_len;  /* Sense Length */
0286     __le32  resid;      /* Residue : # bytes under or over run */
0287 };
0288 
0289 /*
0290  * snic_itmf: host->firmware request
0291  *
0292  * used for requesting the firmware to abort a request and/or send out
0293  * a task management function
0294  *
0295  * the req_id field is valid in case of abort task and clear task
0296  */
0297 struct snic_itmf {
0298     u8  tm_type;    /* SCSI Task Management request */
0299     u8  resvd;
0300     __le16  flags;      /* flags */
0301     __le32  req_id;     /* Command id of snic req to be aborted */
0302     __le64  tgt_id;     /* Target ID */
0303     __le64  lun_id;     /* Destination LUN ID */
0304     __le16  timeout;    /* in sec */
0305 };
0306 
0307 /*
0308  * Task Management Request
0309  */
0310 enum snic_itmf_tm_type {
0311     SNIC_ITMF_ABTS_TASK = 0x01, /* Abort Task */
0312     SNIC_ITMF_ABTS_TASK_SET,    /* Abort Task Set */
0313     SNIC_ITMF_CLR_TASK,     /* Clear Task */
0314     SNIC_ITMF_CLR_TASKSET,      /* Clear Task Set */
0315     SNIC_ITMF_LUN_RESET,        /* Lun Reset */
0316     SNIC_ITMF_ABTS_TASK_TERM,   /* Supported for SAN Targets */
0317 };
0318 
0319 /*
0320  * snic_itmf_cmpl: firmware -> host resposne
0321  *
0322  * used for sending the host a response for a itmf request
0323  */
0324 struct snic_itmf_cmpl {
0325     __le32  nterminated;    /* # IOs terminated as a result of tmf */
0326     u8  flags;      /* flags */
0327     u8  _resvd[3];
0328 };
0329 
0330 /*
0331  * itmfl_cmpl flags
0332  * Bit 0 : 1 - Num terminated field valid
0333  * Bit 1 - 7 : Reserved
0334  */
0335 #define SNIC_NUM_TERM_VALID 0x01    /* Number of IOs terminated */
0336 
0337 /*
0338  * snic_hba_reset: host -> firmware request
0339  *
0340  * used for requesting firmware to reset snic
0341  */
0342 struct snic_hba_reset {
0343     __le16  flags;      /* flags */
0344     u8  _resvd[6];
0345 };
0346 
0347 /*
0348  * snic_hba_reset_cmpl: firmware -> host response
0349  *
0350  * Used by firmware to respond to the host's hba reset request
0351  */
0352 struct snic_hba_reset_cmpl {
0353     u8  flags;      /* flags : more info needs to be added*/
0354     u8  _resvd[7];
0355 };
0356 
0357 /*
0358  * snic_notify_msg: firmware -> host response
0359  *
0360  * Used by firmware to notify host of the last work queue entry received
0361  */
0362 struct snic_notify_msg {
0363     __le32  wqe_num;    /* wq entry number */
0364     u8  flags;      /* flags, macros */
0365     u8  _resvd[4];
0366 };
0367 
0368 
0369 #define SNIC_EVDATA_LEN     24  /* in bytes */
0370 /* snic_async_evnotify: firmware -> host notification
0371  *
0372  * Used by firmware to notify the host about configuration/state changes
0373  */
0374 struct snic_async_evnotify {
0375     u8  FLS_EVENT_DESC;
0376     u8  vnic;           /* vnic id */
0377     u8  _resvd[2];
0378     __le32  ev_id;          /* Event ID */
0379     u8  ev_data[SNIC_EVDATA_LEN]; /* Event Data */
0380     u8  _resvd2[4];
0381 };
0382 
0383 /* async event flags */
0384 enum snic_ev_type {
0385     SNIC_EV_TGT_OFFLINE = 0x01, /* Target Offline, PL contains TGT ID */
0386     SNIC_EV_TGT_ONLINE, /* Target Online, PL contains TGT ID */
0387     SNIC_EV_LUN_OFFLINE,    /* LUN Offline, PL contains LUN ID */
0388     SNIC_EV_LUN_ONLINE, /* LUN Online, PL contains LUN ID */
0389     SNIC_EV_CONF_CHG,   /* Dev Config/Attr Change Event */
0390     SNIC_EV_TGT_ADDED,  /* Target Added */
0391     SNIC_EV_TGT_DELTD,  /* Target Del'd, PL contains TGT ID */
0392     SNIC_EV_LUN_ADDED,  /* LUN Added */
0393     SNIC_EV_LUN_DELTD,  /* LUN Del'd, PL cont. TGT & LUN ID */
0394 
0395     SNIC_EV_DISC_CMPL = 0x10, /* Discovery Completed Event */
0396 };
0397 
0398 
0399 #define SNIC_HOST_REQ_LEN   128 /*Exp length of host req, wq desc sz*/
0400 /* Payload 88 bytes = 128 - 24 - 16 */
0401 #define SNIC_HOST_REQ_PAYLOAD   ((int)(SNIC_HOST_REQ_LEN -      \
0402                     sizeof(struct snic_io_hdr) -    \
0403                     (2 * sizeof(u64)) - sizeof(ulong)))
0404 
0405 /*
0406  * snic_host_req: host -> firmware request
0407  *
0408  * Basic structure for all snic requests that are sent from the host to
0409  * firmware. They are 128 bytes in size.
0410  */
0411 struct snic_host_req {
0412     u64 ctrl_data[2];   /*16 bytes - Control Data */
0413     struct snic_io_hdr hdr;
0414     union {
0415         /*
0416          * Entry specific space, last byte contains color
0417          */
0418         u8  buf[SNIC_HOST_REQ_PAYLOAD];
0419 
0420         /*
0421          * Exchange firmware version
0422          */
0423         struct snic_exch_ver_req    exch_ver;
0424 
0425         /* report targets */
0426         struct snic_report_tgts     rpt_tgts;
0427 
0428         /* io request */
0429         struct snic_icmnd       icmnd;
0430 
0431         /* task management request */
0432         struct snic_itmf        itmf;
0433 
0434         /* hba reset */
0435         struct snic_hba_reset       reset;
0436     } u;
0437 
0438     ulong req_pa;
0439 }; /* end of snic_host_req structure */
0440 
0441 
0442 #define SNIC_FW_REQ_LEN     64 /* Expected length of fw req */
0443 struct snic_fw_req {
0444     struct snic_io_hdr hdr;
0445     union {
0446         /*
0447          * Entry specific space, last byte contains color
0448          */
0449         u8  buf[SNIC_FW_REQ_LEN - sizeof(struct snic_io_hdr)];
0450 
0451         /* Exchange Version Response */
0452         struct snic_exch_ver_rsp    exch_ver_cmpl;
0453 
0454         /* Report Targets Response */
0455         struct snic_report_tgts_cmpl    rpt_tgts_cmpl;
0456 
0457         /* scsi response */
0458         struct snic_icmnd_cmpl      icmnd_cmpl;
0459 
0460         /* task management response */
0461         struct snic_itmf_cmpl       itmf_cmpl;
0462 
0463         /* hba reset response */
0464         struct snic_hba_reset_cmpl  reset_cmpl;
0465 
0466         /* notify message */
0467         struct snic_notify_msg      ack;
0468 
0469         /* async notification event */
0470         struct snic_async_evnotify  async_ev;
0471 
0472     } u;
0473 }; /* end of snic_fw_req structure */
0474 
0475 /*
0476  * Auxillary macro to verify specific snic req/cmpl structures
0477  * to ensure that it will be aligned to 64 bit, and not using
0478  * color bit field
0479  */
0480 #define VERIFY_REQ_SZ(x)
0481 #define VERIFY_CMPL_SZ(x)
0482 
0483 /*
0484  * Access routines to encode and decode the color bit, which is the most
0485  * significant bit of the structure.
0486  */
0487 static inline void
0488 snic_color_enc(struct snic_fw_req *req, u8 color)
0489 {
0490     u8 *c = ((u8 *) req) + sizeof(struct snic_fw_req) - 1;
0491 
0492     if (color)
0493         *c |= 0x80;
0494     else
0495         *c &= ~0x80;
0496 }
0497 
0498 static inline void
0499 snic_color_dec(struct snic_fw_req *req, u8 *color)
0500 {
0501     u8 *c = ((u8 *) req) + sizeof(struct snic_fw_req) - 1;
0502 
0503     *color = *c >> 7;
0504 
0505     /* Make sure color bit is read from desc *before* other fields
0506      * are read from desc. Hardware guarantees color bit is last
0507      * bit (byte) written. Adding the rmb() prevents the compiler
0508      * and/or CPU from reordering the reads which would potentially
0509      * result in reading stale values.
0510      */
0511     rmb();
0512 }
0513 #endif /* end of __SNIC_FWINT_H */