drivers/net/ethernet/pensando/ionic/ionic_rx_filter.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/pensando/ionic/ionic_rx_filter.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/pensando/ionic/ionic_rx_filter.c
Extension
.c
Size
16405 bytes
Lines
620
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 sync_item {
	struct list_head list;
	struct ionic_rx_filter f;
};

void ionic_rx_filter_sync(struct ionic_lif *lif)
{
	struct device *dev = lif->ionic->dev;
	struct list_head sync_add_list;
	struct list_head sync_del_list;
	struct sync_item *sync_item;
	struct ionic_rx_filter *f;
	struct hlist_head *head;
	struct hlist_node *tmp;
	struct sync_item *spos;
	unsigned int i;

	INIT_LIST_HEAD(&sync_add_list);
	INIT_LIST_HEAD(&sync_del_list);

	clear_bit(IONIC_LIF_F_FILTER_SYNC_NEEDED, lif->state);

	/* Copy the filters to be added and deleted
	 * into a separate local list that needs no locking.
	 */
	spin_lock_bh(&lif->rx_filters.lock);
	for (i = 0; i < IONIC_RX_FILTER_HLISTS; i++) {
		head = &lif->rx_filters.by_id[i];
		hlist_for_each_entry_safe(f, tmp, head, by_id) {
			if (f->state == IONIC_FILTER_STATE_NEW ||
			    f->state == IONIC_FILTER_STATE_OLD) {
				sync_item = devm_kzalloc(dev, sizeof(*sync_item),
							 GFP_ATOMIC);
				if (!sync_item)
					goto loop_out;

				sync_item->f = *f;

				if (f->state == IONIC_FILTER_STATE_NEW)
					list_add(&sync_item->list, &sync_add_list);
				else
					list_add(&sync_item->list, &sync_del_list);
			}
		}
	}
loop_out:
	spin_unlock_bh(&lif->rx_filters.lock);

	/* If the add or delete fails, it won't get marked as sync'd
	 * and will be tried again in the next sync action.
	 * Do the deletes first in case we're in an overflow state and
	 * they can clear room for some new filters
	 */
	list_for_each_entry_safe(sync_item, spos, &sync_del_list, list) {
		ionic_lif_filter_del(lif, &sync_item->f.cmd);

		list_del(&sync_item->list);
		devm_kfree(dev, sync_item);
	}

	list_for_each_entry_safe(sync_item, spos, &sync_add_list, list) {
		ionic_lif_filter_add(lif, &sync_item->f.cmd);

		list_del(&sync_item->list);
		devm_kfree(dev, sync_item);
	}
}

Annotation

Implementation Notes