drivers/net/ethernet/engleder/tsnep_tc.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/engleder/tsnep_tc.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/engleder/tsnep_tc.c
Extension
.c
Size
11437 bytes
Lines
467
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 (gcl->operation[i].properties & ~mask) {
			addr = gcl->addr +
			       sizeof(struct tsnep_gcl_operation) * i;

			gcl->operation[i].properties &= mask;
			iowrite32(gcl->operation[i].properties, addr);

			break;
		}
	}
}

static u64 tsnep_insert_gcl_operation(struct tsnep_gcl *gcl, int ref,
				      u64 change, u32 interval)
{
	u32 properties;

	properties = gcl->operation[ref].properties & TSNEP_GCL_MASK;
	/* change to new list directly after inserted operation */
	properties |= TSNEP_GCL_CHANGE;

	/* last operation of list is reserved to insert operation */
	tsnep_write_gcl_operation(gcl, TSNEP_GCL_COUNT - 1, properties,
				  interval, false);

	return tsnep_set_gcl_change(gcl, ref, change, true);
}

static u64 tsnep_extend_gcl(struct tsnep_gcl *gcl, u64 start, u32 extension)
{
	int ref = gcl->count - 1;
	u32 interval = gcl->operation[ref].interval + extension;

	start -= gcl->operation[ref].interval;

	return tsnep_insert_gcl_operation(gcl, ref, start, interval);
}

static u64 tsnep_cut_gcl(struct tsnep_gcl *gcl, u64 start, u64 cycle_time)
{
	u64 sum = 0;
	int i;

	/* find operation which shall be cutted */
	for (i = 0; i < gcl->count; i++) {
		u64 sum_tmp = sum + gcl->operation[i].interval;
		u64 interval;

		/* sum up operations as long as cycle time is not exceeded */
		if (sum_tmp > cycle_time)
			break;

		/* remaining interval must be big enough for hardware */
		interval = cycle_time - sum_tmp;
		if (interval > 0 && interval < TSNEP_GCL_MIN_INTERVAL)
			break;

		sum = sum_tmp;
	}
	if (sum == cycle_time) {
		/* no need to cut operation itself or whole cycle
		 * => change exactly at operation
		 */
		return tsnep_set_gcl_change(gcl, i, start + sum, false);
	}
	return tsnep_insert_gcl_operation(gcl, i, start + sum,
					  cycle_time - sum);
}

static int tsnep_enable_gcl(struct tsnep_adapter *adapter,
			    struct tsnep_gcl *gcl, struct tsnep_gcl *curr)
{
	u64 system_time;
	u64 timeout;
	u64 limit;

	/* estimate timeout limit after timeout enable, actually timeout limit
	 * in hardware will be earlier than estimate so we are on the safe side
	 */
	tsnep_get_system_time(adapter, &system_time);
	timeout = system_time + TSNEP_GC_TIMEOUT;

	if (curr)
		limit = timeout + curr->change_limit;
	else
		limit = timeout;

	gcl->start_time = tsnep_gcl_start_after(gcl, limit);

	/* gate control time register is only 32bit => time shall be in the near

Annotation

Implementation Notes