drivers/net/wireless/ath/ath10k/sdio.c

Source file repositories/reference/linux-study-clean/drivers/net/wireless/ath/ath10k/sdio.c

File Facts

System
Linux kernel
Corpus path
drivers/net/wireless/ath/ath10k/sdio.c
Extension
.c
Size
68143 bytes
Lines
2685
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 (id >= ATH10K_HTC_EP_COUNT) {
			ath10k_warn(ar, "invalid endpoint in look-ahead: %d\n",
				    id);
			ret = -ENOMEM;
			goto out;
		}

		ep = &htc->endpoint[id];

		if (ep->service_id == 0) {
			ath10k_warn(ar, "ep %d is not connected\n", id);
			ret = -ENOMEM;
			goto out;
		}

		pkt = &ar_sdio->rx_pkts[i];

		if (pkt->part_of_bundle && !pkt->last_in_bundle) {
			/* Only read lookahead's from RX trailers
			 * for the last packet in a bundle.
			 */
			lookahead_idx--;
			lookaheads_local = NULL;
			n_lookahead_local = NULL;
		}

		ret = ath10k_sdio_mbox_rx_process_packet(ar,
							 pkt,
							 lookaheads_local,
							 n_lookahead_local);
		if (ret)
			goto out;

		if (!pkt->trailer_only) {
			cb = ATH10K_SKB_RXCB(pkt->skb);
			cb->eid = id;

			skb_queue_tail(&ar_sdio->rx_head, pkt->skb);
			queue_work(ar->workqueue_aux,
				   &ar_sdio->async_work_rx);
		} else {
			kfree_skb(pkt->skb);
		}

		/* The RX complete handler now owns the skb...*/
		pkt->skb = NULL;
		pkt->alloc_len = 0;
	}

	ret = 0;

out:
	/* Free all packets that was not passed on to the RX completion
	 * handler...
	 */
	for (; i < ar_sdio->n_rx_pkts; i++)
		ath10k_sdio_mbox_free_rx_pkt(&ar_sdio->rx_pkts[i]);

	return ret;
}

static int ath10k_sdio_mbox_alloc_bundle(struct ath10k *ar,
					 struct ath10k_sdio_rx_data *rx_pkts,
					 struct ath10k_htc_hdr *htc_hdr,
					 size_t full_len, size_t act_len,
					 size_t *bndl_cnt)
{
	int ret, i;
	u8 max_msgs = ar->htc.max_msgs_per_htc_bundle;

	*bndl_cnt = ath10k_htc_get_bundle_count(max_msgs, htc_hdr->flags);

	if (*bndl_cnt > max_msgs) {
		ath10k_warn(ar,
			    "HTC bundle length %u exceeds maximum %u\n",
			    le16_to_cpu(htc_hdr->len),
			    max_msgs);
		return -ENOMEM;
	}

	/* Allocate bndl_cnt extra skb's for the bundle.
	 * The package containing the
	 * ATH10K_HTC_FLAG_BUNDLE_MASK flag is not included
	 * in bndl_cnt. The skb for that packet will be
	 * allocated separately.
	 */
	for (i = 0; i < *bndl_cnt; i++) {
		ret = ath10k_sdio_mbox_alloc_rx_pkt(&rx_pkts[i],
						    act_len,
						    full_len,

Annotation

Implementation Notes