/*
 * All Rights Reserved (C) 2021-2025
 * Exoligent SARL (Colombes, France)
 * Website: www.exoligent.com
 * Author : Maxime Coroyer <maxime.coroyer@exoligent.com>
 */

#ifndef __POWERFIP_DRV_PCI_H__
#define __POWERFIP_DRV_PCI_H__

#include <linux/cdev.h>
#include <linux/semaphore.h>
#include <linux/ktime.h>

#include "powerfip-drv.h"

#define PCI_MAJOR 0   /* dynamic major by default */
#define MBOX_IN 1
#define MBOX_OUT 0
#define IRQ_TIMEOUT_MS 5000 /* 5s */
#define IRQ_VECS_MAX 4

extern int pci_major;

/* mailboxes (communication) */
struct pwrfip_mbox {
    int index;
    int type; /* MBOX_IN, MBOX_OUT */
    /* registers */
    uint32_t *config;
    uint32_t *status;
    uint32_t *data_wsz;
    uint32_t *data;
    /* host irq */
    int has_it_cap;
    int it_flag;
    wait_queue_head_t it_mutex;
    spinlock_t it_lock;
};

struct pwrfip_dev {
    struct pci_dev *pdev; /* non-null after pciprobe */
    struct device *dev;
    struct cdev cdev;
    struct pwrfip_dev_infos infos;
    void *remap[DEVICE_COUNT_RESOURCE]; /* iomem bar remapped */
    int is_open; /* 0: free - 1: busy */
    struct list_head link; /* double linked list */
    uint32_t minor; /* minor device number (device index) */
    /* irq part */
    struct pwrfip_dev_irq irq;
    bool has_msi_cap;
    int nb_irq_vecs;
    /* dma part */
    bool has_dma_cap;
    enum dma_data_direction dma_dir;
    size_t dma_bsz;
    dma_addr_t dma_addr;
    void *dma_buffer;
    bool dma_xfer_in_progress; /* transfer in progress */
    /* mbox part */
    struct pwrfip_mbox mbox[PWRFIP_MBOX_COUNT];
    struct pwrfip_dev_mbox_req req; /* request packet */
    struct pwrfip_dev_mbox_rep rep; /* response packet */
};

extern struct file_operations pwrfip_fops;

#endif // __POWERFIP_DRV_PCI_H__
