drivers/net/wireless/ath/ath11k/dbring.c

Source file repositories/reference/linux-study-clean/drivers/net/wireless/ath/ath11k/dbring.c

File Facts

System
Linux kernel
Corpus path
drivers/net/wireless/ath/ath11k/dbring.c
Extension
.c
Size
10567 bytes
Lines
428
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 (!buff->payload) {
			kfree(buff);
			break;
		}
		ret = ath11k_dbring_bufs_replenish(ar, ring, buff, id);
		if (ret) {
			ath11k_warn(ar->ab, "failed to replenish db ring num_remain %d req_ent %d\n",
				    num_remain, req_entries);
			kfree(buff->payload);
			kfree(buff);
			break;
		}
		num_remain--;
	}

	spin_unlock_bh(&srng->lock);

	return num_remain;
}

int ath11k_dbring_wmi_cfg_setup(struct ath11k *ar,
				struct ath11k_dbring *ring,
				enum wmi_direct_buffer_module id)
{
	struct ath11k_wmi_pdev_dma_ring_cfg_req_cmd param = {};
	int ret, i;

	if (id >= WMI_DIRECT_BUF_MAX)
		return -EINVAL;

	param.module_id		= id;
	param.base_paddr_lo	= lower_32_bits(ring->refill_srng.paddr);
	param.base_paddr_hi	= upper_32_bits(ring->refill_srng.paddr);
	param.head_idx_paddr_lo	= lower_32_bits(ring->hp_addr);
	param.head_idx_paddr_hi = upper_32_bits(ring->hp_addr);
	param.tail_idx_paddr_lo = lower_32_bits(ring->tp_addr);
	param.tail_idx_paddr_hi = upper_32_bits(ring->tp_addr);
	param.num_elems		= ring->bufs_max;
	param.buf_size		= ring->buf_sz;
	param.num_resp_per_event = ring->num_resp_per_event;
	param.event_timeout_ms	= ring->event_timeout_ms;

	/* For single pdev, 2GHz and 5GHz use one DBR. */
	if (ar->ab->hw_params.single_pdev_only) {
		for (i = 0; i < ar->ab->target_pdev_count; i++) {
			param.pdev_id = ar->ab->target_pdev_ids[i].pdev_id;
			ret = ath11k_wmi_pdev_dma_ring_cfg(ar, &param);
			if (ret) {
				ath11k_warn(ar->ab, "failed to setup db ring cfg\n");
				return ret;
			}
		}
	} else {
		param.pdev_id = DP_SW2HW_MACID(ring->pdev_id);
		ret = ath11k_wmi_pdev_dma_ring_cfg(ar, &param);
		if (ret) {
			ath11k_warn(ar->ab, "failed to setup db ring cfg\n");
			return ret;
		}
	}

	return 0;
}

int ath11k_dbring_set_cfg(struct ath11k *ar, struct ath11k_dbring *ring,
			  u32 num_resp_per_event, u32 event_timeout_ms,
			  int (*handler)(struct ath11k *,
					 struct ath11k_dbring_data *))
{
	if (WARN_ON(!ring))
		return -EINVAL;

	ring->num_resp_per_event = num_resp_per_event;
	ring->event_timeout_ms = event_timeout_ms;
	ring->handler = handler;

	return 0;
}

int ath11k_dbring_buf_setup(struct ath11k *ar,
			    struct ath11k_dbring *ring,
			    struct ath11k_dbring_cap *db_cap)
{
	struct ath11k_base *ab = ar->ab;
	struct hal_srng *srng;
	int ret;

	srng = &ab->hal.srng_list[ring->refill_srng.ring_id];
	ring->bufs_max = ring->refill_srng.size /
		ath11k_hal_srng_get_entrysize(ab, HAL_RXDMA_DIR_BUF);

Annotation

Implementation Notes