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

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

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/huawei/hinic3/hinic3_rss.c
Extension
.c
Size
9069 bytes
Lines
337
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

// SPDX-License-Identifier: GPL-2.0
// Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved.

#include <linux/ethtool.h>

#include "hinic3_cmdq.h"
#include "hinic3_hwdev.h"
#include "hinic3_hwif.h"
#include "hinic3_mbox.h"
#include "hinic3_nic_cfg.h"
#include "hinic3_nic_dev.h"
#include "hinic3_rss.h"

static void hinic3_fillout_indir_tbl(struct net_device *netdev, u16 *indir)
{
	struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
	u16 i, num_qps;

	num_qps = nic_dev->q_params.num_qps;
	for (i = 0; i < L2NIC_RSS_INDIR_SIZE; i++)
		indir[i] = ethtool_rxfh_indir_default(i, num_qps);
}

static int hinic3_rss_cfg(struct hinic3_hwdev *hwdev, u8 rss_en, u16 num_qps)
{
	struct mgmt_msg_params msg_params = {};
	struct l2nic_cmd_cfg_rss rss_cfg = {};
	int err;

	rss_cfg.func_id = hinic3_global_func_id(hwdev);
	rss_cfg.rss_en = rss_en;
	rss_cfg.rq_priority_number = 0;
	rss_cfg.num_qps = num_qps;

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

	err = hinic3_send_mbox_to_mgmt(hwdev, MGMT_MOD_L2NIC,
				       L2NIC_CMD_CFG_RSS, &msg_params);
	if (err || rss_cfg.msg_head.status) {
		dev_err(hwdev->dev, "Failed to set rss cfg, err: %d, status: 0x%x\n",
			err, rss_cfg.msg_head.status);
		return -EINVAL;
	}

	return 0;
}

static void hinic3_init_rss_parameters(struct net_device *netdev)
{
	struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);

	nic_dev->rss_hash_type = HINIC3_RSS_HASH_ENGINE_TYPE_XOR;
	nic_dev->rss_type.tcp_ipv6_ext = 1;
	nic_dev->rss_type.ipv6_ext = 1;
	nic_dev->rss_type.tcp_ipv6 = 1;
	nic_dev->rss_type.ipv6 = 1;
	nic_dev->rss_type.tcp_ipv4 = 1;
	nic_dev->rss_type.ipv4 = 1;
	nic_dev->rss_type.udp_ipv6 = 1;
	nic_dev->rss_type.udp_ipv4 = 1;
}

static void decide_num_qps(struct net_device *netdev)
{
	struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
	unsigned int dev_cpus;

	dev_cpus = netif_get_num_default_rss_queues();
	nic_dev->q_params.num_qps = min(dev_cpus, nic_dev->max_qps);
}

static int alloc_rss_resource(struct net_device *netdev)
{
	struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);

	nic_dev->rss_hkey = kmalloc_array(L2NIC_RSS_KEY_SIZE,
					  sizeof(nic_dev->rss_hkey[0]),
					  GFP_KERNEL);
	if (!nic_dev->rss_hkey)
		return -ENOMEM;

	netdev_rss_key_fill(nic_dev->rss_hkey, L2NIC_RSS_KEY_SIZE);

	nic_dev->rss_indir = kcalloc(L2NIC_RSS_INDIR_SIZE, sizeof(u16),
				     GFP_KERNEL);
	if (!nic_dev->rss_indir) {
		kfree(nic_dev->rss_hkey);
		nic_dev->rss_hkey = NULL;
		return -ENOMEM;
	}

Annotation

Implementation Notes