diff options
Diffstat (limited to 'drivers/net/ipa/ipa_endpoint.c')
-rw-r--r-- | drivers/net/ipa/ipa_endpoint.c | 90 |
1 files changed, 51 insertions, 39 deletions
diff --git a/drivers/net/ipa/ipa_endpoint.c b/drivers/net/ipa/ipa_endpoint.c index ccc99ad983eb..ab02669bae4e 100644 --- a/drivers/net/ipa/ipa_endpoint.c +++ b/drivers/net/ipa/ipa_endpoint.c @@ -75,8 +75,6 @@ struct ipa_status { #define IPA_STATUS_FLAGS1_RT_RULE_ID_FMASK GENMASK(31, 22) #define IPA_STATUS_FLAGS2_TAG_FMASK GENMASK_ULL(63, 16) -#ifdef IPA_VALIDATE - 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) @@ -88,11 +86,6 @@ static bool ipa_endpoint_data_valid_one(struct ipa *ipa, u32 count, if (ipa_gsi_endpoint_data_empty(data)) return true; - /* IPA v4.5+ uses checksum offload, not yet supported by RMNet */ - if (ipa->version >= IPA_VERSION_4_5) - if (data->endpoint.config.checksum) - return false; - if (!data->toward_ipa) { if (data->endpoint.filter_support) { dev_err(dev, "filtering not supported for " @@ -230,27 +223,6 @@ static bool ipa_endpoint_data_valid(struct ipa *ipa, u32 count, return true; } -#else /* !IPA_VALIDATE */ - -static bool ipa_endpoint_data_valid(struct ipa *ipa, u32 count, - const struct ipa_gsi_endpoint_data *data) -{ - const struct ipa_gsi_endpoint_data *dp = data; - enum ipa_endpoint_name name; - - if (ipa->version < IPA_VERSION_4_5) - return true; - - /* IPA v4.5+ uses checksum offload, not yet supported by RMNet */ - for (name = 0; name < count; name++, dp++) - if (data->endpoint.config.checksum) - return false; - - return true; -} - -#endif /* !IPA_VALIDATE */ - /* 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) @@ -457,28 +429,34 @@ int ipa_endpoint_modem_exception_reset_all(struct ipa *ipa) static void ipa_endpoint_init_cfg(struct ipa_endpoint *endpoint) { u32 offset = IPA_REG_ENDP_INIT_CFG_N_OFFSET(endpoint->endpoint_id); + enum ipa_cs_offload_en enabled; u32 val = 0; /* FRAG_OFFLOAD_EN is 0 */ if (endpoint->data->checksum) { + enum ipa_version version = endpoint->ipa->version; + if (endpoint->toward_ipa) { u32 checksum_offset; - val |= u32_encode_bits(IPA_CS_OFFLOAD_UL, - CS_OFFLOAD_EN_FMASK); /* Checksum header offset is in 4-byte units */ checksum_offset = sizeof(struct rmnet_map_header); checksum_offset /= sizeof(u32); val |= u32_encode_bits(checksum_offset, CS_METADATA_HDR_OFFSET_FMASK); + + enabled = version < IPA_VERSION_4_5 + ? IPA_CS_OFFLOAD_UL + : IPA_CS_OFFLOAD_INLINE; } else { - val |= u32_encode_bits(IPA_CS_OFFLOAD_DL, - CS_OFFLOAD_EN_FMASK); + enabled = version < IPA_VERSION_4_5 + ? IPA_CS_OFFLOAD_DL + : IPA_CS_OFFLOAD_INLINE; } } else { - val |= u32_encode_bits(IPA_CS_OFFLOAD_NONE, - CS_OFFLOAD_EN_FMASK); + enabled = IPA_CS_OFFLOAD_NONE; } + val |= u32_encode_bits(enabled, CS_OFFLOAD_EN_FMASK); /* CS_GEN_QMB_MASTER_SEL is 0 */ iowrite32(val, endpoint->ipa->reg_virt + offset); @@ -498,6 +476,27 @@ static void ipa_endpoint_init_nat(struct ipa_endpoint *endpoint) iowrite32(val, endpoint->ipa->reg_virt + offset); } +static u32 +ipa_qmap_header_size(enum ipa_version version, struct ipa_endpoint *endpoint) +{ + u32 header_size = sizeof(struct rmnet_map_header); + + /* Without checksum offload, we just have the MAP header */ + if (!endpoint->data->checksum) + return header_size; + + if (version < IPA_VERSION_4_5) { + /* Checksum header inserted for AP TX endpoints only */ + if (endpoint->toward_ipa) + header_size += sizeof(struct rmnet_map_ul_csum_header); + } else { + /* Checksum header is used in both directions */ + header_size += sizeof(struct rmnet_map_v5_csum_header); + } + + return header_size; +} + /** * ipa_endpoint_init_hdr() - Initialize HDR endpoint configuration register * @endpoint: Endpoint pointer @@ -526,13 +525,11 @@ static void ipa_endpoint_init_hdr(struct ipa_endpoint *endpoint) u32 val = 0; if (endpoint->data->qmap) { - size_t header_size = sizeof(struct rmnet_map_header); enum ipa_version version = ipa->version; + size_t header_size; - /* We might supply a checksum header after the QMAP header */ - if (endpoint->toward_ipa && endpoint->data->checksum) - header_size += sizeof(struct rmnet_map_ul_csum_header); - val |= ipa_header_size_encoded(version, header_size); + header_size = ipa_qmap_header_size(version, endpoint); + val = ipa_header_size_encoded(version, header_size); /* Define how to fill fields in a received QMAP header */ if (!endpoint->toward_ipa) { @@ -1734,6 +1731,21 @@ int ipa_endpoint_config(struct ipa *ipa) u32 max; u32 val; + /* Prior to IPAv3.5, the FLAVOR_0 register was not supported. + * Furthermore, the endpoints were not grouped such that TX + * endpoint numbers started with 0 and RX endpoints had numbers + * higher than all TX endpoints, so we can't do the simple + * direction check used for newer hardware below. + * + * For hardware that doesn't support the FLAVOR_0 register, + * just set the available mask to support any endpoint, and + * assume the configuration is valid. + */ + if (ipa->version < IPA_VERSION_3_5) { + ipa->available = ~0; + return 0; + } + /* Find out about the endpoints supplied by the hardware, and ensure * the highest one doesn't exceed the number we support. */ |