drivers/net/ethernet/hisilicon/hibmcge/hbg_main.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/hisilicon/hibmcge/hbg_main.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/hisilicon/hibmcge/hbg_main.c
Extension
.c
Size
13293 bytes
Lines
532
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: operation-table or driver-model contract
Status
pattern 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

static const struct net_device_ops hbg_netdev_ops = {
	.ndo_open		= hbg_net_open,
	.ndo_stop		= hbg_net_stop,
	.ndo_start_xmit		= hbg_net_start_xmit,
	.ndo_validate_addr	= eth_validate_addr,
	.ndo_set_mac_address	= hbg_net_set_mac_address,
	.ndo_change_mtu		= hbg_net_change_mtu,
	.ndo_tx_timeout		= hbg_net_tx_timeout,
	.ndo_set_rx_mode	= hbg_net_set_rx_mode,
	.ndo_get_stats64	= hbg_net_get_stats,
	.ndo_eth_ioctl		= phy_do_ioctl_running,
};

static void hbg_service_task(struct work_struct *work)
{
	struct hbg_priv *priv = container_of(work, struct hbg_priv,
					     service_task.work);

	if (test_and_clear_bit(HBG_NIC_STATE_NEED_RESET, &priv->state))
		hbg_err_reset(priv);

	if (test_and_clear_bit(HBG_NIC_STATE_NP_LINK_FAIL, &priv->state))
		hbg_fix_np_link_fail(priv);

	hbg_diagnose_message_push(priv);

	/* The type of statistics register is u32,
	 * To prevent the statistics register from overflowing,
	 * the driver dumps the statistics every 30 seconds.
	 */
	if (time_after(jiffies, priv->last_update_stats_time + 30 * HZ)) {
		hbg_update_stats(priv);
		priv->last_update_stats_time = jiffies;
	}

	schedule_delayed_work(&priv->service_task,
			      msecs_to_jiffies(MSEC_PER_SEC));
}

void hbg_err_reset_task_schedule(struct hbg_priv *priv)
{
	set_bit(HBG_NIC_STATE_NEED_RESET, &priv->state);
	schedule_delayed_work(&priv->service_task, 0);
}

void hbg_np_link_fail_task_schedule(struct hbg_priv *priv)
{
	set_bit(HBG_NIC_STATE_NP_LINK_FAIL, &priv->state);
	schedule_delayed_work(&priv->service_task, 0);
}

static void hbg_cancel_delayed_work_sync(void *data)
{
	cancel_delayed_work_sync(data);
}

static int hbg_delaywork_init(struct hbg_priv *priv)
{
	INIT_DELAYED_WORK(&priv->service_task, hbg_service_task);
	schedule_delayed_work(&priv->service_task, 0);
	return devm_add_action_or_reset(&priv->pdev->dev,
					hbg_cancel_delayed_work_sync,
					&priv->service_task);
}

static int hbg_mac_filter_init(struct hbg_priv *priv)
{
	struct hbg_dev_specs *dev_specs = &priv->dev_specs;
	struct hbg_mac_filter *filter = &priv->filter;
	struct hbg_mac_table_entry *tmp_table;

	tmp_table = devm_kcalloc(&priv->pdev->dev, dev_specs->uc_mac_num,
				 sizeof(*tmp_table), GFP_KERNEL);
	if (!tmp_table)
		return -ENOMEM;

	filter->mac_table = tmp_table;
	filter->table_max_len = dev_specs->uc_mac_num;
	filter->enabled = true;

	hbg_hw_set_mac_filter_enable(priv, filter->enabled);
	return 0;
}

static void hbg_init_user_def(struct hbg_priv *priv)
{
	struct ethtool_pauseparam *pause_param = &priv->user_def.pause_param;

	priv->mac.pause_autoneg = HBG_STATUS_ENABLE;

Annotation

Implementation Notes