drivers/net/ethernet/qlogic/qed/qed_nvmetcp.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/qlogic/qed/qed_nvmetcp.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/qlogic/qed/qed_nvmetcp.c
Extension
.c
Size
24650 bytes
Lines
830
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (p_conn) {
			list_del(&p_conn->list_entry);
			qed_nvmetcp_free_connection(p_hwfn, p_conn);
		}
	}

	kfree(p_hwfn->p_nvmetcp_info);
	p_hwfn->p_nvmetcp_info = NULL;
}

static int qed_nvmetcp_acquire_conn(struct qed_dev *cdev,
				    u32 *handle,
				    u32 *fw_cid, void __iomem **p_doorbell)
{
	struct qed_hash_nvmetcp_con *hash_con;
	int rc;

	/* Allocate a hashed connection */
	hash_con = kzalloc_obj(*hash_con, GFP_ATOMIC);
	if (!hash_con)
		return -ENOMEM;

	/* Acquire the connection */
	rc = qed_nvmetcp_acquire_connection(QED_AFFIN_HWFN(cdev),
					    &hash_con->con);
	if (rc) {
		DP_NOTICE(cdev, "Failed to acquire Connection\n");
		kfree(hash_con);

		return rc;
	}

	/* Added the connection to hash table */
	*handle = hash_con->con->icid;
	*fw_cid = hash_con->con->fw_cid;
	hash_add(cdev->connections, &hash_con->node, *handle);
	if (p_doorbell)
		*p_doorbell = qed_nvmetcp_get_db_addr(QED_AFFIN_HWFN(cdev),
						      *handle);

	return 0;
}

static int qed_nvmetcp_release_conn(struct qed_dev *cdev, u32 handle)
{
	struct qed_hash_nvmetcp_con *hash_con;

	hash_con = qed_nvmetcp_get_hash(cdev, handle);
	if (!hash_con) {
		DP_NOTICE(cdev, "Failed to find connection for handle %d\n",
			  handle);

		return -EINVAL;
	}

	hlist_del(&hash_con->node);
	qed_nvmetcp_release_connection(QED_AFFIN_HWFN(cdev), hash_con->con);
	kfree(hash_con);

	return 0;
}

static int qed_nvmetcp_offload_conn(struct qed_dev *cdev, u32 handle,
				    struct qed_nvmetcp_params_offload *conn_info)
{
	struct qed_hash_nvmetcp_con *hash_con;
	struct qed_nvmetcp_conn *con;

	hash_con = qed_nvmetcp_get_hash(cdev, handle);
	if (!hash_con) {
		DP_NOTICE(cdev, "Failed to find connection for handle %d\n",
			  handle);

		return -EINVAL;
	}

	/* Update the connection with information from the params */
	con = hash_con->con;

	/* FW initializations */
	con->layer_code = NVMETCP_SLOW_PATH_LAYER_CODE;
	con->sq_pbl_addr = conn_info->sq_pbl_addr;
	con->nvmetcp_cccid_max_range = conn_info->nvmetcp_cccid_max_range;
	con->nvmetcp_cccid_itid_table_addr = conn_info->nvmetcp_cccid_itid_table_addr;
	con->default_cq = conn_info->default_cq;
	SET_FIELD(con->offl_flags, NVMETCP_CONN_OFFLOAD_PARAMS_TARGET_MODE, 0);
	SET_FIELD(con->offl_flags, NVMETCP_CONN_OFFLOAD_PARAMS_NVMETCP_MODE, 1);
	SET_FIELD(con->offl_flags, NVMETCP_CONN_OFFLOAD_PARAMS_TCP_ON_CHIP_1B, 1);

	/* Networking and TCP stack initializations */

Annotation

Implementation Notes