drivers/net/wireless/microchip/wilc1000/wlan.c

Source file repositories/reference/linux-study-clean/drivers/net/wireless/microchip/wilc1000/wlan.c

File Facts

System
Linux kernel
Corpus path
drivers/net/wireless/microchip/wilc1000/wlan.c
Extension
.c
Size
42071 bytes
Lines
1811
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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 (f->pending_acks[i].ack_num < bigger_ack_num) {
			struct txq_entry_t *tqe;

			tqe = f->pending_acks[i].txqe;
			if (tqe) {
				wilc_wlan_txq_remove(wilc, tqe->q_num, tqe);
				tqe->status = 1;
				if (tqe->tx_complete_func)
					tqe->tx_complete_func(tqe->priv,
							      tqe->status);
				kfree(tqe);
				dropped++;
			}
		}
	}
	f->pending_acks_idx = 0;
	f->tcp_session = 0;

	if (f->pending_base == 0)
		f->pending_base = MAX_TCP_SESSION;
	else
		f->pending_base = 0;

	spin_unlock_irqrestore(&wilc->txq_spinlock, flags);

	while (dropped > 0) {
		wait_for_completion_timeout(&wilc->txq_event,
					    msecs_to_jiffies(1));
		dropped--;
	}
}

void wilc_enable_tcp_ack_filter(struct wilc_vif *vif, bool value)
{
	vif->ack_filter.enabled = value;
}

static int wilc_wlan_txq_add_cfg_pkt(struct wilc_vif *vif, u8 *buffer,
				     u32 buffer_size)
{
	struct txq_entry_t *tqe;
	struct wilc *wilc = vif->wilc;

	netdev_dbg(vif->ndev, "Adding config packet ...\n");
	if (wilc->quit) {
		netdev_dbg(vif->ndev, "Return due to clear function\n");
		complete(&wilc->cfg_event);
		return 0;
	}

	tqe = kmalloc_obj(*tqe, GFP_ATOMIC);
	if (!tqe) {
		complete(&wilc->cfg_event);
		return 0;
	}

	tqe->type = WILC_CFG_PKT;
	tqe->buffer = buffer;
	tqe->buffer_size = buffer_size;
	tqe->tx_complete_func = NULL;
	tqe->priv = NULL;
	tqe->q_num = AC_VO_Q;
	tqe->ack_idx = NOT_TCP_ACK;
	tqe->vif = vif;

	wilc_wlan_txq_add_to_head(vif, AC_VO_Q, tqe);

	return 1;
}

static bool is_ac_q_limit(struct wilc *wl, u8 q_num)
{
	u8 factors[NQUEUES] = {1, 1, 1, 1};
	u16 i;
	unsigned long flags;
	struct wilc_tx_queue_status *q = &wl->tx_q_limit;
	u8 end_index;
	u8 q_limit;
	bool ret = false;

	spin_lock_irqsave(&wl->txq_spinlock, flags);
	if (!q->initialized) {
		for (i = 0; i < AC_BUFFER_SIZE; i++)
			q->buffer[i] = i % NQUEUES;

		for (i = 0; i < NQUEUES; i++) {
			q->cnt[i] = AC_BUFFER_SIZE * factors[i] / NQUEUES;
			q->sum += q->cnt[i];
		}
		q->end_index = AC_BUFFER_SIZE - 1;

Annotation

Implementation Notes