drivers/net/ethernet/marvell/prestera/prestera_router.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/marvell/prestera/prestera_router.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/marvell/prestera/prestera_router.c
Extension
.c
Size
43120 bytes
Lines
1646
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

struct prestera_kern_neigh_cache_key {
	struct prestera_ip_addr addr;
	struct net_device *dev;
};

struct prestera_kern_neigh_cache {
	struct prestera_kern_neigh_cache_key key;
	struct rhash_head ht_node;
	struct list_head kern_fib_cache_list;
	/* Hold prepared nh_neigh info if is in_kernel */
	struct prestera_neigh_info nh_neigh_info;
	/* Indicate if neighbour is reachable by direct route */
	bool reachable;
	/* Lock cache if neigh is present in kernel */
	bool in_kernel;
};

struct prestera_kern_fib_cache_key {
	struct prestera_ip_addr addr;
	u32 prefix_len;
	u32 kern_tb_id; /* tb_id from kernel (not fixed) */
};

/* Subscribing on neighbours in kernel */
struct prestera_kern_fib_cache {
	struct prestera_kern_fib_cache_key key;
	struct {
		struct prestera_fib_key fib_key;
		enum prestera_fib_type fib_type;
		struct prestera_nexthop_group_key nh_grp_key;
	} lpm_info; /* hold prepared lpm info */
	/* Indicate if route is not overlapped by another table */
	struct rhash_head ht_node; /* node of prestera_router */
	struct prestera_kern_neigh_cache_head {
		struct prestera_kern_fib_cache *this;
		struct list_head head;
		struct prestera_kern_neigh_cache *n_cache;
	} kern_neigh_cache_head[PRESTERA_NHGR_SIZE_MAX];
	union {
		struct fib_notifier_info info; /* point to any of 4/6 */
		struct fib_entry_notifier_info fen4_info;
	};
	bool reachable;
};

static const struct rhashtable_params __prestera_kern_neigh_cache_ht_params = {
	.key_offset  = offsetof(struct prestera_kern_neigh_cache, key),
	.head_offset = offsetof(struct prestera_kern_neigh_cache, ht_node),
	.key_len     = sizeof(struct prestera_kern_neigh_cache_key),
	.automatic_shrinking = true,
};

static const struct rhashtable_params __prestera_kern_fib_cache_ht_params = {
	.key_offset  = offsetof(struct prestera_kern_fib_cache, key),
	.head_offset = offsetof(struct prestera_kern_fib_cache, ht_node),
	.key_len     = sizeof(struct prestera_kern_fib_cache_key),
	.automatic_shrinking = true,
};

/* This util to be used, to convert kernel rules for default vr in hw_vr */
static u32 prestera_fix_tb_id(u32 tb_id)
{
	if (tb_id == RT_TABLE_UNSPEC ||
	    tb_id == RT_TABLE_LOCAL ||
	    tb_id == RT_TABLE_DEFAULT)
		tb_id = RT_TABLE_MAIN;

	return tb_id;
}

static void
prestera_util_fen_info2fib_cache_key(struct fib_notifier_info *info,
				     struct prestera_kern_fib_cache_key *key)
{
	struct fib_entry_notifier_info *fen_info =
		container_of(info, struct fib_entry_notifier_info, info);

	memset(key, 0, sizeof(*key));
	key->addr.v = PRESTERA_IPV4;
	key->addr.u.ipv4 = cpu_to_be32(fen_info->dst);
	key->prefix_len = fen_info->dst_len;
	key->kern_tb_id = fen_info->tb_id;
}

static int prestera_util_nhc2nc_key(struct prestera_switch *sw,
				    struct fib_nh_common *nhc,
				    struct prestera_kern_neigh_cache_key *nk)
{
	memset(nk, 0, sizeof(*nk));
	if (nhc->nhc_gw_family == AF_INET) {

Annotation

Implementation Notes