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

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

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/microchip/sparx5/sparx5_sdlb.c
Extension
.c
Size
8144 bytes
Lines
339
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 (itr == idx) {
				*group = i;
				return 0; /* Found it */
			}
			if (itr == next)
				break; /* Was not found */

			itr = next;
		}
	}

	return -EINVAL;
}

static int sparx5_sdlb_group_link(struct sparx5 *sparx5, u32 group, u32 idx,
				  u32 first, u32 next, bool empty)
{
	/* Stop leaking */
	sparx5_sdlb_group_disable(sparx5, group);

	if (empty)
		return 0;

	/* Link insertion lb to next lb */
	spx5_wr(ANA_AC_SDLB_XLB_NEXT_LBSET_NEXT_SET(next) |
			ANA_AC_SDLB_XLB_NEXT_LBGRP_SET(group),
		sparx5, ANA_AC_SDLB_XLB_NEXT(idx));

	/* Set the first lb */
	spx5_wr(ANA_AC_SDLB_XLB_START_LBSET_START_SET(first), sparx5,
		ANA_AC_SDLB_XLB_START(group));

	/* Start leaking */
	sparx5_sdlb_group_enable(sparx5, group);

	return 0;
};

int sparx5_sdlb_group_add(struct sparx5 *sparx5, u32 group, u32 idx)
{
	u32 first, next;

	/* We always add to head of the list */
	first = idx;

	if (sparx5_sdlb_group_is_empty(sparx5, group))
		next = idx;
	else
		next = sparx5_sdlb_group_get_first(sparx5, group);

	return sparx5_sdlb_group_link(sparx5, group, idx, first, next, false);
}

int sparx5_sdlb_group_del(struct sparx5 *sparx5, u32 group, u32 idx)
{
	u32 first, next, prev;
	bool empty = false;

	if (sparx5_sdlb_group_get_adjacent(sparx5, group, idx, &prev, &next,
					   &first) < 0) {
		pr_err("%s:%d Could not find idx: %d in group: %d", __func__,
		       __LINE__, idx, group);
		return -EINVAL;
	}

	if (sparx5_sdlb_group_is_singular(sparx5, group)) {
		empty = true;
	} else if (sparx5_sdlb_group_is_last(sparx5, group, idx)) {
		/* idx is removed, prev is now last */
		idx = prev;
		next = prev;
	} else if (sparx5_sdlb_group_is_first(sparx5, group, idx)) {
		/* idx is removed and points to itself, first is next */
		first = next;
		next = idx;
	} else {
		/* Next is not touched */
		idx = prev;
	}

	return sparx5_sdlb_group_link(sparx5, group, idx, first, next, empty);
}

void sparx5_sdlb_group_init(struct sparx5 *sparx5, u64 max_rate, u32 min_burst,
			    u32 frame_size, u32 idx)
{
	const struct sparx5_ops *ops = sparx5->data->ops;
	u32 thres_shift, mask = 0x01, power = 0;
	struct sparx5_sdlb_group *group;
	u64 max_token;

Annotation

Implementation Notes