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

Commit b2608311 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'qed-Enhance-storage-APIs'



Yuval Mintz says:

====================
qed: Enhance storage APIs

This series is intended to add additional information and features
to the API between qed and its storage protocol drivers [qedi, qedf].

Patch #2 adds some information stored on device such as wwpn & wwnn
to allow qedf utilize it; #1 fixes an issue with the reading of those
values [which were unused until now].

Patch #3 would allow the protocol drivers access to images on persistent
storage which is a prerequirement for adding boot from SAN support.

Patch #4 adds infrastrucutre to a future feature for qedi.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 3a5f8997 dc4528e9
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -2071,16 +2071,22 @@ static void qed_hw_set_feat(struct qed_hwfn *p_hwfn)
							 QED_VF_L2_QUE));
	}

	if (p_hwfn->hw_info.personality == QED_PCI_FCOE)
		feat_num[QED_FCOE_CQ] =  min_t(u32, sb_cnt.cnt,
					       RESC_NUM(p_hwfn,
							QED_CMDQS_CQS));

	if (p_hwfn->hw_info.personality == QED_PCI_ISCSI)
		feat_num[QED_ISCSI_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 ISCSI_CQ=%d #SBS=%d\n",
		   "#PF_L2_QUEUES=%d VF_L2_QUEUES=%d #ROCE_CNQ=%d FCOE_CQ=%d ISCSI_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)sb_cnt.cnt);
}
+14 −0
Original line number Diff line number Diff line
@@ -141,6 +141,15 @@ qed_sp_fcoe_func_start(struct qed_hwfn *p_hwfn,
	p_data = &p_ramrod->init_ramrod_data;
	fcoe_pf_params = &p_hwfn->pf_params.fcoe_pf_params;

	/* Sanity */
	if (fcoe_pf_params->num_cqs > p_hwfn->hw_info.feat_num[QED_FCOE_CQ]) {
		DP_ERR(p_hwfn,
		       "Cannot satisfy CQ amount. CQs requested %d, CQs available %d. Aborting function start\n",
		       fcoe_pf_params->num_cqs,
		       p_hwfn->hw_info.feat_num[QED_FCOE_CQ]);
		return -EINVAL;
	}

	p_data->mtu = cpu_to_le16(fcoe_pf_params->mtu);
	tmp = cpu_to_le16(fcoe_pf_params->sq_num_pbl_pages);
	p_data->sq_num_pages_in_pbl = tmp;
@@ -739,6 +748,11 @@ static int qed_fill_fcoe_dev_info(struct qed_dev *cdev,
	info->secondary_bdq_rq_addr =
	    qed_fcoe_get_secondary_bdq_prod(hwfn, BDQ_ID_RQ);

	info->wwpn = hwfn->mcp_info->func_info.wwn_port;
	info->wwnn = hwfn->mcp_info->func_info.wwn_node;

	info->num_cqs = FEAT_NUM(hwfn, QED_FCOE_CQ);

	return rc;
}

+66 −0
Original line number Diff line number Diff line
@@ -488,6 +488,54 @@ static int qed_sp_iscsi_conn_update(struct qed_hwfn *p_hwfn,
	return qed_spq_post(p_hwfn, p_ent, NULL);
}

static int
qed_sp_iscsi_mac_update(struct qed_hwfn *p_hwfn,
			struct qed_iscsi_conn *p_conn,
			enum spq_mode comp_mode,
			struct qed_spq_comp_cb *p_comp_addr)
{
	struct iscsi_spe_conn_mac_update *p_ramrod = NULL;
	struct qed_spq_entry *p_ent = NULL;
	struct qed_sp_init_data init_data;
	int rc = -EINVAL;
	u8 ucval;

	/* Get SPQ entry */
	memset(&init_data, 0, sizeof(init_data));
	init_data.cid = p_conn->icid;
	init_data.opaque_fid = p_hwfn->hw_info.opaque_fid;
	init_data.comp_mode = comp_mode;
	init_data.p_comp_data = p_comp_addr;

	rc = qed_sp_init_request(p_hwfn, &p_ent,
				 ISCSI_RAMROD_CMD_ID_MAC_UPDATE,
				 PROTOCOLID_ISCSI, &init_data);
	if (rc)
		return rc;

	p_ramrod = &p_ent->ramrod.iscsi_conn_mac_update;
	p_ramrod->hdr.op_code = ISCSI_RAMROD_CMD_ID_MAC_UPDATE;
	SET_FIELD(p_ramrod->hdr.flags,
		  ISCSI_SLOW_PATH_HDR_LAYER_CODE, p_conn->layer_code);

	p_ramrod->conn_id = cpu_to_le16(p_conn->conn_id);
	p_ramrod->fw_cid = cpu_to_le32(p_conn->icid);
	ucval = p_conn->remote_mac[1];
	((u8 *)(&p_ramrod->remote_mac_addr_hi))[0] = ucval;
	ucval = p_conn->remote_mac[0];
	((u8 *)(&p_ramrod->remote_mac_addr_hi))[1] = ucval;
	ucval = p_conn->remote_mac[3];
	((u8 *)(&p_ramrod->remote_mac_addr_mid))[0] = ucval;
	ucval = p_conn->remote_mac[2];
	((u8 *)(&p_ramrod->remote_mac_addr_mid))[1] = ucval;
	ucval = p_conn->remote_mac[5];
	((u8 *)(&p_ramrod->remote_mac_addr_lo))[0] = ucval;
	ucval = p_conn->remote_mac[4];
	((u8 *)(&p_ramrod->remote_mac_addr_lo))[1] = ucval;

	return qed_spq_post(p_hwfn, p_ent, NULL);
}

static int qed_sp_iscsi_conn_terminate(struct qed_hwfn *p_hwfn,
				       struct qed_iscsi_conn *p_conn,
				       enum spq_mode comp_mode,
@@ -1324,6 +1372,23 @@ static int qed_iscsi_stats(struct qed_dev *cdev, struct qed_iscsi_stats *stats)
	return qed_iscsi_get_stats(QED_LEADING_HWFN(cdev), stats);
}

static int qed_iscsi_change_mac(struct qed_dev *cdev,
				u32 handle, const u8 *mac)
{
	struct qed_hash_iscsi_con *hash_con;

	hash_con = qed_iscsi_get_hash(cdev, handle);
	if (!hash_con) {
		DP_NOTICE(cdev, "Failed to find connection for handle %d\n",
			  handle);
		return -EINVAL;
	}

	return qed_sp_iscsi_mac_update(QED_LEADING_HWFN(cdev),
				       hash_con->con,
				       QED_SPQ_MODE_EBLOCK, NULL);
}

void qed_get_protocol_stats_iscsi(struct qed_dev *cdev,
				  struct qed_mcp_iscsi_stats *stats)
{
@@ -1358,6 +1423,7 @@ static const struct qed_iscsi_ops qed_iscsi_ops_pass = {
	.destroy_conn = &qed_iscsi_destroy_conn,
	.clear_sq = &qed_iscsi_clear_conn_sq,
	.get_stats = &qed_iscsi_stats,
	.change_mac = &qed_iscsi_change_mac,
};

const struct qed_iscsi_ops *qed_get_iscsi_ops(void)
+18 −0
Original line number Diff line number Diff line
@@ -269,6 +269,8 @@ int qed_fill_dev_info(struct qed_dev *cdev,
		if (QED_LEADING_HWFN(cdev)->hw_info.b_wol_support ==
		    QED_WOL_SUPPORT_PME)
			dev_info->wol_support = true;

		dev_info->abs_pf_id = QED_LEADING_HWFN(cdev)->abs_pf_id;
	} else {
		qed_vf_get_fw_version(&cdev->hwfns[0], &dev_info->fw_major,
				      &dev_info->fw_minor, &dev_info->fw_rev,
@@ -1533,6 +1535,21 @@ static int qed_drain(struct qed_dev *cdev)
	return 0;
}

static int qed_nvm_get_image(struct qed_dev *cdev, enum qed_nvm_images type,
			     u8 *buf, u16 len)
{
	struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev);
	struct qed_ptt *ptt = qed_ptt_acquire(hwfn);
	int rc;

	if (!ptt)
		return -EAGAIN;

	rc = qed_mcp_get_nvm_image(hwfn, ptt, type, buf, len);
	qed_ptt_release(hwfn, ptt);
	return rc;
}

static void qed_get_coalesce(struct qed_dev *cdev, u16 *rx_coal, u16 *tx_coal)
{
	*rx_coal = cdev->rx_coalesce_usecs;
@@ -1710,6 +1727,7 @@ const struct qed_common_ops qed_common_ops_pass = {
	.dbg_all_data_size = &qed_dbg_all_data_size,
	.chain_alloc = &qed_chain_alloc,
	.chain_free = &qed_chain_free,
	.nvm_get_image = &qed_nvm_get_image,
	.get_coalesce = &qed_get_coalesce,
	.set_coalesce = &qed_set_coalesce,
	.set_led = &qed_set_led,
+93 −4
Original line number Diff line number Diff line
@@ -1736,10 +1736,10 @@ int qed_mcp_fill_shmem_func_info(struct qed_hwfn *p_hwfn,
		DP_NOTICE(p_hwfn, "MAC is 0 in shmem\n");
	}

	info->wwn_port = (u64)shmem_info.fcoe_wwn_port_name_upper |
			 (((u64)shmem_info.fcoe_wwn_port_name_lower) << 32);
	info->wwn_node = (u64)shmem_info.fcoe_wwn_node_name_upper |
			 (((u64)shmem_info.fcoe_wwn_node_name_lower) << 32);
	info->wwn_port = (u64)shmem_info.fcoe_wwn_port_name_lower |
			 (((u64)shmem_info.fcoe_wwn_port_name_upper) << 32);
	info->wwn_node = (u64)shmem_info.fcoe_wwn_node_name_lower |
			 (((u64)shmem_info.fcoe_wwn_node_name_upper) << 32);

	info->ovlan = (u16)(shmem_info.ovlan_stag & FUNC_MF_CFG_OV_STAG_MASK);

@@ -2310,6 +2310,95 @@ int qed_mcp_bist_nvm_test_get_image_att(struct qed_hwfn *p_hwfn,
	return rc;
}

static int
qed_mcp_get_nvm_image_att(struct qed_hwfn *p_hwfn,
			  struct qed_ptt *p_ptt,
			  enum qed_nvm_images image_id,
			  struct qed_nvm_image_att *p_image_att)
{
	struct bist_nvm_image_att mfw_image_att;
	enum nvm_image_type type;
	u32 num_images, i;
	int rc;

	/* Translate image_id into MFW definitions */
	switch (image_id) {
	case QED_NVM_IMAGE_ISCSI_CFG:
		type = NVM_TYPE_ISCSI_CFG;
		break;
	case QED_NVM_IMAGE_FCOE_CFG:
		type = NVM_TYPE_FCOE_CFG;
		break;
	default:
		DP_NOTICE(p_hwfn, "Unknown request of image_id %08x\n",
			  image_id);
		return -EINVAL;
	}

	/* Learn number of images, then traverse and see if one fits */
	rc = qed_mcp_bist_nvm_test_get_num_images(p_hwfn, p_ptt, &num_images);
	if (rc || !num_images)
		return -EINVAL;

	for (i = 0; i < num_images; i++) {
		rc = qed_mcp_bist_nvm_test_get_image_att(p_hwfn, p_ptt,
							 &mfw_image_att, i);
		if (rc)
			return rc;

		if (type == mfw_image_att.image_type)
			break;
	}
	if (i == num_images) {
		DP_VERBOSE(p_hwfn, QED_MSG_STORAGE,
			   "Failed to find nvram image of type %08x\n",
			   image_id);
		return -EINVAL;
	}

	p_image_att->start_addr = mfw_image_att.nvm_start_addr;
	p_image_att->length = mfw_image_att.len;

	return 0;
}

int qed_mcp_get_nvm_image(struct qed_hwfn *p_hwfn,
			  struct qed_ptt *p_ptt,
			  enum qed_nvm_images image_id,
			  u8 *p_buffer, u32 buffer_len)
{
	struct qed_nvm_image_att image_att;
	int rc;

	memset(p_buffer, 0, buffer_len);

	rc = qed_mcp_get_nvm_image_att(p_hwfn, p_ptt, image_id, &image_att);
	if (rc)
		return rc;

	/* Validate sizes - both the image's and the supplied buffer's */
	if (image_att.length <= 4) {
		DP_VERBOSE(p_hwfn, QED_MSG_STORAGE,
			   "Image [%d] is too small - only %d bytes\n",
			   image_id, image_att.length);
		return -EINVAL;
	}

	/* Each NVM image is suffixed by CRC; Upper-layer has no need for it */
	image_att.length -= 4;

	if (image_att.length > buffer_len) {
		DP_VERBOSE(p_hwfn,
			   QED_MSG_STORAGE,
			   "Image [%d] is too big - %08x bytes where only %08x are available\n",
			   image_id, image_att.length, buffer_len);
		return -ENOMEM;
	}

	return qed_mcp_nvm_read(p_hwfn->cdev, image_att.start_addr,
				p_buffer, image_att.length);
}

static enum resource_id_enum qed_mcp_get_mfw_res_id(enum qed_resources res_id)
{
	enum resource_id_enum mfw_res_id = RESOURCE_NUM_INVALID;
Loading