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.
工具与软件:
在 SDK 8.6及更低版本中使用本机 Linux 驱动程序时、CPSW 端口8上的以太网通信无法成功进行。
由于 ALE 丢弃哪个端口8接收数据、ALE GET 字段和 SET 字段屏蔽端口8信息出现问题。
CPSW ALE 具有75位 ALE 条目、存储在三个32位字中。 使用 cpsw_ale_get_field()/cpsw_ale_set_field()进行读/写时、函数假定该字段
将被严格包含在一个字中。 这种 情况并非如此、ALE 字段条目最多可涵盖两个字。
例如: VLAN 条目在 word2、word3中有未标记的文件。
以下修复将添加对跨两个字的读取/写入 ALE 字段的支持。
修复:
文件名: drivers/net/ti/cpsw_ale.c
补丁:
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