2198 lines · 62.4 KB · C
RawDownload
// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * Copyright (C) 2019-2024 Linaro Ltd. */ #include <linux/bitfield.h>#include <linux/bits.h>#include <linux/device.h>#include <linux/dma-direction.h>#include <linux/if_rmnet.h>#include <linux/types.h> #include "gsi.h"#include "gsi_trans.h"#include "ipa.h"#include "ipa_cmd.h"#include "ipa_data.h"#include "ipa_endpoint.h"#include "ipa_gsi.h"#include "ipa_interrupt.h"#include "ipa_mem.h"#include "ipa_modem.h"#include "ipa_power.h"#include "ipa_reg.h"#include "ipa_table.h"#include "ipa_version.h" /* Hardware is told about receive buffers once a "batch" has been queued */#define IPA_REPLENISH_BATCH	16		/* Must be non-zero */ /* The amount of RX buffer space consumed by standard skb overhead */#define IPA_RX_BUFFER_OVERHEAD	(PAGE_SIZE - SKB_MAX_ORDER(NET_SKB_PAD, 0)) /* Where to find the QMAP mux_id for a packet within modem-supplied metadata */#define IPA_ENDPOINT_QMAP_METADATA_MASK		0x000000ff /* host byte order */ #define IPA_ENDPOINT_RESET_AGGR_RETRY_MAX	3 /** enum ipa_status_opcode - IPA status opcode field hardware values */enum ipa_status_opcode {				/* *Not* a bitmask */	IPA_STATUS_OPCODE_PACKET		= 1,	IPA_STATUS_OPCODE_NEW_RULE_PACKET	= 2,	IPA_STATUS_OPCODE_DROPPED_PACKET	= 4,	IPA_STATUS_OPCODE_SUSPENDED_PACKET	= 8,	IPA_STATUS_OPCODE_LOG			= 16,	IPA_STATUS_OPCODE_DCMP			= 32,	IPA_STATUS_OPCODE_PACKET_2ND_PASS	= 64,}; /** enum ipa_status_exception - IPA status exception field hardware values */enum ipa_status_exception {				/* *Not* a bitmask */	/* 0 means no exception */	IPA_STATUS_EXCEPTION_DEAGGR		= 1,	IPA_STATUS_EXCEPTION_IPTYPE		= 4,	IPA_STATUS_EXCEPTION_PACKET_LENGTH	= 8,	IPA_STATUS_EXCEPTION_FRAG_RULE_MISS	= 16,	IPA_STATUS_EXCEPTION_SW_FILTER		= 32,	IPA_STATUS_EXCEPTION_NAT		= 64,		/* IPv4 */	IPA_STATUS_EXCEPTION_IPV6_CONN_TRACK	= 64,		/* IPv6 */	IPA_STATUS_EXCEPTION_UC			= 128,	IPA_STATUS_EXCEPTION_INVALID_ENDPOINT	= 129,	IPA_STATUS_EXCEPTION_HEADER_INSERT	= 136,	IPA_STATUS_EXCEPTION_CHEKCSUM		= 229,}; /** enum ipa_status_mask - IPA status mask field bitmask hardware values */enum ipa_status_mask {	IPA_STATUS_MASK_FRAG_PROCESS		= BIT(0),	IPA_STATUS_MASK_FILT_PROCESS		= BIT(1),	IPA_STATUS_MASK_NAT_PROCESS		= BIT(2),	IPA_STATUS_MASK_ROUTE_PROCESS		= BIT(3),	IPA_STATUS_MASK_TAG_VALID		= BIT(4),	IPA_STATUS_MASK_FRAGMENT		= BIT(5),	IPA_STATUS_MASK_FIRST_FRAGMENT		= BIT(6),	IPA_STATUS_MASK_V4			= BIT(7),	IPA_STATUS_MASK_CKSUM_PROCESS		= BIT(8),	IPA_STATUS_MASK_AGGR_PROCESS		= BIT(9),	IPA_STATUS_MASK_DEST_EOT		= BIT(10),	IPA_STATUS_MASK_DEAGGR_PROCESS		= BIT(11),	IPA_STATUS_MASK_DEAGG_FIRST		= BIT(12),	IPA_STATUS_MASK_SRC_EOT			= BIT(13),	IPA_STATUS_MASK_PREV_EOT		= BIT(14),	IPA_STATUS_MASK_BYTE_LIMIT		= BIT(15),}; /* Special IPA filter/router rule field value indicating "rule miss" */#define IPA_STATUS_RULE_MISS	0x3ff	/* 10-bit filter/router rule fields */ /** The IPA status nat_type field uses enum ipa_nat_type hardware values */ /* enum ipa_status_field_id - IPA packet status structure field identifiers */enum ipa_status_field_id {	STATUS_OPCODE,			/* enum ipa_status_opcode */	STATUS_EXCEPTION,		/* enum ipa_status_exception */	STATUS_MASK,			/* enum ipa_status_mask (bitmask) */	STATUS_LENGTH,	STATUS_SRC_ENDPOINT,	STATUS_DST_ENDPOINT,	STATUS_METADATA,	STATUS_FILTER_LOCAL,		/* Boolean */	STATUS_FILTER_HASH,		/* Boolean */	STATUS_FILTER_GLOBAL,		/* Boolean */	STATUS_FILTER_RETAIN,		/* Boolean */	STATUS_FILTER_RULE_INDEX,	STATUS_ROUTER_LOCAL,		/* Boolean */	STATUS_ROUTER_HASH,		/* Boolean */	STATUS_UCP,			/* Boolean */	STATUS_ROUTER_TABLE,	STATUS_ROUTER_RULE_INDEX,	STATUS_NAT_HIT,			/* Boolean */	STATUS_NAT_INDEX,	STATUS_NAT_TYPE,		/* enum ipa_nat_type */	STATUS_TAG_LOW32,		/* Low-order 32 bits of 48-bit tag */	STATUS_TAG_HIGH16,		/* High-order 16 bits of 48-bit tag */	STATUS_SEQUENCE,	STATUS_TIME_OF_DAY,	STATUS_HEADER_LOCAL,		/* Boolean */	STATUS_HEADER_OFFSET,	STATUS_FRAG_HIT,		/* Boolean */	STATUS_FRAG_RULE_INDEX,}; /* Size in bytes of an IPA packet status structure */#define IPA_STATUS_SIZE			sizeof(__le32[8]) /* IPA status structure decoder; looks up field values for a structure */static u32 ipa_status_extract(struct ipa *ipa, const void *data,			      enum ipa_status_field_id field){	enum ipa_version version = ipa->version;	const __le32 *word = data; 	switch (field) {	case STATUS_OPCODE:		return le32_get_bits(word[0], GENMASK(7, 0));	case STATUS_EXCEPTION:		return le32_get_bits(word[0], GENMASK(15, 8));	case STATUS_MASK:		return le32_get_bits(word[0], GENMASK(31, 16));	case STATUS_LENGTH:		return le32_get_bits(word[1], GENMASK(15, 0));	case STATUS_SRC_ENDPOINT:		if (version < IPA_VERSION_5_0)			return le32_get_bits(word[1], GENMASK(20, 16));		return le32_get_bits(word[1], GENMASK(23, 16));	/* Status word 1, bits 21-23 are reserved (not IPA v5.0+) */	/* Status word 1, bits 24-26 are reserved (IPA v5.0+) */	case STATUS_DST_ENDPOINT:		if (version < IPA_VERSION_5_0)			return le32_get_bits(word[1], GENMASK(28, 24));		return le32_get_bits(word[7], GENMASK(23, 16));	/* Status word 1, bits 29-31 are reserved */	case STATUS_METADATA:		return le32_to_cpu(word[2]);	case STATUS_FILTER_LOCAL:		return le32_get_bits(word[3], GENMASK(0, 0));	case STATUS_FILTER_HASH:		return le32_get_bits(word[3], GENMASK(1, 1));	case STATUS_FILTER_GLOBAL:		return le32_get_bits(word[3], GENMASK(2, 2));	case STATUS_FILTER_RETAIN:		return le32_get_bits(word[3], GENMASK(3, 3));	case STATUS_FILTER_RULE_INDEX:		return le32_get_bits(word[3], GENMASK(13, 4));	/* ROUTER_TABLE is in word 3, bits 14-21 (IPA v5.0+) */	case STATUS_ROUTER_LOCAL:		if (version < IPA_VERSION_5_0)			return le32_get_bits(word[3], GENMASK(14, 14));		return le32_get_bits(word[1], GENMASK(27, 27));	case STATUS_ROUTER_HASH:		if (version < IPA_VERSION_5_0)			return le32_get_bits(word[3], GENMASK(15, 15));		return le32_get_bits(word[1], GENMASK(28, 28));	case STATUS_UCP:		if (version < IPA_VERSION_5_0)			return le32_get_bits(word[3], GENMASK(16, 16));		return le32_get_bits(word[7], GENMASK(31, 31));	case STATUS_ROUTER_TABLE:		if (version < IPA_VERSION_5_0)			return le32_get_bits(word[3], GENMASK(21, 17));		return le32_get_bits(word[3], GENMASK(21, 14));	case STATUS_ROUTER_RULE_INDEX:		return le32_get_bits(word[3], GENMASK(31, 22));	case STATUS_NAT_HIT:		return le32_get_bits(word[4], GENMASK(0, 0));	case STATUS_NAT_INDEX:		return le32_get_bits(word[4], GENMASK(13, 1));	case STATUS_NAT_TYPE:		return le32_get_bits(word[4], GENMASK(15, 14));	case STATUS_TAG_LOW32:		return le32_get_bits(word[4], GENMASK(31, 16)) |			(le32_get_bits(word[5], GENMASK(15, 0)) << 16);	case STATUS_TAG_HIGH16:		return le32_get_bits(word[5], GENMASK(31, 16));	case STATUS_SEQUENCE:		return le32_get_bits(word[6], GENMASK(7, 0));	case STATUS_TIME_OF_DAY:		return le32_get_bits(word[6], GENMASK(31, 8));	case STATUS_HEADER_LOCAL:		return le32_get_bits(word[7], GENMASK(0, 0));	case STATUS_HEADER_OFFSET:		return le32_get_bits(word[7], GENMASK(10, 1));	case STATUS_FRAG_HIT:		return le32_get_bits(word[7], GENMASK(11, 11));	case STATUS_FRAG_RULE_INDEX:		return le32_get_bits(word[7], GENMASK(15, 12));	/* Status word 7, bits 16-30 are reserved */	/* Status word 7, bit 31 is reserved (not IPA v5.0+) */	default:		WARN(true, "%s: bad field_id %u\n", __func__, field);		return 0;	}} /* Compute the aggregation size value to use for a given buffer size */static u32 ipa_aggr_size_kb(u32 rx_buffer_size, bool aggr_hard_limit){	/* A hard aggregation limit will not be crossed; aggregation closes	 * if saving incoming data would cross the hard byte limit boundary.	 *	 * With a soft limit, aggregation closes *after* the size boundary	 * has been crossed.  In that case the limit must leave enough space	 * after that limit to receive a full MTU of data plus overhead.	 */	if (!aggr_hard_limit)		rx_buffer_size -= IPA_MTU + IPA_RX_BUFFER_OVERHEAD; 	/* The byte limit is encoded as a number of kilobytes */ 	return rx_buffer_size / SZ_1K;} static bool ipa_endpoint_data_valid_one(struct ipa *ipa, u32 count,			    const struct ipa_gsi_endpoint_data *all_data,			    const struct ipa_gsi_endpoint_data *data){	const struct ipa_gsi_endpoint_data *other_data;	enum ipa_endpoint_name other_name;	struct device *dev = ipa->dev; 	if (ipa_gsi_endpoint_data_empty(data))		return true; 	if (!data->toward_ipa) {		const struct ipa_endpoint_rx *rx_config;		const struct reg *reg;		u32 buffer_size;		u32 aggr_size;		u32 limit; 		if (data->endpoint.filter_support) {			dev_err(dev, "filtering not supported for "					"RX endpoint %u\n",				data->endpoint_id);			return false;		} 		/* Nothing more to check for non-AP RX */		if (data->ee_id != GSI_EE_AP)			return true; 		rx_config = &data->endpoint.config.rx; 		/* The buffer size must hold an MTU plus overhead */		buffer_size = rx_config->buffer_size;		limit = IPA_MTU + IPA_RX_BUFFER_OVERHEAD;		if (buffer_size < limit) {			dev_err(dev, "RX buffer size too small for RX endpoint %u (%u < %u)\n",				data->endpoint_id, buffer_size, limit);			return false;		} 		if (!data->endpoint.config.aggregation) {			bool result = true; 			/* No aggregation; check for bogus aggregation data */			if (rx_config->aggr_time_limit) {				dev_err(dev,					"time limit with no aggregation for RX endpoint %u\n",					data->endpoint_id);				result = false;			} 			if (rx_config->aggr_hard_limit) {				dev_err(dev, "hard limit with no aggregation for RX endpoint %u\n",					data->endpoint_id);				result = false;			} 			if (rx_config->aggr_close_eof) {				dev_err(dev, "close EOF with no aggregation for RX endpoint %u\n",					data->endpoint_id);				result = false;			} 			return result;	/* Nothing more to check */		} 		/* For an endpoint supporting receive aggregation, the byte		 * limit defines the point at which aggregation closes.  This		 * check ensures the receive buffer size doesn't result in a		 * limit that exceeds what's representable in the aggregation		 * byte limit field.		 */		aggr_size = ipa_aggr_size_kb(buffer_size - NET_SKB_PAD,					     rx_config->aggr_hard_limit);		reg = ipa_reg(ipa, ENDP_INIT_AGGR); 		limit = reg_field_max(reg, BYTE_LIMIT);		if (aggr_size > limit) {			dev_err(dev, "aggregated size too large for RX endpoint %u (%u KB > %u KB)\n",				data->endpoint_id, aggr_size, limit); 			return false;		} 		return true;	/* Nothing more to check for RX */	} 	/* Starting with IPA v4.5 sequencer replication is obsolete */	if (ipa->version >= IPA_VERSION_4_5) {		if (data->endpoint.config.tx.seq_rep_type) {			dev_err(dev, "no-zero seq_rep_type TX endpoint %u\n",				data->endpoint_id);			return false;		}	} 	if (data->endpoint.config.status_enable) {		other_name = data->endpoint.config.tx.status_endpoint;		if (other_name >= count) {			dev_err(dev, "status endpoint name %u out of range "					"for endpoint %u\n",				other_name, data->endpoint_id);			return false;		} 		/* Status endpoint must be defined... */		other_data = &all_data[other_name];		if (ipa_gsi_endpoint_data_empty(other_data)) {			dev_err(dev, "DMA endpoint name %u undefined "					"for endpoint %u\n",				other_name, data->endpoint_id);			return false;		} 		/* ...and has to be an RX endpoint... */		if (other_data->toward_ipa) {			dev_err(dev,				"status endpoint for endpoint %u not RX\n",				data->endpoint_id);			return false;		} 		/* ...and if it's to be an AP endpoint... */		if (other_data->ee_id == GSI_EE_AP) {			/* ...make sure it has status enabled. */			if (!other_data->endpoint.config.status_enable) {				dev_err(dev,					"status not enabled for endpoint %u\n",					other_data->endpoint_id);				return false;			}		}	} 	if (data->endpoint.config.dma_mode) {		other_name = data->endpoint.config.dma_endpoint;		if (other_name >= count) {			dev_err(dev, "DMA endpoint name %u out of range "					"for endpoint %u\n",				other_name, data->endpoint_id);			return false;		} 		other_data = &all_data[other_name];		if (ipa_gsi_endpoint_data_empty(other_data)) {			dev_err(dev, "DMA endpoint name %u undefined "					"for endpoint %u\n",				other_name, data->endpoint_id);			return false;		}	} 	return true;} /* Validate endpoint configuration data.  Return max defined endpoint ID */static u32 ipa_endpoint_max(struct ipa *ipa, u32 count,			    const struct ipa_gsi_endpoint_data *data){	const struct ipa_gsi_endpoint_data *dp = data;	struct device *dev = ipa->dev;	enum ipa_endpoint_name name;	u32 max; 	if (count > IPA_ENDPOINT_COUNT) {		dev_err(dev, "too many endpoints specified (%u > %u)\n",			count, IPA_ENDPOINT_COUNT);		return 0;	} 	/* Make sure needed endpoints have defined data */	if (ipa_gsi_endpoint_data_empty(&data[IPA_ENDPOINT_AP_COMMAND_TX])) {		dev_err(dev, "command TX endpoint not defined\n");		return 0;	}	if (ipa_gsi_endpoint_data_empty(&data[IPA_ENDPOINT_AP_LAN_RX])) {		dev_err(dev, "LAN RX endpoint not defined\n");		return 0;	}	if (ipa_gsi_endpoint_data_empty(&data[IPA_ENDPOINT_AP_MODEM_TX])) {		dev_err(dev, "AP->modem TX endpoint not defined\n");		return 0;	}	if (ipa_gsi_endpoint_data_empty(&data[IPA_ENDPOINT_AP_MODEM_RX])) {		dev_err(dev, "AP<-modem RX endpoint not defined\n");		return 0;	} 	max = 0;	for (name = 0; name < count; name++, dp++) {		if (!ipa_endpoint_data_valid_one(ipa, count, data, dp))			return 0;		max = max_t(u32, max, dp->endpoint_id);	} 	return max;} /* Allocate a transaction to use on a non-command endpoint */static struct gsi_trans *ipa_endpoint_trans_alloc(struct ipa_endpoint *endpoint,						  u32 tre_count){	struct gsi *gsi = &endpoint->ipa->gsi;	u32 channel_id = endpoint->channel_id;	enum dma_data_direction direction; 	direction = endpoint->toward_ipa ? DMA_TO_DEVICE : DMA_FROM_DEVICE; 	return gsi_channel_trans_alloc(gsi, channel_id, tre_count, direction);} /* suspend_delay represents suspend for RX, delay for TX endpoints. * Note that suspend is not supported starting with IPA v4.0, and * delay mode should not be used starting with IPA v4.2. */static boolipa_endpoint_init_ctrl(struct ipa_endpoint *endpoint, bool suspend_delay){	struct ipa *ipa = endpoint->ipa;	const struct reg *reg;	u32 field_id;	u32 offset;	bool state;	u32 mask;	u32 val; 	if (endpoint->toward_ipa)		WARN_ON(ipa->version >= IPA_VERSION_4_2);	else		WARN_ON(ipa->version >= IPA_VERSION_4_0); 	reg = ipa_reg(ipa, ENDP_INIT_CTRL);	offset = reg_n_offset(reg, endpoint->endpoint_id);	val = ioread32(ipa->reg_virt + offset); 	field_id = endpoint->toward_ipa ? ENDP_DELAY : ENDP_SUSPEND;	mask = reg_bit(reg, field_id); 	state = !!(val & mask); 	/* Don't bother if it's already in the requested state */	if (suspend_delay != state) {		val ^= mask;		iowrite32(val, ipa->reg_virt + offset);	} 	return state;} /* We don't care what the previous state was for delay mode */static voidipa_endpoint_program_delay(struct ipa_endpoint *endpoint, bool enable){	/* Delay mode should not be used for IPA v4.2+ */	WARN_ON(endpoint->ipa->version >= IPA_VERSION_4_2);	WARN_ON(!endpoint->toward_ipa); 	(void)ipa_endpoint_init_ctrl(endpoint, enable);} static bool ipa_endpoint_aggr_active(struct ipa_endpoint *endpoint){	u32 endpoint_id = endpoint->endpoint_id;	struct ipa *ipa = endpoint->ipa;	u32 unit = endpoint_id / 32;	const struct reg *reg;	u32 val;

Lines 1–500 of 2198.