Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 55c11941 authored by Merav Sicron's avatar Merav Sicron Committed by David S. Miller
Browse files

bnx2x: Support loading cnic resources at run-time



This patch replaces the BCM_CNIC define with a flag which can change at run-time
and which does not use the CONFIG_CNIC kconfig option.
For the PF/hypervisor driver cnic is always supported, however allocation of
cnic resources and configuration of the HW for offload mode is done only when
the cnic module registers bnx2x.

Signed-off-by: default avatarMerav Sicron <meravs@broadcom.com>
Signed-off-by: default avatarDmitry Kravkov <dmitry@broadcom.com>
Signed-off-by: default avatarEilon Greenstein <eilong@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent babc6727
Loading
Loading
Loading
Loading
+83 −49
Original line number Diff line number Diff line
@@ -34,18 +34,10 @@

#include "bnx2x_hsi.h"

#if defined(CONFIG_CNIC) || defined(CONFIG_CNIC_MODULE)
#define BCM_CNIC 1
#include "../cnic_if.h"
#endif

#ifdef BCM_CNIC
#define BNX2X_MIN_MSIX_VEC_CNT 3
#define BNX2X_MSIX_VEC_FP_START 2
#else
#define BNX2X_MIN_MSIX_VEC_CNT 2
#define BNX2X_MSIX_VEC_FP_START 1
#endif

#define BNX2X_MIN_MSIX_VEC_CNT(bp)		((bp)->min_msix_vec_cnt)

#include <linux/mdio.h>

@@ -256,15 +248,10 @@ enum {
	/* FCoE L2 */
#define	BNX2X_FCOE_ETH_CID(bp)		(BNX2X_CNIC_START_ETH_CID(bp) + 1)

/** Additional rings budgeting */
#ifdef BCM_CNIC
#define CNIC_PRESENT			1
#define FCOE_PRESENT			1
#else
#define CNIC_PRESENT			0
#define FCOE_PRESENT			0
#endif /* BCM_CNIC */
#define NON_ETH_CONTEXT_USE	(FCOE_PRESENT)
#define CNIC_SUPPORT(bp)		((bp)->cnic_support)
#define CNIC_ENABLED(bp)		((bp)->cnic_enabled)
#define CNIC_LOADED(bp)			((bp)->cnic_loaded)
#define FCOE_INIT(bp)			((bp)->fcoe_init)

#define AEU_IN_ATTN_BITS_PXPPCICLOCKCLIENT_PARITY_ERROR \
	AEU_INPUTS_ATTN_BITS_PXPPCICLOCKCLIENT_PARITY_ERROR
@@ -297,9 +284,7 @@ enum {
	OOO_TXQ_IDX_OFFSET,
};
#define MAX_ETH_TXQ_IDX(bp)	(BNX2X_NUM_NON_CNIC_QUEUES(bp) * (bp)->max_cos)
#ifdef BCM_CNIC
#define FCOE_TXQ_IDX(bp)	(MAX_ETH_TXQ_IDX(bp) + FCOE_TXQ_IDX_OFFSET)
#endif

/* fast path */
/*
@@ -585,15 +570,9 @@ struct bnx2x_fastpath {
						->var)


#define IS_ETH_FP(fp)			(fp->index < \
					 BNX2X_NUM_ETH_QUEUES(fp->bp))
#ifdef BCM_CNIC
#define IS_FCOE_FP(fp)			(fp->index == FCOE_IDX(fp->bp))
#define IS_ETH_FP(fp)		((fp)->index < BNX2X_NUM_ETH_QUEUES((fp)->bp))
#define IS_FCOE_FP(fp)		((fp)->index == FCOE_IDX((fp)->bp))
#define IS_FCOE_IDX(idx)	((idx) == FCOE_IDX(bp))
#else
#define IS_FCOE_FP(fp)		false
#define IS_FCOE_IDX(idx)	false
#endif


/* MC hsi */
@@ -886,6 +865,18 @@ struct bnx2x_common {
					 (CHIP_REV(bp) == CHIP_REV_Bx))
#define CHIP_IS_E3A0(bp)		(CHIP_IS_E3(bp) && \
					 (CHIP_REV(bp) == CHIP_REV_Ax))
/* This define is used in two main places:
 * 1. In the early stages of nic_load, to know if to configrue Parser / Searcher
 * to nic-only mode or to offload mode. Offload mode is configured if either the
 * chip is E1x (where MIC_MODE register is not applicable), or if cnic already
 * registered for this port (which means that the user wants storage services).
 * 2. During cnic-related load, to know if offload mode is already configured in
 * the HW or needs to be configrued.
 * Since the transition from nic-mode to offload-mode in HW causes traffic
 * coruption, nic-mode is configured only in ports on which storage services
 * where never requested.
 */
#define CONFIGURE_NIC_MODE(bp)		(!CHIP_IS_E1x(bp) && !CNIC_ENABLED(bp))

	int			flash_size;
#define BNX2X_NVRAM_1MB_SIZE			0x20000	/* 1M bit in bytes */
@@ -1003,18 +994,15 @@ union cdu_context {
#define CDU_ILT_PAGE_SZ		(8192 << CDU_ILT_PAGE_SZ_HW) /* 32K */
#define ILT_PAGE_CIDS		(CDU_ILT_PAGE_SZ / sizeof(union cdu_context))

#ifdef BCM_CNIC
#define CNIC_ISCSI_CID_MAX	256
#define CNIC_FCOE_CID_MAX	2048
#define CNIC_CID_MAX		(CNIC_ISCSI_CID_MAX + CNIC_FCOE_CID_MAX)
#define CNIC_ILT_LINES		DIV_ROUND_UP(CNIC_CID_MAX, ILT_PAGE_CIDS)
#endif

#define QM_ILT_PAGE_SZ_HW	0
#define QM_ILT_PAGE_SZ		(4096 << QM_ILT_PAGE_SZ_HW) /* 4K */
#define QM_CID_ROUND		1024

#ifdef BCM_CNIC
/* TM (timers) host DB constants */
#define TM_ILT_PAGE_SZ_HW	0
#define TM_ILT_PAGE_SZ		(4096 << TM_ILT_PAGE_SZ_HW) /* 4K */
@@ -1032,8 +1020,6 @@ union cdu_context {
#define SRC_T2_SZ		SRC_ILT_SZ
#define SRC_ILT_LINES		DIV_ROUND_UP(SRC_ILT_SZ, SRC_ILT_PAGE_SZ)

#endif

#define MAX_DMAE_C		8

/* DMA memory not used in fastpath */
@@ -1227,7 +1213,6 @@ struct bnx2x {
	struct bnx2x_sp_objs	*sp_objs;
	struct bnx2x_fp_stats	*fp_stats;
	struct bnx2x_fp_txdata	*bnx2x_txq;
	int			bnx2x_txq_size;
	void __iomem		*regview;
	void __iomem		*doorbells;
	u16			db_size;
@@ -1350,6 +1335,15 @@ struct bnx2x {
#define NO_ISCSI_OOO(bp)	((bp)->flags & NO_ISCSI_OOO_FLAG)
#define NO_FCOE(bp)		((bp)->flags & NO_FCOE_FLAG)

	u8			cnic_support;
	bool			cnic_enabled;
	bool			cnic_loaded;

	/* Flag that indicates that we can start looking for FCoE L2 queue
	 * completions in the default status block.
	 */
	bool			fcoe_init;

	int			pm_cap;
	int			mrrs;

@@ -1420,6 +1414,8 @@ struct bnx2x {
#define BNX2X_MAX_COS			3
#define BNX2X_MAX_TX_COS		2
	int			num_queues;
	uint			num_ethernet_queues;
	uint			num_cnic_queues;
	int			num_napi_queues;
	int			disable_tpa;

@@ -1433,6 +1429,7 @@ struct bnx2x {
	u8			igu_dsb_id;
	u8			igu_base_sb;
	u8			igu_sb_cnt;
	u8			min_msix_vec_cnt;

	dma_addr_t		def_status_blk_mapping;

@@ -1478,16 +1475,16 @@ struct bnx2x {
 * Maximum supported number of RSS queues: number of IGU SBs minus one that goes
 * to CNIC.
 */
#define BNX2X_MAX_RSS_COUNT(bp)	((bp)->igu_sb_cnt - CNIC_PRESENT)
#define BNX2X_MAX_RSS_COUNT(bp)	((bp)->igu_sb_cnt - CNIC_SUPPORT(bp))

/*
 * Maximum CID count that might be required by the bnx2x:
 * Max RSS * Max_Tx_Multi_Cos + FCoE + iSCSI
 */
#define BNX2X_L2_CID_COUNT(bp)	(BNX2X_NUM_ETH_QUEUES(bp) * BNX2X_MULTI_TX_COS \
				+ NON_ETH_CONTEXT_USE + CNIC_PRESENT)
				+ 2 * CNIC_SUPPORT(bp))
#define BNX2X_L2_MAX_CID(bp)	(BNX2X_MAX_RSS_COUNT(bp) * BNX2X_MULTI_TX_COS \
				+ NON_ETH_CONTEXT_USE + CNIC_PRESENT)
				+ 2 * CNIC_SUPPORT(bp))
#define L2_ILT_LINES(bp)	(DIV_ROUND_UP(BNX2X_L2_CID_COUNT(bp),\
					ILT_PAGE_CIDS))

@@ -1495,9 +1492,6 @@ struct bnx2x {

	int			dropless_fc;

#ifdef BCM_CNIC
	u32			cnic_flags;
#define BNX2X_CNIC_FLAG_MAC_SET		1
	void			*t2;
	dma_addr_t		t2_mapping;
	struct cnic_ops	__rcu	*cnic_ops;
@@ -1518,7 +1512,6 @@ struct bnx2x {

	/* Start index of the "special" (CNIC related) L2 cleints */
	u8				cnic_base_cl_id;
#endif

	int			dmae_ready;
	/* used to synchronize dmae accesses */
@@ -1647,9 +1640,9 @@ struct bnx2x {
/* Tx queues may be less or equal to Rx queues */
extern int num_queues;
#define BNX2X_NUM_QUEUES(bp)	(bp->num_queues)
#define BNX2X_NUM_ETH_QUEUES(bp) (BNX2X_NUM_QUEUES(bp) - NON_ETH_CONTEXT_USE)
#define BNX2X_NUM_ETH_QUEUES(bp) ((bp)->num_ethernet_queues)
#define BNX2X_NUM_NON_CNIC_QUEUES(bp)	(BNX2X_NUM_QUEUES(bp) - \
					 NON_ETH_CONTEXT_USE)
					 (bp)->num_cnic_queues)
#define BNX2X_NUM_RX_QUEUES(bp)	BNX2X_NUM_QUEUES(bp)

#define is_multi(bp)		(BNX2X_NUM_QUEUES(bp) > 1)
@@ -1689,6 +1682,13 @@ struct bnx2x_func_init_params {
	u16		spq_prod;	/* valid iff FUNC_FLG_SPQ */
};

#define for_each_cnic_queue(bp, var) \
	for ((var) = BNX2X_NUM_ETH_QUEUES(bp); (var) < BNX2X_NUM_QUEUES(bp); \
	     (var)++) \
		if (skip_queue(bp, var))	\
			continue;		\
		else

#define for_each_eth_queue(bp, var) \
	for ((var) = 0; (var) < BNX2X_NUM_ETH_QUEUES(bp); (var)++)

@@ -1702,6 +1702,22 @@ struct bnx2x_func_init_params {
		else

/* Skip forwarding FP */
#define for_each_valid_rx_queue(bp, var)			\
	for ((var) = 0;						\
	     (var) < (CNIC_LOADED(bp) ? BNX2X_NUM_QUEUES(bp) :	\
		      BNX2X_NUM_ETH_QUEUES(bp));		\
	     (var)++)						\
		if (skip_rx_queue(bp, var))			\
			continue;				\
		else

#define for_each_rx_queue_cnic(bp, var) \
	for ((var) = BNX2X_NUM_ETH_QUEUES(bp); (var) < BNX2X_NUM_QUEUES(bp); \
	     (var)++) \
		if (skip_rx_queue(bp, var))	\
			continue;		\
		else

#define for_each_rx_queue(bp, var) \
	for ((var) = 0; (var) < BNX2X_NUM_QUEUES(bp); (var)++) \
		if (skip_rx_queue(bp, var))	\
@@ -1709,6 +1725,22 @@ struct bnx2x_func_init_params {
		else

/* Skip OOO FP */
#define for_each_valid_tx_queue(bp, var)			\
	for ((var) = 0;						\
	     (var) < (CNIC_LOADED(bp) ? BNX2X_NUM_QUEUES(bp) :	\
		      BNX2X_NUM_ETH_QUEUES(bp));		\
	     (var)++)						\
		if (skip_tx_queue(bp, var))			\
			continue;				\
		else

#define for_each_tx_queue_cnic(bp, var) \
	for ((var) = BNX2X_NUM_ETH_QUEUES(bp); (var) < BNX2X_NUM_QUEUES(bp); \
	     (var)++) \
		if (skip_tx_queue(bp, var))	\
			continue;		\
		else

#define for_each_tx_queue(bp, var) \
	for ((var) = 0; (var) < BNX2X_NUM_QUEUES(bp); (var)++) \
		if (skip_tx_queue(bp, var))	\
@@ -2179,7 +2211,6 @@ void bnx2x_notify_link_changed(struct bnx2x *bp);
#define BNX2X_MF_SD_PROTOCOL(bp) \
	((bp)->mf_config[BP_VN(bp)] & FUNC_MF_CFG_PROTOCOL_MASK)

#ifdef BCM_CNIC
#define BNX2X_IS_MF_SD_PROTOCOL_ISCSI(bp) \
	(BNX2X_MF_SD_PROTOCOL(bp) == FUNC_MF_CFG_PROTOCOL_ISCSI)

@@ -2196,9 +2227,12 @@ void bnx2x_notify_link_changed(struct bnx2x *bp);
#define IS_MF_STORAGE_SD(bp) (IS_MF_SD(bp) && \
				(BNX2X_IS_MF_SD_PROTOCOL_ISCSI(bp) || \
				 BNX2X_IS_MF_SD_PROTOCOL_FCOE(bp)))
#else
#define IS_MF_FCOE_AFEX(bp)	false
#endif

enum {
	SWITCH_UPDATE,
	AFEX_UPDATE,
};

#define NUM_MACS	8

#endif /* bnx2x.h */
+313 −147

File changed.

Preview size limit exceeded, changes collapsed.

+65 −22
Original line number Diff line number Diff line
@@ -238,7 +238,6 @@ irqreturn_t bnx2x_msix_sp_int(int irq, void *dev_instance);
 * @dev_instance:	private instance
 */
irqreturn_t bnx2x_interrupt(int irq, void *dev_instance);
#ifdef BCM_CNIC

/**
 * bnx2x_cnic_notify - send command to cnic driver
@@ -262,8 +261,6 @@ void bnx2x_setup_cnic_irq_info(struct bnx2x *bp);
 */
void bnx2x_setup_cnic_info(struct bnx2x *bp);

#endif

/**
 * bnx2x_int_enable - enable HW interrupts.
 *
@@ -283,7 +280,7 @@ void bnx2x_int_enable(struct bnx2x *bp);
void bnx2x_int_disable_sync(struct bnx2x *bp, int disable_hw);

/**
 * bnx2x_nic_init - init driver internals.
 * bnx2x_nic_init_cnic - init driver internals for cnic.
 *
 * @bp:		driver handle
 * @load_code:	COMMON, PORT or FUNCTION
@@ -293,8 +290,25 @@ void bnx2x_int_disable_sync(struct bnx2x *bp, int disable_hw);
 *  - status blocks
 *  - etc.
 */
void bnx2x_nic_init(struct bnx2x *bp, u32 load_code);
void bnx2x_nic_init_cnic(struct bnx2x *bp);

/**
 * bnx2x_nic_init - init driver internals.
 *
 * @bp:		driver handle
 *
 * Initializes:
 *  - rings
 *  - status blocks
 *  - etc.
 */
void bnx2x_nic_init(struct bnx2x *bp, u32 load_code);
/**
 * bnx2x_alloc_mem_cnic - allocate driver's memory for cnic.
 *
 * @bp:		driver handle
 */
int bnx2x_alloc_mem_cnic(struct bnx2x *bp);
/**
 * bnx2x_alloc_mem - allocate driver's memory.
 *
@@ -302,6 +316,12 @@ void bnx2x_nic_init(struct bnx2x *bp, u32 load_code);
 */
int bnx2x_alloc_mem(struct bnx2x *bp);

/**
 * bnx2x_free_mem_cnic - release driver's memory for cnic.
 *
 * @bp:		driver handle
 */
void bnx2x_free_mem_cnic(struct bnx2x *bp);
/**
 * bnx2x_free_mem - release driver's memory.
 *
@@ -407,6 +427,7 @@ bool bnx2x_reset_is_done(struct bnx2x *bp, int engine);
void bnx2x_set_reset_in_progress(struct bnx2x *bp);
void bnx2x_set_reset_global(struct bnx2x *bp);
void bnx2x_disable_close_the_gate(struct bnx2x *bp);
int bnx2x_init_hw_func_cnic(struct bnx2x *bp);

/**
 * bnx2x_sp_event - handle ramrods completion.
@@ -423,6 +444,14 @@ void bnx2x_sp_event(struct bnx2x_fastpath *fp, union eth_rx_cqe *rr_cqe);
 */
void bnx2x_ilt_set_info(struct bnx2x *bp);

/**
 * bnx2x_ilt_set_cnic_info - prepare ILT configurations for SRC
 * and TM.
 *
 * @bp:		driver handle
 */
void bnx2x_ilt_set_info_cnic(struct bnx2x *bp);

/**
 * bnx2x_dcbx_init - initialize dcbx protocol.
 *
@@ -491,12 +520,17 @@ int bnx2x_resume(struct pci_dev *pdev);
/* Release IRQ vectors */
void bnx2x_free_irq(struct bnx2x *bp);

void bnx2x_free_fp_mem_cnic(struct bnx2x *bp);
void bnx2x_free_fp_mem(struct bnx2x *bp);
int bnx2x_alloc_fp_mem_cnic(struct bnx2x *bp);
int bnx2x_alloc_fp_mem(struct bnx2x *bp);
void bnx2x_init_rx_rings(struct bnx2x *bp);
void bnx2x_init_rx_rings_cnic(struct bnx2x *bp);
void bnx2x_free_skbs_cnic(struct bnx2x *bp);
void bnx2x_free_skbs(struct bnx2x *bp);
void bnx2x_netif_stop(struct bnx2x *bp, int disable_hw);
void bnx2x_netif_start(struct bnx2x *bp);
int bnx2x_load_cnic(struct bnx2x *bp);

/**
 * bnx2x_enable_msix - set msix configuration.
@@ -547,7 +581,7 @@ void bnx2x_free_mem_bp(struct bnx2x *bp);
 */
int bnx2x_change_mtu(struct net_device *dev, int new_mtu);

#if defined(NETDEV_FCOE_WWNN) && defined(BCM_CNIC)
#ifdef NETDEV_FCOE_WWNN
/**
 * bnx2x_fcoe_get_wwn - return the requested WWN value for this port
 *
@@ -793,23 +827,39 @@ static inline void bnx2x_free_rx_sge(struct bnx2x *bp,
	sge->addr_lo = 0;
}

static inline void bnx2x_add_all_napi(struct bnx2x *bp)
static inline void bnx2x_add_all_napi_cnic(struct bnx2x *bp)
{
	int i;

	bp->num_napi_queues = bp->num_queues;
	/* Add NAPI objects */
	for_each_rx_queue_cnic(bp, i)
		netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi),
			       bnx2x_poll, BNX2X_NAPI_WEIGHT);
}

static inline void bnx2x_add_all_napi(struct bnx2x *bp)
{
	int i;

	/* Add NAPI objects */
	for_each_rx_queue(bp, i)
	for_each_eth_queue(bp, i)
		netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi),
			       bnx2x_poll, BNX2X_NAPI_WEIGHT);
}

static inline void bnx2x_del_all_napi_cnic(struct bnx2x *bp)
{
	int i;

	for_each_rx_queue_cnic(bp, i)
		netif_napi_del(&bnx2x_fp(bp, i, napi));
}

static inline void bnx2x_del_all_napi(struct bnx2x *bp)
{
	int i;

	for_each_rx_queue(bp, i)
	for_each_eth_queue(bp, i)
		netif_napi_del(&bnx2x_fp(bp, i, napi));
}

@@ -979,11 +1029,9 @@ static inline u8 bnx2x_stats_id(struct bnx2x_fastpath *fp)
{
	struct bnx2x *bp = fp->bp;
	if (!CHIP_IS_E1x(bp)) {
#ifdef BCM_CNIC
		/* there are special statistics counters for FCoE 136..140 */
		if (IS_FCOE_FP(fp))
			return bp->cnic_base_cl_id + (bp->pf_num >> 1);
#endif
		return fp->cl_id;
	}
	return fp->cl_id + BP_PORT(bp) * FP_SB_MAX_E1x;
@@ -1102,7 +1150,6 @@ static inline void bnx2x_init_txdata(struct bnx2x *bp,
	   txdata->cid, txdata->txq_index);
}

#ifdef BCM_CNIC
static inline u8 bnx2x_cnic_eth_cl_id(struct bnx2x *bp, u8 cl_idx)
{
	return bp->cnic_base_cl_id + cl_idx +
@@ -1162,7 +1209,6 @@ static inline void bnx2x_init_fcoe_fp(struct bnx2x *bp)
	   fp->index, bp, fp->status_blk.e2_sb, fp->cl_id, fp->fw_sb_id,
	   fp->igu_sb_id);
}
#endif

static inline int bnx2x_clean_tx_queue(struct bnx2x *bp,
				       struct bnx2x_fp_txdata *txdata)
@@ -1280,7 +1326,7 @@ static inline bool bnx2x_mtu_allows_gro(int mtu)
	 */
	return mtu <= SGE_PAGE_SIZE && (U_ETH_SGL_SIZE * fpp) <= MAX_SKB_FRAGS;
}
#ifdef BCM_CNIC

/**
 * bnx2x_get_iscsi_info - update iSCSI params according to licensing info.
 *
@@ -1288,7 +1334,6 @@ static inline bool bnx2x_mtu_allows_gro(int mtu)
 *
 */
void bnx2x_get_iscsi_info(struct bnx2x *bp);
#endif

/**
 * bnx2x_link_sync_notify - send notification to other functions.
@@ -1340,13 +1385,11 @@ static inline void bnx2x_update_drv_flags(struct bnx2x *bp, u32 flags, u32 set)

static inline bool bnx2x_is_valid_ether_addr(struct bnx2x *bp, u8 *addr)
{
	if (is_valid_ether_addr(addr))
	if (is_valid_ether_addr(addr) ||
	    (is_zero_ether_addr(addr) &&
	     (IS_MF_STORAGE_SD(bp) || IS_MF_FCOE_AFEX(bp))))
		return true;
#ifdef BCM_CNIC
	if (is_zero_ether_addr(addr) &&
	    (IS_MF_STORAGE_SD(bp) || IS_MF_FCOE_AFEX(bp)))
		return true;
#endif

	return false;
}

+4 −4
Original line number Diff line number Diff line
@@ -1908,10 +1908,10 @@ static void bnx2x_dcbnl_get_perm_hw_addr(struct net_device *netdev,
	/* first the HW mac address */
	memcpy(perm_addr, netdev->dev_addr, netdev->addr_len);

#ifdef BCM_CNIC
	if (CNIC_LOADED(bp))
		/* second SAN address */
	memcpy(perm_addr+netdev->addr_len, bp->fip_mac, netdev->addr_len);
#endif
		memcpy(perm_addr+netdev->addr_len, bp->fip_mac,
		       netdev->addr_len);
}

static void bnx2x_dcbnl_set_pg_tccfg_tx(struct net_device *netdev, int prio,
+3 −1
Original line number Diff line number Diff line
@@ -2901,7 +2901,9 @@ static void bnx2x_get_channels(struct net_device *dev,
static void bnx2x_change_num_queues(struct bnx2x *bp, int num_rss)
{
	bnx2x_disable_msi(bp);
	BNX2X_NUM_QUEUES(bp) = num_rss + NON_ETH_CONTEXT_USE;
	bp->num_ethernet_queues = num_rss;
	bp->num_queues = bp->num_ethernet_queues + bp->num_cnic_queues;
	BNX2X_DEV_INFO("set number of queues to %d\n", bp->num_queues);
	bnx2x_set_int_mode(bp);
}

Loading