drivers/net/ethernet/huawei/hinic3/hinic3_hw_comm.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/huawei/hinic3/hinic3_hw_comm.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/huawei/hinic3/hinic3_hw_comm.c
Extension
.c
Size
16299 bytes
Lines
611
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: implementation source
Status
source 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 (err) {
			dev_warn(hwdev->dev, "Wait firmware FLR timeout\n");
			ret = err;
		}
	}

	hinic3_toggle_doorbell(hwif, ENABLE_DOORBELL);

	err = hinic3_reinit_cmdq_ctxts(hwdev);
	if (err) {
		dev_warn(hwdev->dev, "Failed to reinit cmdq\n");
		ret = err;
	}

	return ret;
}

int hinic3_set_bdf_ctxt(struct hinic3_hwdev *hwdev,
			struct comm_cmd_bdf_info *bdf_info)
{
	struct mgmt_msg_params msg_params = {};
	int err;

	mgmt_msg_params_init_default(&msg_params, bdf_info, sizeof(*bdf_info));

	err = hinic3_send_mbox_to_mgmt(hwdev, MGMT_MOD_COMM,
				       COMM_CMD_SEND_BDF_INFO, &msg_params);
	if (err || bdf_info->head.status) {
		dev_err(hwdev->dev,
			"Failed to set bdf info to fw, err: %d, status: 0x%x\n",
			err, bdf_info->head.status);
		return -EFAULT;
	}

	return 0;
}

static int hinic3_sync_time(struct hinic3_hwdev *hwdev, u64 time)
{
	struct comm_cmd_sync_time time_info = {};
	struct mgmt_msg_params msg_params = {};
	int err;

	time_info.mstime = time;

	mgmt_msg_params_init_default(&msg_params, &time_info,
				     sizeof(time_info));

	err = hinic3_send_mbox_to_mgmt(hwdev, MGMT_MOD_COMM,
				       COMM_CMD_SYNC_TIME, &msg_params);
	if (err || time_info.head.status) {
		dev_err(hwdev->dev,
			"Failed to sync time to mgmt, err: %d, status: 0x%x\n",
			err, time_info.head.status);
		return -EFAULT;
	}

	return 0;
}

void hinic3_sync_time_to_fw(struct hinic3_hwdev *hwdev)
{
	struct timespec64 ts = {};
	u64 time;
	int err;

	ktime_get_real_ts64(&ts);
	time = (u64)(ts.tv_sec * MSEC_PER_SEC + ts.tv_nsec / NSEC_PER_MSEC);

	err = hinic3_sync_time(hwdev, time);
	if (err)
		dev_err(hwdev->dev,
			"Synchronize UTC time to firmware failed, err=%d\n",
			err);
}

static int get_hw_rx_buf_size_idx(int rx_buf_sz, u16 *buf_sz_idx)
{
	/* Supported RX buffer sizes in bytes. Configured by array index. */
	static const int supported_sizes[16] = {
		[0] = 32,     [1] = 64,     [2] = 96,     [3] = 128,
		[4] = 192,    [5] = 256,    [6] = 384,    [7] = 512,
		[8] = 768,    [9] = 1024,   [10] = 1536,  [11] = 2048,
		[12] = 3072,  [13] = 4096,  [14] = 8192,  [15] = 16384,
	};
	u16 idx;

	/* Scan from biggest to smallest. Choose supported size that is equal or
	 * smaller. For smaller value HW will under-utilize posted buffers. For
	 * bigger value HW may overrun posted buffers.

Annotation

Implementation Notes