bfa_ioc.h 8.4 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241
/*
 * Linux network driver for Brocade Converged Network Adapter.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License (GPL) Version 2 as
 * published by the Free Software Foundation
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 */
/*
 * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
 * All rights reserved
 * www.brocade.com
 */

#ifndef __BFA_IOC_H__
#define __BFA_IOC_H__

#include "bfa_sm.h"
#include "bfi.h"
#include "cna.h"

#define BFA_IOC_TOV		3000	/* msecs */
#define BFA_IOC_HWSEM_TOV	500	/* msecs */
#define BFA_IOC_HB_TOV		500	/* msecs */
#define BFA_IOC_HWINIT_MAX	2
#define BFA_IOC_TOV_RECOVER	BFA_IOC_HB_TOV

/**
 * Generic Scatter Gather Element used by driver
 */
struct bfa_sge {
	u32	sg_len;
	void	*sg_addr;
};

/**
 * PCI device information required by IOC
 */
struct bfa_pcidev {
	int	pci_slot;
	u8	pci_func;
	u16	device_id;
	void	__iomem *pci_bar_kva;
};

/**
 * Structure used to remember the DMA-able memory block's KVA and Physical
 * Address
 */
struct bfa_dma {
	void	*kva;	/* ! Kernel virtual address	*/
	u64	pa;	/* ! Physical address		*/
};

#define BFA_DMA_ALIGN_SZ	256

/**
 * 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	*/

/**
 * @brief BFA dma address assignment macro
 */
#define bfa_dma_addr_set(dma_addr, pa)	\
		__bfa_dma_addr_set(&dma_addr, (u64)pa)

static inline void
__bfa_dma_addr_set(union bfi_addr_u *dma_addr, u64 pa)
{
	dma_addr->a32.addr_lo = (u32) pa;
	dma_addr->a32.addr_hi = (u32) (upper_32_bits(pa));
}

/**
 * @brief BFA dma address assignment macro. (big endian format)
 */
#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 = (u32) htonl(pa);
	dma_addr->a32.addr_hi = (u32) htonl(upper_32_bits(pa));
}

struct bfa_ioc_regs {
	void __iomem *hfn_mbox_cmd;
	void __iomem *hfn_mbox;
	void __iomem *lpu_mbox_cmd;
	void __iomem *lpu_mbox;
	void __iomem *pss_ctl_reg;
	void __iomem *pss_err_status_reg;
	void __iomem *app_pll_fast_ctl_reg;
	void __iomem *app_pll_slow_ctl_reg;
	void __iomem *ioc_sem_reg;
	void __iomem *ioc_usage_sem_reg;
	void __iomem *ioc_init_sem_reg;
	void __iomem *ioc_usage_reg;
	void __iomem *host_page_num_fn;
	void __iomem *heartbeat;
	void __iomem *ioc_fwstate;
	void __iomem *ll_halt;
	void __iomem *err_set;
	void __iomem *shirq_isr_next;
	void __iomem *shirq_msk_next;
	void __iomem *smem_page_start;
	u32	smem_pg0;
};

/**
 * IOC Mailbox structures
 */
struct bfa_mbox_cmd {
	struct list_head	qe;
	u32			msg[BFI_IOC_MSGSZ];
};

/**
 * IOC mailbox module
 */
typedef void (*bfa_ioc_mbox_mcfunc_t)(void *cbarg, struct bfi_mbmsg *m);
struct bfa_ioc_mbox_mod {
	struct list_head	cmd_q;		/*!< pending mbox queue	*/
	int			nmclass;	/*!< number of handlers */
	struct {
		bfa_ioc_mbox_mcfunc_t	cbfn;	/*!< message handlers	*/
		void			*cbarg;
	} mbhdlr[BFI_MC_MAX];
};

/**
 * IOC callback function interfaces
 */
typedef void (*bfa_ioc_enable_cbfn_t)(void *bfa, enum bfa_status status);
typedef void (*bfa_ioc_disable_cbfn_t)(void *bfa);
typedef void (*bfa_ioc_hbfail_cbfn_t)(void *bfa);
typedef void (*bfa_ioc_reset_cbfn_t)(void *bfa);
struct bfa_ioc_cbfn {
	bfa_ioc_enable_cbfn_t	enable_cbfn;
	bfa_ioc_disable_cbfn_t	disable_cbfn;
	bfa_ioc_hbfail_cbfn_t	hbfail_cbfn;
	bfa_ioc_reset_cbfn_t	reset_cbfn;
};

/**
 * Heartbeat failure notification queue element.
 */
struct bfa_ioc_hbfail_notify {
	struct list_head	qe;
	bfa_ioc_hbfail_cbfn_t	cbfn;
	void			*cbarg;
};

/**
 * Initialize a heartbeat failure notification structure
 */
#define bfa_ioc_hbfail_init(__notify, __cbfn, __cbarg) do {	\
	(__notify)->cbfn = (__cbfn);				\
	(__notify)->cbarg = (__cbarg);				\
} while (0)

struct bfa_ioc {
	bfa_fsm_t		fsm;
	struct bfa 		*bfa;
	struct bfa_pcidev 	pcidev;
	struct bfa_timer_mod	*timer_mod;
	struct timer_list 	ioc_timer;
	struct timer_list 	sem_timer;
	struct timer_list	hb_timer;
	u32			hb_count;
	u32			retry_count;
	struct list_head	hb_notify_q;
	void			*dbg_fwsave;
	int			dbg_fwsave_len;
	bool			dbg_fwsave_once;
	enum bfi_mclass		ioc_mc;
	struct bfa_ioc_regs 	ioc_regs;
	struct bfa_ioc_drv_stats stats;
	bool			auto_recover;
	bool			fcmode;
	bool			ctdev;
	bool			cna;
	bool			pllinit;
	bool   			stats_busy;	/*!< outstanding stats */
	u8			port_id;

	struct bfa_dma		attr_dma;
	struct bfi_ioc_attr	*attr;
	struct bfa_ioc_cbfn	*cbfn;
	struct bfa_ioc_mbox_mod	mbox_mod;
	struct bfa_ioc_hwif	*ioc_hwif;
};

struct bfa_ioc_hwif {
	enum bfa_status (*ioc_pll_init) (void __iomem *rb, bool fcmode);
	bool		(*ioc_firmware_lock)	(struct bfa_ioc *ioc);
	void		(*ioc_firmware_unlock)	(struct bfa_ioc *ioc);
	void		(*ioc_reg_init)	(struct bfa_ioc *ioc);
	void		(*ioc_map_port)	(struct bfa_ioc *ioc);
	void		(*ioc_isr_mode_set)	(struct bfa_ioc *ioc,
					bool msix);
	void		(*ioc_notify_hbfail)	(struct bfa_ioc *ioc);
	void		(*ioc_ownership_reset)	(struct bfa_ioc *ioc);
};

#define bfa_ioc_pcifn(__ioc)		((__ioc)->pcidev.pci_func)
#define bfa_ioc_devid(__ioc)		((__ioc)->pcidev.device_id)
#define bfa_ioc_bar0(__ioc)		((__ioc)->pcidev.pci_bar_kva)
#define bfa_ioc_portid(__ioc)		((__ioc)->port_id)
#define bfa_ioc_fetch_stats(__ioc, __stats) \
		(((__stats)->drv_stats) = (__ioc)->stats)
#define bfa_ioc_clr_stats(__ioc)	\
		memset(&(__ioc)->stats, 0, sizeof((__ioc)->stats))
#define bfa_ioc_maxfrsize(__ioc)	((__ioc)->attr->maxfrsize)
#define bfa_ioc_rx_bbcredit(__ioc)	((__ioc)->attr->rx_bbcredit)
#define bfa_ioc_speed_sup(__ioc)	\
	BFI_ADAPTER_GETP(SPEED, (__ioc)->attr->adapter_prop)
#define bfa_ioc_get_nports(__ioc)	\
	BFI_ADAPTER_GETP(NPORTS, (__ioc)->attr->adapter_prop)

#define bfa_ioc_stats(_ioc, _stats)	((_ioc)->stats._stats++)
#define BFA_IOC_FWIMG_MINSZ	(16 * 1024)
#define BFA_IOC_FWIMG_TYPE(__ioc)					\
	(((__ioc)->ctdev) ? 						\
	 (((__ioc)->fcmode) ? BFI_IMAGE_CT_FC : BFI_IMAGE_CT_CNA) :	\
	 BFI_IMAGE_CB_FC)
#define BFA_IOC_FW_SMEM_SIZE(__ioc)					\
	(((__ioc)->ctdev) ? BFI_SMEM_CT_SIZE : BFI_SMEM_CB_SIZE)
#define BFA_IOC_FLASH_CHUNK_NO(off)		(off / BFI_FLASH_CHUNK_SZ_WORDS)
#define BFA_IOC_FLASH_OFFSET_IN_CHUNK(off)	(off % BFI_FLASH_CHUNK_SZ_WORDS)
#define BFA_IOC_FLASH_CHUNK_ADDR(chunkno)  (chunkno * BFI_FLASH_CHUNK_SZ_WORDS)

/**
 * IOC mailbox interface
 */
242 243 244
void bfa_nw_ioc_mbox_queue(struct bfa_ioc *ioc, struct bfa_mbox_cmd *cmd);
void bfa_nw_ioc_mbox_isr(struct bfa_ioc *ioc);
void bfa_nw_ioc_mbox_regisr(struct bfa_ioc *ioc, enum bfi_mclass mc,
245 246 247 248 249 250 251 252 253 254 255 256 257 258 259
		bfa_ioc_mbox_mcfunc_t cbfn, void *cbarg);

/**
 * IOC interfaces
 */

#define bfa_ioc_pll_init_asic(__ioc) \
	((__ioc)->ioc_hwif->ioc_pll_init((__ioc)->pcidev.pci_bar_kva, \
			   (__ioc)->fcmode))

#define	bfa_ioc_isr_mode_set(__ioc, __msix)			\
			((__ioc)->ioc_hwif->ioc_isr_mode_set(__ioc, __msix))
#define	bfa_ioc_ownership_reset(__ioc)				\
			((__ioc)->ioc_hwif->ioc_ownership_reset(__ioc))

260
void bfa_nw_ioc_set_ct_hwif(struct bfa_ioc *ioc);
261

262
void bfa_nw_ioc_attach(struct bfa_ioc *ioc, void *bfa,
263
		struct bfa_ioc_cbfn *cbfn);
264 265 266
void bfa_nw_ioc_auto_recover(bool auto_recover);
void bfa_nw_ioc_detach(struct bfa_ioc *ioc);
void bfa_nw_ioc_pci_init(struct bfa_ioc *ioc, struct bfa_pcidev *pcidev,
267
		enum bfi_mclass mc);
268 269 270 271 272 273 274 275 276
u32 bfa_nw_ioc_meminfo(void);
void bfa_nw_ioc_mem_claim(struct bfa_ioc *ioc,  u8 *dm_kva, u64 dm_pa);
void bfa_nw_ioc_enable(struct bfa_ioc *ioc);
void bfa_nw_ioc_disable(struct bfa_ioc *ioc);

void bfa_nw_ioc_error_isr(struct bfa_ioc *ioc);

void bfa_nw_ioc_get_attr(struct bfa_ioc *ioc, struct bfa_ioc_attr *ioc_attr);
void bfa_nw_ioc_hbfail_register(struct bfa_ioc *ioc,
277
	struct bfa_ioc_hbfail_notify *notify);
278 279 280 281
bool bfa_nw_ioc_sem_get(void __iomem *sem_reg);
void bfa_nw_ioc_sem_release(void __iomem *sem_reg);
void bfa_nw_ioc_hw_sem_release(struct bfa_ioc *ioc);
void bfa_nw_ioc_fwver_get(struct bfa_ioc *ioc,
282
			struct bfi_ioc_image_hdr *fwhdr);
283
bool bfa_nw_ioc_fwver_cmp(struct bfa_ioc *ioc,
284
			struct bfi_ioc_image_hdr *fwhdr);
285
mac_t bfa_nw_ioc_get_mac(struct bfa_ioc *ioc);
286 287 288 289

/*
 * Timeout APIs
 */
290 291 292
void bfa_nw_ioc_timeout(void *ioc);
void bfa_nw_ioc_hb_check(void *ioc);
void bfa_nw_ioc_sem_timeout(void *ioc);
293 294 295 296 297 298 299 300

/*
 * F/W Image Size & Chunk
 */
u32 *bfa_cb_image_get_chunk(int type, u32 off);
u32 bfa_cb_image_get_size(int type);

#endif /* __BFA_IOC_H__ */