net: ipa: add new most-significant bits to registers
IPA v4.5 adds a few fields to the endpoint header and extended header configuration registers that represent new high-order bits for certain offsets and sizes. Add code to incorporate these upper bits into the registers for IPA v4.5. This includes creating ipa_header_size_encoded(), which handles encoding the metadata offset field for use in the ENDP_INIT_HDR register in a way appropriate for the hardware version. This and ipa_metadata_offset_encoded() ensure the mask argument passed to u32_encode_bits() is constant. Signed-off-by: Alex Elder <elder@linaro.org> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
5b6cd69e89
commit
1af15c2a78
@ -485,28 +485,34 @@ static void ipa_endpoint_init_cfg(struct ipa_endpoint *endpoint)
|
||||
static void ipa_endpoint_init_hdr(struct ipa_endpoint *endpoint)
|
||||
{
|
||||
u32 offset = IPA_REG_ENDP_INIT_HDR_N_OFFSET(endpoint->endpoint_id);
|
||||
struct ipa *ipa = endpoint->ipa;
|
||||
u32 val = 0;
|
||||
|
||||
if (endpoint->data->qmap) {
|
||||
size_t header_size = sizeof(struct rmnet_map_header);
|
||||
enum ipa_version version = ipa->version;
|
||||
|
||||
/* 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 |= u32_encode_bits(header_size, HDR_LEN_FMASK);
|
||||
val |= ipa_header_size_encoded(version, header_size);
|
||||
|
||||
/* Define how to fill fields in a received QMAP header */
|
||||
if (!endpoint->toward_ipa) {
|
||||
u32 off; /* Field offset within header */
|
||||
u32 offset; /* Field offset within header */
|
||||
|
||||
/* Where IPA will write the metadata value */
|
||||
off = offsetof(struct rmnet_map_header, mux_id);
|
||||
val |= u32_encode_bits(off, HDR_OFST_METADATA_FMASK);
|
||||
offset = offsetof(struct rmnet_map_header, mux_id);
|
||||
val |= ipa_metadata_offset_encoded(version, offset);
|
||||
|
||||
/* Where IPA will write the length */
|
||||
off = offsetof(struct rmnet_map_header, pkt_len);
|
||||
offset = offsetof(struct rmnet_map_header, pkt_len);
|
||||
/* Upper bits are stored in HDR_EXT with IPA v4.5 */
|
||||
if (version == IPA_VERSION_4_5)
|
||||
offset &= field_mask(HDR_OFST_PKT_SIZE_FMASK);
|
||||
|
||||
val |= HDR_OFST_PKT_SIZE_VALID_FMASK;
|
||||
val |= u32_encode_bits(off, HDR_OFST_PKT_SIZE_FMASK);
|
||||
val |= u32_encode_bits(offset, HDR_OFST_PKT_SIZE_FMASK);
|
||||
}
|
||||
/* For QMAP TX, metadata offset is 0 (modem assumes this) */
|
||||
val |= HDR_OFST_METADATA_VALID_FMASK;
|
||||
@ -517,13 +523,14 @@ static void ipa_endpoint_init_hdr(struct ipa_endpoint *endpoint)
|
||||
/* HDR_METADATA_REG_VALID is 0 (TX only) */
|
||||
}
|
||||
|
||||
iowrite32(val, endpoint->ipa->reg_virt + offset);
|
||||
iowrite32(val, ipa->reg_virt + offset);
|
||||
}
|
||||
|
||||
static void ipa_endpoint_init_hdr_ext(struct ipa_endpoint *endpoint)
|
||||
{
|
||||
u32 offset = IPA_REG_ENDP_INIT_HDR_EXT_N_OFFSET(endpoint->endpoint_id);
|
||||
u32 pad_align = endpoint->data->rx.pad_align;
|
||||
struct ipa *ipa = endpoint->ipa;
|
||||
u32 val = 0;
|
||||
|
||||
val |= HDR_ENDIANNESS_FMASK; /* big endian */
|
||||
@ -545,9 +552,23 @@ static void ipa_endpoint_init_hdr_ext(struct ipa_endpoint *endpoint)
|
||||
if (!endpoint->toward_ipa)
|
||||
val |= u32_encode_bits(pad_align, HDR_PAD_TO_ALIGNMENT_FMASK);
|
||||
|
||||
iowrite32(val, endpoint->ipa->reg_virt + offset);
|
||||
}
|
||||
/* IPA v4.5 adds some most-significant bits to a few fields,
|
||||
* two of which are defined in the HDR (not HDR_EXT) register.
|
||||
*/
|
||||
if (ipa->version == IPA_VERSION_4_5) {
|
||||
/* HDR_TOTAL_LEN_OR_PAD_OFFSET is 0, so MSB is 0 */
|
||||
if (endpoint->data->qmap && !endpoint->toward_ipa) {
|
||||
u32 offset;
|
||||
|
||||
offset = offsetof(struct rmnet_map_header, pkt_len);
|
||||
offset >>= hweight32(HDR_OFST_PKT_SIZE_FMASK);
|
||||
val |= u32_encode_bits(offset,
|
||||
HDR_OFST_PKT_SIZE_MSB_FMASK);
|
||||
/* HDR_ADDITIONAL_CONST_LEN is 0 so MSB is 0 */
|
||||
}
|
||||
}
|
||||
iowrite32(val, ipa->reg_virt + offset);
|
||||
}
|
||||
|
||||
static void ipa_endpoint_init_hdr_metadata_mask(struct ipa_endpoint *endpoint)
|
||||
{
|
||||
|
@ -367,6 +367,40 @@ enum ipa_cs_offload_en {
|
||||
#define HDR_LEN_MSB_FMASK GENMASK(29, 28)
|
||||
#define HDR_OFST_METADATA_MSB_FMASK GENMASK(31, 30)
|
||||
|
||||
/* Encoded value for ENDP_INIT_HDR register HDR_LEN* field(s) */
|
||||
static inline u32 ipa_header_size_encoded(enum ipa_version version,
|
||||
u32 header_size)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
val = u32_encode_bits(header_size, HDR_LEN_FMASK);
|
||||
if (version < IPA_VERSION_4_5)
|
||||
return val;
|
||||
|
||||
/* IPA v4.5 adds a few more most-significant bits */
|
||||
header_size >>= hweight32(HDR_LEN_FMASK);
|
||||
val |= u32_encode_bits(header_size, HDR_LEN_MSB_FMASK);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
/* Encoded value for ENDP_INIT_HDR register OFST_METADATA* field(s) */
|
||||
static inline u32 ipa_metadata_offset_encoded(enum ipa_version version,
|
||||
u32 offset)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
val = u32_encode_bits(offset, HDR_OFST_METADATA_FMASK);
|
||||
if (version < IPA_VERSION_4_5)
|
||||
return val;
|
||||
|
||||
/* IPA v4.5 adds a few more most-significant bits */
|
||||
offset >>= hweight32(HDR_OFST_METADATA_FMASK);
|
||||
val |= u32_encode_bits(offset, HDR_OFST_METADATA_MSB_FMASK);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
#define IPA_REG_ENDP_INIT_HDR_EXT_N_OFFSET(ep) \
|
||||
(0x00000814 + 0x0070 * (ep))
|
||||
#define HDR_ENDIANNESS_FMASK GENMASK(0, 0)
|
||||
@ -461,7 +495,7 @@ enum ipa_aggr_type {
|
||||
|
||||
#define IPA_REG_ENDP_INIT_RSRC_GRP_N_OFFSET(ep) \
|
||||
(0x00000838 + 0x0070 * (ep))
|
||||
/* Encoded value for RSRC_GRP endpoint register RSRC_GRP field */
|
||||
/* Encoded value for ENDP_INIT_RSRC_GRP register RSRC_GRP field */
|
||||
static inline u32 rsrc_grp_encoded(enum ipa_version version, u32 rsrc_grp)
|
||||
{
|
||||
switch (version) {
|
||||
@ -492,7 +526,7 @@ static inline u32 rsrc_grp_encoded(enum ipa_version version, u32 rsrc_grp)
|
||||
* @IPA_SEQ_INVALID: invalid sequencer type
|
||||
*
|
||||
* The values defined here are broken into 4-bit nibbles that are written
|
||||
* into fields of the INIT_SEQ_N endpoint registers.
|
||||
* into fields of the ENDP_INIT_SEQ registers.
|
||||
*/
|
||||
enum ipa_seq_type {
|
||||
IPA_SEQ_DMA_ONLY = 0x0000,
|
||||
|
Loading…
x
Reference in New Issue
Block a user