bfa_ioc.h 11.9 KB
Newer Older
1
/*
2
 * Linux network driver for QLogic BR-series Converged Network Adapter.
3 4 5 6 7 8 9 10 11 12 13
 *
 * 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.
 */
/*
14 15
 * Copyright (c) 2005-2014 Brocade Communications Systems, Inc.
 * Copyright (c) 2014-2015 QLogic Corporation
16
 * All rights reserved
17
 * www.qlogic.com
18 19 20 21 22
 */

#ifndef __BFA_IOC_H__
#define __BFA_IOC_H__

R
Rasesh Mody 已提交
23
#include "bfa_cs.h"
24 25 26 27 28 29
#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 */
30
#define BFA_IOC_POLL_TOV	200	/* msecs */
K
Krishna Gudipati 已提交
31 32
#define BNA_DBG_FWTRC_LEN      (BFI_IOC_TRC_ENTS * BFI_IOC_TRC_ENT_SZ + \
				BFI_IOC_TRC_HDR_SZ)
33

34
/* PCI device information required by IOC */
35 36 37 38
struct bfa_pcidev {
	int	pci_slot;
	u8	pci_func;
	u16	device_id;
R
Rasesh Mody 已提交
39
	u16	ssid;
40 41 42
	void	__iomem *pci_bar_kva;
};

43
/* Structure used to remember the DMA-able memory block's KVA and Physical
44 45 46 47 48 49 50 51 52
 * Address
 */
struct bfa_dma {
	void	*kva;	/* ! Kernel virtual address	*/
	u64	pa;	/* ! Physical address		*/
};

#define BFA_DMA_ALIGN_SZ	256

53
/* smem size for Crossbow and Catapult */
54 55 56
#define BFI_SMEM_CB_SIZE	0x200000U	/* ! 2MB for crossbow	*/
#define BFI_SMEM_CT_SIZE	0x280000U	/* ! 2.5MB for catapult	*/

57
/* BFA dma address assignment macro. (big endian format) */
58 59 60 61 62 63 64 65 66
#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));
}

67 68 69 70 71 72 73 74 75 76
#define bfa_alen_set(__alen, __len, __pa)	\
	__bfa_alen_set(__alen, __len, (u64)__pa)

static inline void
__bfa_alen_set(struct bfi_alen *alen, u32 len, u64 pa)
{
	alen->al_len = cpu_to_be32(len);
	bfa_dma_be_addr_set(alen->al_addr, pa);
}

77 78 79 80 81
struct bfa_ioc_regs {
	void __iomem *hfn_mbox_cmd;
	void __iomem *hfn_mbox;
	void __iomem *lpu_mbox_cmd;
	void __iomem *lpu_mbox;
82
	void __iomem *lpu_read_stat;
83 84 85 86 87 88 89 90 91 92 93
	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;
R
Rasesh Mody 已提交
94
	void __iomem *alt_ioc_fwstate;
95
	void __iomem *ll_halt;
R
Rasesh Mody 已提交
96
	void __iomem *alt_ll_halt;
97
	void __iomem *err_set;
R
Rasesh Mody 已提交
98
	void __iomem *ioc_fail_sync;
99 100 101 102 103 104
	void __iomem *shirq_isr_next;
	void __iomem *shirq_msk_next;
	void __iomem *smem_page_start;
	u32	smem_pg0;
};

105
/* IOC Mailbox structures */
106
typedef void (*bfa_mbox_cmd_cbfn_t)(void *cbarg);
107 108
struct bfa_mbox_cmd {
	struct list_head	qe;
109 110 111
	bfa_mbox_cmd_cbfn_t     cbfn;
	void		    *cbarg;
	u32     msg[BFI_IOC_MSGSZ];
112 113
};

114
/* IOC mailbox module */
115 116 117 118 119 120 121 122 123 124
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];
};

125
/* IOC callback function interfaces */
126 127 128 129 130 131 132 133 134 135 136
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;
};

137
/* IOC event notification mechanism. */
138 139 140 141 142 143 144 145 146 147 148 149 150 151
enum bfa_ioc_event {
	BFA_IOC_E_ENABLED	= 1,
	BFA_IOC_E_DISABLED	= 2,
	BFA_IOC_E_FAILED	= 3,
};

typedef void (*bfa_ioc_notify_cbfn_t)(void *, enum bfa_ioc_event);

struct bfa_ioc_notify {
	struct list_head	qe;
	bfa_ioc_notify_cbfn_t	cbfn;
	void			*cbarg;
};

152
/* Initialize a IOC event notification structure */
153
#define bfa_ioc_notify_init(__notify, __cbfn, __cbarg) do {	\
154 155 156 157
	(__notify)->cbfn = (__cbfn);				\
	(__notify)->cbarg = (__cbarg);				\
} while (0)

R
Rasesh Mody 已提交
158 159 160
struct bfa_iocpf {
	bfa_fsm_t		fsm;
	struct bfa_ioc		*ioc;
161
	bool			fw_mismatch_notified;
R
Rasesh Mody 已提交
162
	bool			auto_recover;
163
	u32			poll_time;
R
Rasesh Mody 已提交
164 165
};

166 167
struct bfa_ioc {
	bfa_fsm_t		fsm;
R
Rasesh Mody 已提交
168 169 170 171 172
	struct bfa		*bfa;
	struct bfa_pcidev	pcidev;
	struct timer_list	ioc_timer;
	struct timer_list	iocpf_timer;
	struct timer_list	sem_timer;
173 174
	struct timer_list	hb_timer;
	u32			hb_count;
175
	struct list_head	notify_q;
176 177 178
	void			*dbg_fwsave;
	int			dbg_fwsave_len;
	bool			dbg_fwsave_once;
179
	enum bfi_pcifn_class	clscode;
R
Rasesh Mody 已提交
180
	struct bfa_ioc_regs	ioc_regs;
181 182 183
	struct bfa_ioc_drv_stats stats;
	bool			fcmode;
	bool			pllinit;
R
Rasesh Mody 已提交
184
	bool			stats_busy;	/*!< outstanding stats */
185 186 187 188 189 190
	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;
191
	const struct bfa_ioc_hwif *ioc_hwif;
R
Rasesh Mody 已提交
192
	struct bfa_iocpf	iocpf;
193 194 195 196 197 198 199
	enum bfi_asic_gen	asic_gen;
	enum bfi_asic_mode	asic_mode;
	enum bfi_port_mode	port0_mode;
	enum bfi_port_mode	port1_mode;
	enum bfa_mode		port_mode;
	u8			ad_cap_bm;	/*!< adapter cap bit mask */
	u8			port_mode_cfg;	/*!< config port mode */
200 201 202
};

struct bfa_ioc_hwif {
203 204
	enum bfa_status (*ioc_pll_init) (void __iomem *rb,
						enum bfi_asic_mode m);
205 206 207 208 209 210
	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);
R
Rasesh Mody 已提交
211
	void		(*ioc_notify_fail)	(struct bfa_ioc *ioc);
212
	void		(*ioc_ownership_reset)	(struct bfa_ioc *ioc);
213
	bool		(*ioc_sync_start)       (struct bfa_ioc *ioc);
R
Rasesh Mody 已提交
214 215 216 217
	void		(*ioc_sync_join)	(struct bfa_ioc *ioc);
	void		(*ioc_sync_leave)	(struct bfa_ioc *ioc);
	void		(*ioc_sync_ack)		(struct bfa_ioc *ioc);
	bool		(*ioc_sync_complete)	(struct bfa_ioc *ioc);
218
	bool		(*ioc_lpu_read_stat)	(struct bfa_ioc *ioc);
R
Rasesh Mody 已提交
219 220 221 222 223 224 225
	void		(*ioc_set_fwstate)	(struct bfa_ioc *ioc,
					enum bfi_ioc_state fwstate);
	enum bfi_ioc_state (*ioc_get_fwstate) (struct bfa_ioc *ioc);
	void		(*ioc_set_alt_fwstate)	(struct bfa_ioc *ioc,
					enum bfi_ioc_state fwstate);
	enum bfi_ioc_state (*ioc_get_alt_fwstate) (struct bfa_ioc *ioc);

226 227 228 229 230 231
};

#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)
232
#define bfa_ioc_asic_gen(__ioc)		((__ioc)->asic_gen)
233 234
#define bfa_ioc_is_default(__ioc)	\
	(bfa_ioc_pcifn(__ioc) == bfa_ioc_portid(__ioc))
235 236 237 238 239 240 241 242 243 244 245 246
#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++)
R
Rasesh Mody 已提交
247 248
#define bfa_ioc_stats_hb_count(_ioc, _hb_count)	\
	((_ioc)->stats.hb_count = (_hb_count))
249 250
#define BFA_IOC_FWIMG_MINSZ	(16 * 1024)
#define BFA_IOC_FW_SMEM_SIZE(__ioc)					\
251 252
	((bfa_ioc_asic_gen(__ioc) == BFI_ASIC_GEN_CB)			\
	? BFI_SMEM_CB_SIZE : BFI_SMEM_CT_SIZE)
253 254 255 256
#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)

257
/* IOC mailbox interface */
R
Rasesh Mody 已提交
258 259 260
bool bfa_nw_ioc_mbox_queue(struct bfa_ioc *ioc,
			struct bfa_mbox_cmd *cmd,
			bfa_mbox_cmd_cbfn_t cbfn, void *cbarg);
261 262
void bfa_nw_ioc_mbox_isr(struct bfa_ioc *ioc);
void bfa_nw_ioc_mbox_regisr(struct bfa_ioc *ioc, enum bfi_mclass mc,
263 264
		bfa_ioc_mbox_mcfunc_t cbfn, void *cbarg);

265
/* IOC interfaces */
266 267 268

#define bfa_ioc_pll_init_asic(__ioc) \
	((__ioc)->ioc_hwif->ioc_pll_init((__ioc)->pcidev.pci_bar_kva, \
269
			   (__ioc)->asic_mode))
270

271 272 273 274
#define	bfa_ioc_isr_mode_set(__ioc, __msix) do {			\
	if ((__ioc)->ioc_hwif->ioc_isr_mode_set)			\
		((__ioc)->ioc_hwif->ioc_isr_mode_set(__ioc, __msix));	\
} while (0)
275 276 277
#define	bfa_ioc_ownership_reset(__ioc)				\
			((__ioc)->ioc_hwif->ioc_ownership_reset(__ioc))

278 279 280 281 282
#define bfa_ioc_lpu_read_stat(__ioc) do {				\
		if ((__ioc)->ioc_hwif->ioc_lpu_read_stat)		\
			((__ioc)->ioc_hwif->ioc_lpu_read_stat(__ioc));	\
} while (0)

283
void bfa_nw_ioc_set_ct_hwif(struct bfa_ioc *ioc);
284
void bfa_nw_ioc_set_ct2_hwif(struct bfa_ioc *ioc);
285
void bfa_nw_ioc_ct2_poweron(struct bfa_ioc *ioc);
286

287
void bfa_nw_ioc_attach(struct bfa_ioc *ioc, void *bfa,
288
		struct bfa_ioc_cbfn *cbfn);
289 290 291
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,
292
		enum bfi_pcifn_class clscode);
293 294 295 296 297 298
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);
299
bool bfa_nw_ioc_is_disabled(struct bfa_ioc *ioc);
K
Krishna Gudipati 已提交
300
bool bfa_nw_ioc_is_operational(struct bfa_ioc *ioc);
301
void bfa_nw_ioc_get_attr(struct bfa_ioc *ioc, struct bfa_ioc_attr *ioc_attr);
R
Rasesh Mody 已提交
302
enum bfa_status bfa_nw_ioc_fwsig_invalidate(struct bfa_ioc *ioc);
303 304
void bfa_nw_ioc_notify_register(struct bfa_ioc *ioc,
	struct bfa_ioc_notify *notify);
305 306 307 308
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,
309
			struct bfi_ioc_image_hdr *fwhdr);
310
bool bfa_nw_ioc_fwver_cmp(struct bfa_ioc *ioc,
311
			struct bfi_ioc_image_hdr *fwhdr);
I
Ivan Vecera 已提交
312
void bfa_nw_ioc_get_mac(struct bfa_ioc *ioc, u8 *mac);
K
Krishna Gudipati 已提交
313 314 315
void bfa_nw_ioc_debug_memclaim(struct bfa_ioc *ioc, void *dbg_fwsave);
int bfa_nw_ioc_debug_fwtrc(struct bfa_ioc *ioc, void *trcdata, int *trclen);
int bfa_nw_ioc_debug_fwsave(struct bfa_ioc *ioc, void *trcdata, int *trclen);
316 317 318 319

/*
 * Timeout APIs
 */
320 321
void bfa_nw_ioc_timeout(void *ioc);
void bfa_nw_ioc_hb_check(void *ioc);
R
Rasesh Mody 已提交
322 323
void bfa_nw_iocpf_timeout(void *ioc);
void bfa_nw_iocpf_sem_timeout(void *ioc);
324 325 326 327

/*
 * F/W Image Size & Chunk
 */
328 329
u32 *bfa_cb_image_get_chunk(enum bfi_asic_gen asic_gen, u32 off);
u32 bfa_cb_image_get_size(enum bfi_asic_gen asic_gen);
330

331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368
/*
 *	Flash module specific
 */
typedef void	(*bfa_cb_flash) (void *cbarg, enum bfa_status status);

struct bfa_flash {
	struct bfa_ioc *ioc;		/* back pointer to ioc */
	u32		type;		/* partition type */
	u8		instance;	/* partition instance */
	u8		rsv[3];
	u32		op_busy;	/*  operation busy flag */
	u32		residue;	/*  residual length */
	u32		offset;		/*  offset */
	enum bfa_status	status;		/*  status */
	u8		*dbuf_kva;	/*  dma buf virtual address */
	u64		dbuf_pa;	/*  dma buf physical address */
	bfa_cb_flash	cbfn;		/*  user callback function */
	void		*cbarg;		/*  user callback arg */
	u8		*ubuf;		/*  user supplied buffer */
	u32		addr_off;	/*  partition address offset */
	struct bfa_mbox_cmd mb;		/*  mailbox */
	struct bfa_ioc_notify ioc_notify; /*  ioc event notify */
};

enum bfa_status bfa_nw_flash_get_attr(struct bfa_flash *flash,
			struct bfa_flash_attr *attr,
			bfa_cb_flash cbfn, void *cbarg);
enum bfa_status bfa_nw_flash_update_part(struct bfa_flash *flash,
			u32 type, u8 instance, void *buf, u32 len, u32 offset,
			bfa_cb_flash cbfn, void *cbarg);
enum bfa_status bfa_nw_flash_read_part(struct bfa_flash *flash,
			u32 type, u8 instance, void *buf, u32 len, u32 offset,
			bfa_cb_flash cbfn, void *cbarg);
u32	bfa_nw_flash_meminfo(void);
void	bfa_nw_flash_attach(struct bfa_flash *flash,
			    struct bfa_ioc *ioc, void *dev);
void	bfa_nw_flash_memclaim(struct bfa_flash *flash, u8 *dm_kva, u64 dm_pa);

369
#endif /* __BFA_IOC_H__ */