Tool/software:
The Ethernet communication on CPSW Port-8 is not successful using Native Linux Driver in SDK version 8.6 and below.
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.
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