Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 436b3d6e authored by qctecmdr Service's avatar qctecmdr Service Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: ipa: Add support for pdn in hal"

parents e544c896 d59d06ba
Loading
Loading
Loading
Loading
+8 −10
Original line number Diff line number Diff line
@@ -4664,15 +4664,11 @@ static int ipa3_post_init(const struct ipa3_plat_drv_res *resource_p,
		flt_tbl->rule_ids = &ipa3_ctx->flt_rule_ids[IPA_IP_v6];
	}

	if (!ipa3_ctx->apply_rg10_wa) {
	result = ipa3_init_interrupts();
	if (result) {
		IPAERR("ipa initialization of interrupts failed\n");
		result = -ENODEV;
			goto fail_register_device;
		}
	} else {
		IPADBG("Initialization of ipa interrupts skipped\n");
		goto fail_init_interrupts;
	}

	/*
@@ -4802,6 +4798,9 @@ static int ipa3_post_init(const struct ipa3_plat_drv_res *resource_p,
	gsi_deregister_device(ipa3_ctx->gsi_dev_hdl, false);
fail_register_device:
	ipa3_destroy_flt_tbl_idrs();
fail_init_interrupts:
	 ipa3_remove_interrupt_handler(IPA_TX_SUSPEND_IRQ);
	 ipa3_interrupts_destroy(ipa3_res.ipa_irq, &ipa3_ctx->master_pdev->dev);
fail_allok_pkt_init:
	ipa3_nat_ipv6ct_destroy_devices();
fail_nat_ipv6ct_init_dev:
@@ -5205,7 +5204,6 @@ static int ipa3_pre_init(const struct ipa3_plat_drv_res *resource_p,
	ipa3_ctx->skip_uc_pipe_reset = resource_p->skip_uc_pipe_reset;
	ipa3_ctx->tethered_flow_control = resource_p->tethered_flow_control;
	ipa3_ctx->ee = resource_p->ee;
	ipa3_ctx->apply_rg10_wa = resource_p->apply_rg10_wa;
	ipa3_ctx->gsi_ch20_wa = resource_p->gsi_ch20_wa;
	ipa3_ctx->use_ipa_pm = resource_p->use_ipa_pm;
	ipa3_ctx->wdi_over_pcie = resource_p->wdi_over_pcie;
+0 −13
Original line number Diff line number Diff line
@@ -107,19 +107,6 @@ int ipa3_disable_data_path(u32 clnt_hdl)
	if (ipa3_ctx->ipa_hw_type < IPA_HW_v4_0) {
		/* Suspend the pipe */
		if (IPA_CLIENT_IS_CONS(ep->client)) {
			/*
			 * for RG10 workaround uC needs to be loaded before
			 * pipe can be suspended in this case.
			 */
			if (ipa3_ctx->apply_rg10_wa && ipa3_uc_state_check()) {
				IPADBG("uC is not loaded yet, waiting...\n");
				res = wait_for_completion_timeout(
					&ipa3_ctx->uc_loaded_completion_obj,
					60 * HZ);
				if (res == 0)
					IPADBG("timeout waiting for uC load\n");
			}

			memset(&ep_cfg_ctrl, 0, sizeof(struct ipa_ep_cfg_ctrl));
			ep_cfg_ctrl.ipa_ep_suspend = true;
			res = ipa3_cfg_ep_ctrl(clnt_hdl, &ep_cfg_ctrl);
+0 −16
Original line number Diff line number Diff line
@@ -1006,20 +1006,6 @@ struct ipa3_rx_pkt_wrapper {
	struct ipa3_sys_context *sys;
};

/**
 * struct ipa_pdn_entry - IPA PDN config table entry
 * @public_ip: the PDN's public ip
 * @src_metadata: the PDN's metadata to be replaced for source NAT
 * @dst_metadata: the PDN's metadata to be replaced for destination NAT
 * @resrvd: reserved field
 */
struct ipa_pdn_entry {
	u32 public_ip;
	u32 src_metadata;
	u32 dst_metadata;
	u32 resrvd;
};

/**
 * struct ipa3_nat_ipv6ct_tmp_mem - NAT/IPv6CT temporary memory
 *
@@ -2495,7 +2481,6 @@ int ipa3_uc_interface_init(void);
int ipa3_uc_is_gsi_channel_empty(enum ipa_client_type ipa_client);
int ipa3_uc_state_check(void);
int ipa3_uc_loaded_check(void);
void ipa3_uc_load_notify(void);
int ipa3_uc_send_cmd(u32 cmd, u32 opcode, u32 expected_status,
		    bool polling_mode, unsigned long timeout_jiffies);
void ipa3_uc_register_handlers(enum ipa3_hw_features feature,
@@ -2526,7 +2511,6 @@ int ipa3_uc_send_remote_ipa_info(u32 remote_addr, uint32_t mbox_n);
void ipa3_tag_destroy_imm(void *user1, int user2);
const struct ipa_gsi_ep_config *ipa3_get_gsi_ep_info
	(enum ipa_client_type client);
void ipa3_uc_rg10_write_reg(enum ipahal_reg_name reg, u32 n, u32 val);

/* Hardware stats */

+6 −26
Original line number Diff line number Diff line
@@ -136,20 +136,6 @@ static int ipa3_handle_interrupt(int irq_num, bool isr_context)
		suspend_interrupt_data->endpoints = suspend_data;
		interrupt_data = suspend_interrupt_data;
		break;
	case IPA_UC_IRQ_0:
		if (ipa3_ctx->apply_rg10_wa) {
			/*
			 * Early detect of uC crash. If RG10 workaround is
			 * enable uC crash will not be detected as before
			 * processing uC event the interrupt is cleared using
			 * uC register write which times out as it crashed
			 * already.
			 */
			if (ipa3_ctx->uc_ctx.uc_sram_mmio->eventOp ==
			    IPA_HW_2_CPU_EVENT_ERROR)
				ipa3_ctx->uc_ctx.uc_failed = true;
		}
		break;
	default:
		break;
	}
@@ -212,7 +198,7 @@ static void ipa3_enable_tx_suspend_wa(struct work_struct *work)
	en |= suspend_bmask;
	IPADBG("enable TX_SUSPEND_IRQ, IPA_IRQ_EN_EE reg, write val = %u\n"
		, en);
	ipa3_uc_rg10_write_reg(IPA_IRQ_EN_EE_n, ipa_ee, en);
	ipahal_write_reg_n(IPA_IRQ_EN_EE_n, ipa_ee, en);
	ipa3_process_interrupts(false);
	IPA_ACTIVE_CLIENTS_DEC_SIMPLE();

@@ -240,7 +226,7 @@ static void ipa3_tx_suspend_interrupt_wa(void)
	val &= ~suspend_bmask;
	IPADBG("Disabling TX_SUSPEND_IRQ, write val: %u to IPA_IRQ_EN_EE reg\n",
		val);
	ipa3_uc_rg10_write_reg(IPA_IRQ_EN_EE_n, ipa_ee, val);
	ipahal_write_reg_n(IPA_IRQ_EN_EE_n, ipa_ee, val);

	IPADBG_LOW(" processing suspend interrupt work-around, delayed work\n");

@@ -295,7 +281,7 @@ static void ipa3_process_interrupts(bool isr_context)
				 * clearing unhandled interrupts
				 */
				if (uc_irq)
					ipa3_uc_rg10_write_reg(IPA_IRQ_CLR_EE_n,
					ipahal_write_reg_n(IPA_IRQ_CLR_EE_n,
							ipa_ee, bmsk);

				/*
@@ -314,17 +300,11 @@ static void ipa3_process_interrupts(bool isr_context)
				 * to avoid clearing interrupt data
				 */
				if (!uc_irq)
					ipa3_uc_rg10_write_reg(IPA_IRQ_CLR_EE_n,
					ipahal_write_reg_n(IPA_IRQ_CLR_EE_n,
							ipa_ee, bmsk);
			}
			bmsk = bmsk << 1;
		}
		/*
		 * In case uC failed interrupt cannot be cleared.
		 * Device will crash as part of handling uC event handler.
		 */
		if (ipa3_ctx->apply_rg10_wa && ipa3_ctx->uc_ctx.uc_failed)
			break;

		reg = ipahal_read_reg_n(IPA_IRQ_STTS_EE_n, ipa_ee);
		/* since the suspend interrupt HW bug we must
@@ -416,7 +396,7 @@ int ipa3_add_interrupt_handler(enum ipa_irq_type interrupt,
	IPADBG("read IPA_IRQ_EN_EE_n register. reg = %d\n", val);
	bmsk = 1 << irq_num;
	val |= bmsk;
	ipa3_uc_rg10_write_reg(IPA_IRQ_EN_EE_n, ipa_ee, val);
	ipahal_write_reg_n(IPA_IRQ_EN_EE_n, ipa_ee, val);
	IPADBG("wrote IPA_IRQ_EN_EE_n register. reg = %d\n", val);

	/* register SUSPEND_IRQ_EN_EE_n_ADDR for L2 interrupt*/
@@ -482,7 +462,7 @@ int ipa3_remove_interrupt_handler(enum ipa_irq_type interrupt)
	val = ipahal_read_reg_n(IPA_IRQ_EN_EE_n, ipa_ee);
	bmsk = 1 << irq_num;
	val &= ~bmsk;
	ipa3_uc_rg10_write_reg(IPA_IRQ_EN_EE_n, ipa_ee, val);
	ipahal_write_reg_n(IPA_IRQ_EN_EE_n, ipa_ee, val);

	return 0;
}
+45 −22
Original line number Diff line number Diff line
@@ -917,14 +917,21 @@ int ipa3_nat_init_cmd(struct ipa_ioc_v4_nat_init *init)
	}

	if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_0) {
		struct ipa_pdn_entry *pdn_entries;
		struct ipahal_nat_pdn_entry pdn_entry;

		/* store ip in pdn entries cache array */
		pdn_entries = ipa3_ctx->nat_mem.pdn_mem.base;
		pdn_entries[0].public_ip = init->ip_addr;
		pdn_entries[0].dst_metadata = 0;
		pdn_entries[0].src_metadata = 0;
		pdn_entries[0].resrvd = 0;
		/* store ip in pdn entry cache array */
		pdn_entry.public_ip = init->ip_addr;
		pdn_entry.src_metadata = 0;
		pdn_entry.dst_metadata = 0;

		result = ipahal_nat_construct_entry(
			IPAHAL_NAT_IPV4_PDN,
			&pdn_entry,
			ipa3_ctx->nat_mem.pdn_mem.base);
		if (result) {
			IPAERR("Fail to construct NAT pdn entry\n");
			return result;
		}

		IPADBG("Public ip address:0x%x\n", init->ip_addr);
	}
@@ -1082,7 +1089,8 @@ int ipa3_nat_mdfy_pdn(struct ipa_ioc_nat_pdn_entry *mdfy_pdn)
	struct ipahal_imm_cmd_pyld *cmd_pyld;
	int result = 0;
	struct ipa3_nat_mem *nat_ctx = &(ipa3_ctx->nat_mem);
	struct ipa_pdn_entry *pdn_entries = NULL;
	struct ipahal_nat_pdn_entry pdn_fields;
	size_t entry_size;

	IPADBG("\n");

@@ -1107,27 +1115,42 @@ int ipa3_nat_mdfy_pdn(struct ipa_ioc_nat_pdn_entry *mdfy_pdn)
		goto bail;
	}

	pdn_entries = nat_ctx->pdn_mem.base;

	/* store ip in pdn entries cache array */
	pdn_entries[mdfy_pdn->pdn_index].public_ip =
		mdfy_pdn->public_ip;
	pdn_entries[mdfy_pdn->pdn_index].dst_metadata =
		mdfy_pdn->dst_metadata;
	pdn_entries[mdfy_pdn->pdn_index].src_metadata =
		mdfy_pdn->src_metadata;
	/* store ip in pdn entry cache array */
	pdn_fields.public_ip = mdfy_pdn->public_ip;
	pdn_fields.dst_metadata = mdfy_pdn->dst_metadata;
	pdn_fields.src_metadata = mdfy_pdn->src_metadata;

	/* mark tethering bit for remote modem */
	if (ipa3_ctx->ipa_hw_type == IPA_HW_v4_1)
		pdn_entries[mdfy_pdn->pdn_index].src_metadata |=
	if (ipa3_ctx->ipa_hw_type == IPA_HW_v4_1) {
		pdn_fields.src_metadata |=
			IPA_QMAP_TETH_BIT;
	}

	/* get size of the entry */
	result = ipahal_nat_entry_size(
		IPAHAL_NAT_IPV4_PDN,
		&entry_size);
	if (result) {
		IPAERR("Failed to retrieve pdn entry size\n");
		goto bail;
	}

	result = ipahal_nat_construct_entry(
		IPAHAL_NAT_IPV4_PDN,
		&pdn_fields,
		(nat_ctx->pdn_mem.base +
		(mdfy_pdn->pdn_index)*(entry_size)));
	if (result) {
		IPAERR("Fail to construct NAT pdn entry\n");
		goto bail;
	}

	IPADBG("Modify PDN in index: %d Public ip address:%pI4h\n",
		mdfy_pdn->pdn_index,
		&pdn_entries[mdfy_pdn->pdn_index].public_ip);
		&pdn_fields.public_ip);
	IPADBG("Modify PDN dst metadata: 0x%x src metadata: 0x%x\n",
		pdn_entries[mdfy_pdn->pdn_index].dst_metadata,
		pdn_entries[mdfy_pdn->pdn_index].src_metadata);
		pdn_fields.dst_metadata,
		pdn_fields.src_metadata);

	/* Copy the PDN config table to SRAM */
	ipa3_nat_create_modify_pdn_cmd(&mem_cmd, false);
Loading