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

Commit c4c3138a authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: ipa: support GRO feature for netmgrd"

parents c952020e 8b10679f
Loading
Loading
Loading
Loading
+89 −9
Original line number Diff line number Diff line
@@ -25,16 +25,24 @@
#define POLLING_MIN_SLEEP_TX 400
#define POLLING_MAX_SLEEP_TX 500
/* 8K less 1 nominal MTU (1500 bytes) rounded to units of KB */
#define IPA_MTU 1500
#define IPA_GENERIC_AGGR_BYTE_LIMIT 6
#define IPA_GENERIC_AGGR_TIME_LIMIT 1
#define IPA_GENERIC_AGGR_PKT_LIMIT 0

#define IPA_GENERIC_RX_BUFF_BASE_SZ 8192
#define IPA_REAL_GENERIC_RX_BUFF_SZ (SKB_DATA_ALIGN(\
		IPA_GENERIC_RX_BUFF_BASE_SZ + NET_SKB_PAD) +\
#define IPA_REAL_GENERIC_RX_BUFF_SZ(X) (SKB_DATA_ALIGN(\
		(X) + NET_SKB_PAD) +\
		SKB_DATA_ALIGN(sizeof(struct skb_shared_info)))
#define IPA_GENERIC_RX_BUFF_SZ (IPA_GENERIC_RX_BUFF_BASE_SZ -\
		(IPA_REAL_GENERIC_RX_BUFF_SZ - IPA_GENERIC_RX_BUFF_BASE_SZ))
#define IPA_GENERIC_RX_BUFF_SZ(X) ((X) -\
		(IPA_REAL_GENERIC_RX_BUFF_SZ(X) - (X)))
#define IPA_GENERIC_RX_BUFF_LIMIT (\
		IPA_REAL_GENERIC_RX_BUFF_SZ(\
		IPA_GENERIC_RX_BUFF_BASE_SZ) -\
		IPA_GENERIC_RX_BUFF_BASE_SZ)

/* less 1 nominal MTU (1500 bytes) rounded to units of KB */
#define IPA_ADJUST_AGGR_BYTE_LIMIT(X) (((X) - IPA_MTU)/1000)

#define IPA_WLAN_RX_POOL_SZ 100
#define IPA_WLAN_RX_POOL_SZ_LOW_WM 5
@@ -65,6 +73,8 @@ static void ipa_wq_repl_rx(struct work_struct *work);
static void ipa_dma_memcpy_notify(struct ipa_sys_context *sys,
		struct sps_iovec *iovec);

static u32 ipa_adjust_ra_buff_base_sz(u32 aggr_byte_limit);

static void ipa_wq_write_done_common(struct ipa_sys_context *sys, u32 cnt)
{
	struct ipa_tx_pkt_wrapper *tx_pkt_expected;
@@ -2125,6 +2135,12 @@ static int ipa_wan_rx_pyld_hdlr(struct sk_buff *skb,
		IPAERR("ZLT\n");
		goto bail;
	}

	if (ipa_ctx->ipa_client_apps_wan_cons_agg_gro) {
		sys->ep->client_notify(sys->ep->priv,
					IPA_RECEIVE, (unsigned long)(skb));
		return rc;
	}
	/*
	 * payload splits across 2 buff or more,
	 * take the start of the payload from prev_skb
@@ -2132,6 +2148,7 @@ static int ipa_wan_rx_pyld_hdlr(struct sk_buff *skb,
	if (sys->len_rem)
		wan_rx_handle_splt_pyld(skb, sys);


	while (skb->len) {
		IPADBG("LEN_REM %d\n", skb->len);
		if (skb->len < IPA_PKT_STATUS_SIZE) {
@@ -2566,26 +2583,69 @@ static int ipa_assign_policy(struct ipa_sys_connect_params *in,
						replenish_rx_work_func);
				INIT_WORK(&sys->repl_work, ipa_wq_repl_rx);
				atomic_set(&sys->curr_polling_state, 0);
				sys->rx_buff_sz = IPA_GENERIC_RX_BUFF_SZ;
				sys->rx_buff_sz = IPA_GENERIC_RX_BUFF_SZ(
					IPA_GENERIC_RX_BUFF_BASE_SZ);
				sys->get_skb = ipa_get_skb_ipa_rx;
				sys->free_skb = ipa_free_skb_rx;
				in->ipa_ep_cfg.aggr.aggr_en = IPA_ENABLE_AGGR;
				in->ipa_ep_cfg.aggr.aggr = IPA_GENERIC;
				in->ipa_ep_cfg.aggr.aggr_byte_limit =
					IPA_GENERIC_AGGR_BYTE_LIMIT;
				in->ipa_ep_cfg.aggr.aggr_time_limit =
					IPA_GENERIC_AGGR_TIME_LIMIT;
				in->ipa_ep_cfg.aggr.aggr_pkt_limit =
					IPA_GENERIC_AGGR_PKT_LIMIT;
				if (in->client == IPA_CLIENT_APPS_LAN_CONS) {
					sys->pyld_hdlr = ipa_lan_rx_pyld_hdlr;
					sys->rx_pool_sz =
						IPA_GENERIC_RX_POOL_SZ;
					in->ipa_ep_cfg.aggr.aggr_byte_limit =
					IPA_GENERIC_AGGR_BYTE_LIMIT;
					in->ipa_ep_cfg.aggr.aggr_pkt_limit =
					IPA_GENERIC_AGGR_PKT_LIMIT;
				} else if (in->client ==
						IPA_CLIENT_APPS_WAN_CONS) {
					sys->pyld_hdlr = ipa_wan_rx_pyld_hdlr;
					sys->rx_pool_sz =
						ipa_ctx->wan_rx_ring_size;
					if (ipa_ctx->
					ipa_client_apps_wan_cons_agg_gro) {
						IPAERR("get close-by %u\n",
						ipa_adjust_ra_buff_base_sz(
						in->ipa_ep_cfg.aggr.
						aggr_byte_limit));
						IPAERR("set rx_buff_sz %lu\n",
						(unsigned long int)
						IPA_GENERIC_RX_BUFF_SZ(
						ipa_adjust_ra_buff_base_sz(
						in->ipa_ep_cfg.
							aggr.aggr_byte_limit)));
						/* disable ipa_status */
						sys->ep->status.
							status_en = false;
						sys->rx_buff_sz =
						IPA_GENERIC_RX_BUFF_SZ(
						ipa_adjust_ra_buff_base_sz(
						in->ipa_ep_cfg.aggr.
							aggr_byte_limit));
						in->ipa_ep_cfg.aggr.
							aggr_byte_limit =
						sys->rx_buff_sz < in->
						ipa_ep_cfg.aggr.
						aggr_byte_limit ?
						IPA_ADJUST_AGGR_BYTE_LIMIT(
						sys->rx_buff_sz) :
						IPA_ADJUST_AGGR_BYTE_LIMIT(
						in->ipa_ep_cfg.
						aggr.aggr_byte_limit);
						IPAERR("set aggr_limit %lu\n",
						(unsigned long int)
						in->ipa_ep_cfg.aggr.
						aggr_byte_limit);
					} else {
						in->ipa_ep_cfg.aggr.
							aggr_byte_limit =
						IPA_GENERIC_AGGR_BYTE_LIMIT;
						in->ipa_ep_cfg.aggr.
							aggr_pkt_limit =
						IPA_GENERIC_AGGR_PKT_LIMIT;
					}
				}
				if (nr_cpu_ids > 1)
					sys->repl_hdlr =
@@ -3001,3 +3061,23 @@ int ipa_sys_teardown(u32 clnt_hdl)
	return 0;
}
EXPORT_SYMBOL(ipa_sys_teardown);

/**
 * ipa_adjust_ra_buff_base_sz()
 *
 * Return value: the largest power of two which is smaller
 * than the input value
 */
static u32 ipa_adjust_ra_buff_base_sz(u32 aggr_byte_limit)
{
	aggr_byte_limit += IPA_MTU;
	aggr_byte_limit += IPA_GENERIC_RX_BUFF_LIMIT;
	aggr_byte_limit--;
	aggr_byte_limit |= aggr_byte_limit >> 1;
	aggr_byte_limit |= aggr_byte_limit >> 2;
	aggr_byte_limit |= aggr_byte_limit >> 4;
	aggr_byte_limit |= aggr_byte_limit >> 8;
	aggr_byte_limit |= aggr_byte_limit >> 16;
	aggr_byte_limit++;
	return aggr_byte_limit >> 1;
}
+4 −0
Original line number Diff line number Diff line
@@ -1125,6 +1125,7 @@ struct ipa_sps_pm {
 * @uc_wdi_ctx: WDI specific fields for uC interface
 * @ipa_num_pipes: The number of pipes used by IPA HW
 * @skip_uc_pipe_reset: Indicates whether pipe reset via uC needs to be avoided
 * @ipa_client_apps_wan_cons_agg_gro: RMNET_IOCTL_INGRESS_FORMAT_AGG_DATA

 * IPA context - holds all relevant info about IPA driver and its state
 */
@@ -1226,6 +1227,9 @@ struct ipa_context {
	u32 peer_bam_map_cnt;
	u32 wdi_map_cnt;
	bool use_dma_zone;

	/* RMNET_IOCTL_INGRESS_FORMAT_AGG_DATA */
	bool ipa_client_apps_wan_cons_agg_gro;
};

/**
+40 −0
Original line number Diff line number Diff line
@@ -43,6 +43,13 @@
#define IPA_EOT_COAL_GRAN_MIN (1)
#define IPA_EOT_COAL_GRAN_MAX (16)

#define IPA_AGGR_BYTE_LIMIT (\
		IPA_ENDP_INIT_AGGR_N_AGGR_BYTE_LIMIT_BMSK >> \
		IPA_ENDP_INIT_AGGR_N_AGGR_BYTE_LIMIT_SHFT)
#define IPA_AGGR_PKT_LIMIT (\
		IPA_ENDP_INIT_AGGR_n_AGGR_PKT_LIMIT_BMSK >> \
		IPA_ENDP_INIT_AGGR_n_AGGR_PKT_LIMIT_SHFT)

static const int ipa_ofst_meq32[] = { IPA_OFFSET_MEQ32_0,
					IPA_OFFSET_MEQ32_1, -1 };
static const int ipa_ofst_meq128[] = { IPA_OFFSET_MEQ128_0,
@@ -4802,3 +4809,36 @@ u32 ipa_get_num_pipes(void)
		return IPA_MAX_NUM_PIPES;
}
EXPORT_SYMBOL(ipa_get_num_pipes);

/**
 * ipa_disable_apps_wan_cons_deaggr()- set ipa_ctx->ipa_client_apps_wan_cons_agg_gro
 *
 * Return value: 0 or negative in case of failure
 */
int ipa_disable_apps_wan_cons_deaggr(uint32_t agg_size, uint32_t agg_count)
{
	int res = -1;

	/* checking if IPA-HW can support */
	if ((agg_size >> 10) >
		IPA_AGGR_BYTE_LIMIT) {
		IPAWANERR("IPA-AGG byte limit %d\n",
		IPA_AGGR_BYTE_LIMIT);
		IPAWANERR("exceed aggr_byte_limit\n");
		return res;
		}
	if (agg_count >
		IPA_AGGR_PKT_LIMIT) {
		IPAWANERR("IPA-AGG pkt limit %d\n",
		IPA_AGGR_PKT_LIMIT);
		IPAWANERR("exceed aggr_pkt_limit\n");
		return res;
	}

	if (ipa_ctx) {
		ipa_ctx->ipa_client_apps_wan_cons_agg_gro = true;
		return 0;
	}
	return res;
}
EXPORT_SYMBOL(ipa_disable_apps_wan_cons_deaggr);
+22 −0
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@
#include <soc/qcom/subsystem_notif.h>
#include "ipa_qmi_service.h"
#include <linux/rmnet_ipa_fd_ioctl.h>
#include <linux/ipa.h>

#define WWAN_METADATA_SHFT 24
#define WWAN_METADATA_MASK 0xFF000000
@@ -1429,6 +1430,27 @@ static int ipa_wwan_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
				ipa_to_apps_ep_cfg.ipa_ep_cfg.cfg.
					cs_offload_en = 2;

			if ((extend_ioctl_data.u.data) &
					RMNET_IOCTL_INGRESS_FORMAT_AGG_DATA) {
				IPAWANERR("get AGG size %d count %d\n",
					extend_ioctl_data.u.
					ingress_format.agg_size,
					extend_ioctl_data.u.
					ingress_format.agg_count);
				if (!ipa_disable_apps_wan_cons_deaggr(
					extend_ioctl_data.u.
					ingress_format.agg_size,
					extend_ioctl_data.
					u.ingress_format.agg_count)) {
					ipa_to_apps_ep_cfg.ipa_ep_cfg.aggr.
					aggr_byte_limit = extend_ioctl_data.
					u.ingress_format.agg_size;
					ipa_to_apps_ep_cfg.ipa_ep_cfg.aggr.
					aggr_pkt_limit = extend_ioctl_data.
					u.ingress_format.agg_count;
				}
			}

			ipa_to_apps_ep_cfg.ipa_ep_cfg.hdr.hdr_len = 4;
			ipa_to_apps_ep_cfg.ipa_ep_cfg.hdr.
				hdr_ofst_metadata_valid = 1;
+6 −0
Original line number Diff line number Diff line
@@ -1412,6 +1412,8 @@ bool ipa_get_modem_cfg_emb_pipe_flt(void);
struct device *ipa_get_dma_dev(void);
struct iommu_domain *ipa_get_smmu_domain(void);

int ipa_disable_apps_wan_cons_deaggr(uint32_t agg_size, uint32_t agg_count);

#else /* CONFIG_IPA */

/*
@@ -2141,6 +2143,10 @@ static inline int ipa_release_wdi_mapping(u32 num_buffers,
	return -EINVAL;
}

static inline int ipa_disable_apps_wan_cons_deaggr(void)
{
	return -EINVAL;
}
#endif /* CONFIG_IPA*/

#endif /* _IPA_H_ */