Commit 897e87a1 authored by Shai Malin's avatar Shai Malin Committed by David S. Miller
Browse files

qed: Add NVMeTCP Offload PF Level FW and HW HSI



This patch introduces the NVMeTCP device and PF level HSI and HSI
functionality in order to initialize and interact with the HW device.
The patch also adds qed NVMeTCP personality.

This patch is based on the qede, qedr, qedi, qedf drivers HSI.

Acked-by: default avatarIgor Russkikh <irusskikh@marvell.com>
Signed-off-by: default avatarDean Balandin <dbalandin@marvell.com>
Signed-off-by: default avatarPrabhakar Kushwaha <pkushwaha@marvell.com>
Signed-off-by: default avatarOmkar Kulkarni <okulkarni@marvell.com>
Signed-off-by: default avatarShai Malin <smalin@marvell.com>
Signed-off-by: default avatarMichal Kalderon <mkalderon@marvell.com>
Signed-off-by: default avatarAriel Elior <aelior@marvell.com>
Reviewed-by: default avatarHannes Reinecke <hare@suse.de>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 1bd4f571
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -110,6 +110,9 @@ config QED_RDMA
config QED_ISCSI
	bool

config QED_NVMETCP
	bool

config QED_FCOE
	bool

+2 −0
Original line number Diff line number Diff line
@@ -28,6 +28,8 @@ qed-$(CONFIG_QED_ISCSI) += qed_iscsi.o
qed-$(CONFIG_QED_LL2) += qed_ll2.o
qed-$(CONFIG_QED_OOO) += qed_ooo.o

qed-$(CONFIG_QED_NVMETCP) += qed_nvmetcp.o

qed-$(CONFIG_QED_RDMA) +=	\
	qed_iwarp.o		\
	qed_rdma.o		\
+6 −0
Original line number Diff line number Diff line
@@ -200,6 +200,7 @@ enum qed_pci_personality {
	QED_PCI_ETH,
	QED_PCI_FCOE,
	QED_PCI_ISCSI,
	QED_PCI_NVMETCP,
	QED_PCI_ETH_ROCE,
	QED_PCI_ETH_IWARP,
	QED_PCI_ETH_RDMA,
@@ -239,6 +240,7 @@ enum QED_FEATURE {
	QED_PF_L2_QUE,
	QED_VF,
	QED_RDMA_CNQ,
	QED_NVMETCP_CQ,
	QED_ISCSI_CQ,
	QED_FCOE_CQ,
	QED_VF_L2_QUE,
@@ -284,6 +286,8 @@ struct qed_hw_info {
	((dev)->hw_info.personality == QED_PCI_FCOE)
#define QED_IS_ISCSI_PERSONALITY(dev)					\
	((dev)->hw_info.personality == QED_PCI_ISCSI)
#define QED_IS_NVMETCP_PERSONALITY(dev)					\
	((dev)->hw_info.personality == QED_PCI_NVMETCP)

	/* Resource Allocation scheme results */
	u32				resc_start[QED_MAX_RESC];
@@ -592,6 +596,7 @@ struct qed_hwfn {
	struct qed_ooo_info		*p_ooo_info;
	struct qed_rdma_info		*p_rdma_info;
	struct qed_iscsi_info		*p_iscsi_info;
	struct qed_nvmetcp_info		*p_nvmetcp_info;
	struct qed_fcoe_info		*p_fcoe_info;
	struct qed_pf_params		pf_params;

@@ -828,6 +833,7 @@ struct qed_dev {
		struct qed_eth_cb_ops		*eth;
		struct qed_fcoe_cb_ops		*fcoe;
		struct qed_iscsi_cb_ops		*iscsi;
		struct qed_nvmetcp_cb_ops	*nvmetcp;
	} protocol_ops;
	void				*ops_cookie;

+25 −2
Original line number Diff line number Diff line
@@ -2072,7 +2072,6 @@ int qed_cxt_set_pf_params(struct qed_hwfn *p_hwfn, u32 rdma_tasks)
						    PROTOCOLID_FCOE,
						    p_params->num_cons,
						    0);

			qed_cxt_set_proto_tid_count(p_hwfn, PROTOCOLID_FCOE,
						    QED_CXT_FCOE_TID_SEG, 0,
						    p_params->num_tasks, true);
@@ -2093,7 +2092,6 @@ int qed_cxt_set_pf_params(struct qed_hwfn *p_hwfn, u32 rdma_tasks)
						    PROTOCOLID_TCP_ULP,
						    p_params->num_cons,
						    0);

			qed_cxt_set_proto_tid_count(p_hwfn,
						    PROTOCOLID_TCP_ULP,
						    QED_CXT_TCP_ULP_TID_SEG,
@@ -2106,6 +2104,29 @@ int qed_cxt_set_pf_params(struct qed_hwfn *p_hwfn, u32 rdma_tasks)
		}
		break;
	}
	case QED_PCI_NVMETCP:
	{
		struct qed_nvmetcp_pf_params *p_params;

		p_params = &p_hwfn->pf_params.nvmetcp_pf_params;

		if (p_params->num_cons && p_params->num_tasks) {
			qed_cxt_set_proto_cid_count(p_hwfn,
						    PROTOCOLID_TCP_ULP,
						    p_params->num_cons,
						    0);
			qed_cxt_set_proto_tid_count(p_hwfn,
						    PROTOCOLID_TCP_ULP,
						    QED_CXT_TCP_ULP_TID_SEG,
						    0,
						    p_params->num_tasks,
						    true);
		} else {
			DP_INFO(p_hwfn->cdev,
				"NvmeTCP personality used without setting params!\n");
		}
		break;
	}
	default:
		return -EINVAL;
	}
@@ -2129,6 +2150,7 @@ int qed_cxt_get_tid_mem_info(struct qed_hwfn *p_hwfn,
		seg = QED_CXT_FCOE_TID_SEG;
		break;
	case QED_PCI_ISCSI:
	case QED_PCI_NVMETCP:
		proto = PROTOCOLID_TCP_ULP;
		seg = QED_CXT_TCP_ULP_TID_SEG;
		break;
@@ -2455,6 +2477,7 @@ int qed_cxt_get_task_ctx(struct qed_hwfn *p_hwfn,
		seg = QED_CXT_FCOE_TID_SEG;
		break;
	case QED_PCI_ISCSI:
	case QED_PCI_NVMETCP:
		proto = PROTOCOLID_TCP_ULP;
		seg = QED_CXT_TCP_ULP_TID_SEG;
		break;
+42 −6
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@
#include "qed_sriov.h"
#include "qed_vf.h"
#include "qed_rdma.h"
#include "qed_nvmetcp.h"

static DEFINE_SPINLOCK(qm_lock);

@@ -667,7 +668,8 @@ qed_llh_set_engine_affin(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
	}

	/* Storage PF is bound to a single engine while L2 PF uses both */
	if (QED_IS_FCOE_PERSONALITY(p_hwfn) || QED_IS_ISCSI_PERSONALITY(p_hwfn))
	if (QED_IS_FCOE_PERSONALITY(p_hwfn) || QED_IS_ISCSI_PERSONALITY(p_hwfn) ||
	    QED_IS_NVMETCP_PERSONALITY(p_hwfn))
		eng = cdev->fir_affin ? QED_ENG1 : QED_ENG0;
	else			/* L2_PERSONALITY */
		eng = QED_BOTH_ENG;
@@ -1164,6 +1166,9 @@ void qed_llh_remove_mac_filter(struct qed_dev *cdev,
	if (!test_bit(QED_MF_LLH_MAC_CLSS, &cdev->mf_bits))
		goto out;

	if (QED_IS_NVMETCP_PERSONALITY(p_hwfn))
		return;

	ether_addr_copy(filter.mac.addr, mac_addr);
	rc = qed_llh_shadow_remove_filter(cdev, ppfid, &filter, &filter_idx,
					  &ref_cnt);
@@ -1381,6 +1386,11 @@ void qed_resc_free(struct qed_dev *cdev)
			qed_ooo_free(p_hwfn);
		}

		if (p_hwfn->hw_info.personality == QED_PCI_NVMETCP) {
			qed_nvmetcp_free(p_hwfn);
			qed_ooo_free(p_hwfn);
		}

		if (QED_IS_RDMA_PERSONALITY(p_hwfn) && rdma_info) {
			qed_spq_unregister_async_cb(p_hwfn, rdma_info->proto);
			qed_rdma_info_free(p_hwfn);
@@ -1423,6 +1433,7 @@ static u32 qed_get_pq_flags(struct qed_hwfn *p_hwfn)
		flags |= PQ_FLAGS_OFLD;
		break;
	case QED_PCI_ISCSI:
	case QED_PCI_NVMETCP:
		flags |= PQ_FLAGS_ACK | PQ_FLAGS_OOO | PQ_FLAGS_OFLD;
		break;
	case QED_PCI_ETH_ROCE:
@@ -2263,7 +2274,8 @@ int qed_resc_alloc(struct qed_dev *cdev)
			 * at the same time
			 */
			n_eqes += num_cons + 2 * MAX_NUM_VFS_BB + n_srq;
		} else if (p_hwfn->hw_info.personality == QED_PCI_ISCSI) {
		} else if (p_hwfn->hw_info.personality == QED_PCI_ISCSI ||
			   p_hwfn->hw_info.personality == QED_PCI_NVMETCP) {
			num_cons =
			    qed_cxt_get_proto_cid_count(p_hwfn,
							PROTOCOLID_TCP_ULP,
@@ -2313,6 +2325,15 @@ int qed_resc_alloc(struct qed_dev *cdev)
				goto alloc_err;
		}

		if (p_hwfn->hw_info.personality == QED_PCI_NVMETCP) {
			rc = qed_nvmetcp_alloc(p_hwfn);
			if (rc)
				goto alloc_err;
			rc = qed_ooo_alloc(p_hwfn);
			if (rc)
				goto alloc_err;
		}

		if (QED_IS_RDMA_PERSONALITY(p_hwfn)) {
			rc = qed_rdma_info_alloc(p_hwfn);
			if (rc)
@@ -2393,6 +2414,11 @@ void qed_resc_setup(struct qed_dev *cdev)
			qed_iscsi_setup(p_hwfn);
			qed_ooo_setup(p_hwfn);
		}

		if (p_hwfn->hw_info.personality == QED_PCI_NVMETCP) {
			qed_nvmetcp_setup(p_hwfn);
			qed_ooo_setup(p_hwfn);
		}
	}
}

@@ -2854,7 +2880,8 @@ static int qed_hw_init_pf(struct qed_hwfn *p_hwfn,

	/* Protocol Configuration */
	STORE_RT_REG(p_hwfn, PRS_REG_SEARCH_TCP_RT_OFFSET,
		     (p_hwfn->hw_info.personality == QED_PCI_ISCSI) ? 1 : 0);
		     ((p_hwfn->hw_info.personality == QED_PCI_ISCSI) ||
			 (p_hwfn->hw_info.personality == QED_PCI_NVMETCP)) ? 1 : 0);
	STORE_RT_REG(p_hwfn, PRS_REG_SEARCH_FCOE_RT_OFFSET,
		     (p_hwfn->hw_info.personality == QED_PCI_FCOE) ? 1 : 0);
	STORE_RT_REG(p_hwfn, PRS_REG_SEARCH_ROCE_RT_OFFSET, 0);
@@ -3535,14 +3562,21 @@ static void qed_hw_set_feat(struct qed_hwfn *p_hwfn)
		feat_num[QED_ISCSI_CQ] = min_t(u32, sb_cnt.cnt,
					       RESC_NUM(p_hwfn,
							QED_CMDQS_CQS));

	if (QED_IS_NVMETCP_PERSONALITY(p_hwfn))
		feat_num[QED_NVMETCP_CQ] = min_t(u32, sb_cnt.cnt,
						 RESC_NUM(p_hwfn,
							  QED_CMDQS_CQS));

	DP_VERBOSE(p_hwfn,
		   NETIF_MSG_PROBE,
		   "#PF_L2_QUEUES=%d VF_L2_QUEUES=%d #ROCE_CNQ=%d FCOE_CQ=%d ISCSI_CQ=%d #SBS=%d\n",
		   "#PF_L2_QUEUES=%d VF_L2_QUEUES=%d #ROCE_CNQ=%d FCOE_CQ=%d ISCSI_CQ=%d NVMETCP_CQ=%d #SBS=%d\n",
		   (int)FEAT_NUM(p_hwfn, QED_PF_L2_QUE),
		   (int)FEAT_NUM(p_hwfn, QED_VF_L2_QUE),
		   (int)FEAT_NUM(p_hwfn, QED_RDMA_CNQ),
		   (int)FEAT_NUM(p_hwfn, QED_FCOE_CQ),
		   (int)FEAT_NUM(p_hwfn, QED_ISCSI_CQ),
		   (int)FEAT_NUM(p_hwfn, QED_NVMETCP_CQ),
		   (int)sb_cnt.cnt);
}

@@ -3734,7 +3768,8 @@ int qed_hw_get_dflt_resc(struct qed_hwfn *p_hwfn,
		break;
	case QED_BDQ:
		if (p_hwfn->hw_info.personality != QED_PCI_ISCSI &&
		    p_hwfn->hw_info.personality != QED_PCI_FCOE)
		    p_hwfn->hw_info.personality != QED_PCI_FCOE &&
			p_hwfn->hw_info.personality != QED_PCI_NVMETCP)
			*p_resc_num = 0;
		else
			*p_resc_num = 1;
@@ -3755,7 +3790,8 @@ int qed_hw_get_dflt_resc(struct qed_hwfn *p_hwfn,
			*p_resc_start = 0;
		else if (p_hwfn->cdev->num_ports_in_engine == 4)
			*p_resc_start = p_hwfn->port_id;
		else if (p_hwfn->hw_info.personality == QED_PCI_ISCSI)
		else if (p_hwfn->hw_info.personality == QED_PCI_ISCSI ||
			 p_hwfn->hw_info.personality == QED_PCI_NVMETCP)
			*p_resc_start = p_hwfn->port_id;
		else if (p_hwfn->hw_info.personality == QED_PCI_FCOE)
			*p_resc_start = p_hwfn->port_id + 2;
Loading