Skip to content

Commit 1af15c2

Browse files
Alex Elderkuba-moo
authored andcommitted
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 <[email protected]> Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 5b6cd69 commit 1af15c2

File tree

2 files changed

+66
-11
lines changed

2 files changed

+66
-11
lines changed

drivers/net/ipa/ipa_endpoint.c

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -485,28 +485,34 @@ static void ipa_endpoint_init_cfg(struct ipa_endpoint *endpoint)
485485
static void ipa_endpoint_init_hdr(struct ipa_endpoint *endpoint)
486486
{
487487
u32 offset = IPA_REG_ENDP_INIT_HDR_N_OFFSET(endpoint->endpoint_id);
488+
struct ipa *ipa = endpoint->ipa;
488489
u32 val = 0;
489490

490491
if (endpoint->data->qmap) {
491492
size_t header_size = sizeof(struct rmnet_map_header);
493+
enum ipa_version version = ipa->version;
492494

493495
/* We might supply a checksum header after the QMAP header */
494496
if (endpoint->toward_ipa && endpoint->data->checksum)
495497
header_size += sizeof(struct rmnet_map_ul_csum_header);
496-
val |= u32_encode_bits(header_size, HDR_LEN_FMASK);
498+
val |= ipa_header_size_encoded(version, header_size);
497499

498500
/* Define how to fill fields in a received QMAP header */
499501
if (!endpoint->toward_ipa) {
500-
u32 off; /* Field offset within header */
502+
u32 offset; /* Field offset within header */
501503

502504
/* Where IPA will write the metadata value */
503-
off = offsetof(struct rmnet_map_header, mux_id);
504-
val |= u32_encode_bits(off, HDR_OFST_METADATA_FMASK);
505+
offset = offsetof(struct rmnet_map_header, mux_id);
506+
val |= ipa_metadata_offset_encoded(version, offset);
505507

506508
/* Where IPA will write the length */
507-
off = offsetof(struct rmnet_map_header, pkt_len);
509+
offset = offsetof(struct rmnet_map_header, pkt_len);
510+
/* Upper bits are stored in HDR_EXT with IPA v4.5 */
511+
if (version == IPA_VERSION_4_5)
512+
offset &= field_mask(HDR_OFST_PKT_SIZE_FMASK);
513+
508514
val |= HDR_OFST_PKT_SIZE_VALID_FMASK;
509-
val |= u32_encode_bits(off, HDR_OFST_PKT_SIZE_FMASK);
515+
val |= u32_encode_bits(offset, HDR_OFST_PKT_SIZE_FMASK);
510516
}
511517
/* For QMAP TX, metadata offset is 0 (modem assumes this) */
512518
val |= HDR_OFST_METADATA_VALID_FMASK;
@@ -517,13 +523,14 @@ static void ipa_endpoint_init_hdr(struct ipa_endpoint *endpoint)
517523
/* HDR_METADATA_REG_VALID is 0 (TX only) */
518524
}
519525

520-
iowrite32(val, endpoint->ipa->reg_virt + offset);
526+
iowrite32(val, ipa->reg_virt + offset);
521527
}
522528

523529
static void ipa_endpoint_init_hdr_ext(struct ipa_endpoint *endpoint)
524530
{
525531
u32 offset = IPA_REG_ENDP_INIT_HDR_EXT_N_OFFSET(endpoint->endpoint_id);
526532
u32 pad_align = endpoint->data->rx.pad_align;
533+
struct ipa *ipa = endpoint->ipa;
527534
u32 val = 0;
528535

529536
val |= HDR_ENDIANNESS_FMASK; /* big endian */
@@ -545,10 +552,24 @@ static void ipa_endpoint_init_hdr_ext(struct ipa_endpoint *endpoint)
545552
if (!endpoint->toward_ipa)
546553
val |= u32_encode_bits(pad_align, HDR_PAD_TO_ALIGNMENT_FMASK);
547554

548-
iowrite32(val, endpoint->ipa->reg_virt + offset);
555+
/* IPA v4.5 adds some most-significant bits to a few fields,
556+
* two of which are defined in the HDR (not HDR_EXT) register.
557+
*/
558+
if (ipa->version == IPA_VERSION_4_5) {
559+
/* HDR_TOTAL_LEN_OR_PAD_OFFSET is 0, so MSB is 0 */
560+
if (endpoint->data->qmap && !endpoint->toward_ipa) {
561+
u32 offset;
562+
563+
offset = offsetof(struct rmnet_map_header, pkt_len);
564+
offset >>= hweight32(HDR_OFST_PKT_SIZE_FMASK);
565+
val |= u32_encode_bits(offset,
566+
HDR_OFST_PKT_SIZE_MSB_FMASK);
567+
/* HDR_ADDITIONAL_CONST_LEN is 0 so MSB is 0 */
568+
}
569+
}
570+
iowrite32(val, ipa->reg_virt + offset);
549571
}
550572

551-
552573
static void ipa_endpoint_init_hdr_metadata_mask(struct ipa_endpoint *endpoint)
553574
{
554575
u32 endpoint_id = endpoint->endpoint_id;

drivers/net/ipa/ipa_reg.h

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,40 @@ enum ipa_cs_offload_en {
367367
#define HDR_LEN_MSB_FMASK GENMASK(29, 28)
368368
#define HDR_OFST_METADATA_MSB_FMASK GENMASK(31, 30)
369369

370+
/* Encoded value for ENDP_INIT_HDR register HDR_LEN* field(s) */
371+
static inline u32 ipa_header_size_encoded(enum ipa_version version,
372+
u32 header_size)
373+
{
374+
u32 val;
375+
376+
val = u32_encode_bits(header_size, HDR_LEN_FMASK);
377+
if (version < IPA_VERSION_4_5)
378+
return val;
379+
380+
/* IPA v4.5 adds a few more most-significant bits */
381+
header_size >>= hweight32(HDR_LEN_FMASK);
382+
val |= u32_encode_bits(header_size, HDR_LEN_MSB_FMASK);
383+
384+
return val;
385+
}
386+
387+
/* Encoded value for ENDP_INIT_HDR register OFST_METADATA* field(s) */
388+
static inline u32 ipa_metadata_offset_encoded(enum ipa_version version,
389+
u32 offset)
390+
{
391+
u32 val;
392+
393+
val = u32_encode_bits(offset, HDR_OFST_METADATA_FMASK);
394+
if (version < IPA_VERSION_4_5)
395+
return val;
396+
397+
/* IPA v4.5 adds a few more most-significant bits */
398+
offset >>= hweight32(HDR_OFST_METADATA_FMASK);
399+
val |= u32_encode_bits(offset, HDR_OFST_METADATA_MSB_FMASK);
400+
401+
return val;
402+
}
403+
370404
#define IPA_REG_ENDP_INIT_HDR_EXT_N_OFFSET(ep) \
371405
(0x00000814 + 0x0070 * (ep))
372406
#define HDR_ENDIANNESS_FMASK GENMASK(0, 0)
@@ -461,7 +495,7 @@ enum ipa_aggr_type {
461495

462496
#define IPA_REG_ENDP_INIT_RSRC_GRP_N_OFFSET(ep) \
463497
(0x00000838 + 0x0070 * (ep))
464-
/* Encoded value for RSRC_GRP endpoint register RSRC_GRP field */
498+
/* Encoded value for ENDP_INIT_RSRC_GRP register RSRC_GRP field */
465499
static inline u32 rsrc_grp_encoded(enum ipa_version version, u32 rsrc_grp)
466500
{
467501
switch (version) {
@@ -492,7 +526,7 @@ static inline u32 rsrc_grp_encoded(enum ipa_version version, u32 rsrc_grp)
492526
* @IPA_SEQ_INVALID: invalid sequencer type
493527
*
494528
* The values defined here are broken into 4-bit nibbles that are written
495-
* into fields of the INIT_SEQ_N endpoint registers.
529+
* into fields of the ENDP_INIT_SEQ registers.
496530
*/
497531
enum ipa_seq_type {
498532
IPA_SEQ_DMA_ONLY = 0x0000,

0 commit comments

Comments
 (0)