This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[FAQ] TDA4VM: How to fix the communication failure on CPSW Port-8 in Native Linux Driver on SDK version 8.6 and below.

Part Number: TDA4VM

Tool/software:

The Ethernet communication on CPSW Port-8 is not successful using Native Linux Driver in SDK version 8.6 and below.

  • ALE get filed and set filed has issue in masking port-8 information due to which port-8 receive data will be dropped by ALE.

    CPSW ALE has 75 bit ALE entries which is are stored in three 32 bit words. With Read/Write using cpsw_ale_get_field()/cpsw_ale_set_field(), the function assumes that the field
    will be strictly contained within one word. This is not the case and ALE field entries can span up to two words.

    Ex: VLAN entry has un-tag filed spread in word2, word3.

    The following fix will add support for reading/writing ALE fields which span two words.

    Fix:
    file name: drivers/net/ethernet/ti/cpsw_ale.c

    Patch:

    From 0badc8f20da335c699895cb92353e10f9f6dc109 Mon Sep 17 00:00:00 2001
    From: Tanmay Patil <t-patil@ti.com>
    Date: Mon, 24 Apr 2023 14:28:24 +0530
    Subject: [PATCH] net: ethernet: ti: cpsw_ale: Fix ale field set and get
    
    CPSW ALE has 75 bit ALE entries which is are stored in 3
    32 bit words. With Read/Write using cpsw_ale_get_field()/
    cpsw_ale_set_field(), the function assumes that the field
    will be strictly contained within one word. This is not
    the case and ALE field entries can span upto two words.
    
    This commit adds the support for reading/writing ALE
    fields which span two words.
    
    Signed-off-by: Tanmay Patil <t-patil@ti.com>
    ---
     drivers/net/ethernet/ti/cpsw_ale.c | 22 +++++++++++++++++-----
     1 file changed, 17 insertions(+), 5 deletions(-)
    
    diff --git a/drivers/net/ethernet/ti/cpsw_ale.c b/drivers/net/ethernet/ti/cpsw_ale.c
    index 6d60373d15e0..dc8d6f8e7dda 100644
    --- a/drivers/net/ethernet/ti/cpsw_ale.c
    +++ b/drivers/net/ethernet/ti/cpsw_ale.c
    @@ -106,23 +106,35 @@ struct cpsw_ale_dev_id {
     
     static inline int cpsw_ale_get_field(u32 *ale_entry, u32 start, u32 bits)
     {
    -	int idx;
    +	int idx, idx2;
    +	u32 hi_val = 0;
     
     	idx    = start / 32;
    +	idx2 = (start + bits - 1) / 32;
    +	if (idx != idx2) {
    +		idx2 = 2 - idx2; /* flip */
    +		hi_val = ale_entry[idx2] << ((idx2 * 32) - start);
    +	}
     	start -= idx * 32;
     	idx    = 2 - idx; /* flip */
    -	return (ale_entry[idx] >> start) & BITMASK(bits);
    +	return (hi_val + (ale_entry[idx] >> start)) & BITMASK(bits);
     }
     
     static inline void cpsw_ale_set_field(u32 *ale_entry, u32 start, u32 bits,
     				      u32 value)
     {
    -	int idx;
    +	int idx, idx2;
     
     	value &= BITMASK(bits);
    -	idx    = start / 32;
    +	idx = start / 32;
    +	idx2 = (start + bits - 1) / 32;
    +	if (idx != idx2) {
    +		idx2 = 2 - idx2; /* flip */
    +		ale_entry[idx2] &= ~(BITMASK(bits + start - (idx2 * 32)));
    +		ale_entry[idx2] |= (value >> ((idx2 * 32) - start));
    +	}
     	start -= idx * 32;
    -	idx    = 2 - idx; /* flip */
    +	idx = 2 - idx; /* flip */
     	ale_entry[idx] &= ~(BITMASK(bits) << start);
     	ale_entry[idx] |=  (value << start);
     }
    -- 
    2.25.1



    Note:
    Above issue is addressed in TI SDK 9.0 onwards, Issue will see only in SDK 8.6 and below.