drivers/net/wwan/t7xx/t7xx_dpmaif.c

Source file repositories/reference/linux-study-clean/drivers/net/wwan/t7xx/t7xx_dpmaif.c

File Facts

System
Linux kernel
Corpus path
drivers/net/wwan/t7xx/t7xx_dpmaif.c
Extension
.c
Size
40287 bytes
Lines
1282
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 (intr_status & DP_DL_INT_BATCNT_LEN_ERR) {
			t7xx_dpmaif_set_intr_para(para, DPF_INTR_DL_BATCNT_LEN_ERR, DPF_RX_QNO_DFT);
			hw_info->isr_en_mask.ap_dl_l2intr_en_msk &= ~DP_DL_INT_BATCNT_LEN_ERR;
			iowrite32(DP_DL_INT_BATCNT_LEN_ERR,
				  hw_info->pcie_base + DPMAIF_AO_UL_APDL_L2TIMSR0);
		}

		if (intr_status & DP_DL_INT_PITCNT_LEN_ERR) {
			t7xx_dpmaif_set_intr_para(para, DPF_INTR_DL_PITCNT_LEN_ERR, DPF_RX_QNO_DFT);
			hw_info->isr_en_mask.ap_dl_l2intr_en_msk &= ~DP_DL_INT_PITCNT_LEN_ERR;
			iowrite32(DP_DL_INT_PITCNT_LEN_ERR,
				  hw_info->pcie_base + DPMAIF_AO_UL_APDL_L2TIMSR0);
		}

		if (intr_status & DP_DL_INT_PKT_EMPTY_MSK)
			t7xx_dpmaif_set_intr_para(para, DPF_INTR_DL_PKT_EMPTY_SET, DPF_RX_QNO_DFT);

		if (intr_status & DP_DL_INT_FRG_EMPTY_MSK)
			t7xx_dpmaif_set_intr_para(para, DPF_INTR_DL_FRG_EMPTY_SET, DPF_RX_QNO_DFT);

		if (intr_status & DP_DL_INT_MTU_ERR_MSK)
			t7xx_dpmaif_set_intr_para(para, DPF_INTR_DL_MTU_ERR, DPF_RX_QNO_DFT);

		if (intr_status & DP_DL_INT_FRG_LEN_ERR_MSK)
			t7xx_dpmaif_set_intr_para(para, DPF_INTR_DL_FRGCNT_LEN_ERR, DPF_RX_QNO_DFT);

		if (intr_status & DP_DL_INT_Q0_PITCNT_LEN_ERR) {
			t7xx_dpmaif_set_intr_para(para, DPF_INTR_DL_Q0_PITCNT_LEN_ERR, BIT(qno));
			t7xx_dpmaif_dlq_mask_rx_pitcnt_len_err_intr(hw_info, qno);
		}

		if (intr_status & DP_DL_INT_HPC_ENT_TYPE_ERR)
			t7xx_dpmaif_set_intr_para(para, DPF_INTR_DL_HPC_ENT_TYPE_ERR,
						  DPF_RX_QNO_DFT);

		if (intr_status & DP_DL_INT_Q0_DONE) {
			/* Mask RX done interrupt immediately after it occurs, do not clear
			 * the interrupt if the mask operation fails.
			 */
			if (!t7xx_mask_dlq_intr(hw_info, qno))
				t7xx_dpmaif_set_intr_para(para, DPF_INTR_DL_Q0_DONE, BIT(qno));
			else
				intr_status &= ~DP_DL_INT_Q0_DONE;
		}
	} else {
		if (intr_status & DP_DL_INT_Q1_PITCNT_LEN_ERR) {
			t7xx_dpmaif_set_intr_para(para, DPF_INTR_DL_Q1_PITCNT_LEN_ERR, BIT(qno));
			t7xx_dpmaif_dlq_mask_rx_pitcnt_len_err_intr(hw_info, qno);
		}

		if (intr_status & DP_DL_INT_Q1_DONE) {
			if (!t7xx_mask_dlq_intr(hw_info, qno))
				t7xx_dpmaif_set_intr_para(para, DPF_INTR_DL_Q1_DONE, BIT(qno));
			else
				intr_status &= ~DP_DL_INT_Q1_DONE;
		}
	}

	intr_status |= DP_DL_INT_BATCNT_LEN_ERR;
	/* Clear interrupt status */
	iowrite32(intr_status, hw_info->pcie_base + DPMAIF_AP_APDL_L2TISAR0);
}

/**
 * t7xx_dpmaif_hw_get_intr_cnt() - Reads interrupt status and count from HW.
 * @hw_info: Pointer to struct hw_info.
 * @para: Pointer to struct dpmaif_hw_intr_st_para.
 * @qno: Queue number.
 *
 * Reads RX/TX interrupt status from HW and clears UL/DL status as needed.
 *
 * Return: Interrupt count.
 */
int t7xx_dpmaif_hw_get_intr_cnt(struct dpmaif_hw_info *hw_info,
				struct dpmaif_hw_intr_st_para *para, int qno)
{
	u32 rx_intr_status, tx_intr_status = 0;
	u32 rx_intr_qdone, tx_intr_qdone = 0;

	rx_intr_status = ioread32(hw_info->pcie_base + DPMAIF_AP_APDL_L2TISAR0);
	rx_intr_qdone = ioread32(hw_info->pcie_base + DPMAIF_AO_UL_APDL_L2TIMR0);

	/* TX interrupt status */
	if (qno == DPF_RX_QNO_DFT) {
		/* All ULQ and DLQ0 interrupts use the same source no need to check ULQ interrupts
		 * when a DLQ1 interrupt has occurred.
		 */
		tx_intr_status = ioread32(hw_info->pcie_base + DPMAIF_AP_L2TISAR0);
		tx_intr_qdone = ioread32(hw_info->pcie_base + DPMAIF_AO_UL_AP_L2TIMR0);
	}

Annotation

Implementation Notes