// 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. Load more
// 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 bool ipa_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 void ipa_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;