drivers/net/ethernet/microchip/lan966x/lan966x_taprio.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/microchip/lan966x/lan966x_taprio.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/microchip/lan966x/lan966x_taprio.c
Extension
.c
Size
14217 bytes
Lines
529
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 (state == LAN966X_TAPRIO_STATE_OPERATING) {
			lan966x_taprio_list_state_set(port,
						      LAN966X_TAPRIO_STATE_TERMINATING);
			operating = true;
		}

		/* If the entry was in pending and now gets in admin, then there
		 * is nothing else to do, so just bail out
		 */
		state = lan966x_taprio_list_state_get(port);
		if (pending &&
		    state == LAN966X_TAPRIO_STATE_ADMIN)
			return 0;

		/* If the list was in operating and now is in terminating or
		 * admin, then is OK to exit but it needs to wait until the list
		 * will get in admin. It is not required to set the state
		 * again.
		 */
		if (operating &&
		    (state == LAN966X_TAPRIO_STATE_TERMINATING ||
		     state == LAN966X_TAPRIO_STATE_ADMIN))
			break;

	} while (!time_after(jiffies, end));

	end = jiffies + msecs_to_jiffies(LAN966X_TAPRIO_TIMEOUT_MS);
	do {
		state = lan966x_taprio_list_state_get(port);
		if (state == LAN966X_TAPRIO_STATE_ADMIN)
			break;

	} while (!time_after(jiffies, end));

	/* If the list was in operating mode, it could be stopped while some
	 * queues where closed, so make sure to restore "all-queues-open"
	 */
	if (operating) {
		lan_wr(QSYS_TAS_GS_CTRL_HSCH_POS_SET(port->chip_port),
		       lan966x, QSYS_TAS_GS_CTRL);

		lan_wr(QSYS_TAS_GATE_STATE_TAS_GATE_STATE_SET(0xff),
		       lan966x, QSYS_TAS_GATE_STATE);
	}

	return 0;
}

static int lan966x_taprio_shutdown(struct lan966x_port *port)
{
	u32 i, list, state;
	int err;

	for (i = 0; i < LAN966X_TAPRIO_ENTRIES_PER_PORT; ++i) {
		list = lan966x_taprio_list_index(port, i);
		state = lan966x_taprio_list_index_state_get(port, list);
		if (state == LAN966X_TAPRIO_STATE_ADMIN)
			continue;

		err = lan966x_taprio_list_shutdown(port, list);
		if (err)
			return err;
	}

	return 0;
}

/* Find a suitable list for a new schedule. First priority is a list in state
 * pending. Second priority is a list in state admin.
 */
static int lan966x_taprio_find_list(struct lan966x_port *port,
				    struct tc_taprio_qopt_offload *qopt,
				    int *new_list, int *obs_list)
{
	int state[LAN966X_TAPRIO_ENTRIES_PER_PORT];
	int list[LAN966X_TAPRIO_ENTRIES_PER_PORT];
	int err, oper = -1;
	u32 i;

	*new_list = -1;
	*obs_list = -1;

	/* If there is already an entry in operating mode, return this list in
	 * obs_list, such that when the new list will get activated the
	 * operating list will be stopped. In this way is possible to have
	 * smooth transitions between the lists
	 */
	for (i = 0; i < LAN966X_TAPRIO_ENTRIES_PER_PORT; ++i) {
		list[i] = lan966x_taprio_list_index(port, i);
		state[i] = lan966x_taprio_list_index_state_get(port, list[i]);

Annotation

Implementation Notes