drivers/net/ethernet/google/gve/gve_flow_rule.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/google/gve/gve_flow_rule.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/google/gve/gve_flow_rule.c
Extension
.c
Size
9448 bytes
Lines
299
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 (fsp->location == be32_to_cpu(rules_cache[i].location)) {
			rule = &rules_cache[i];
			break;
		}
	}

	if (!rule)
		return -EINVAL;

	err = gve_fill_ethtool_flow_spec(fsp, rule);

	return err;
}

int gve_get_flow_rule_ids(struct gve_priv *priv, struct ethtool_rxnfc *cmd, u32 *rule_locs)
{
	__be32 *rule_ids_cache = priv->flow_rules_cache.rule_ids_cache;
	u32 *cache_num = &priv->flow_rules_cache.rule_ids_cache_num;
	u32 starting_rule_id = 0;
	u32 i = 0, j = 0;
	int err = 0;

	if (!priv->max_flow_rules)
		return -EOPNOTSUPP;

	do {
		err = gve_adminq_query_flow_rules(priv, GVE_FLOW_RULE_QUERY_IDS,
						  starting_rule_id);
		if (err)
			return err;

		for (i = 0; i < *cache_num; i++) {
			if (j >= cmd->rule_cnt)
				return -EMSGSIZE;

			rule_locs[j++] = be32_to_cpu(rule_ids_cache[i]);
			starting_rule_id = be32_to_cpu(rule_ids_cache[i]) + 1;
		}
	} while (*cache_num != 0);
	cmd->data = priv->max_flow_rules;

	return err;
}

int gve_add_flow_rule(struct gve_priv *priv, struct ethtool_rxnfc *cmd)
{
	struct ethtool_rx_flow_spec *fsp = &cmd->fs;
	struct gve_adminq_flow_rule *rule = NULL;
	int err;

	if (!priv->max_flow_rules)
		return -EOPNOTSUPP;

	rule = kvzalloc_obj(*rule);
	if (!rule)
		return -ENOMEM;

	err = gve_generate_flow_rule(priv, fsp, rule);
	if (err)
		goto out;

	err = gve_adminq_add_flow_rule(priv, rule, fsp->location);

out:
	kvfree(rule);
	if (err)
		dev_err(&priv->pdev->dev, "Failed to add the flow rule: %u", fsp->location);

	return err;
}

int gve_del_flow_rule(struct gve_priv *priv, struct ethtool_rxnfc *cmd)
{
	struct ethtool_rx_flow_spec *fsp = (struct ethtool_rx_flow_spec *)&cmd->fs;

	if (!priv->max_flow_rules)
		return -EOPNOTSUPP;

	return gve_adminq_del_flow_rule(priv, fsp->location);
}

Annotation

Implementation Notes