bfa_ioc.h 11.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/*
 * 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__

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

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

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

#define BFA_DMA_ALIGN_SZ	256

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

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

66 67 68 69 70 71 72 73 74 75
#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);
}

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

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

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

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

136
/* IOC event notification mechanism. */
137 138 139 140 141 142 143 144 145 146 147 148 149 150
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;
};

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

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

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

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

225 226 227 228 229 230
};

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

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

264
/* IOC interfaces */
265 266 267

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

270 271 272 273
#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)
274 275 276
#define	bfa_ioc_ownership_reset(__ioc)				\
			((__ioc)->ioc_hwif->ioc_ownership_reset(__ioc))

277 278 279 280 281
#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)

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

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

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

/*
 * F/W Image Size & Chunk
 */
327 328
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);
329

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

368
#endif /* __BFA_IOC_H__ */