GNU Linux-libre 6.8.7-gnu
[releases.git] / drivers / scsi / snic / snic_fwint.h
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /* Copyright 2014 Cisco Systems, Inc.  All rights reserved. */
3
4 #ifndef __SNIC_FWINT_H
5 #define __SNIC_FWINT_H
6
7 #define SNIC_CDB_LEN    32      /* SCSI CDB size 32, can be used for 16 bytes */
8 #define LUN_ADDR_LEN    8
9
10 /*
11  * Command entry type
12  */
13 enum snic_io_type {
14         /*
15          * Initiator request types
16          */
17         SNIC_REQ_REPORT_TGTS = 0x2,     /* Report Targets */
18         SNIC_REQ_ICMND,                 /* Initiator command for SCSI IO */
19         SNIC_REQ_ITMF,                  /* Initiator command for Task Mgmt */
20         SNIC_REQ_HBA_RESET,             /* SNIC Reset */
21         SNIC_REQ_EXCH_VER,              /* Exchange Version Information */
22         SNIC_REQ_TGT_INFO,              /* Backend/Target Information */
23         SNIC_REQ_BOOT_LUNS,
24
25         /*
26          * Response type
27          */
28         SNIC_RSP_REPORT_TGTS_CMPL = 0x12,/* Report Targets Completion */
29         SNIC_RSP_ICMND_CMPL,            /* SCSI IO Completion */
30         SNIC_RSP_ITMF_CMPL,             /* Task Management Completion */
31         SNIC_RSP_HBA_RESET_CMPL,        /* SNIC Reset Completion */
32         SNIC_RSP_EXCH_VER_CMPL,         /* Exchange Version Completion*/
33         SNIC_RSP_BOOT_LUNS_CMPL,
34
35         /*
36          * Misc Request types
37          */
38         SNIC_MSG_ACK = 0x80,            /* Ack: snic_notify_msg */
39         SNIC_MSG_ASYNC_EVNOTIFY,        /* Asynchronous Event Notification */
40 }; /* end of enum snic_io_type */
41
42
43 /*
44  * Header status codes from firmware
45  */
46 enum snic_io_status {
47         SNIC_STAT_IO_SUCCESS = 0,       /* request was successful */
48
49         /*
50          * If a request to the fw is rejected, the original request header
51          * will be returned with the status set to one of the following:
52          */
53         SNIC_STAT_INVALID_HDR,  /* header contains invalid data */
54         SNIC_STAT_OUT_OF_RES,   /* out of resources to complete request */
55         SNIC_STAT_INVALID_PARM, /* some parameter in request is not valid */
56         SNIC_STAT_REQ_NOT_SUP,  /* req type is not supported */
57         SNIC_STAT_IO_NOT_FOUND, /* requested IO was not found */
58
59         /*
60          * Once a request is processed, the fw will usually return
61          * a cmpl message type. In cases where errors occurred,
62          * the header status would be filled in with one of the following:
63          */
64         SNIC_STAT_ABORTED,              /* req was aborted */
65         SNIC_STAT_TIMEOUT,              /* req was timed out */
66         SNIC_STAT_SGL_INVALID,          /* req was aborted due to sgl error */
67         SNIC_STAT_DATA_CNT_MISMATCH,    /*recv/sent more/less data than expec */
68         SNIC_STAT_FW_ERR,               /* req was terminated due to fw error */
69         SNIC_STAT_ITMF_REJECT,          /* itmf req was rejected by target */
70         SNIC_STAT_ITMF_FAIL,            /* itmf req was failed */
71         SNIC_STAT_ITMF_INCORRECT_LUN,   /* itmf req has incorrect LUN id*/
72         SNIC_STAT_CMND_REJECT,          /* req was invalid and rejected */
73         SNIC_STAT_DEV_OFFLINE,          /* req sent to offline device */
74         SNIC_STAT_NO_BOOTLUN,
75         SNIC_STAT_SCSI_ERR,             /* SCSI error returned by Target. */
76         SNIC_STAT_NOT_READY,            /* sNIC Subsystem is not ready */
77         SNIC_STAT_FATAL_ERROR,          /* sNIC is in unrecoverable state */
78 }; /* end of enum snic_io_status */
79
80 /*
81  * snic_io_hdr : host <--> firmware
82  *
83  * for any other message that will be queued to firmware should
84  *  have the following request header
85  */
86 struct snic_io_hdr {
87         __le32  hid;
88         __le32  cmnd_id;        /* tag here */
89         ulong   init_ctx;       /* initiator context */
90         u8      type;           /* request/response type */
91         u8      status;         /* header status entry */
92         u8      protocol;       /* Protocol specific, may needed for RoCE*/
93         u8      flags;
94         __le16  sg_cnt;
95         u16     resvd;
96 };
97
98 /* auxillary funciton for encoding the snic_io_hdr */
99 static inline void
100 snic_io_hdr_enc(struct snic_io_hdr *hdr, u8 typ, u8 status, u32 id, u32 hid,
101                 u16 sg_cnt, ulong ctx)
102 {
103         hdr->type = typ;
104         hdr->status = status;
105         hdr->protocol = 0;
106         hdr->hid = cpu_to_le32(hid);
107         hdr->cmnd_id = cpu_to_le32(id);
108         hdr->sg_cnt = cpu_to_le16(sg_cnt);
109         hdr->init_ctx = ctx;
110         hdr->flags = 0;
111 }
112
113 /* auxillary funciton for decoding the snic_io_hdr */
114 static inline void
115 snic_io_hdr_dec(struct snic_io_hdr *hdr, u8 *typ, u8 *stat, u32 *cmnd_id,
116                 u32 *hid, ulong *ctx)
117 {
118         *typ = hdr->type;
119         *stat = hdr->status;
120         *hid = le32_to_cpu(hdr->hid);
121         *cmnd_id = le32_to_cpu(hdr->cmnd_id);
122         *ctx = hdr->init_ctx;
123 }
124
125 /*
126  * snic_host_info: host -> firmware
127  *
128  * Used for sending host information to firmware, and request fw version
129  */
130 struct snic_exch_ver_req {
131         __le32  drvr_ver;       /* for debugging, when fw dump captured */
132         __le32  os_type;        /* for OS specific features */
133 };
134
135 /*
136  * os_type flags
137  * Bit 0-7 : OS information
138  * Bit 8-31: Feature/Capability Information
139  */
140 #define SNIC_OS_LINUX   0x1
141 #define SNIC_OS_WIN     0x2
142 #define SNIC_OS_ESX     0x3
143
144 /*
145  * HBA Capabilities
146  * Bit 1: Reserved.
147  * Bit 2: Dynamic Discovery of LUNs.
148  * Bit 3: Async event notifications on tgt online/offline events.
149  * Bit 4: IO timeout support in FW.
150  * Bit 5-31: Reserved.
151  */
152 #define SNIC_HBA_CAP_DDL        0x02    /* Supports Dynamic Discovery of LUNs */
153 #define SNIC_HBA_CAP_AEN        0x04    /* Supports Async Event Noitifcation */
154 #define SNIC_HBA_CAP_TMO        0x08    /* Supports IO timeout in FW */
155
156 /*
157  * snic_exch_ver_rsp : firmware -> host
158  *
159  * Used by firmware to send response to version request
160  */
161 struct snic_exch_ver_rsp {
162         __le32  version;
163         __le32  hid;
164         __le32  max_concur_ios;         /* max concurrent ios */
165         __le32  max_sgs_per_cmd;        /* max sgls per IO */
166         __le32  max_io_sz;              /* max io size supported */
167         __le32  hba_cap;                /* hba capabilities */
168         __le32  max_tgts;               /* max tgts supported */
169         __le16  io_timeout;             /* FW extended timeout */
170         u16     rsvd;
171 };
172
173
174 /*
175  * snic_report_tgts : host -> firmware request
176  *
177  * Used by the host to request list of targets
178  */
179 struct snic_report_tgts {
180         __le16  sg_cnt;
181         __le16  flags;          /* specific flags from fw */
182         u8      _resvd[4];
183         __le64  sg_addr;        /* Points to SGL */
184         __le64  sense_addr;
185 };
186
187 enum snic_type {
188         SNIC_NONE = 0x0,
189         SNIC_DAS,
190         SNIC_SAN,
191 };
192
193
194 /* Report Target Response */
195 enum snic_tgt_type {
196         SNIC_TGT_NONE = 0x0,
197         SNIC_TGT_DAS,   /* DAS Target */
198         SNIC_TGT_SAN,   /* SAN Target */
199 };
200
201 /* target id format */
202 struct snic_tgt_id {
203         __le32  tgt_id;         /* target id */
204         __le16  tgt_type;       /* tgt type */
205         __le16  vnic_id;        /* corresponding vnic id */
206 };
207
208 /*
209  * snic_report_tgts_cmpl : firmware -> host response
210  *
211  * Used by firmware to send response to Report Targets request
212  */
213 struct snic_report_tgts_cmpl {
214         __le32  tgt_cnt;        /* Number of Targets accessible */
215         u32     _resvd;
216 };
217
218 /*
219  * Command flags
220  *
221  * Bit 0: Read flags
222  * Bit 1: Write flag
223  * Bit 2: ESGL - sg/esg array contains extended sg
224  *        ESGE - is a host buffer contains sg elements
225  * Bit 3-4: Task Attributes
226  *              00b - simple
227  *              01b - head of queue
228  *              10b - ordered
229  * Bit 5-7: Priority - future use
230  * Bit 8-15: Reserved
231  */
232
233 #define SNIC_ICMND_WR           0x01    /* write command */
234 #define SNIC_ICMND_RD           0x02    /* read command */
235 #define SNIC_ICMND_ESGL         0x04    /* SGE/ESGE array contains valid data*/
236
237 /*
238  * Priority/Task Attribute settings
239  */
240 #define SNIC_ICMND_TSK_SHIFT            2       /* task attr starts at bit 2 */
241 #define SNIC_ICMND_TSK_MASK(x)          ((x>>SNIC_ICMND_TSK_SHIFT) & ~(0xffff))
242 #define SNIC_ICMND_TSK_SIMPLE           0       /* simple task attr */
243 #define SNIC_ICMND_TSK_HEAD_OF_QUEUE    1       /* head of qeuue task attr */
244 #define SNIC_ICMND_TSK_ORDERED          2       /* ordered task attr */
245
246 #define SNIC_ICMND_PRI_SHIFT            5       /* prio val starts at bit 5 */
247
248 /*
249  * snic_icmnd : host-> firmware request
250  *
251  * used for sending out an initiator SCSI 16/32-byte command
252  */
253 struct snic_icmnd {
254         __le16  sg_cnt;         /* Number of SG Elements */
255         __le16  flags;          /* flags */
256         __le32  sense_len;      /* Sense buffer length */
257         __le64  tgt_id;         /* Destination Target ID */
258         __le64  lun_id;         /* Destination LUN ID */
259         u8      cdb_len;
260         u8      _resvd;
261         __le16  time_out;       /* ms time for Res allocations fw to handle io*/
262         __le32  data_len;       /* Total number of bytes to be transferred */
263         u8      cdb[SNIC_CDB_LEN];
264         __le64  sg_addr;        /* Points to SG List */
265         __le64  sense_addr;     /* Sense buffer address */
266 };
267
268
269 /* Response flags */
270 /* Bit 0: Under run
271  * Bit 1: Over Run
272  * Bit 2-7: Reserved
273  */
274 #define SNIC_ICMND_CMPL_UNDR_RUN        0x01    /* resid under and valid */
275 #define SNIC_ICMND_CMPL_OVER_RUN        0x02    /* resid over and valid */
276
277 /*
278  * snic_icmnd_cmpl: firmware -> host response
279  *
280  * Used for sending the host a response to an icmnd (initiator command)
281  */
282 struct snic_icmnd_cmpl {
283         u8      scsi_status;    /* value as per SAM */
284         u8      flags;
285         __le16  sense_len;      /* Sense Length */
286         __le32  resid;          /* Residue : # bytes under or over run */
287 };
288
289 /*
290  * snic_itmf: host->firmware request
291  *
292  * used for requesting the firmware to abort a request and/or send out
293  * a task management function
294  *
295  * the req_id field is valid in case of abort task and clear task
296  */
297 struct snic_itmf {
298         u8      tm_type;        /* SCSI Task Management request */
299         u8      resvd;
300         __le16  flags;          /* flags */
301         __le32  req_id;         /* Command id of snic req to be aborted */
302         __le64  tgt_id;         /* Target ID */
303         __le64  lun_id;         /* Destination LUN ID */
304         __le16  timeout;        /* in sec */
305 };
306
307 /*
308  * Task Management Request
309  */
310 enum snic_itmf_tm_type {
311         SNIC_ITMF_ABTS_TASK = 0x01,     /* Abort Task */
312         SNIC_ITMF_ABTS_TASK_SET,        /* Abort Task Set */
313         SNIC_ITMF_CLR_TASK,             /* Clear Task */
314         SNIC_ITMF_CLR_TASKSET,          /* Clear Task Set */
315         SNIC_ITMF_LUN_RESET,            /* Lun Reset */
316         SNIC_ITMF_ABTS_TASK_TERM,       /* Supported for SAN Targets */
317 };
318
319 /*
320  * snic_itmf_cmpl: firmware -> host resposne
321  *
322  * used for sending the host a response for a itmf request
323  */
324 struct snic_itmf_cmpl {
325         __le32  nterminated;    /* # IOs terminated as a result of tmf */
326         u8      flags;          /* flags */
327         u8      _resvd[3];
328 };
329
330 /*
331  * itmfl_cmpl flags
332  * Bit 0 : 1 - Num terminated field valid
333  * Bit 1 - 7 : Reserved
334  */
335 #define SNIC_NUM_TERM_VALID     0x01    /* Number of IOs terminated */
336
337 /*
338  * snic_hba_reset: host -> firmware request
339  *
340  * used for requesting firmware to reset snic
341  */
342 struct snic_hba_reset {
343         __le16  flags;          /* flags */
344         u8      _resvd[6];
345 };
346
347 /*
348  * snic_hba_reset_cmpl: firmware -> host response
349  *
350  * Used by firmware to respond to the host's hba reset request
351  */
352 struct snic_hba_reset_cmpl {
353         u8      flags;          /* flags : more info needs to be added*/
354         u8      _resvd[7];
355 };
356
357 /*
358  * snic_notify_msg: firmware -> host response
359  *
360  * Used by firmware to notify host of the last work queue entry received
361  */
362 struct snic_notify_msg {
363         __le32  wqe_num;        /* wq entry number */
364         u8      flags;          /* flags, macros */
365         u8      _resvd[4];
366 };
367
368
369 #define SNIC_EVDATA_LEN         24      /* in bytes */
370 /* snic_async_evnotify: firmware -> host notification
371  *
372  * Used by firmware to notify the host about configuration/state changes
373  */
374 struct snic_async_evnotify {
375         u8      FLS_EVENT_DESC;
376         u8      vnic;                   /* vnic id */
377         u8      _resvd[2];
378         __le32  ev_id;                  /* Event ID */
379         u8      ev_data[SNIC_EVDATA_LEN]; /* Event Data */
380         u8      _resvd2[4];
381 };
382
383 /* async event flags */
384 enum snic_ev_type {
385         SNIC_EV_TGT_OFFLINE = 0x01, /* Target Offline, PL contains TGT ID */
386         SNIC_EV_TGT_ONLINE,     /* Target Online, PL contains TGT ID */
387         SNIC_EV_LUN_OFFLINE,    /* LUN Offline, PL contains LUN ID */
388         SNIC_EV_LUN_ONLINE,     /* LUN Online, PL contains LUN ID */
389         SNIC_EV_CONF_CHG,       /* Dev Config/Attr Change Event */
390         SNIC_EV_TGT_ADDED,      /* Target Added */
391         SNIC_EV_TGT_DELTD,      /* Target Del'd, PL contains TGT ID */
392         SNIC_EV_LUN_ADDED,      /* LUN Added */
393         SNIC_EV_LUN_DELTD,      /* LUN Del'd, PL cont. TGT & LUN ID */
394
395         SNIC_EV_DISC_CMPL = 0x10, /* Discovery Completed Event */
396 };
397
398
399 #define SNIC_HOST_REQ_LEN       128     /*Exp length of host req, wq desc sz*/
400 /* Payload 88 bytes = 128 - 24 - 16 */
401 #define SNIC_HOST_REQ_PAYLOAD   ((int)(SNIC_HOST_REQ_LEN -              \
402                                         sizeof(struct snic_io_hdr) -    \
403                                         (2 * sizeof(u64)) - sizeof(ulong)))
404
405 /*
406  * snic_host_req: host -> firmware request
407  *
408  * Basic structure for all snic requests that are sent from the host to
409  * firmware. They are 128 bytes in size.
410  */
411 struct snic_host_req {
412         u64     ctrl_data[2];   /*16 bytes - Control Data */
413         struct snic_io_hdr hdr;
414         union {
415                 /*
416                  * Entry specific space, last byte contains color
417                  */
418                 u8      buf[SNIC_HOST_REQ_PAYLOAD];
419
420                 /*
421                  * Exchange firmware version
422                  */
423                 struct snic_exch_ver_req        exch_ver;
424
425                 /* report targets */
426                 struct snic_report_tgts         rpt_tgts;
427
428                 /* io request */
429                 struct snic_icmnd               icmnd;
430
431                 /* task management request */
432                 struct snic_itmf                itmf;
433
434                 /* hba reset */
435                 struct snic_hba_reset           reset;
436         } u;
437
438         ulong req_pa;
439 }; /* end of snic_host_req structure */
440
441
442 #define SNIC_FW_REQ_LEN         64 /* Expected length of fw req */
443 struct snic_fw_req {
444         struct snic_io_hdr hdr;
445         union {
446                 /*
447                  * Entry specific space, last byte contains color
448                  */
449                 u8      buf[SNIC_FW_REQ_LEN - sizeof(struct snic_io_hdr)];
450
451                 /* Exchange Version Response */
452                 struct snic_exch_ver_rsp        exch_ver_cmpl;
453
454                 /* Report Targets Response */
455                 struct snic_report_tgts_cmpl    rpt_tgts_cmpl;
456
457                 /* scsi response */
458                 struct snic_icmnd_cmpl          icmnd_cmpl;
459
460                 /* task management response */
461                 struct snic_itmf_cmpl           itmf_cmpl;
462
463                 /* hba reset response */
464                 struct snic_hba_reset_cmpl      reset_cmpl;
465
466                 /* notify message */
467                 struct snic_notify_msg          ack;
468
469                 /* async notification event */
470                 struct snic_async_evnotify      async_ev;
471
472         } u;
473 }; /* end of snic_fw_req structure */
474
475 /*
476  * Auxillary macro to verify specific snic req/cmpl structures
477  * to ensure that it will be aligned to 64 bit, and not using
478  * color bit field
479  */
480 #define VERIFY_REQ_SZ(x)
481 #define VERIFY_CMPL_SZ(x)
482
483 /*
484  * Access routines to encode and decode the color bit, which is the most
485  * significant bit of the structure.
486  */
487 static inline void
488 snic_color_enc(struct snic_fw_req *req, u8 color)
489 {
490         u8 *c = ((u8 *) req) + sizeof(struct snic_fw_req) - 1;
491
492         if (color)
493                 *c |= 0x80;
494         else
495                 *c &= ~0x80;
496 }
497
498 static inline void
499 snic_color_dec(struct snic_fw_req *req, u8 *color)
500 {
501         u8 *c = ((u8 *) req) + sizeof(struct snic_fw_req) - 1;
502
503         *color = *c >> 7;
504
505         /* Make sure color bit is read from desc *before* other fields
506          * are read from desc. Hardware guarantees color bit is last
507          * bit (byte) written. Adding the rmb() prevents the compiler
508          * and/or CPU from reordering the reads which would potentially
509          * result in reading stale values.
510          */
511         rmb();
512 }
513 #endif /* end of __SNIC_FWINT_H */