^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0-or-later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * CXL Flash Device Driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Written by: Manoj N. Kumar <manoj@linux.vnet.ibm.com>, IBM Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Matthew R. Ochs <mrochs@linux.vnet.ibm.com>, IBM Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copyright (C) 2015 IBM Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #ifndef _CXLFLASH_COMMON_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #define _CXLFLASH_COMMON_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/async.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/cdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/irq_poll.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/rwsem.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <scsi/scsi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <scsi/scsi_cmnd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <scsi/scsi_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include "backend.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) extern const struct file_operations cxlflash_cxl_fops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define MAX_CONTEXT CXLFLASH_MAX_CONTEXT /* num contexts per afu */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define MAX_FC_PORTS CXLFLASH_MAX_FC_PORTS /* max ports per AFU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define LEGACY_FC_PORTS 2 /* legacy ports per AFU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define CHAN2PORTBANK(_x) ((_x) >> ilog2(CXLFLASH_NUM_FC_PORTS_PER_BANK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define CHAN2BANKPORT(_x) ((_x) & (CXLFLASH_NUM_FC_PORTS_PER_BANK - 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define CHAN2PORTMASK(_x) (1 << (_x)) /* channel to port mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define PORTMASK2CHAN(_x) (ilog2((_x))) /* port mask to channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define PORTNUM2CHAN(_x) ((_x) - 1) /* port number to channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define CXLFLASH_BLOCK_SIZE 4096 /* 4K blocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define CXLFLASH_MAX_XFER_SIZE 16777216 /* 16MB transfer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define CXLFLASH_MAX_SECTORS (CXLFLASH_MAX_XFER_SIZE/512) /* SCSI wants
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * max_sectors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * in units of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * 512 byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * sectors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define MAX_RHT_PER_CONTEXT (PAGE_SIZE / sizeof(struct sisl_rht_entry))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) /* AFU command retry limit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define MC_RETRY_CNT 5 /* Sufficient for SCSI and certain AFU errors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) /* Command management definitions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define CXLFLASH_MAX_CMDS 256
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define CXLFLASH_MAX_CMDS_PER_LUN CXLFLASH_MAX_CMDS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) /* RRQ for master issued cmds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define NUM_RRQ_ENTRY CXLFLASH_MAX_CMDS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) /* SQ for master issued cmds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define NUM_SQ_ENTRY CXLFLASH_MAX_CMDS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) /* Hardware queue definitions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define CXLFLASH_DEF_HWQS 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define CXLFLASH_MAX_HWQS 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define PRIMARY_HWQ 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) static inline void check_sizes(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) BUILD_BUG_ON_NOT_POWER_OF_2(CXLFLASH_NUM_FC_PORTS_PER_BANK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) BUILD_BUG_ON_NOT_POWER_OF_2(CXLFLASH_MAX_CMDS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) /* AFU defines a fixed size of 4K for command buffers (borrow 4K page define) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define CMD_BUFSIZE SIZE_4K
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) enum cxlflash_lr_state {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) LINK_RESET_INVALID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) LINK_RESET_REQUIRED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) LINK_RESET_COMPLETE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) enum cxlflash_init_state {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) INIT_STATE_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) INIT_STATE_PCI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) INIT_STATE_AFU,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) INIT_STATE_SCSI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) INIT_STATE_CDEV
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) enum cxlflash_state {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) STATE_PROBING, /* Initial state during probe */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) STATE_PROBED, /* Temporary state, probe completed but EEH occurred */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) STATE_NORMAL, /* Normal running state, everything good */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) STATE_RESET, /* Reset state, trying to reset/recover */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) STATE_FAILTERM /* Failed/terminating state, error out users/threads */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) enum cxlflash_hwq_mode {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) HWQ_MODE_RR, /* Roundrobin (default) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) HWQ_MODE_TAG, /* Distribute based on block MQ tag */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) HWQ_MODE_CPU, /* CPU affinity */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) MAX_HWQ_MODE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * Each context has its own set of resource handles that is visible
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) * only from that context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) struct cxlflash_cfg {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) struct afu *afu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) const struct cxlflash_backend_ops *ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) struct pci_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) struct pci_device_id *dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) struct Scsi_Host *host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) int num_fc_ports;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) struct cdev cdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) struct device *chardev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) ulong cxlflash_regs_pci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) struct work_struct work_q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) enum cxlflash_init_state init_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) enum cxlflash_lr_state lr_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) int lr_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) atomic_t scan_host_needed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) void *afu_cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) atomic_t recovery_threads;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) struct mutex ctx_recovery_mutex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) struct mutex ctx_tbl_list_mutex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) struct rw_semaphore ioctl_rwsem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) struct ctx_info *ctx_tbl[MAX_CONTEXT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) struct list_head ctx_err_recovery; /* contexts w/ recovery pending */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) struct file_operations cxl_fops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) /* Parameters that are LUN table related */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) int last_lun_index[MAX_FC_PORTS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) int promote_lun_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) struct list_head lluns; /* list of llun_info structs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) wait_queue_head_t tmf_waitq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) spinlock_t tmf_slock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) bool tmf_active;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) bool ws_unmap; /* Write-same unmap supported */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) wait_queue_head_t reset_waitq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) enum cxlflash_state state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) async_cookie_t async_reset_cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) struct afu_cmd {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) struct sisl_ioarcb rcb; /* IOARCB (cache line aligned) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) struct sisl_ioasa sa; /* IOASA must follow IOARCB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) struct afu *parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) struct scsi_cmnd *scp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) struct completion cevent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) struct list_head queue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) u32 hwq_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) u8 cmd_tmf:1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) cmd_aborted:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) struct list_head list; /* Pending commands link */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) /* As per the SISLITE spec the IOARCB EA has to be 16-byte aligned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) * However for performance reasons the IOARCB/IOASA should be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) * cache line aligned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) } __aligned(cache_line_size());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) static inline struct afu_cmd *sc_to_afuc(struct scsi_cmnd *sc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) return PTR_ALIGN(scsi_cmd_priv(sc), __alignof__(struct afu_cmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) static inline struct afu_cmd *sc_to_afuci(struct scsi_cmnd *sc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) struct afu_cmd *afuc = sc_to_afuc(sc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) INIT_LIST_HEAD(&afuc->queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) return afuc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) static inline struct afu_cmd *sc_to_afucz(struct scsi_cmnd *sc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) struct afu_cmd *afuc = sc_to_afuc(sc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) memset(afuc, 0, sizeof(*afuc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) return sc_to_afuci(sc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) struct hwq {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) /* Stuff requiring alignment go first. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) struct sisl_ioarcb sq[NUM_SQ_ENTRY]; /* 16K SQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) u64 rrq_entry[NUM_RRQ_ENTRY]; /* 2K RRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) /* Beware of alignment till here. Preferably introduce new
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) * fields after this point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) struct afu *afu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) void *ctx_cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) struct sisl_host_map __iomem *host_map; /* MC host map */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) struct sisl_ctrl_map __iomem *ctrl_map; /* MC control map */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) ctx_hndl_t ctx_hndl; /* master's context handle */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) u32 index; /* Index of this hwq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) int num_irqs; /* Number of interrupts requested for context */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) struct list_head pending_cmds; /* Commands pending completion */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) atomic_t hsq_credits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) spinlock_t hsq_slock; /* Hardware send queue lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) struct sisl_ioarcb *hsq_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) struct sisl_ioarcb *hsq_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) struct sisl_ioarcb *hsq_curr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) spinlock_t hrrq_slock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) u64 *hrrq_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) u64 *hrrq_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) u64 *hrrq_curr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) bool toggle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) bool hrrq_online;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) s64 room;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) struct irq_poll irqpoll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) } __aligned(cache_line_size());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) struct afu {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) struct hwq hwqs[CXLFLASH_MAX_HWQS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) int (*send_cmd)(struct afu *afu, struct afu_cmd *cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) int (*context_reset)(struct hwq *hwq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) /* AFU HW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) struct cxlflash_afu_map __iomem *afu_map; /* entire MMIO map */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) atomic_t cmds_active; /* Number of currently active AFU commands */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) struct mutex sync_active; /* Mutex to serialize AFU commands */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) u64 hb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) u32 internal_lun; /* User-desired LUN mode for this AFU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) u32 num_hwqs; /* Number of hardware queues */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) u32 desired_hwqs; /* Desired h/w queues, effective on AFU reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) enum cxlflash_hwq_mode hwq_mode; /* Steering mode for h/w queues */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) u32 hwq_rr_count; /* Count to distribute traffic for roundrobin */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) char version[16];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) u64 interface_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) u32 irqpoll_weight;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) struct cxlflash_cfg *parent; /* Pointer back to parent cxlflash_cfg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) static inline struct hwq *get_hwq(struct afu *afu, u32 index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) WARN_ON(index >= CXLFLASH_MAX_HWQS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) return &afu->hwqs[index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) static inline bool afu_is_irqpoll_enabled(struct afu *afu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) return !!afu->irqpoll_weight;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) static inline bool afu_has_cap(struct afu *afu, u64 cap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) u64 afu_cap = afu->interface_version >> SISL_INTVER_CAP_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) return afu_cap & cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) static inline bool afu_is_ocxl_lisn(struct afu *afu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) return afu_has_cap(afu, SISL_INTVER_CAP_OCXL_LISN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) static inline bool afu_is_afu_debug(struct afu *afu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) return afu_has_cap(afu, SISL_INTVER_CAP_AFU_DEBUG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) static inline bool afu_is_lun_provision(struct afu *afu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) return afu_has_cap(afu, SISL_INTVER_CAP_LUN_PROVISION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) static inline bool afu_is_sq_cmd_mode(struct afu *afu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) return afu_has_cap(afu, SISL_INTVER_CAP_SQ_CMD_MODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) static inline bool afu_is_ioarrin_cmd_mode(struct afu *afu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) return afu_has_cap(afu, SISL_INTVER_CAP_IOARRIN_CMD_MODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) static inline u64 lun_to_lunid(u64 lun)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) __be64 lun_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) int_to_scsilun(lun, (struct scsi_lun *)&lun_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) return be64_to_cpu(lun_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) static inline struct fc_port_bank __iomem *get_fc_port_bank(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) struct cxlflash_cfg *cfg, int i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) struct afu *afu = cfg->afu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) return &afu->afu_map->global.bank[CHAN2PORTBANK(i)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) static inline __be64 __iomem *get_fc_port_regs(struct cxlflash_cfg *cfg, int i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) struct fc_port_bank __iomem *fcpb = get_fc_port_bank(cfg, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) return &fcpb->fc_port_regs[CHAN2BANKPORT(i)][0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) static inline __be64 __iomem *get_fc_port_luns(struct cxlflash_cfg *cfg, int i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) struct fc_port_bank __iomem *fcpb = get_fc_port_bank(cfg, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) return &fcpb->fc_port_luns[CHAN2BANKPORT(i)][0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) int cxlflash_afu_sync(struct afu *afu, ctx_hndl_t c, res_hndl_t r, u8 mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) void cxlflash_list_init(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) void cxlflash_term_global_luns(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) void cxlflash_free_errpage(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) int cxlflash_ioctl(struct scsi_device *sdev, unsigned int cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) void __user *arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) void cxlflash_stop_term_user_contexts(struct cxlflash_cfg *cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) int cxlflash_mark_contexts_error(struct cxlflash_cfg *cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) void cxlflash_term_local_luns(struct cxlflash_cfg *cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) void cxlflash_restore_luntable(struct cxlflash_cfg *cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) #endif /* ifndef _CXLFLASH_COMMON_H */