drivers/net/ethernet/microchip/sparx5/sparx5_tc_matchall.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/microchip/sparx5/sparx5_tc_matchall.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/microchip/sparx5/sparx5_tc_matchall.c
Extension
.c
Size
5105 bytes
Lines
205
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) {
			switch (err) {
			case -EEXIST:
				NL_SET_ERR_MSG_MOD(tmo->common.extack,
						   "Mirroring already exists");
				break;
			case -EINVAL:
				NL_SET_ERR_MSG_MOD(tmo->common.extack,
						   "Cannot mirror a monitor port");
				break;
			case -ENOENT:
				NL_SET_ERR_MSG_MOD(tmo->common.extack,
						   "No more mirror probes available");
				break;
			default:
				NL_SET_ERR_MSG_MOD(tmo->common.extack,
						   "Unknown error");
				break;
			}
			return err;
		}
		/* Get baseline stats for this port */
		sparx5_mirror_stats(mall_entry, &tmo->stats);
		break;
	case FLOW_ACTION_GOTO:
		err = vcap_enable_lookups(sparx5->vcap_ctrl, ndev,
					  tmo->common.chain_index,
					  action->chain_index, tmo->cookie,
					  true);
		if (err == -EFAULT) {
			NL_SET_ERR_MSG_MOD(tmo->common.extack,
					   "Unsupported goto chain");
			return -EOPNOTSUPP;
		}
		if (err == -EADDRINUSE) {
			NL_SET_ERR_MSG_MOD(tmo->common.extack,
					   "VCAP already enabled");
			return -EOPNOTSUPP;
		}
		if (err == -EADDRNOTAVAIL) {
			NL_SET_ERR_MSG_MOD(tmo->common.extack,
					   "Already matching this chain");
			return -EOPNOTSUPP;
		}
		if (err) {
			NL_SET_ERR_MSG_MOD(tmo->common.extack,
					   "Could not enable VCAP lookups");
			return err;
		}
		break;
	default:
		NL_SET_ERR_MSG_MOD(tmo->common.extack, "Unsupported action");
		return -EOPNOTSUPP;
	}

	list_add_tail(&mall_entry->list, &sparx5->mall_entries);

	return 0;
}

static int sparx5_tc_matchall_destroy(struct net_device *ndev,
				      struct tc_cls_matchall_offload *tmo,
				      bool ingress)
{
	struct sparx5_port *port = netdev_priv(ndev);
	struct sparx5 *sparx5 = port->sparx5;
	struct sparx5_mall_entry *entry;
	int err = 0;

	entry = sparx5_tc_matchall_entry_find(&sparx5->mall_entries,
					      tmo->cookie);
	if (!entry)
		return -ENOENT;

	if (entry->type == FLOW_ACTION_MIRRED) {
		sparx5_mirror_del(entry);
	} else if (entry->type == FLOW_ACTION_GOTO) {
		err = vcap_enable_lookups(sparx5->vcap_ctrl, ndev,
					  0, 0, tmo->cookie, false);
	} else {
		NL_SET_ERR_MSG_MOD(tmo->common.extack, "Unsupported action");
		err = -EOPNOTSUPP;
	}

	list_del(&entry->list);

	return err;
}

static int sparx5_tc_matchall_stats(struct net_device *ndev,

Annotation

Implementation Notes