diff mbox series

[02/20] ethernet: ucc_geth: fix definition and size of ucc_geth_tx_global_pram

Message ID 20201205191744.7847-3-rasmus.villemoes@prevas.dk
State Superseded
Headers show
Series [01/20] ethernet: ucc_geth: set dev->max_mtu to 1518 | expand

Commit Message

Rasmus Villemoes Dec. 5, 2020, 7:17 p.m. UTC
Table 8-53 in the QUICC Engine Reference manual shows definitions of
fields up to a size of 192 bytes, not just 128. But in table 8-111,
one does find the text

  Base Address of the Global Transmitter Parameter RAM Page. [...]
  The user needs to allocate 128 bytes for this page. The address must
  be aligned to the page size.

I've checked both rev. 7 (11/2015) and rev. 9 (05/2018) of the manual;
they both have this inconsistency (and the table numbers are the
same).

Adding a bit of debug printing, on my board the struct
ucc_geth_tx_global_pram is allocated at offset 0x880, while
the (opaque) ucc_geth_thread_data_tx gets allocated immediately
afterwards, at 0x900. So whatever the engine writes into the thread
data overlaps with the tail of the global tx pram (and devmem says
that something does get written during a simple ping).

I haven't observed any failure that could be attributed to this, but
it seems to be the kind of thing that would be extremely hard to
debug. So extend the struct definition so that we do allocate 192
bytes.

Signed-off-by: Rasmus Villemoes <rasmus.villemoes@prevas.dk>
---
 drivers/net/ethernet/freescale/ucc_geth.h | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

Comments

Leo Li Dec. 8, 2020, 7:14 p.m. UTC | #1
On Sat, Dec 5, 2020 at 1:21 PM Rasmus Villemoes
<rasmus.villemoes@prevas.dk> wrote:
>

> Table 8-53 in the QUICC Engine Reference manual shows definitions of

> fields up to a size of 192 bytes, not just 128. But in table 8-111,

> one does find the text

>

>   Base Address of the Global Transmitter Parameter RAM Page. [...]

>   The user needs to allocate 128 bytes for this page. The address must

>   be aligned to the page size.

>

> I've checked both rev. 7 (11/2015) and rev. 9 (05/2018) of the manual;

> they both have this inconsistency (and the table numbers are the

> same).


This does seem to be an inconsistency.  I will try to see if I can
find someone who is familiar with this as this is really an old IP.

Figure 8-61 does mention that size = 128 byte + 64 byte if ....    But
this part is not clear also.  Not sure if the size of the parameter
RAM is really conditional.

>

> Adding a bit of debug printing, on my board the struct

> ucc_geth_tx_global_pram is allocated at offset 0x880, while

> the (opaque) ucc_geth_thread_data_tx gets allocated immediately

> afterwards, at 0x900. So whatever the engine writes into the thread

> data overlaps with the tail of the global tx pram (and devmem says

> that something does get written during a simple ping).


The overlapping does seem to be a problem.  Maybe these global
parameters are not sampled at runtime or the parameter RAM is really
only using 128byte depending on the operation mode.

Are you getting useful information by reading from the additional 64
bytes, or getting changed behavior for setting these bytes after your
changes?

>

> I haven't observed any failure that could be attributed to this, but

> it seems to be the kind of thing that would be extremely hard to

> debug. So extend the struct definition so that we do allocate 192

> bytes.

>

> Signed-off-by: Rasmus Villemoes <rasmus.villemoes@prevas.dk>

> ---

>  drivers/net/ethernet/freescale/ucc_geth.h | 9 ++++++++-

>  1 file changed, 8 insertions(+), 1 deletion(-)

>

> diff --git a/drivers/net/ethernet/freescale/ucc_geth.h b/drivers/net/ethernet/freescale/ucc_geth.h

> index 3fe903972195..c80bed2c995c 100644

> --- a/drivers/net/ethernet/freescale/ucc_geth.h

> +++ b/drivers/net/ethernet/freescale/ucc_geth.h

> @@ -575,7 +575,14 @@ struct ucc_geth_tx_global_pram {

>         u32 vtagtable[0x8];     /* 8 4-byte VLAN tags */

>         u32 tqptr;              /* a base pointer to the Tx Queues Memory

>                                    Region */

> -       u8 res2[0x80 - 0x74];

> +       u8 res2[0x78 - 0x74];

> +       u64 snums_en;

> +       u32 l2l3baseptr;        /* top byte consists of a few other bit fields */

> +

> +       u16 mtu[8];

> +       u8 res3[0xa8 - 0x94];

> +       u32 wrrtablebase;       /* top byte is reserved */

> +       u8 res4[0xc0 - 0xac];

>  } __packed;

>

>  /* structure representing Extended Filtering Global Parameters in PRAM */

> --

> 2.23.0

>
Rasmus Villemoes Dec. 8, 2020, 8:12 p.m. UTC | #2
On 08/12/2020 20.14, Li Yang wrote:
> On Sat, Dec 5, 2020 at 1:21 PM Rasmus Villemoes

> <rasmus.villemoes@prevas.dk> wrote:

>>

>> Table 8-53 in the QUICC Engine Reference manual shows definitions of

>> fields up to a size of 192 bytes, not just 128. But in table 8-111,

>> one does find the text

>>

>>   Base Address of the Global Transmitter Parameter RAM Page. [...]

>>   The user needs to allocate 128 bytes for this page. The address must

>>   be aligned to the page size.

>>

>> I've checked both rev. 7 (11/2015) and rev. 9 (05/2018) of the manual;

>> they both have this inconsistency (and the table numbers are the

>> same).

> 

> This does seem to be an inconsistency.  I will try to see if I can

> find someone who is familiar with this as this is really an old IP.

> 

> Figure 8-61 does mention that size = 128 byte + 64 byte if ....    But

> this part is not clear also.


Hm, indeed, that sentence is simply cut short, it literally says
"Additional 64 bytes are needed if". The next line contains
"Hierarchical Scheduler, or IP" in a smaller font, but that seems to be
a label for the arrow.

> 

> The overlapping does seem to be a problem.  Maybe these global

> parameters are not sampled at runtime or the parameter RAM is really

> only using 128byte depending on the operation mode.


Yes, I'm thinking something like that is likely to be the case, since
this hasn't seemed to ever cause any problems. But who knows, maybe a
few frames just get fragmented very occasionally becauces the MTU0 field
spuriously has some random small value.

> 

> Are you getting useful information by reading from the additional 64

> bytes, 


AFAICT, after the additional allocation, the extra 64 bytes stay at 0,
but that's to be expected; they are supposed to be written by the CPU
and read by the engine AFAIU.

or getting changed behavior for setting these bytes after your
> changes?


No, as I said:

>> I haven't observed any failure that could be attributed to this,


I haven't played around with explicitly writing to those 64 bytes after
initialization. This whole series started because I searched for the
string "MTU" in the manual, but at the end, it didn't seem that I
actually needed to modify those MTU fields.

Rasmus
diff mbox series

Patch

diff --git a/drivers/net/ethernet/freescale/ucc_geth.h b/drivers/net/ethernet/freescale/ucc_geth.h
index 3fe903972195..c80bed2c995c 100644
--- a/drivers/net/ethernet/freescale/ucc_geth.h
+++ b/drivers/net/ethernet/freescale/ucc_geth.h
@@ -575,7 +575,14 @@  struct ucc_geth_tx_global_pram {
 	u32 vtagtable[0x8];	/* 8 4-byte VLAN tags */
 	u32 tqptr;		/* a base pointer to the Tx Queues Memory
 				   Region */
-	u8 res2[0x80 - 0x74];
+	u8 res2[0x78 - 0x74];
+	u64 snums_en;
+	u32 l2l3baseptr;	/* top byte consists of a few other bit fields */
+
+	u16 mtu[8];
+	u8 res3[0xa8 - 0x94];
+	u32 wrrtablebase;	/* top byte is reserved */
+	u8 res4[0xc0 - 0xac];
 } __packed;
 
 /* structure representing Extended Filtering Global Parameters in PRAM */