/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2005-2014 Brocade Communications Systems, Inc.
* Copyright (c) 2014- QLogic Corporation.
* All rights reserved
* www.qlogic.com
*
* Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter.
*/
#ifndef __BFA_IOC_H__
#define __BFA_IOC_H__
#include "bfad_drv.h"
#include "bfa_cs.h"
#include "bfi.h"
#define BFA_DBG_FWTRC_ENTS (BFI_IOC_TRC_ENTS)
#define BFA_DBG_FWTRC_LEN \
(BFA_DBG_FWTRC_ENTS * sizeof(struct bfa_trc_s) + \
(sizeof(struct bfa_trc_mod_s) - \
BFA_TRC_MAX * sizeof(struct bfa_trc_s)))
/*
* BFA timer declarations
*/
typedef void (*bfa_timer_cbfn_t)(void *);
/*
* BFA timer data structure
*/
struct bfa_timer_s {
struct list_head qe;
bfa_timer_cbfn_t timercb;
void *arg;
int timeout; /* in millisecs */
};
/*
* Timer module structure
*/
struct bfa_timer_mod_s {
struct list_head timer_q;
};
#define BFA_TIMER_FREQ 200 /* specified in millisecs */
void bfa_timer_beat(struct bfa_timer_mod_s *mod);
void bfa_timer_begin(struct bfa_timer_mod_s *mod, struct bfa_timer_s *timer,
bfa_timer_cbfn_t timercb, void *arg,
unsigned int timeout);
void bfa_timer_stop(struct bfa_timer_s *timer);
/*
* Generic Scatter Gather Element used by driver
*/
struct bfa_sge_s {
u32 sg_len;
void *sg_addr;
};
#define bfa_sge_word_swap(__sge) do { \
((u32 *)(__sge))[0] = swab32(((u32 *)(__sge))[0]); \
((u32 *)(__sge))[1] = swab32(((u32 *)(__sge))[1]); \
((u32 *)(__sge))[2] = swab32(((u32 *)(__sge))[2]); \
} while (0)
#define bfa_swap_words(_x) ( \
((u64)(_x) << 32) | ((u64)(_x) >> 32))
#ifdef __BIG_ENDIAN
#define bfa_sge_to_be(_x)
#define bfa_sge_to_le(_x) bfa_sge_word_swap(_x)
#define bfa_sgaddr_le(_x) bfa_swap_words(_x)
#else
#define bfa_sge_to_be(_x) bfa_sge_word_swap(_x)
#define bfa_sge_to_le(_x)
#define bfa_sgaddr_le(_x) (_x)
#endif
/*
* BFA memory resources
*/
struct bfa_mem_dma_s {
struct list_head qe; /* Queue of DMA elements */
u32 mem_len; /* Total Length in Bytes */
u8 *kva; /* kernel virtual address */
u64 dma; /* dma address if DMA memory */
u8 *kva_curp; /* kva allocation cursor */
u64 dma_curp; /* dma allocation cursor */
};
#define bfa_mem_dma_t struct bfa_mem_dma_s
struct bfa_mem_kva_s {
struct list_head qe; /* Queue of KVA elements */
u32 mem_len; /* Total Length in Bytes */
u8 *kva; /* kernel virtual address */
u8 *kva_curp; /* kva allocation cursor */
};
#define bfa_mem_kva_t struct bfa_mem_kva_s
struct bfa_meminfo_s {
struct bfa_mem_dma_s dma_info;
struct bfa_mem_kva_s kva_info;
};
/* BFA memory segment setup helpers */
static inline void bfa_mem_dma_setup(struct bfa_meminfo_s *meminfo,
struct bfa_mem_dma_s *dm_ptr,
size_t seg_sz)
{
dm_ptr->mem_len = seg_sz;
if (seg_sz)
list_add_tail(&dm_ptr->qe, &meminfo->dma_info.qe);
}
static inline void bfa_mem_kva_setup(struct bfa_meminfo_s *meminfo,
struct bfa_mem_kva_s *kva_ptr,
size_t seg_sz)
{
kva_ptr->mem_len = seg_sz;
if (seg_sz)
list_add_tail(&kva_ptr->qe, &meminfo->kva_info.qe);
}
/* BFA dma memory segments iterator */
#define bfa_mem_dma_sptr(_mod, _i) (&(_mod)->dma_seg[(_i)])
#define bfa_mem_dma_seg_iter(_mod, _sptr, _nr, _i) \
for (_i = 0, _sptr = bfa_mem_dma_sptr(_mod, _i); _i < (_nr); \
_i++, _sptr = bfa_mem_dma_sptr(_mod, _i))
#define bfa_mem_kva_curp(_mod) ((_mod)->kva_seg.kva_curp)
#define bfa_mem_dma_virt(_sptr) ((_sptr)->kva_curp)
#define bfa_mem_dma_phys(_sptr) ((_sptr)->dma_curp)
#define bfa_mem_dma_len(_sptr) ((_sptr)->mem_len)
/* Get the corresponding dma buf kva for a req - from the tag */
#define bfa_mem_get_dmabuf_kva(_mod, _tag, _rqsz) \
(((u8 *)(_mod)->dma_seg[BFI_MEM_SEG_FROM_TAG(_tag, _rqsz)].kva_curp) +\
BFI_MEM_SEG_REQ_OFFSET(_tag, _rqsz) * (_rqsz))
/* Get the corresponding dma buf pa for a req - from the tag */
#define bfa_mem_get_dmabuf_pa(_mod, _tag, _rqsz) \
((_mod)->dma_seg[BFI_MEM_SEG_FROM_TAG(_tag, _rqsz)].dma_curp + \
BFI_MEM_SEG_REQ_OFFSET(_tag, _rqsz) * (_rqsz))
/*
* PCI device information required by IOC
*/
struct bfa_pcidev_s {
int pci_slot;
u8 pci_func;
u16 device_id;
u16 ssid;
void __iomem *pci_bar_kva;
};
/*
* Structure used to remember the DMA-able memory block's KVA and Physical
* Address
*/
struct bfa_dma_s {
void *kva; /* ! Kernel virtual address */
u64 pa; /* ! Physical address */
};
#define BFA_DMA_ALIGN_SZ 256
#define BFA_ROUNDUP(_l, _s) (((_l) + ((_s) - 1)) & ~((_s) - 1))
/*
* smem size for Crossbow and Catapult
*/
#define BFI_SMEM_CB_SIZE 0x200000U /* ! 2MB for crossbow */
#define BFI_SMEM_CT_SIZE 0x280000U /* ! 2.5MB for catapult */
#define bfa_dma_be_addr_set(dma_addr, pa) \
__bfa_dma_be_addr_set(&dma_addr, (u64)pa)
static inline void
__bfa_dma_be_addr_set(union bfi_addr_u *dma_addr, u64 pa)
{
dma_addr->a32.addr_lo = cpu_to_be32(pa);
dma_addr->a32.addr_hi = cpu_to_be32(pa >> 32);
}
#define bfa_alen_set(__alen, __len, __pa) \
__bfa_alen_set(__alen, __len, (u64)__pa)
static inline void
__bfa_alen_set(struct bfi_alen_s *alen, u32 len, u64 pa)
{
alen->al_len