Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003   * Marvell UMI head file
0004   *
0005   * Copyright 2011 Marvell. <jyli@marvell.com>
0006  */
0007 
0008 #ifndef MVUMI_H
0009 #define MVUMI_H
0010 
0011 #define MAX_BASE_ADDRESS    6
0012 
0013 #define VER_MAJOR       1
0014 #define VER_MINOR       1
0015 #define VER_OEM         0
0016 #define VER_BUILD       1500
0017 
0018 #define MV_DRIVER_NAME          "mvumi"
0019 #define PCI_DEVICE_ID_MARVELL_MV9143    0x9143
0020 #define PCI_DEVICE_ID_MARVELL_MV9580    0x9580
0021 
0022 #define MVUMI_INTERNAL_CMD_WAIT_TIME    45
0023 #define MVUMI_INQUIRY_LENGTH        44
0024 #define MVUMI_INQUIRY_UUID_OFF      36
0025 #define MVUMI_INQUIRY_UUID_LEN      8
0026 
0027 #define IS_DMA64            (sizeof(dma_addr_t) == 8)
0028 
0029 enum mvumi_qc_result {
0030     MV_QUEUE_COMMAND_RESULT_SENT = 0,
0031     MV_QUEUE_COMMAND_RESULT_NO_RESOURCE,
0032 };
0033 
0034 struct mvumi_hw_regs {
0035     /* For CPU */
0036     void *main_int_cause_reg;
0037     void *enpointa_mask_reg;
0038     void *enpointb_mask_reg;
0039     void *rstoutn_en_reg;
0040     void *ctrl_sts_reg;
0041     void *rstoutn_mask_reg;
0042     void *sys_soft_rst_reg;
0043 
0044     /* For Doorbell */
0045     void *pciea_to_arm_drbl_reg;
0046     void *arm_to_pciea_drbl_reg;
0047     void *arm_to_pciea_mask_reg;
0048     void *pciea_to_arm_msg0;
0049     void *pciea_to_arm_msg1;
0050     void *arm_to_pciea_msg0;
0051     void *arm_to_pciea_msg1;
0052 
0053     /* reset register */
0054     void *reset_request;
0055     void *reset_enable;
0056 
0057     /* For Message Unit */
0058     void *inb_list_basel;
0059     void *inb_list_baseh;
0060     void *inb_aval_count_basel;
0061     void *inb_aval_count_baseh;
0062     void *inb_write_pointer;
0063     void *inb_read_pointer;
0064     void *outb_list_basel;
0065     void *outb_list_baseh;
0066     void *outb_copy_basel;
0067     void *outb_copy_baseh;
0068     void *outb_copy_pointer;
0069     void *outb_read_pointer;
0070     void *inb_isr_cause;
0071     void *outb_isr_cause;
0072     void *outb_coal_cfg;
0073     void *outb_coal_timeout;
0074 
0075     /* Bit setting for HW */
0076     u32 int_comaout;
0077     u32 int_comaerr;
0078     u32 int_dl_cpu2pciea;
0079     u32 int_mu;
0080     u32 int_drbl_int_mask;
0081     u32 int_main_int_mask;
0082     u32 cl_pointer_toggle;
0083     u32 cl_slot_num_mask;
0084     u32 clic_irq;
0085     u32 clic_in_err;
0086     u32 clic_out_err;
0087 };
0088 
0089 struct mvumi_dyn_list_entry {
0090     u32 src_low_addr;
0091     u32 src_high_addr;
0092     u32 if_length;
0093     u32 reserve;
0094 };
0095 
0096 #define SCSI_CMD_MARVELL_SPECIFIC   0xE1
0097 #define CDB_CORE_MODULE         0x1
0098 #define CDB_CORE_SHUTDOWN       0xB
0099 
0100 enum {
0101     DRBL_HANDSHAKE          = 1 << 0,
0102     DRBL_SOFT_RESET         = 1 << 1,
0103     DRBL_BUS_CHANGE         = 1 << 2,
0104     DRBL_EVENT_NOTIFY       = 1 << 3,
0105     DRBL_MU_RESET           = 1 << 4,
0106     DRBL_HANDSHAKE_ISR      = DRBL_HANDSHAKE,
0107 
0108     /*
0109     * Command flag is the flag for the CDB command itself
0110     */
0111     /* 1-non data; 0-data command */
0112     CMD_FLAG_NON_DATA       = 1 << 0,
0113     CMD_FLAG_DMA            = 1 << 1,
0114     CMD_FLAG_PIO            = 1 << 2,
0115     /* 1-host read data */
0116     CMD_FLAG_DATA_IN        = 1 << 3,
0117     /* 1-host write data */
0118     CMD_FLAG_DATA_OUT       = 1 << 4,
0119     CMD_FLAG_PRDT_IN_HOST       = 1 << 5,
0120 };
0121 
0122 #define APICDB0_EVENT           0xF4
0123 #define APICDB1_EVENT_GETEVENT      0
0124 #define APICDB1_HOST_GETEVENT       1
0125 #define MAX_EVENTS_RETURNED     6
0126 
0127 #define DEVICE_OFFLINE  0
0128 #define DEVICE_ONLINE   1
0129 
0130 struct mvumi_hotplug_event {
0131     u16 size;
0132     u8 dummy[2];
0133     u8 bitmap[];
0134 };
0135 
0136 struct mvumi_driver_event {
0137     u32 time_stamp;
0138     u32 sequence_no;
0139     u32 event_id;
0140     u8  severity;
0141     u8  param_count;
0142     u16 device_id;
0143     u32 params[4];
0144     u8  sense_data_length;
0145     u8  Reserved1;
0146     u8  sense_data[30];
0147 };
0148 
0149 struct mvumi_event_req {
0150     unsigned char   count;
0151     unsigned char   reserved[3];
0152     struct mvumi_driver_event  events[MAX_EVENTS_RETURNED];
0153 };
0154 
0155 struct mvumi_events_wq {
0156     struct work_struct work_q;
0157     struct mvumi_hba *mhba;
0158     unsigned int event;
0159     void *param;
0160 };
0161 
0162 #define HS_CAPABILITY_SUPPORT_COMPACT_SG    (1U << 4)
0163 #define HS_CAPABILITY_SUPPORT_PRD_HOST      (1U << 5)
0164 #define HS_CAPABILITY_SUPPORT_DYN_SRC       (1U << 6)
0165 #define HS_CAPABILITY_NEW_PAGE_IO_DEPTH_DEF (1U << 14)
0166 
0167 #define MVUMI_MAX_SG_ENTRY  32
0168 #define SGD_EOT         (1L << 27)
0169 #define SGD_EOT_CP      (1L << 22)
0170 
0171 struct mvumi_sgl {
0172     u32 baseaddr_l;
0173     u32 baseaddr_h;
0174     u32 flags;
0175     u32 size;
0176 };
0177 struct mvumi_compact_sgl {
0178     u32 baseaddr_l;
0179     u32 baseaddr_h;
0180     u32 flags;
0181 };
0182 
0183 #define GET_COMPACT_SGD_SIZE(sgd)   \
0184     ((((struct mvumi_compact_sgl *)(sgd))->flags) & 0x3FFFFFL)
0185 
0186 #define SET_COMPACT_SGD_SIZE(sgd, sz) do {          \
0187     (((struct mvumi_compact_sgl *)(sgd))->flags) &= ~0x3FFFFFL; \
0188     (((struct mvumi_compact_sgl *)(sgd))->flags) |= (sz);       \
0189 } while (0)
0190 #define sgd_getsz(_mhba, sgd, sz) do {              \
0191     if (_mhba->hba_capability & HS_CAPABILITY_SUPPORT_COMPACT_SG)   \
0192         (sz) = GET_COMPACT_SGD_SIZE(sgd);   \
0193     else \
0194         (sz) = (sgd)->size;         \
0195 } while (0)
0196 
0197 #define sgd_setsz(_mhba, sgd, sz) do {              \
0198     if (_mhba->hba_capability & HS_CAPABILITY_SUPPORT_COMPACT_SG)   \
0199         SET_COMPACT_SGD_SIZE(sgd, sz);      \
0200     else \
0201         (sgd)->size = (sz);         \
0202 } while (0)
0203 
0204 #define sgd_inc(_mhba, sgd) do {    \
0205     if (_mhba->hba_capability & HS_CAPABILITY_SUPPORT_COMPACT_SG)   \
0206         sgd = (struct mvumi_sgl *)(((unsigned char *) (sgd)) + 12); \
0207     else \
0208         sgd = (struct mvumi_sgl *)(((unsigned char *) (sgd)) + 16); \
0209 } while (0)
0210 
0211 struct mvumi_res {
0212     struct list_head entry;
0213     dma_addr_t bus_addr;
0214     void *virt_addr;
0215     unsigned int size;
0216     unsigned short type;    /* enum Resource_Type */
0217 };
0218 
0219 /* Resource type */
0220 enum resource_type {
0221     RESOURCE_CACHED_MEMORY = 0,
0222     RESOURCE_UNCACHED_MEMORY
0223 };
0224 
0225 struct mvumi_sense_data {
0226     u8 error_code:7;
0227     u8 valid:1;
0228     u8 segment_number;
0229     u8 sense_key:4;
0230     u8 reserved:1;
0231     u8 incorrect_length:1;
0232     u8 end_of_media:1;
0233     u8 file_mark:1;
0234     u8 information[4];
0235     u8 additional_sense_length;
0236     u8 command_specific_information[4];
0237     u8 additional_sense_code;
0238     u8 additional_sense_code_qualifier;
0239     u8 field_replaceable_unit_code;
0240     u8 sense_key_specific[3];
0241 };
0242 
0243 /* Request initiator must set the status to REQ_STATUS_PENDING. */
0244 #define REQ_STATUS_PENDING      0x80
0245 
0246 struct mvumi_cmd {
0247     struct list_head queue_pointer;
0248     struct mvumi_msg_frame *frame;
0249     dma_addr_t frame_phys;
0250     struct scsi_cmnd *scmd;
0251     atomic_t sync_cmd;
0252     void *data_buf;
0253     unsigned short request_id;
0254     unsigned char cmd_status;
0255 };
0256 
0257 struct mvumi_cmd_priv {
0258     struct mvumi_cmd *cmd_priv;
0259 };
0260 
0261 static inline struct mvumi_cmd_priv *mvumi_priv(struct scsi_cmnd *cmd)
0262 {
0263     return scsi_cmd_priv(cmd);
0264 }
0265 
0266 /*
0267  * the function type of the in bound frame
0268  */
0269 #define CL_FUN_SCSI_CMD         0x1
0270 
0271 struct mvumi_msg_frame {
0272     u16 device_id;
0273     u16 tag;
0274     u8 cmd_flag;
0275     u8 req_function;
0276     u8 cdb_length;
0277     u8 sg_counts;
0278     u32 data_transfer_length;
0279     u16 request_id;
0280     u16 reserved1;
0281     u8 cdb[MAX_COMMAND_SIZE];
0282     u32 payload[1];
0283 };
0284 
0285 /*
0286  * the respond flag for data_payload of the out bound frame
0287  */
0288 #define CL_RSP_FLAG_NODATA      0x0
0289 #define CL_RSP_FLAG_SENSEDATA       0x1
0290 
0291 struct mvumi_rsp_frame {
0292     u16 device_id;
0293     u16 tag;
0294     u8 req_status;
0295     u8 rsp_flag;    /* Indicates the type of Data_Payload.*/
0296     u16 request_id;
0297     u32 payload[1];
0298 };
0299 
0300 struct mvumi_ob_data {
0301     struct list_head list;
0302     unsigned char data[];
0303 };
0304 
0305 struct version_info {
0306     u32 ver_major;
0307     u32 ver_minor;
0308     u32 ver_oem;
0309     u32 ver_build;
0310 };
0311 
0312 #define FW_MAX_DELAY            30
0313 #define MVUMI_FW_BUSY           (1U << 0)
0314 #define MVUMI_FW_ATTACH         (1U << 1)
0315 #define MVUMI_FW_ALLOC          (1U << 2)
0316 
0317 /*
0318  * State is the state of the MU
0319  */
0320 #define FW_STATE_IDLE           0
0321 #define FW_STATE_STARTING       1
0322 #define FW_STATE_HANDSHAKING        2
0323 #define FW_STATE_STARTED        3
0324 #define FW_STATE_ABORT          4
0325 
0326 #define HANDSHAKE_SIGNATURE     0x5A5A5A5AL
0327 #define HANDSHAKE_READYSTATE        0x55AA5AA5L
0328 #define HANDSHAKE_DONESTATE     0x55AAA55AL
0329 
0330 /* HandShake Status definition */
0331 #define HS_STATUS_OK            1
0332 #define HS_STATUS_ERR           2
0333 #define HS_STATUS_INVALID       3
0334 
0335 /* HandShake State/Cmd definition */
0336 #define HS_S_START          1
0337 #define HS_S_RESET          2
0338 #define HS_S_PAGE_ADDR          3
0339 #define HS_S_QUERY_PAGE         4
0340 #define HS_S_SEND_PAGE          5
0341 #define HS_S_END            6
0342 #define HS_S_ABORT          7
0343 #define HS_PAGE_VERIFY_SIZE     128
0344 
0345 #define HS_GET_STATE(a)         (a & 0xFFFF)
0346 #define HS_GET_STATUS(a)        ((a & 0xFFFF0000) >> 16)
0347 #define HS_SET_STATE(a, b)      (a |= (b & 0xFFFF))
0348 #define HS_SET_STATUS(a, b)     (a |= ((b & 0xFFFF) << 16))
0349 
0350 /* handshake frame */
0351 struct mvumi_hs_frame {
0352     u16 size;
0353     /* host information */
0354     u8 host_type;
0355     u8 reserved_1[1];
0356     struct version_info host_ver; /* bios or driver version */
0357 
0358     /* controller information */
0359     u32 system_io_bus;
0360     u32 slot_number;
0361     u32 intr_level;
0362     u32 intr_vector;
0363 
0364     /* communication list configuration */
0365     u32 ib_baseaddr_l;
0366     u32 ib_baseaddr_h;
0367     u32 ob_baseaddr_l;
0368     u32 ob_baseaddr_h;
0369 
0370     u8 ib_entry_size;
0371     u8 ob_entry_size;
0372     u8 ob_depth;
0373     u8 ib_depth;
0374 
0375     /* system time */
0376     u64 seconds_since1970;
0377 };
0378 
0379 struct mvumi_hs_header {
0380     u8  page_code;
0381     u8  checksum;
0382     u16 frame_length;
0383     u32 frame_content[1];
0384 };
0385 
0386 /*
0387  * the page code type of the handshake header
0388  */
0389 #define HS_PAGE_FIRM_CAP    0x1
0390 #define HS_PAGE_HOST_INFO   0x2
0391 #define HS_PAGE_FIRM_CTL    0x3
0392 #define HS_PAGE_CL_INFO     0x4
0393 #define HS_PAGE_TOTAL       0x5
0394 
0395 #define HSP_SIZE(i) sizeof(struct mvumi_hs_page##i)
0396 
0397 #define HSP_MAX_SIZE ({                 \
0398     int size, m1, m2;               \
0399     m1 = max(HSP_SIZE(1), HSP_SIZE(3));     \
0400     m2 = max(HSP_SIZE(2), HSP_SIZE(4));     \
0401     size = max(m1, m2);             \
0402     size;                       \
0403 })
0404 
0405 /* The format of the page code for Firmware capability */
0406 struct mvumi_hs_page1 {
0407     u8 pagecode;
0408     u8 checksum;
0409     u16 frame_length;
0410 
0411     u16 number_of_ports;
0412     u16 max_devices_support;
0413     u16 max_io_support;
0414     u16 umi_ver;
0415     u32 max_transfer_size;
0416     struct version_info fw_ver;
0417     u8 cl_in_max_entry_size;
0418     u8 cl_out_max_entry_size;
0419     u8 cl_inout_list_depth;
0420     u8 total_pages;
0421     u16 capability;
0422     u16 reserved1;
0423 };
0424 
0425 /* The format of the page code for Host information */
0426 struct mvumi_hs_page2 {
0427     u8 pagecode;
0428     u8 checksum;
0429     u16 frame_length;
0430 
0431     u8 host_type;
0432     u8 host_cap;
0433     u8 reserved[2];
0434     struct version_info host_ver;
0435     u32 system_io_bus;
0436     u32 slot_number;
0437     u32 intr_level;
0438     u32 intr_vector;
0439     u64 seconds_since1970;
0440 };
0441 
0442 /* The format of the page code for firmware control  */
0443 struct mvumi_hs_page3 {
0444     u8  pagecode;
0445     u8  checksum;
0446     u16 frame_length;
0447     u16 control;
0448     u8  reserved[2];
0449     u32 host_bufferaddr_l;
0450     u32 host_bufferaddr_h;
0451     u32 host_eventaddr_l;
0452     u32 host_eventaddr_h;
0453 };
0454 
0455 struct mvumi_hs_page4 {
0456     u8  pagecode;
0457     u8  checksum;
0458     u16 frame_length;
0459     u32 ib_baseaddr_l;
0460     u32 ib_baseaddr_h;
0461     u32 ob_baseaddr_l;
0462     u32 ob_baseaddr_h;
0463     u8  ib_entry_size;
0464     u8  ob_entry_size;
0465     u8  ob_depth;
0466     u8  ib_depth;
0467 };
0468 
0469 struct mvumi_tag {
0470     unsigned short *stack;
0471     unsigned short top;
0472     unsigned short size;
0473 };
0474 
0475 struct mvumi_device {
0476     struct list_head list;
0477     struct scsi_device *sdev;
0478     u64 wwid;
0479     u8  dev_type;
0480     int id;
0481 };
0482 
0483 struct mvumi_hba {
0484     void *base_addr[MAX_BASE_ADDRESS];
0485     u32 pci_base[MAX_BASE_ADDRESS];
0486     void *mmio;
0487     struct list_head cmd_pool;
0488     struct Scsi_Host *shost;
0489     wait_queue_head_t int_cmd_wait_q;
0490     struct pci_dev *pdev;
0491     unsigned int unique_id;
0492     atomic_t fw_outstanding;
0493     struct mvumi_instance_template *instancet;
0494 
0495     void *ib_list;
0496     dma_addr_t ib_list_phys;
0497 
0498     void *ib_frame;
0499     dma_addr_t ib_frame_phys;
0500 
0501     void *ob_list;
0502     dma_addr_t ob_list_phys;
0503 
0504     void *ib_shadow;
0505     dma_addr_t ib_shadow_phys;
0506 
0507     void *ob_shadow;
0508     dma_addr_t ob_shadow_phys;
0509 
0510     void *handshake_page;
0511     dma_addr_t handshake_page_phys;
0512 
0513     unsigned int global_isr;
0514     unsigned int isr_status;
0515 
0516     unsigned short max_sge;
0517     unsigned short max_target_id;
0518     unsigned char *target_map;
0519     unsigned int max_io;
0520     unsigned int list_num_io;
0521     unsigned int ib_max_size;
0522     unsigned int ob_max_size;
0523     unsigned int ib_max_size_setting;
0524     unsigned int ob_max_size_setting;
0525     unsigned int max_transfer_size;
0526     unsigned char hba_total_pages;
0527     unsigned char fw_flag;
0528     unsigned char request_id_enabled;
0529     unsigned char eot_flag;
0530     unsigned short hba_capability;
0531     unsigned short io_seq;
0532 
0533     unsigned int ib_cur_slot;
0534     unsigned int ob_cur_slot;
0535     unsigned int fw_state;
0536     struct mutex sas_discovery_mutex;
0537 
0538     struct list_head ob_data_list;
0539     struct list_head free_ob_list;
0540     struct list_head res_list;
0541     struct list_head waiting_req_list;
0542 
0543     struct mvumi_tag tag_pool;
0544     struct mvumi_cmd **tag_cmd;
0545     struct mvumi_hw_regs *regs;
0546     struct mutex device_lock;
0547     struct list_head mhba_dev_list;
0548     struct list_head shost_dev_list;
0549     struct task_struct *dm_thread;
0550     atomic_t pnp_count;
0551 };
0552 
0553 struct mvumi_instance_template {
0554     void (*fire_cmd) (struct mvumi_hba *, struct mvumi_cmd *);
0555     void (*enable_intr) (struct mvumi_hba *);
0556     void (*disable_intr) (struct mvumi_hba *);
0557     int (*clear_intr) (void *);
0558     unsigned int (*read_fw_status_reg) (struct mvumi_hba *);
0559     unsigned int (*check_ib_list) (struct mvumi_hba *);
0560     int (*check_ob_list) (struct mvumi_hba *, unsigned int *,
0561                   unsigned int *);
0562     int (*reset_host) (struct mvumi_hba *);
0563 };
0564 
0565 extern struct timezone sys_tz;
0566 #endif