drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_fd.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_fd.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_fd.c
Extension
.c
Size
73546 bytes
Lines
2594
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 (old_rule->state == HCLGE_FD_TO_ADD) {
			hclge_fd_dec_rule_cnt(hdev, old_rule->location);
			hclge_fd_free_node(hdev, old_rule);
			return;
		}
		old_rule->state = HCLGE_FD_TO_DEL;
		break;
	}
}

static struct hclge_fd_rule *hclge_find_fd_rule(struct hlist_head *hlist,
						u16 location,
						struct hclge_fd_rule **parent)
{
	struct hclge_fd_rule *rule;
	struct hlist_node *node;

	hlist_for_each_entry_safe(rule, node, hlist, rule_node) {
		if (rule->location == location)
			return rule;
		else if (rule->location > location)
			return NULL;
		/* record the parent node, use to keep the nodes in fd_rule_list
		 * in ascend order.
		 */
		*parent = rule;
	}

	return NULL;
}

/* insert fd rule node in ascend order according to rule->location */
static void hclge_fd_insert_rule_node(struct hlist_head *hlist,
				      struct hclge_fd_rule *rule,
				      struct hclge_fd_rule *parent)
{
	INIT_HLIST_NODE(&rule->rule_node);

	if (parent)
		hlist_add_behind(&rule->rule_node, &parent->rule_node);
	else
		hlist_add_head(&rule->rule_node, hlist);
}

static int hclge_fd_set_user_def_cmd(struct hclge_dev *hdev,
				     struct hclge_fd_user_def_cfg *cfg)
{
	struct hclge_fd_user_def_cfg_cmd *req;
	struct hclge_desc desc;
	u16 data = 0;
	int ret;

	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_FD_USER_DEF_OP, false);

	req = (struct hclge_fd_user_def_cfg_cmd *)desc.data;

	hnae3_set_bit(data, HCLGE_FD_USER_DEF_EN_B, cfg[0].ref_cnt > 0);
	hnae3_set_field(data, HCLGE_FD_USER_DEF_OFT_M,
			HCLGE_FD_USER_DEF_OFT_S, cfg[0].offset);
	req->ol2_cfg = cpu_to_le16(data);

	data = 0;
	hnae3_set_bit(data, HCLGE_FD_USER_DEF_EN_B, cfg[1].ref_cnt > 0);
	hnae3_set_field(data, HCLGE_FD_USER_DEF_OFT_M,
			HCLGE_FD_USER_DEF_OFT_S, cfg[1].offset);
	req->ol3_cfg = cpu_to_le16(data);

	data = 0;
	hnae3_set_bit(data, HCLGE_FD_USER_DEF_EN_B, cfg[2].ref_cnt > 0);
	hnae3_set_field(data, HCLGE_FD_USER_DEF_OFT_M,
			HCLGE_FD_USER_DEF_OFT_S, cfg[2].offset);
	req->ol4_cfg = cpu_to_le16(data);

	ret = hclge_cmd_send(&hdev->hw, &desc, 1);
	if (ret)
		dev_err(&hdev->pdev->dev,
			"failed to set fd user def data, ret= %d\n", ret);
	return ret;
}

static void hclge_sync_fd_user_def_cfg(struct hclge_dev *hdev, bool locked)
{
	int ret;

	if (!test_and_clear_bit(HCLGE_STATE_FD_USER_DEF_CHANGED, &hdev->state))
		return;

	if (!locked)
		spin_lock_bh(&hdev->fd_rule_lock);

Annotation

Implementation Notes