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

Commit ec6ba945 authored by Vladislav Zolotarov's avatar Vladislav Zolotarov Committed by David S. Miller
Browse files

bnx2x: add FCoE ring



Includes new driver structures and FW/HW configuration for FCoE ring

Signed-off-by: default avatarVladislav Zolotarov <vladz@broadcom.com>
Signed-off-by: default avatarShmulik Ravid-Rabinovitz <shmulikr@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 a3d22a68
Loading
Loading
Loading
Loading
+108 −10
Original line number Diff line number Diff line
@@ -13,6 +13,8 @@

#ifndef BNX2X_H
#define BNX2X_H
#include <linux/netdevice.h>
#include <linux/types.h>

/* compilation time flags */

@@ -199,10 +201,25 @@ void bnx2x_panic_dump(struct bnx2x *bp);
/* EQ completions */
#define HC_SP_INDEX_EQ_CONS			7

/* FCoE L2 connection completions */
#define HC_SP_INDEX_ETH_FCOE_TX_CQ_CONS		6
#define HC_SP_INDEX_ETH_FCOE_RX_CQ_CONS		4
/* iSCSI L2 */
#define HC_SP_INDEX_ETH_ISCSI_CQ_CONS		5
#define HC_SP_INDEX_ETH_ISCSI_RX_CQ_CONS	1

/* Special clients parameters */

/* SB indices */
/* FCoE L2 */
#define BNX2X_FCOE_L2_RX_INDEX \
	(&bp->def_status_blk->sp_sb.\
	index_values[HC_SP_INDEX_ETH_FCOE_RX_CQ_CONS])

#define BNX2X_FCOE_L2_TX_INDEX \
	(&bp->def_status_blk->sp_sb.\
	index_values[HC_SP_INDEX_ETH_FCOE_TX_CQ_CONS])

/**
 *  CIDs and CLIDs:
 *  CLIDs below is a CLID for func 0, then the CLID for other
@@ -215,12 +232,19 @@ void bnx2x_panic_dump(struct bnx2x *bp);
#define BNX2X_ISCSI_ETH_CL_ID		17
#define BNX2X_ISCSI_ETH_CID		17

/* FCoE L2 */
#define BNX2X_FCOE_ETH_CL_ID		18
#define BNX2X_FCOE_ETH_CID		18

/** Additional rings budgeting */
#ifdef BCM_CNIC
#define CNIC_CONTEXT_USE		1
#define FCOE_CONTEXT_USE		1
#else
#define CNIC_CONTEXT_USE		0
#define FCOE_CONTEXT_USE		0
#endif /* BCM_CNIC */
#define NONE_ETH_CONTEXT_USE	(FCOE_CONTEXT_USE)

#define AEU_IN_ATTN_BITS_PXPPCICLOCKCLIENT_PARITY_ERROR \
	AEU_INPUTS_ATTN_BITS_PXPPCICLOCKCLIENT_PARITY_ERROR
@@ -401,6 +425,17 @@ struct bnx2x_fastpath {
};

#define bnx2x_fp(bp, nr, var)		(bp->fp[nr].var)
#ifdef BCM_CNIC
/* FCoE L2 `fastpath' is right after the eth entries */
#define FCOE_IDX			BNX2X_NUM_ETH_QUEUES(bp)
#define bnx2x_fcoe_fp(bp)		(&bp->fp[FCOE_IDX])
#define bnx2x_fcoe(bp, var)		(bnx2x_fcoe_fp(bp)->var)
#define IS_FCOE_FP(fp)			(fp->index == FCOE_IDX)
#define IS_FCOE_IDX(idx)		((idx) == FCOE_IDX)
#else
#define IS_FCOE_FP(fp)		false
#define IS_FCOE_IDX(idx)	false
#endif


/* MC hsi */
@@ -669,7 +704,9 @@ struct bnx2x_port {
enum {
	CAM_ETH_LINE = 0,
	CAM_ISCSI_ETH_LINE,
	CAM_MAX_PF_LINE = CAM_ISCSI_ETH_LINE
	CAM_FIP_ETH_LINE,
	CAM_FIP_MCAST_LINE,
	CAM_MAX_PF_LINE = CAM_FIP_MCAST_LINE
};
/* number of MACs per function in NIG memory - used for SI mode */
#define NIG_LLH_FUNC_MEM_SIZE		16
@@ -714,6 +751,14 @@ enum {
 */
#define L2_FP_COUNT(cid_cnt)	((cid_cnt) - CNIC_CONTEXT_USE)

/*
 * The number of FP-SB allocated by the driver == max number of regular L2
 * queues + 1 for the CNIC which also consumes an FP-SB
 */
#define FP_SB_COUNT(cid_cnt)	((cid_cnt) - FCOE_CONTEXT_USE)
#define NUM_IGU_SB_REQUIRED(cid_cnt) \
				(FP_SB_COUNT(cid_cnt) - NONE_ETH_CONTEXT_USE)

union cdu_context {
	struct eth_context eth;
	char pad[1024];
@@ -726,7 +771,8 @@ union cdu_context {

#ifdef BCM_CNIC
#define CNIC_ISCSI_CID_MAX	256
#define CNIC_CID_MAX		(CNIC_ISCSI_CID_MAX)
#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

@@ -922,6 +968,10 @@ struct bnx2x {
#define DISABLE_MSI_FLAG		0x200
#define BP_NOMCP(bp)			(bp->flags & NO_MCP_FLAG)
#define MF_FUNC_DIS			0x1000
#define FCOE_MACS_SET			0x2000
#define NO_FCOE_FLAG			0x4000

#define NO_FCOE(bp)		((bp)->flags & NO_FCOE_FLAG)

	int			pf_num;	/* absolute PF number */
	int			pfid;	/* per-path PF number */
@@ -1069,7 +1119,8 @@ struct bnx2x {
	u16			cnic_kwq_pending;
	u16			cnic_spq_pending;
	struct mutex		cnic_mutex;
	u8			iscsi_mac[6];
	u8			iscsi_mac[ETH_ALEN];
	u8			fip_mac[ETH_ALEN];
#endif

	int			dmae_ready;
@@ -1159,10 +1210,17 @@ struct bnx2x {
#define RSS_IPV6_TCP_CAP	0x0008

#define BNX2X_NUM_QUEUES(bp)	(bp->num_queues)
#define BNX2X_NUM_ETH_QUEUES(bp) (BNX2X_NUM_QUEUES(bp) - NONE_ETH_CONTEXT_USE)

/* ethtool statistics are displayed for all regular ethernet queues and the
 * fcoe L2 queue if not disabled
 */
#define BNX2X_NUM_STAT_QUEUES(bp) (NO_FCOE(bp) ? BNX2X_NUM_ETH_QUEUES(bp) : \
			   (BNX2X_NUM_ETH_QUEUES(bp) + FCOE_CONTEXT_USE))

#define is_multi(bp)		(BNX2X_NUM_QUEUES(bp) > 1)

#define BNX2X_MAX_QUEUES(bp)	(bp->igu_sb_cnt - CNIC_CONTEXT_USE)
#define is_eth_multi(bp)	(BNX2X_NUM_ETH_QUEUES(bp) > 1)

#define RSS_IPV4_CAP_MASK						\
	TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_CAPABILITY
@@ -1255,6 +1313,7 @@ struct bnx2x_client_ramrod_params {
	u16 cl_id;
	u32 cid;
	u8 poll;
#define CLIENT_IS_FCOE			0x01
#define CLIENT_IS_LEADING_RSS		0x02
	u8 flags;
};
@@ -1287,11 +1346,54 @@ struct bnx2x_func_init_params {
	u16		spq_prod;	/* valid iff FUNC_FLG_SPQ */
};

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

#define for_each_nondefault_eth_queue(bp, var) \
			for (var = 1; var < BNX2X_NUM_ETH_QUEUES(bp); var++)

#define for_each_napi_queue(bp, var) \
	for (var = 0; \
		var < BNX2X_NUM_ETH_QUEUES(bp) + FCOE_CONTEXT_USE; var++) \
		if (skip_queue(bp, var))	\
			continue;		\
		else

#define for_each_queue(bp, var) \
			for (var = 0; var < BNX2X_NUM_QUEUES(bp); var++)
	for (var = 0; var < BNX2X_NUM_QUEUES(bp); var++) \
		if (skip_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))	\
			continue;		\
		else

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

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

/* skip rx queue
 * if FCOE l2 support is diabled and this is the fcoe L2 queue
 */
#define skip_rx_queue(bp, idx)	(NO_FCOE(bp) && IS_FCOE_IDX(idx))

/* skip tx queue
 * if FCOE l2 support is diabled and this is the fcoe L2 queue
 */
#define skip_tx_queue(bp, idx)	(NO_FCOE(bp) && IS_FCOE_IDX(idx))

#define skip_queue(bp, idx)	(NO_FCOE(bp) && IS_FCOE_IDX(idx))

#define WAIT_RAMROD_POLL	0x01
#define WAIT_RAMROD_COMMON	0x02
@@ -1615,10 +1717,6 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms,
	MAC_CONFIGURATION_ENTRY_ACTION_TYPE) == \
	(T_ETH_MAC_COMMAND_INVALIDATE))

#define CAM_INVALIDATE(x) \
	(x.target_table_entry.flags = TSTORM_CAM_TARGET_TABLE_ENTRY_ACTION_TYPE)


/* Number of u32 elements in MC hash array */
#define MC_HASH_SIZE			8
#define MC_HASH_OFFSET(bp, i)		(BAR_TSTRORM_INTMEM + \
+64 −17
Original line number Diff line number Diff line
@@ -827,7 +827,7 @@ void bnx2x_init_rx_rings(struct bnx2x *bp)
	DP(NETIF_MSG_IFUP,
	   "mtu %d  rx_buf_size %d\n", bp->dev->mtu, bp->rx_buf_size);

	for_each_queue(bp, j) {
	for_each_rx_queue(bp, j) {
		struct bnx2x_fastpath *fp = &bp->fp[j];

		if (!fp->disable_tpa) {
@@ -880,7 +880,7 @@ void bnx2x_init_rx_rings(struct bnx2x *bp)
		}
	}

	for_each_queue(bp, j) {
	for_each_rx_queue(bp, j) {
		struct bnx2x_fastpath *fp = &bp->fp[j];

		fp->rx_bd_cons = 0;
@@ -911,7 +911,7 @@ static void bnx2x_free_tx_skbs(struct bnx2x *bp)
{
	int i;

	for_each_queue(bp, i) {
	for_each_tx_queue(bp, i) {
		struct bnx2x_fastpath *fp = &bp->fp[i];

		u16 bd_cons = fp->tx_bd_cons;
@@ -929,7 +929,7 @@ static void bnx2x_free_rx_skbs(struct bnx2x *bp)
{
	int i, j;

	for_each_queue(bp, j) {
	for_each_rx_queue(bp, j) {
		struct bnx2x_fastpath *fp = &bp->fp[j];

		for (i = 0; i < NUM_RX_BD; i++) {
@@ -970,7 +970,7 @@ static void bnx2x_free_msix_irqs(struct bnx2x *bp)
#ifdef BCM_CNIC
	offset++;
#endif
	for_each_queue(bp, i) {
	for_each_eth_queue(bp, i) {
		DP(NETIF_MSG_IFDOWN, "about to release fp #%d->%d irq  "
		   "state %x\n", i, bp->msix_table[i + offset].vector,
		   bnx2x_fp(bp, i, state));
@@ -1004,14 +1004,14 @@ int bnx2x_enable_msix(struct bnx2x *bp)
	   bp->msix_table[msix_vec].entry, bp->msix_table[msix_vec].entry);
	msix_vec++;
#endif
	for_each_queue(bp, i) {
	for_each_eth_queue(bp, i) {
		bp->msix_table[msix_vec].entry = msix_vec;
		DP(NETIF_MSG_IFUP, "msix_table[%d].entry = %d "
		   "(fastpath #%u)\n", msix_vec, msix_vec, i);
		msix_vec++;
	}

	req_cnt = BNX2X_NUM_QUEUES(bp) + CNIC_CONTEXT_USE + 1;
	req_cnt = BNX2X_NUM_ETH_QUEUES(bp) + CNIC_CONTEXT_USE + 1;

	rc = pci_enable_msix(bp->pdev, &bp->msix_table[0], req_cnt);

@@ -1067,7 +1067,7 @@ static int bnx2x_req_msix_irqs(struct bnx2x *bp)
#ifdef BCM_CNIC
	offset++;
#endif
	for_each_queue(bp, i) {
	for_each_eth_queue(bp, i) {
		struct bnx2x_fastpath *fp = &bp->fp[i];
		snprintf(fp->name, sizeof(fp->name), "%s-fp-%d",
			 bp->dev->name, i);
@@ -1084,7 +1084,7 @@ static int bnx2x_req_msix_irqs(struct bnx2x *bp)
		fp->state = BNX2X_FP_STATE_IRQ;
	}

	i = BNX2X_NUM_QUEUES(bp);
	i = BNX2X_NUM_ETH_QUEUES(bp);
	offset = 1 + CNIC_CONTEXT_USE;
	netdev_info(bp->dev, "using MSI-X  IRQs: sp %d  fp[%d] %d"
	       " ... fp[%d] %d\n",
@@ -1131,7 +1131,7 @@ static void bnx2x_napi_enable(struct bnx2x *bp)
{
	int i;

	for_each_queue(bp, i)
	for_each_napi_queue(bp, i)
		napi_enable(&bnx2x_fp(bp, i, napi));
}

@@ -1139,7 +1139,7 @@ static void bnx2x_napi_disable(struct bnx2x *bp)
{
	int i;

	for_each_queue(bp, i)
	for_each_napi_queue(bp, i)
		napi_disable(&bnx2x_fp(bp, i, napi));
}

@@ -1181,7 +1181,22 @@ void bnx2x_set_num_queues(struct bnx2x *bp)
		bp->num_queues = 1;
		break;
	}

	/* Add special queues */
	bp->num_queues += NONE_ETH_CONTEXT_USE;
}

#ifdef BCM_CNIC
static inline void bnx2x_set_fcoe_eth_macs(struct bnx2x *bp)
{
	if (!NO_FCOE(bp)) {
		if (!IS_MF_SD(bp))
			bnx2x_set_fip_eth_mac_addr(bp, 1);
		bnx2x_set_all_enode_macs(bp, 1);
		bp->flags |= FCOE_MACS_SET;
	}
}
#endif

static void bnx2x_release_firmware(struct bnx2x *bp)
{
@@ -1191,6 +1206,20 @@ static void bnx2x_release_firmware(struct bnx2x *bp)
	release_firmware(bp->firmware);
}

static inline int bnx2x_set_real_num_queues(struct bnx2x *bp)
{
	int rc, num = bp->num_queues;

#ifdef BCM_CNIC
	if (NO_FCOE(bp))
		num -= FCOE_CONTEXT_USE;

#endif
	netif_set_real_num_tx_queues(bp->dev, num);
	rc = netif_set_real_num_rx_queues(bp->dev, num);
	return rc;
}

/* must be called with rtnl_lock */
int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
{
@@ -1217,10 +1246,9 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
	if (bnx2x_alloc_mem(bp))
		return -ENOMEM;

	netif_set_real_num_tx_queues(bp->dev, bp->num_queues);
	rc = netif_set_real_num_rx_queues(bp->dev, bp->num_queues);
	rc = bnx2x_set_real_num_queues(bp);
	if (rc) {
		BNX2X_ERR("Unable to update real_num_rx_queues\n");
		BNX2X_ERR("Unable to set real_num_queues\n");
		goto load_error0;
	}

@@ -1228,6 +1256,10 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
		bnx2x_fp(bp, i, disable_tpa) =
					((bp->flags & TPA_ENABLE_FLAG) == 0);

#ifdef BCM_CNIC
	/* We don't want TPA on FCoE L2 ring */
	bnx2x_fcoe(bp, disable_tpa) = 1;
#endif
	bnx2x_napi_enable(bp);

	/* Send LOAD_REQUEST command to MCP
@@ -1358,6 +1390,10 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
	/* Now when Clients are configured we are ready to work */
	bp->state = BNX2X_STATE_OPEN;

#ifdef BCM_CNIC
	bnx2x_set_fcoe_eth_macs(bp);
#endif

	bnx2x_set_eth_mac(bp, 1);

	if (bp->port.pmf)
@@ -1416,7 +1452,7 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode)

	/* Free SKBs, SGEs, TPA pool and driver internals */
	bnx2x_free_skbs(bp);
	for_each_queue(bp, i)
	for_each_rx_queue(bp, i)
		bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE);

	/* Release IRQs */
@@ -1487,7 +1523,7 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode)

	/* Free SKBs, SGEs, TPA pool and driver internals */
	bnx2x_free_skbs(bp);
	for_each_queue(bp, i)
	for_each_rx_queue(bp, i)
		bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE);

	bnx2x_free_mem(bp);
@@ -1591,6 +1627,17 @@ int bnx2x_poll(struct napi_struct *napi, int budget)

		/* Fall out from the NAPI loop if needed */
		if (!(bnx2x_has_rx_work(fp) || bnx2x_has_tx_work(fp))) {
#ifdef BCM_CNIC
			/* No need to update SB for FCoE L2 ring as long as
			 * it's connected to the default SB and the SB
			 * has been updated when NAPI was scheduled.
			 */
			if (IS_FCOE_FP(fp)) {
				napi_complete(napi);
				break;
			}
#endif

			bnx2x_update_fpsb_idx(fp);
			/* bnx2x_has_rx_work() reads the status block,
			 * thus we need to ensure that status block indices
@@ -2255,7 +2302,7 @@ int __devinit bnx2x_alloc_mem_bp(struct bnx2x *bp)
	bp->fp = fp;

	/* msix table */
	tbl = kzalloc((bp->l2_cid_count + 1) * sizeof(*tbl),
	tbl = kzalloc((FP_SB_COUNT(bp->l2_cid_count) + 1) * sizeof(*tbl),
				  GFP_KERNEL);
	if (!tbl)
		goto alloc_err;
+50 −3
Original line number Diff line number Diff line
@@ -242,6 +242,30 @@ int bnx2x_release_hw_lock(struct bnx2x *bp, u32 resource);
 */
void bnx2x_set_eth_mac(struct bnx2x *bp, int set);

#ifdef BCM_CNIC
/**
 * Set/Clear FIP MAC(s) at the next enties in the CAM after the ETH
 * MAC(s). This function will wait until the ramdord completion
 * returns.
 *
 * @param bp driver handle
 * @param set set or clear the CAM entry
 *
 * @return 0 if cussess, -ENODEV if ramrod doesn't return.
 */
int bnx2x_set_fip_eth_mac_addr(struct bnx2x *bp, int set);

/**
 * Set/Clear ALL_ENODE mcast MAC.
 *
 * @param bp
 * @param set
 *
 * @return int
 */
int bnx2x_set_all_enode_macs(struct bnx2x *bp, int set);
#endif

/**
 * Set MAC filtering configurations.
 *
@@ -695,7 +719,7 @@ static inline void bnx2x_add_all_napi(struct bnx2x *bp)
	int i;

	/* Add NAPI objects */
	for_each_queue(bp, i)
	for_each_napi_queue(bp, i)
		netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi),
			       bnx2x_poll, BNX2X_NAPI_WEIGHT);
}
@@ -704,7 +728,7 @@ static inline void bnx2x_del_all_napi(struct bnx2x *bp)
{
	int i;

	for_each_queue(bp, i)
	for_each_napi_queue(bp, i)
		netif_napi_del(&bnx2x_fp(bp, i, napi));
}

@@ -870,7 +894,7 @@ static inline void bnx2x_init_tx_rings(struct bnx2x *bp)
{
	int i, j;

	for_each_queue(bp, j) {
	for_each_tx_queue(bp, j) {
		struct bnx2x_fastpath *fp = &bp->fp[j];

		for (i = 1; i <= NUM_TX_RINGS; i++) {
@@ -949,7 +973,30 @@ static inline void bnx2x_set_next_page_rx_cq(struct bnx2x_fastpath *fp)
	}
}

#ifdef BCM_CNIC
static inline void bnx2x_init_fcoe_fp(struct bnx2x *bp)
{
	bnx2x_fcoe(bp, cl_id) = BNX2X_FCOE_ETH_CL_ID +
		BP_E1HVN(bp) * NONE_ETH_CONTEXT_USE;
	bnx2x_fcoe(bp, cid) = BNX2X_FCOE_ETH_CID;
	bnx2x_fcoe(bp, fw_sb_id) = DEF_SB_ID;
	bnx2x_fcoe(bp, igu_sb_id) = bp->igu_dsb_id;
	bnx2x_fcoe(bp, bp) = bp;
	bnx2x_fcoe(bp, state) = BNX2X_FP_STATE_CLOSED;
	bnx2x_fcoe(bp, index) = FCOE_IDX;
	bnx2x_fcoe(bp, rx_cons_sb) = BNX2X_FCOE_L2_RX_INDEX;
	bnx2x_fcoe(bp, tx_cons_sb) = BNX2X_FCOE_L2_TX_INDEX;
	/* qZone id equals to FW (per path) client id */
	bnx2x_fcoe(bp, cl_qzone_id) = bnx2x_fcoe(bp, cl_id) +
		BP_PORT(bp)*(CHIP_IS_E2(bp) ? ETH_MAX_RX_CLIENTS_E2 :
				ETH_MAX_RX_CLIENTS_E1H);
	/* init shortcut */
	bnx2x_fcoe(bp, ustorm_rx_prods_offset) = CHIP_IS_E2(bp) ?
	    USTORM_RX_PRODS_E2_OFFSET(bnx2x_fcoe(bp, cl_qzone_id)) :
	    USTORM_RX_PRODS_E1X_OFFSET(BP_PORT(bp), bnx2x_fcoe_fp(bp)->cl_id);

}
#endif

static inline void __storm_memset_struct(struct bnx2x *bp,
					 u32 addr, size_t size, u32 *data)
+155 −135

File changed.

Preview size limit exceeded, changes collapsed.

+247 −68

File changed.

Preview size limit exceeded, changes collapsed.

Loading