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

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

File Facts

System
Linux kernel
Corpus path
drivers/net/wireless/ath/ath12k/mhi.c
Extension
.c
Size
13468 bytes
Lines
530
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 (ab_pci->mhi_pre_cb == MHI_CB_EE_RDDM) {
			ath12k_dbg(ab, ATH12K_DBG_BOOT,
				   "do not queue again for consecutive RDDM event\n");
			break;
		}

		if (!(test_bit(ATH12K_FLAG_UNREGISTERING, &ab->dev_flags))) {
			set_bit(ATH12K_FLAG_CRASH_FLUSH, &ab->dev_flags);
			set_bit(ATH12K_FLAG_RECOVERY, &ab->dev_flags);
			queue_work(ab->workqueue_aux, &ab->reset_work);
		}
		break;
	default:
		break;
	}

	ab_pci->mhi_pre_cb = cb;
}

static int ath12k_mhi_op_read_reg(struct mhi_controller *mhi_cntrl,
				  void __iomem *addr,
				  u32 *out)
{
	*out = readl(addr);

	return 0;
}

static void ath12k_mhi_op_write_reg(struct mhi_controller *mhi_cntrl,
				    void __iomem *addr,
				    u32 val)
{
	writel(val, addr);
}

int ath12k_mhi_register(struct ath12k_pci *ab_pci)
{
	struct ath12k_base *ab = ab_pci->ab;
	struct mhi_controller *mhi_ctrl;
	unsigned int board_id;
	int ret;
	bool dualmac = false;

	mhi_ctrl = mhi_alloc_controller();
	if (!mhi_ctrl)
		return -ENOMEM;

	ab_pci->mhi_pre_cb = MHI_CB_INVALID;
	ab_pci->mhi_ctrl = mhi_ctrl;
	mhi_ctrl->cntrl_dev = ab->dev;
	mhi_ctrl->regs = ab->mem;
	mhi_ctrl->reg_len = ab->mem_len;
	mhi_ctrl->rddm_size = ab->hw_params->rddm_size;

	if (ab->hw_params->otp_board_id_register) {
		board_id =
			ath12k_pci_read32(ab, ab->hw_params->otp_board_id_register);
		board_id = u32_get_bits(board_id, OTP_BOARD_ID_MASK);

		if (!board_id || (board_id == OTP_INVALID_BOARD_ID)) {
			ath12k_dbg(ab, ATH12K_DBG_BOOT,
				   "failed to read board id\n");
		} else if (board_id & OTP_VALID_DUALMAC_BOARD_ID_MASK) {
			dualmac = true;
			ath12k_dbg(ab, ATH12K_DBG_BOOT,
				   "dualmac fw selected for board id: %x\n", board_id);
		}
	}

	if (dualmac) {
		if (ab->fw.amss_dualmac_data && ab->fw.amss_dualmac_len > 0) {
			/* use MHI firmware file from firmware-N.bin */
			mhi_ctrl->fw_data = ab->fw.amss_dualmac_data;
			mhi_ctrl->fw_sz = ab->fw.amss_dualmac_len;
		} else {
			ath12k_warn(ab, "dualmac firmware IE not present in firmware-N.bin\n");
			ret = -ENOENT;
			goto free_controller;
		}
	} else {
		if (ab->fw.amss_data && ab->fw.amss_len > 0) {
			/* use MHI firmware file from firmware-N.bin */
			mhi_ctrl->fw_data = ab->fw.amss_data;
			mhi_ctrl->fw_sz = ab->fw.amss_len;
		} else {
			/* use the old separate mhi.bin MHI firmware file */
			ath12k_core_create_firmware_path(ab, ATH12K_AMSS_FILE,
							 ab_pci->amss_path,
							 sizeof(ab_pci->amss_path));
			mhi_ctrl->fw_image = ab_pci->amss_path;

Annotation

Implementation Notes