drivers/net/wireless/ath/ath12k/ce.c

Source file repositories/reference/linux-study-clean/drivers/net/wireless/ath/ath12k/ce.c

File Facts

System
Linux kernel
Corpus path
drivers/net/wireless/ath/ath12k/ce.c
Extension
.c
Size
18593 bytes
Lines
756
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 (!skb) {
			ret = -ENOMEM;
			goto exit;
		}

		WARN_ON_ONCE(!IS_ALIGNED((unsigned long)skb->data, 4));

		paddr = dma_map_single(ab->dev, skb->data,
				       skb->len + skb_tailroom(skb),
				       DMA_FROM_DEVICE);
		if (unlikely(dma_mapping_error(ab->dev, paddr))) {
			ath12k_warn(ab, "failed to dma map ce rx buf\n");
			dev_kfree_skb_any(skb);
			ret = -EIO;
			goto exit;
		}

		ATH12K_SKB_RXCB(skb)->paddr = paddr;

		ret = ath12k_ce_rx_buf_enqueue_pipe(pipe, skb, paddr);
		if (ret) {
			ath12k_dbg(ab, ATH12K_DBG_CE, "failed to enqueue rx buf: %d\n",
				   ret);
			dma_unmap_single(ab->dev, paddr,
					 skb->len + skb_tailroom(skb),
					 DMA_FROM_DEVICE);
			dev_kfree_skb_any(skb);
			goto exit;
		}
	}

exit:
	spin_unlock_bh(&ab->ce.ce_lock);
	return ret;
}

static int ath12k_ce_completed_recv_next(struct ath12k_ce_pipe *pipe,
					 struct sk_buff **skb, int *nbytes)
{
	struct ath12k_base *ab = pipe->ab;
	struct hal_ce_srng_dst_status_desc *desc;
	struct hal_srng *srng;
	unsigned int sw_index;
	unsigned int nentries_mask;
	int ret = 0;

	spin_lock_bh(&ab->ce.ce_lock);

	sw_index = pipe->dest_ring->sw_index;
	nentries_mask = pipe->dest_ring->nentries_mask;

	srng = &ab->hal.srng_list[pipe->status_ring->hal_ring_id];

	spin_lock_bh(&srng->lock);

	ath12k_hal_srng_access_begin(ab, srng);

	desc = ath12k_hal_srng_dst_get_next_entry(ab, srng);
	if (!desc) {
		ret = -EIO;
		goto err;
	}

	*nbytes = ath12k_hal_ce_dst_status_get_length(&ab->hal, desc);

	*skb = pipe->dest_ring->skb[sw_index];
	pipe->dest_ring->skb[sw_index] = NULL;

	sw_index = CE_RING_IDX_INCR(nentries_mask, sw_index);
	pipe->dest_ring->sw_index = sw_index;

	pipe->rx_buf_needed++;
err:
	ath12k_hal_srng_access_end(ab, srng);

	spin_unlock_bh(&srng->lock);

	spin_unlock_bh(&ab->ce.ce_lock);

	return ret;
}

static void ath12k_ce_recv_process_cb(struct ath12k_ce_pipe *pipe)
{
	struct ath12k_base *ab = pipe->ab;
	struct sk_buff *skb;
	struct sk_buff_head list;
	unsigned int nbytes, max_nbytes;
	int ret;

Annotation

Implementation Notes