* [PATCH net-next v3 1/2] net: txgbe: Add basic support for new AML devices
@ 2025-01-15 10:24 Jiawen Wu
2025-01-15 10:24 ` [PATCH net-next v3 2/2] net: wangxun: Replace the judgement of MAC type with flags Jiawen Wu
` (2 more replies)
0 siblings, 3 replies; 5+ messages in thread
From: Jiawen Wu @ 2025-01-15 10:24 UTC (permalink / raw)
To: andrew+netdev, davem, edumazet, kuba, pabeni, linux, horms,
netdev
Cc: mengyuanlou, Jiawen Wu
There is a new 40/25/10 Gigabit Ethernet device.
To support basic functions, PHYLINK is temporarily skipped as it is
intended to implement these configurations in the firmware. And the
associated link IRQ is also skipped.
And Implement the new SW-FW interaction interface, which use 64 Byte
message buffer.
Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
---
Changes in v3:
- Use 'err' instead of 'status' as error return
- Use might_sleep() instead of WARN_ON(in_interrupt())
- Use read_poll_timeout()
- Add le32_to_cpu() to convert mbox read buffer
- Adjust comma in enums
Changes in v2:
- Add missing 40G devide IDs
- Add condition for wx->do_reset != NULL
---
.../net/ethernet/wangxun/libwx/wx_ethtool.c | 44 +++-
drivers/net/ethernet/wangxun/libwx/wx_hw.c | 214 +++++++++++++++---
drivers/net/ethernet/wangxun/libwx/wx_lib.c | 25 +-
drivers/net/ethernet/wangxun/libwx/wx_type.h | 29 ++-
drivers/net/ethernet/wangxun/txgbe/txgbe_hw.c | 6 +
.../net/ethernet/wangxun/txgbe/txgbe_irq.c | 7 +
.../net/ethernet/wangxun/txgbe/txgbe_main.c | 43 +++-
.../net/ethernet/wangxun/txgbe/txgbe_phy.c | 6 +
.../net/ethernet/wangxun/txgbe/txgbe_type.h | 14 ++
9 files changed, 334 insertions(+), 54 deletions(-)
diff --git a/drivers/net/ethernet/wangxun/libwx/wx_ethtool.c b/drivers/net/ethernet/wangxun/libwx/wx_ethtool.c
index abe5921dde02..f6b1323e606b 100644
--- a/drivers/net/ethernet/wangxun/libwx/wx_ethtool.c
+++ b/drivers/net/ethernet/wangxun/libwx/wx_ethtool.c
@@ -216,6 +216,9 @@ int wx_nway_reset(struct net_device *netdev)
{
struct wx *wx = netdev_priv(netdev);
+ if (wx->mac.type == wx_mac_aml)
+ return -EOPNOTSUPP;
+
return phylink_ethtool_nway_reset(wx->phylink);
}
EXPORT_SYMBOL(wx_nway_reset);
@@ -225,6 +228,9 @@ int wx_get_link_ksettings(struct net_device *netdev,
{
struct wx *wx = netdev_priv(netdev);
+ if (wx->mac.type == wx_mac_aml)
+ return -EOPNOTSUPP;
+
return phylink_ethtool_ksettings_get(wx->phylink, cmd);
}
EXPORT_SYMBOL(wx_get_link_ksettings);
@@ -234,6 +240,9 @@ int wx_set_link_ksettings(struct net_device *netdev,
{
struct wx *wx = netdev_priv(netdev);
+ if (wx->mac.type == wx_mac_aml)
+ return -EOPNOTSUPP;
+
return phylink_ethtool_ksettings_set(wx->phylink, cmd);
}
EXPORT_SYMBOL(wx_set_link_ksettings);
@@ -243,6 +252,9 @@ void wx_get_pauseparam(struct net_device *netdev,
{
struct wx *wx = netdev_priv(netdev);
+ if (wx->mac.type == wx_mac_aml)
+ return;
+
phylink_ethtool_get_pauseparam(wx->phylink, pause);
}
EXPORT_SYMBOL(wx_get_pauseparam);
@@ -252,6 +264,9 @@ int wx_set_pauseparam(struct net_device *netdev,
{
struct wx *wx = netdev_priv(netdev);
+ if (wx->mac.type == wx_mac_aml)
+ return -EOPNOTSUPP;
+
return phylink_ethtool_set_pauseparam(wx->phylink, pause);
}
EXPORT_SYMBOL(wx_set_pauseparam);
@@ -322,10 +337,17 @@ int wx_set_coalesce(struct net_device *netdev,
if (ec->tx_max_coalesced_frames_irq)
wx->tx_work_limit = ec->tx_max_coalesced_frames_irq;
- if (wx->mac.type == wx_mac_sp)
+ switch (wx->mac.type) {
+ case wx_mac_sp:
max_eitr = WX_SP_MAX_EITR;
- else
+ break;
+ case wx_mac_aml:
+ max_eitr = WX_AML_MAX_EITR;
+ break;
+ default:
max_eitr = WX_EM_MAX_EITR;
+ break;
+ }
if ((ec->rx_coalesce_usecs > (max_eitr >> 2)) ||
(ec->tx_coalesce_usecs > (max_eitr >> 2)))
@@ -347,10 +369,15 @@ int wx_set_coalesce(struct net_device *netdev,
wx->tx_itr_setting = ec->tx_coalesce_usecs;
if (wx->tx_itr_setting == 1) {
- if (wx->mac.type == wx_mac_sp)
+ switch (wx->mac.type) {
+ case wx_mac_sp:
+ case wx_mac_aml:
tx_itr_param = WX_12K_ITR;
- else
+ break;
+ default:
tx_itr_param = WX_20K_ITR;
+ break;
+ }
} else {
tx_itr_param = wx->tx_itr_setting;
}
@@ -383,10 +410,15 @@ static unsigned int wx_max_channels(struct wx *wx)
max_combined = 1;
} else {
/* support up to max allowed queues with RSS */
- if (wx->mac.type == wx_mac_sp)
+ switch (wx->mac.type) {
+ case wx_mac_sp:
+ case wx_mac_aml:
max_combined = 63;
- else
+ break;
+ default:
max_combined = 8;
+ break;
+ }
}
return max_combined;
diff --git a/drivers/net/ethernet/wangxun/libwx/wx_hw.c b/drivers/net/ethernet/wangxun/libwx/wx_hw.c
index deaf670c160e..7198650de096 100644
--- a/drivers/net/ethernet/wangxun/libwx/wx_hw.c
+++ b/drivers/net/ethernet/wangxun/libwx/wx_hw.c
@@ -112,10 +112,15 @@ static void wx_intr_disable(struct wx *wx, u64 qmask)
if (mask)
wr32(wx, WX_PX_IMS(0), mask);
- if (wx->mac.type == wx_mac_sp) {
+ switch (wx->mac.type) {
+ case wx_mac_sp:
+ case wx_mac_aml:
mask = (qmask >> 32);
if (mask)
wr32(wx, WX_PX_IMS(1), mask);
+ break;
+ default:
+ break;
}
}
@@ -126,10 +131,16 @@ void wx_intr_enable(struct wx *wx, u64 qmask)
mask = (qmask & U32_MAX);
if (mask)
wr32(wx, WX_PX_IMC(0), mask);
- if (wx->mac.type == wx_mac_sp) {
+
+ switch (wx->mac.type) {
+ case wx_mac_sp:
+ case wx_mac_aml:
mask = (qmask >> 32);
if (mask)
wr32(wx, WX_PX_IMC(1), mask);
+ break;
+ default:
+ break;
}
}
EXPORT_SYMBOL(wx_intr_enable);
@@ -278,22 +289,8 @@ static int wx_acquire_sw_sync(struct wx *wx, u32 mask)
return ret;
}
-/**
- * wx_host_interface_command - Issue command to manageability block
- * @wx: pointer to the HW structure
- * @buffer: contains the command to write and where the return status will
- * be placed
- * @length: length of buffer, must be multiple of 4 bytes
- * @timeout: time in ms to wait for command completion
- * @return_data: read and return data from the buffer (true) or not (false)
- * Needed because FW structures are big endian and decoding of
- * these fields can be 8 bit or 16 bit based on command. Decoding
- * is not easily understood without making a table of commands.
- * So we will leave this up to the caller to read back the data
- * in these cases.
- **/
-int wx_host_interface_command(struct wx *wx, u32 *buffer,
- u32 length, u32 timeout, bool return_data)
+static int wx_host_interface_command_s(struct wx *wx, u32 *buffer,
+ u32 length, u32 timeout, bool return_data)
{
u32 hdr_size = sizeof(struct wx_hic_hdr);
u32 hicr, i, bi, buf[64] = {};
@@ -301,22 +298,10 @@ int wx_host_interface_command(struct wx *wx, u32 *buffer,
u32 dword_len;
u16 buf_len;
- if (length == 0 || length > WX_HI_MAX_BLOCK_BYTE_LENGTH) {
- wx_err(wx, "Buffer length failure buffersize=%d.\n", length);
- return -EINVAL;
- }
-
status = wx_acquire_sw_sync(wx, WX_MNG_SWFW_SYNC_SW_MB);
if (status != 0)
return status;
- /* Calculate length in DWORDs. We must be DWORD aligned */
- if ((length % (sizeof(u32))) != 0) {
- wx_err(wx, "Buffer length failure, not aligned to dword");
- status = -EINVAL;
- goto rel_out;
- }
-
dword_len = length >> 2;
/* The device driver writes the relevant command block
@@ -391,6 +376,140 @@ int wx_host_interface_command(struct wx *wx, u32 *buffer,
wx_release_sw_sync(wx, WX_MNG_SWFW_SYNC_SW_MB);
return status;
}
+
+static bool wx_poll_fw_reply(struct wx *wx, u32 *buffer,
+ struct wx_hic_hdr *recv_hdr, u8 send_cmd)
+{
+ u32 dword_len = sizeof(struct wx_hic_hdr) >> 2;
+ u32 i;
+
+ /* read hdr */
+ for (i = 0; i < dword_len; i++) {
+ buffer[i] = rd32a(wx, WX_FW2SW_MBOX, i);
+ le32_to_cpus(&buffer[i]);
+ }
+
+ /* check hdr */
+ recv_hdr = (struct wx_hic_hdr *)buffer;
+ if (recv_hdr->cmd == send_cmd &&
+ recv_hdr->index == wx->swfw_index)
+ return true;
+
+ return false;
+}
+
+static int wx_host_interface_command_r(struct wx *wx, u32 *buffer,
+ u32 length, u32 timeout, bool return_data)
+{
+ struct wx_hic_hdr *send_hdr = (struct wx_hic_hdr *)buffer;
+ u32 hdr_size = sizeof(struct wx_hic_hdr);
+ struct wx_hic_hdr *recv_hdr;
+ bool busy, reply;
+ u32 dword_len;
+ u16 buf_len;
+ int err = 0;
+ u8 send_cmd;
+ u32 i;
+
+ /* wait to get lock */
+ might_sleep();
+ err = read_poll_timeout(test_and_set_bit, busy, !busy, 1000, timeout * 1000,
+ false, WX_STATE_SWFW_BUSY, wx->state);
+ if (err)
+ return err;
+
+ /* index to unique seq id for each mbox message */
+ send_hdr->index = wx->swfw_index;
+ send_cmd = send_hdr->cmd;
+
+ dword_len = length >> 2;
+ /* write data to SW-FW mbox array */
+ for (i = 0; i < dword_len; i++) {
+ wr32a(wx, WX_SW2FW_MBOX, i, (__force u32)cpu_to_le32(buffer[i]));
+ /* write flush */
+ rd32a(wx, WX_SW2FW_MBOX, i);
+ }
+
+ /* generate interrupt to notify FW */
+ wr32m(wx, WX_SW2FW_MBOX_CMD, WX_SW2FW_MBOX_CMD_VLD, 0);
+ wr32m(wx, WX_SW2FW_MBOX_CMD, WX_SW2FW_MBOX_CMD_VLD, WX_SW2FW_MBOX_CMD_VLD);
+
+ /* polling reply from FW */
+ err = read_poll_timeout(wx_poll_fw_reply, reply, reply, 1000, 50000,
+ true, wx, buffer, recv_hdr, send_cmd);
+ if (err) {
+ wx_err(wx, "Polling from FW messages timeout, cmd: 0x%x, index: %d\n",
+ send_cmd, wx->swfw_index);
+ goto rel_out;
+ }
+
+ /* expect no reply from FW then return */
+ if (!return_data)
+ goto rel_out;
+
+ /* If there is any thing in data position pull it in */
+ buf_len = recv_hdr->buf_len;
+ if (buf_len == 0)
+ goto rel_out;
+
+ if (length < buf_len + hdr_size) {
+ wx_err(wx, "Buffer not large enough for reply message.\n");
+ err = -EFAULT;
+ goto rel_out;
+ }
+
+ /* Calculate length in DWORDs, add 3 for odd lengths */
+ dword_len = (buf_len + 3) >> 2;
+ for (i = hdr_size >> 2; i <= dword_len; i++) {
+ buffer[i] = rd32a(wx, WX_FW2SW_MBOX, i);
+ le32_to_cpus(&buffer[i]);
+ }
+
+rel_out:
+ /* index++, index replace wx_hic_hdr.checksum */
+ if (send_hdr->index == WX_HIC_HDR_INDEX_MAX)
+ wx->swfw_index = 0;
+ else
+ wx->swfw_index = send_hdr->index + 1;
+
+ clear_bit(WX_STATE_SWFW_BUSY, wx->state);
+ return err;
+}
+
+/**
+ * wx_host_interface_command - Issue command to manageability block
+ * @wx: pointer to the HW structure
+ * @buffer: contains the command to write and where the return status will
+ * be placed
+ * @length: length of buffer, must be multiple of 4 bytes
+ * @timeout: time in ms to wait for command completion
+ * @return_data: read and return data from the buffer (true) or not (false)
+ * Needed because FW structures are big endian and decoding of
+ * these fields can be 8 bit or 16 bit based on command. Decoding
+ * is not easily understood without making a table of commands.
+ * So we will leave this up to the caller to read back the data
+ * in these cases.
+ **/
+int wx_host_interface_command(struct wx *wx, u32 *buffer,
+ u32 length, u32 timeout, bool return_data)
+{
+ if (length == 0 || length > WX_HI_MAX_BLOCK_BYTE_LENGTH) {
+ wx_err(wx, "Buffer length failure buffersize=%d.\n", length);
+ return -EINVAL;
+ }
+
+ /* Calculate length in DWORDs. We must be DWORD aligned */
+ if ((length % (sizeof(u32))) != 0) {
+ wx_err(wx, "Buffer length failure, not aligned to dword");
+ return -EINVAL;
+ }
+
+ if (test_bit(WX_FLAG_SWFW_RING, wx->flags))
+ return wx_host_interface_command_r(wx, buffer, length,
+ timeout, return_data);
+
+ return wx_host_interface_command_s(wx, buffer, length, timeout, return_data);
+}
EXPORT_SYMBOL(wx_host_interface_command);
/**
@@ -423,7 +542,10 @@ static int wx_read_ee_hostif_data(struct wx *wx, u16 offset, u16 *data)
if (status != 0)
return status;
- *data = (u16)rd32a(wx, WX_MNG_MBOX, FW_NVM_DATA_OFFSET);
+ if (!test_bit(WX_FLAG_SWFW_RING, wx->flags))
+ *data = (u16)rd32a(wx, WX_MNG_MBOX, FW_NVM_DATA_OFFSET);
+ else
+ *data = (u16)rd32a(wx, WX_FW2SW_MBOX, FW_NVM_DATA_OFFSET);
return status;
}
@@ -467,6 +589,7 @@ int wx_read_ee_hostif_buffer(struct wx *wx,
u16 words_to_read;
u32 value = 0;
int status;
+ u32 mbox;
u32 i;
/* Take semaphore for the entire operation. */
@@ -499,8 +622,12 @@ int wx_read_ee_hostif_buffer(struct wx *wx,
goto out;
}
+ if (!test_bit(WX_FLAG_SWFW_RING, wx->flags))
+ mbox = WX_MNG_MBOX;
+ else
+ mbox = WX_FW2SW_MBOX;
for (i = 0; i < words_to_read; i++) {
- u32 reg = WX_MNG_MBOX + (FW_NVM_DATA_OFFSET << 2) + 2 * i;
+ u32 reg = mbox + (FW_NVM_DATA_OFFSET << 2) + 2 * i;
value = rd32(wx, reg);
data[current_word] = (u16)(value & 0xffff);
@@ -550,12 +677,17 @@ void wx_init_eeprom_params(struct wx *wx)
}
}
- if (wx->mac.type == wx_mac_sp) {
+ switch (wx->mac.type) {
+ case wx_mac_sp:
+ case wx_mac_aml:
if (wx_read_ee_hostif(wx, WX_SW_REGION_PTR, &data)) {
wx_err(wx, "NVM Read Error\n");
return;
}
data = data >> 1;
+ break;
+ default:
+ break;
}
eeprom->sw_region_offset = data;
@@ -616,8 +748,15 @@ static int wx_set_rar(struct wx *wx, u32 index, u8 *addr, u64 pools,
/* setup VMDq pool mapping */
wr32(wx, WX_PSR_MAC_SWC_VM_L, pools & 0xFFFFFFFF);
- if (wx->mac.type == wx_mac_sp)
+
+ switch (wx->mac.type) {
+ case wx_mac_sp:
+ case wx_mac_aml:
wr32(wx, WX_PSR_MAC_SWC_VM_H, pools >> 32);
+ break;
+ default:
+ break;
+ }
/* HW expects these in little endian so we reverse the byte
* order from network order (big endian) to little endian
@@ -755,9 +894,14 @@ void wx_init_rx_addrs(struct wx *wx)
wx_set_rar(wx, 0, wx->mac.addr, 0, WX_PSR_MAC_SWC_AD_H_AV);
- if (wx->mac.type == wx_mac_sp) {
+ switch (wx->mac.type) {
+ case wx_mac_sp:
+ case wx_mac_aml:
/* clear VMDq pool/queue selection for RAR 0 */
wx_clear_vmdq(wx, 0, WX_CLEAR_VMDQ_ALL);
+ break;
+ default:
+ break;
}
}
diff --git a/drivers/net/ethernet/wangxun/libwx/wx_lib.c b/drivers/net/ethernet/wangxun/libwx/wx_lib.c
index 2b3d6586f44a..e12ea4215160 100644
--- a/drivers/net/ethernet/wangxun/libwx/wx_lib.c
+++ b/drivers/net/ethernet/wangxun/libwx/wx_lib.c
@@ -1781,10 +1781,16 @@ static int wx_alloc_q_vector(struct wx *wx,
/* initialize pointer to rings */
ring = q_vector->ring;
- if (wx->mac.type == wx_mac_sp)
+ switch (wx->mac.type) {
+ case wx_mac_sp:
+ case wx_mac_aml:
default_itr = WX_12K_ITR;
- else
+ break;
+ default:
default_itr = WX_7K_ITR;
+ break;
+ }
+
/* initialize ITR */
if (txr_count && !rxr_count)
/* tx only vector */
@@ -2140,10 +2146,17 @@ void wx_write_eitr(struct wx_q_vector *q_vector)
int v_idx = q_vector->v_idx;
u32 itr_reg;
- if (wx->mac.type == wx_mac_sp)
+ switch (wx->mac.type) {
+ case wx_mac_sp:
itr_reg = q_vector->itr & WX_SP_MAX_EITR;
- else
+ break;
+ case wx_mac_aml:
+ itr_reg = (q_vector->itr >> 3) & WX_AML_MAX_EITR;
+ break;
+ default:
itr_reg = q_vector->itr & WX_EM_MAX_EITR;
+ break;
+ }
itr_reg |= WX_PX_ITR_CNT_WDIS;
@@ -2719,7 +2732,7 @@ int wx_set_features(struct net_device *netdev, netdev_features_t features)
netdev->features = features;
- if (wx->mac.type == wx_mac_sp && changed & NETIF_F_HW_VLAN_CTAG_RX)
+ if (changed & NETIF_F_HW_VLAN_CTAG_RX && wx->do_reset)
wx->do_reset(netdev);
else if (changed & (NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_CTAG_FILTER))
wx_set_rx_mode(netdev);
@@ -2751,7 +2764,7 @@ int wx_set_features(struct net_device *netdev, netdev_features_t features)
break;
}
- if (need_reset)
+ if (need_reset && wx->do_reset)
wx->do_reset(netdev);
return 0;
diff --git a/drivers/net/ethernet/wangxun/libwx/wx_type.h b/drivers/net/ethernet/wangxun/libwx/wx_type.h
index b54bffda027b..ba6e45eeaba6 100644
--- a/drivers/net/ethernet/wangxun/libwx/wx_type.h
+++ b/drivers/net/ethernet/wangxun/libwx/wx_type.h
@@ -264,6 +264,10 @@
#define WX_MNG_MBOX_CTL_FWRDY BIT(2)
#define WX_MNG_BMC2OS_CNT 0x1E090
#define WX_MNG_OS2BMC_CNT 0x1E094
+#define WX_SW2FW_MBOX_CMD 0x1E0A0
+#define WX_SW2FW_MBOX_CMD_VLD BIT(31)
+#define WX_SW2FW_MBOX 0x1E200
+#define WX_FW2SW_MBOX 0x1E300
/************************************* ETH MAC *****************************/
#define WX_MAC_TX_CFG 0x11000
@@ -327,6 +331,7 @@ enum WX_MSCA_CMD_value {
#define WX_12K_ITR 336
#define WX_20K_ITR 200
#define WX_SP_MAX_EITR 0x00000FF8U
+#define WX_AML_MAX_EITR 0x00000FFFU
#define WX_EM_MAX_EITR 0x00007FFCU
/* transmit DMA Registers */
@@ -370,6 +375,7 @@ enum WX_MSCA_CMD_value {
/****************** Manageablility Host Interface defines ********************/
#define WX_HI_MAX_BLOCK_BYTE_LENGTH 256 /* Num of bytes in range */
#define WX_HI_COMMAND_TIMEOUT 1000 /* Process HI command limit */
+#define WX_HIC_HDR_INDEX_MAX 255
#define FW_READ_SHADOW_RAM_CMD 0x31
#define FW_READ_SHADOW_RAM_LEN 0x6
@@ -663,21 +669,30 @@ struct wx_hic_hdr {
u8 cmd_resv;
u8 ret_status;
} cmd_or_resp;
- u8 checksum;
+ union {
+ u8 checksum;
+ u8 index;
+ };
};
struct wx_hic_hdr2_req {
u8 cmd;
u8 buf_lenh;
u8 buf_lenl;
- u8 checksum;
+ union {
+ u8 checksum;
+ u8 index;
+ };
};
struct wx_hic_hdr2_rsp {
u8 cmd;
u8 buf_lenl;
u8 buf_lenh_status; /* 7-5: high bits of buf_len, 4-0: status */
- u8 checksum;
+ union {
+ u8 checksum;
+ u8 index;
+ };
};
union wx_hic_hdr2 {
@@ -716,7 +731,8 @@ struct wx_thermal_sensor_data {
enum wx_mac_type {
wx_mac_unknown = 0,
wx_mac_sp,
- wx_mac_em
+ wx_mac_em,
+ wx_mac_aml,
};
enum sp_media_type {
@@ -1026,10 +1042,12 @@ struct wx_hw_stats {
enum wx_state {
WX_STATE_RESETTING,
- WX_STATE_NBITS, /* must be last */
+ WX_STATE_SWFW_BUSY,
+ WX_STATE_NBITS /* must be last */
};
enum wx_pf_flags {
+ WX_FLAG_SWFW_RING,
WX_FLAG_FDIR_CAPABLE,
WX_FLAG_FDIR_HASH,
WX_FLAG_FDIR_PERFECT,
@@ -1066,6 +1084,7 @@ struct wx {
char eeprom_id[32];
char *driver_name;
enum wx_reset_type reset_type;
+ u8 swfw_index;
/* PHY stuff */
unsigned int link;
diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe_hw.c b/drivers/net/ethernet/wangxun/txgbe/txgbe_hw.c
index cd1372da92a9..4b9921b7bb11 100644
--- a/drivers/net/ethernet/wangxun/txgbe/txgbe_hw.c
+++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_hw.c
@@ -197,6 +197,12 @@ int txgbe_reset_hw(struct wx *wx)
txgbe_reset_misc(wx);
+ if (wx->mac.type != wx_mac_sp) {
+ wr32(wx, TXGBE_PX_PF_BME, 0x1);
+ wr32m(wx, TXGBE_RDM_RSC_CTL, TXGBE_RDM_RSC_CTL_FREE_CTL,
+ TXGBE_RDM_RSC_CTL_FREE_CTL);
+ }
+
wx_clear_hw_cntrs(wx);
/* Store the permanent mac address */
diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe_irq.c b/drivers/net/ethernet/wangxun/txgbe/txgbe_irq.c
index 0ee73a265545..8658a51ee810 100644
--- a/drivers/net/ethernet/wangxun/txgbe/txgbe_irq.c
+++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_irq.c
@@ -166,6 +166,9 @@ static void txgbe_del_irq_domain(struct txgbe *txgbe)
void txgbe_free_misc_irq(struct txgbe *txgbe)
{
+ if (txgbe->wx->mac.type == wx_mac_aml)
+ return;
+
free_irq(txgbe->link_irq, txgbe);
free_irq(txgbe->misc.irq, txgbe);
txgbe_del_irq_domain(txgbe);
@@ -177,6 +180,9 @@ int txgbe_setup_misc_irq(struct txgbe *txgbe)
struct wx *wx = txgbe->wx;
int hwirq, err;
+ if (wx->mac.type == wx_mac_aml)
+ goto skip_sp_irq;
+
txgbe->misc.nirqs = 1;
txgbe->misc.domain = irq_domain_add_simple(NULL, txgbe->misc.nirqs, 0,
&txgbe_misc_irq_domain_ops, txgbe);
@@ -206,6 +212,7 @@ int txgbe_setup_misc_irq(struct txgbe *txgbe)
if (err)
goto free_msic_irq;
+skip_sp_irq:
wx->misc_irq_domain = true;
return 0;
diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe_main.c b/drivers/net/ethernet/wangxun/txgbe/txgbe_main.c
index f77450268036..ffe42b77de3e 100644
--- a/drivers/net/ethernet/wangxun/txgbe/txgbe_main.c
+++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_main.c
@@ -34,6 +34,12 @@ char txgbe_driver_name[] = "txgbe";
static const struct pci_device_id txgbe_pci_tbl[] = {
{ PCI_VDEVICE(WANGXUN, TXGBE_DEV_ID_SP1000), 0},
{ PCI_VDEVICE(WANGXUN, TXGBE_DEV_ID_WX1820), 0},
+ { PCI_VDEVICE(WANGXUN, TXGBE_DEV_ID_AML5010), 0},
+ { PCI_VDEVICE(WANGXUN, TXGBE_DEV_ID_AML5110), 0},
+ { PCI_VDEVICE(WANGXUN, TXGBE_DEV_ID_AML5025), 0},
+ { PCI_VDEVICE(WANGXUN, TXGBE_DEV_ID_AML5125), 0},
+ { PCI_VDEVICE(WANGXUN, TXGBE_DEV_ID_AML5040), 0},
+ { PCI_VDEVICE(WANGXUN, TXGBE_DEV_ID_AML5140), 0},
/* required last entry */
{ .device = 0 }
};
@@ -89,7 +95,18 @@ static void txgbe_up_complete(struct wx *wx)
smp_mb__before_atomic();
wx_napi_enable_all(wx);
- phylink_start(wx->phylink);
+ if (wx->mac.type == wx_mac_aml) {
+ u32 reg;
+
+ reg = rd32(wx, TXGBE_AML_MAC_TX_CFG);
+ reg &= ~TXGBE_AML_MAC_TX_CFG_SPEED_MASK;
+ reg |= TXGBE_AML_MAC_TX_CFG_SPEED_25G;
+ wr32(wx, WX_MAC_TX_CFG, reg);
+ txgbe_enable_sec_tx_path(wx);
+ netif_carrier_on(wx->netdev);
+ } else {
+ phylink_start(wx->phylink);
+ }
/* clear any pending interrupts, may auto mask */
rd32(wx, WX_PX_IC(0));
@@ -167,7 +184,10 @@ void txgbe_down(struct wx *wx)
{
txgbe_disable_device(wx);
txgbe_reset(wx);
- phylink_stop(wx->phylink);
+ if (wx->mac.type == wx_mac_aml)
+ netif_carrier_off(wx->netdev);
+ else
+ phylink_stop(wx->phylink);
wx_clean_all_tx_rings(wx);
wx_clean_all_rx_rings(wx);
@@ -192,6 +212,14 @@ static void txgbe_init_type_code(struct wx *wx)
case TXGBE_DEV_ID_WX1820:
wx->mac.type = wx_mac_sp;
break;
+ case TXGBE_DEV_ID_AML5010:
+ case TXGBE_DEV_ID_AML5110:
+ case TXGBE_DEV_ID_AML5025:
+ case TXGBE_DEV_ID_AML5125:
+ case TXGBE_DEV_ID_AML5040:
+ case TXGBE_DEV_ID_AML5140:
+ wx->mac.type = wx_mac_aml;
+ break;
default:
wx->mac.type = wx_mac_unknown;
break;
@@ -279,6 +307,17 @@ static int txgbe_sw_init(struct wx *wx)
wx->do_reset = txgbe_do_reset;
+ switch (wx->mac.type) {
+ case wx_mac_sp:
+ break;
+ case wx_mac_aml:
+ set_bit(WX_FLAG_SWFW_RING, wx->flags);
+ wx->swfw_index = 0;
+ break;
+ default:
+ break;
+ }
+
return 0;
}
diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe_phy.c b/drivers/net/ethernet/wangxun/txgbe/txgbe_phy.c
index 1ae68f94dd49..41c86249c339 100644
--- a/drivers/net/ethernet/wangxun/txgbe/txgbe_phy.c
+++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_phy.c
@@ -557,6 +557,9 @@ int txgbe_init_phy(struct txgbe *txgbe)
struct wx *wx = txgbe->wx;
int ret;
+ if (wx->mac.type == wx_mac_aml)
+ return 0;
+
if (txgbe->wx->media_type == sp_media_copper)
return txgbe_ext_phy_init(txgbe);
@@ -621,6 +624,9 @@ int txgbe_init_phy(struct txgbe *txgbe)
void txgbe_remove_phy(struct txgbe *txgbe)
{
+ if (txgbe->wx->mac.type == wx_mac_aml)
+ return;
+
if (txgbe->wx->media_type == sp_media_copper) {
phylink_disconnect_phy(txgbe->wx->phylink);
phylink_destroy(txgbe->wx->phylink);
diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe_type.h b/drivers/net/ethernet/wangxun/txgbe/txgbe_type.h
index 629a13e96b85..9c1c26234cad 100644
--- a/drivers/net/ethernet/wangxun/txgbe/txgbe_type.h
+++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_type.h
@@ -10,6 +10,12 @@
/* Device IDs */
#define TXGBE_DEV_ID_SP1000 0x1001
#define TXGBE_DEV_ID_WX1820 0x2001
+#define TXGBE_DEV_ID_AML5010 0x5010
+#define TXGBE_DEV_ID_AML5110 0x5110
+#define TXGBE_DEV_ID_AML5025 0x5025
+#define TXGBE_DEV_ID_AML5125 0x5125
+#define TXGBE_DEV_ID_AML5040 0x5040
+#define TXGBE_DEV_ID_AML5140 0x5140
/* Subsystem IDs */
/* SFP */
@@ -137,6 +143,14 @@
#define TXGBE_RDB_FDIR_FLEX_CFG_MSK BIT(2)
#define TXGBE_RDB_FDIR_FLEX_CFG_OFST(v) FIELD_PREP(GENMASK(7, 3), v)
+/*************************** Amber Lite Registers ****************************/
+#define TXGBE_PX_PF_BME 0x4B8
+#define TXGBE_AML_MAC_TX_CFG 0x11000
+#define TXGBE_AML_MAC_TX_CFG_SPEED_MASK GENMASK(30, 27)
+#define TXGBE_AML_MAC_TX_CFG_SPEED_25G BIT(28)
+#define TXGBE_RDM_RSC_CTL 0x1200C
+#define TXGBE_RDM_RSC_CTL_FREE_CTL BIT(7)
+
/* Checksum and EEPROM pointers */
#define TXGBE_EEPROM_LAST_WORD 0x800
#define TXGBE_EEPROM_CHECKSUM 0x2F
--
2.27.0
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH net-next v3 2/2] net: wangxun: Replace the judgement of MAC type with flags
2025-01-15 10:24 [PATCH net-next v3 1/2] net: txgbe: Add basic support for new AML devices Jiawen Wu
@ 2025-01-15 10:24 ` Jiawen Wu
2025-01-15 15:29 ` [PATCH net-next v3 1/2] net: txgbe: Add basic support for new AML devices Simon Horman
2025-01-16 12:33 ` kernel test robot
2 siblings, 0 replies; 5+ messages in thread
From: Jiawen Wu @ 2025-01-15 10:24 UTC (permalink / raw)
To: andrew+netdev, davem, edumazet, kuba, pabeni, linux, horms,
netdev
Cc: mengyuanlou, Jiawen Wu
Since device MAC types are constantly being added, the judgments of
wx->mac.type are complex. Try to convert the types to flags depending
on functions.
Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
---
drivers/net/ethernet/wangxun/libwx/wx_ethtool.c | 8 ++++----
drivers/net/ethernet/wangxun/libwx/wx_hw.c | 4 ++--
drivers/net/ethernet/wangxun/libwx/wx_type.h | 1 +
drivers/net/ethernet/wangxun/txgbe/txgbe_main.c | 2 ++
4 files changed, 9 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/wangxun/libwx/wx_ethtool.c b/drivers/net/ethernet/wangxun/libwx/wx_ethtool.c
index f6b1323e606b..10cc7260fc4e 100644
--- a/drivers/net/ethernet/wangxun/libwx/wx_ethtool.c
+++ b/drivers/net/ethernet/wangxun/libwx/wx_ethtool.c
@@ -69,7 +69,7 @@ int wx_get_sset_count(struct net_device *netdev, int sset)
switch (sset) {
case ETH_SS_STATS:
- return (wx->mac.type == wx_mac_sp) ?
+ return (test_bit(WX_FLAG_FDIR_CAPABLE, wx->flags)) ?
WX_STATS_LEN + WX_FDIR_STATS_LEN : WX_STATS_LEN;
default:
return -EOPNOTSUPP;
@@ -87,7 +87,7 @@ void wx_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
case ETH_SS_STATS:
for (i = 0; i < WX_GLOBAL_STATS_LEN; i++)
ethtool_puts(&p, wx_gstrings_stats[i].stat_string);
- if (wx->mac.type == wx_mac_sp) {
+ if (test_bit(WX_FLAG_FDIR_CAPABLE, wx->flags)) {
for (i = 0; i < WX_FDIR_STATS_LEN; i++)
ethtool_puts(&p, wx_gstrings_fdir_stats[i].stat_string);
}
@@ -121,7 +121,7 @@ void wx_get_ethtool_stats(struct net_device *netdev,
sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
}
- if (wx->mac.type == wx_mac_sp) {
+ if (test_bit(WX_FLAG_FDIR_CAPABLE, wx->flags)) {
for (k = 0; k < WX_FDIR_STATS_LEN; k++) {
p = (char *)wx + wx_gstrings_fdir_stats[k].stat_offset;
data[i++] = *(u64 *)p;
@@ -196,7 +196,7 @@ void wx_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *info)
unsigned int stats_len = WX_STATS_LEN;
struct wx *wx = netdev_priv(netdev);
- if (wx->mac.type == wx_mac_sp)
+ if (test_bit(WX_FLAG_FDIR_CAPABLE, wx->flags))
stats_len += WX_FDIR_STATS_LEN;
strscpy(info->driver, wx->driver_name, sizeof(info->driver));
diff --git a/drivers/net/ethernet/wangxun/libwx/wx_hw.c b/drivers/net/ethernet/wangxun/libwx/wx_hw.c
index 7198650de096..10c42f681256 100644
--- a/drivers/net/ethernet/wangxun/libwx/wx_hw.c
+++ b/drivers/net/ethernet/wangxun/libwx/wx_hw.c
@@ -1843,7 +1843,7 @@ void wx_configure_rx(struct wx *wx)
/* enable hw crc stripping */
wr32m(wx, WX_RSC_CTL, WX_RSC_CTL_CRC_STRIP, WX_RSC_CTL_CRC_STRIP);
- if (wx->mac.type == wx_mac_sp) {
+ if (test_bit(WX_FLAG_RSC_CAPABLE, wx->flags)) {
u32 psrctl;
/* RSC Setup */
@@ -2495,7 +2495,7 @@ void wx_update_stats(struct wx *wx)
hwstats->b2ogprc += rd32(wx, WX_RDM_BMC2OS_CNT);
hwstats->rdmdrop += rd32(wx, WX_RDM_DRP_PKT);
- if (wx->mac.type == wx_mac_sp) {
+ if (test_bit(WX_FLAG_FDIR_CAPABLE, wx->flags)) {
hwstats->fdirmatch += rd32(wx, WX_RDB_FDIR_MATCH);
hwstats->fdirmiss += rd32(wx, WX_RDB_FDIR_MISS);
}
diff --git a/drivers/net/ethernet/wangxun/libwx/wx_type.h b/drivers/net/ethernet/wangxun/libwx/wx_type.h
index ba6e45eeaba6..c0d8ecfd7f03 100644
--- a/drivers/net/ethernet/wangxun/libwx/wx_type.h
+++ b/drivers/net/ethernet/wangxun/libwx/wx_type.h
@@ -1051,6 +1051,7 @@ enum wx_pf_flags {
WX_FLAG_FDIR_CAPABLE,
WX_FLAG_FDIR_HASH,
WX_FLAG_FDIR_PERFECT,
+ WX_FLAG_RSC_CAPABLE,
WX_PF_FLAGS_NBITS /* must be last */
};
diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe_main.c b/drivers/net/ethernet/wangxun/txgbe/txgbe_main.c
index ffe42b77de3e..12bb947daba4 100644
--- a/drivers/net/ethernet/wangxun/txgbe/txgbe_main.c
+++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_main.c
@@ -293,6 +293,8 @@ static int txgbe_sw_init(struct wx *wx)
wx->atr = txgbe_atr;
wx->configure_fdir = txgbe_configure_fdir;
+ set_bit(WX_FLAG_RSC_CAPABLE, wx->flags);
+
/* enable itr by default in dynamic mode */
wx->rx_itr_setting = 1;
wx->tx_itr_setting = 1;
--
2.27.0
^ permalink raw reply related [flat|nested] 5+ messages in thread* Re: [PATCH net-next v3 1/2] net: txgbe: Add basic support for new AML devices
2025-01-15 10:24 [PATCH net-next v3 1/2] net: txgbe: Add basic support for new AML devices Jiawen Wu
2025-01-15 10:24 ` [PATCH net-next v3 2/2] net: wangxun: Replace the judgement of MAC type with flags Jiawen Wu
@ 2025-01-15 15:29 ` Simon Horman
2025-01-16 6:57 ` Jiawen Wu
2025-01-16 12:33 ` kernel test robot
2 siblings, 1 reply; 5+ messages in thread
From: Simon Horman @ 2025-01-15 15:29 UTC (permalink / raw)
To: Jiawen Wu
Cc: andrew+netdev, davem, edumazet, kuba, pabeni, linux, netdev,
mengyuanlou
On Wed, Jan 15, 2025 at 06:24:07PM +0800, Jiawen Wu wrote:
> There is a new 40/25/10 Gigabit Ethernet device.
>
> To support basic functions, PHYLINK is temporarily skipped as it is
> intended to implement these configurations in the firmware. And the
> associated link IRQ is also skipped.
>
> And Implement the new SW-FW interaction interface, which use 64 Byte
> message buffer.
>
> Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
...
> diff --git a/drivers/net/ethernet/wangxun/libwx/wx_hw.c b/drivers/net/ethernet/wangxun/libwx/wx_hw.c
...
> +static bool wx_poll_fw_reply(struct wx *wx, u32 *buffer,
> + struct wx_hic_hdr *recv_hdr, u8 send_cmd)
> +{
> + u32 dword_len = sizeof(struct wx_hic_hdr) >> 2;
> + u32 i;
> +
> + /* read hdr */
> + for (i = 0; i < dword_len; i++) {
> + buffer[i] = rd32a(wx, WX_FW2SW_MBOX, i);
> + le32_to_cpus(&buffer[i]);
> + }
> +
> + /* check hdr */
> + recv_hdr = (struct wx_hic_hdr *)buffer;
> + if (recv_hdr->cmd == send_cmd &&
> + recv_hdr->index == wx->swfw_index)
> + return true;
Hi Jiawen Wu,
Maybe I am misreading this but, given the way that recv_hdr is
passed to this function, it seems that the same result would
he achieved if recv_hdr was a local variable...
> +
> + return false;
> +}
> +
> +static int wx_host_interface_command_r(struct wx *wx, u32 *buffer,
> + u32 length, u32 timeout, bool return_data)
> +{
> + struct wx_hic_hdr *send_hdr = (struct wx_hic_hdr *)buffer;
> + u32 hdr_size = sizeof(struct wx_hic_hdr);
> + struct wx_hic_hdr *recv_hdr;
> + bool busy, reply;
> + u32 dword_len;
> + u16 buf_len;
> + int err = 0;
> + u8 send_cmd;
> + u32 i;
> +
> + /* wait to get lock */
> + might_sleep();
> + err = read_poll_timeout(test_and_set_bit, busy, !busy, 1000, timeout * 1000,
> + false, WX_STATE_SWFW_BUSY, wx->state);
> + if (err)
> + return err;
> +
> + /* index to unique seq id for each mbox message */
> + send_hdr->index = wx->swfw_index;
> + send_cmd = send_hdr->cmd;
> +
> + dword_len = length >> 2;
> + /* write data to SW-FW mbox array */
> + for (i = 0; i < dword_len; i++) {
> + wr32a(wx, WX_SW2FW_MBOX, i, (__force u32)cpu_to_le32(buffer[i]));
> + /* write flush */
> + rd32a(wx, WX_SW2FW_MBOX, i);
> + }
> +
> + /* generate interrupt to notify FW */
> + wr32m(wx, WX_SW2FW_MBOX_CMD, WX_SW2FW_MBOX_CMD_VLD, 0);
> + wr32m(wx, WX_SW2FW_MBOX_CMD, WX_SW2FW_MBOX_CMD_VLD, WX_SW2FW_MBOX_CMD_VLD);
> +
> + /* polling reply from FW */
> + err = read_poll_timeout(wx_poll_fw_reply, reply, reply, 1000, 50000,
> + true, wx, buffer, recv_hdr, send_cmd);
> + if (err) {
> + wx_err(wx, "Polling from FW messages timeout, cmd: 0x%x, index: %d\n",
> + send_cmd, wx->swfw_index);
> + goto rel_out;
> + }
> +
> + /* expect no reply from FW then return */
> + if (!return_data)
> + goto rel_out;
> +
> + /* If there is any thing in data position pull it in */
> + buf_len = recv_hdr->buf_len;
... and most likely related, recv_hdr appears to be uninitialised here.
This part is flagged by W=1 builds with clang-19, and my Smatch.
> + if (buf_len == 0)
> + goto rel_out;
> +
> + if (length < buf_len + hdr_size) {
> + wx_err(wx, "Buffer not large enough for reply message.\n");
> + err = -EFAULT;
> + goto rel_out;
> + }
> +
> + /* Calculate length in DWORDs, add 3 for odd lengths */
> + dword_len = (buf_len + 3) >> 2;
> + for (i = hdr_size >> 2; i <= dword_len; i++) {
> + buffer[i] = rd32a(wx, WX_FW2SW_MBOX, i);
> + le32_to_cpus(&buffer[i]);
> + }
> +
> +rel_out:
> + /* index++, index replace wx_hic_hdr.checksum */
> + if (send_hdr->index == WX_HIC_HDR_INDEX_MAX)
> + wx->swfw_index = 0;
> + else
> + wx->swfw_index = send_hdr->index + 1;
> +
> + clear_bit(WX_STATE_SWFW_BUSY, wx->state);
> + return err;
> +}
...
^ permalink raw reply [flat|nested] 5+ messages in thread* RE: [PATCH net-next v3 1/2] net: txgbe: Add basic support for new AML devices
2025-01-15 15:29 ` [PATCH net-next v3 1/2] net: txgbe: Add basic support for new AML devices Simon Horman
@ 2025-01-16 6:57 ` Jiawen Wu
0 siblings, 0 replies; 5+ messages in thread
From: Jiawen Wu @ 2025-01-16 6:57 UTC (permalink / raw)
To: 'Simon Horman'
Cc: andrew+netdev, davem, edumazet, kuba, pabeni, linux, netdev,
mengyuanlou
On Wed, Jan 15, 2025 11:30 PM, Simon Horman wrote:
> On Wed, Jan 15, 2025 at 06:24:07PM +0800, Jiawen Wu wrote:
> > There is a new 40/25/10 Gigabit Ethernet device.
> >
> > To support basic functions, PHYLINK is temporarily skipped as it is
> > intended to implement these configurations in the firmware. And the
> > associated link IRQ is also skipped.
> >
> > And Implement the new SW-FW interaction interface, which use 64 Byte
> > message buffer.
> >
> > Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
>
> ...
>
> > diff --git a/drivers/net/ethernet/wangxun/libwx/wx_hw.c b/drivers/net/ethernet/wangxun/libwx/wx_hw.c
>
> ...
>
> > +static bool wx_poll_fw_reply(struct wx *wx, u32 *buffer,
> > + struct wx_hic_hdr *recv_hdr, u8 send_cmd)
> > +{
> > + u32 dword_len = sizeof(struct wx_hic_hdr) >> 2;
> > + u32 i;
> > +
> > + /* read hdr */
> > + for (i = 0; i < dword_len; i++) {
> > + buffer[i] = rd32a(wx, WX_FW2SW_MBOX, i);
> > + le32_to_cpus(&buffer[i]);
> > + }
> > +
> > + /* check hdr */
> > + recv_hdr = (struct wx_hic_hdr *)buffer;
> > + if (recv_hdr->cmd == send_cmd &&
> > + recv_hdr->index == wx->swfw_index)
> > + return true;
>
> Hi Jiawen Wu,
>
> Maybe I am misreading this but, given the way that recv_hdr is
> passed to this function, it seems that the same result would
> he achieved if recv_hdr was a local variable...
Oooh, you are right, I'm too careless.
>
> > +
> > + return false;
> > +}
> > +
> > +static int wx_host_interface_command_r(struct wx *wx, u32 *buffer,
> > + u32 length, u32 timeout, bool return_data)
> > +{
> > + struct wx_hic_hdr *send_hdr = (struct wx_hic_hdr *)buffer;
> > + u32 hdr_size = sizeof(struct wx_hic_hdr);
> > + struct wx_hic_hdr *recv_hdr;
> > + bool busy, reply;
> > + u32 dword_len;
> > + u16 buf_len;
> > + int err = 0;
> > + u8 send_cmd;
> > + u32 i;
> > +
> > + /* wait to get lock */
> > + might_sleep();
> > + err = read_poll_timeout(test_and_set_bit, busy, !busy, 1000, timeout * 1000,
> > + false, WX_STATE_SWFW_BUSY, wx->state);
> > + if (err)
> > + return err;
> > +
> > + /* index to unique seq id for each mbox message */
> > + send_hdr->index = wx->swfw_index;
> > + send_cmd = send_hdr->cmd;
> > +
> > + dword_len = length >> 2;
> > + /* write data to SW-FW mbox array */
> > + for (i = 0; i < dword_len; i++) {
> > + wr32a(wx, WX_SW2FW_MBOX, i, (__force u32)cpu_to_le32(buffer[i]));
> > + /* write flush */
> > + rd32a(wx, WX_SW2FW_MBOX, i);
> > + }
> > +
> > + /* generate interrupt to notify FW */
> > + wr32m(wx, WX_SW2FW_MBOX_CMD, WX_SW2FW_MBOX_CMD_VLD, 0);
> > + wr32m(wx, WX_SW2FW_MBOX_CMD, WX_SW2FW_MBOX_CMD_VLD, WX_SW2FW_MBOX_CMD_VLD);
> > +
> > + /* polling reply from FW */
> > + err = read_poll_timeout(wx_poll_fw_reply, reply, reply, 1000, 50000,
> > + true, wx, buffer, recv_hdr, send_cmd);
> > + if (err) {
> > + wx_err(wx, "Polling from FW messages timeout, cmd: 0x%x, index: %d\n",
> > + send_cmd, wx->swfw_index);
> > + goto rel_out;
> > + }
> > +
> > + /* expect no reply from FW then return */
> > + if (!return_data)
> > + goto rel_out;
> > +
> > + /* If there is any thing in data position pull it in */
> > + buf_len = recv_hdr->buf_len;
>
> ... and most likely related, recv_hdr appears to be uninitialised here.
>
> This part is flagged by W=1 builds with clang-19, and my Smatch.
>
> > + if (buf_len == 0)
> > + goto rel_out;
> > +
> > + if (length < buf_len + hdr_size) {
> > + wx_err(wx, "Buffer not large enough for reply message.\n");
> > + err = -EFAULT;
> > + goto rel_out;
> > + }
> > +
> > + /* Calculate length in DWORDs, add 3 for odd lengths */
> > + dword_len = (buf_len + 3) >> 2;
> > + for (i = hdr_size >> 2; i <= dword_len; i++) {
> > + buffer[i] = rd32a(wx, WX_FW2SW_MBOX, i);
> > + le32_to_cpus(&buffer[i]);
> > + }
> > +
> > +rel_out:
> > + /* index++, index replace wx_hic_hdr.checksum */
> > + if (send_hdr->index == WX_HIC_HDR_INDEX_MAX)
> > + wx->swfw_index = 0;
> > + else
> > + wx->swfw_index = send_hdr->index + 1;
> > +
> > + clear_bit(WX_STATE_SWFW_BUSY, wx->state);
> > + return err;
> > +}
>
> ...
>
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH net-next v3 1/2] net: txgbe: Add basic support for new AML devices
2025-01-15 10:24 [PATCH net-next v3 1/2] net: txgbe: Add basic support for new AML devices Jiawen Wu
2025-01-15 10:24 ` [PATCH net-next v3 2/2] net: wangxun: Replace the judgement of MAC type with flags Jiawen Wu
2025-01-15 15:29 ` [PATCH net-next v3 1/2] net: txgbe: Add basic support for new AML devices Simon Horman
@ 2025-01-16 12:33 ` kernel test robot
2 siblings, 0 replies; 5+ messages in thread
From: kernel test robot @ 2025-01-16 12:33 UTC (permalink / raw)
To: Jiawen Wu, andrew+netdev, davem, edumazet, kuba, pabeni, linux,
horms, netdev
Cc: llvm, oe-kbuild-all, mengyuanlou, Jiawen Wu
Hi Jiawen,
kernel test robot noticed the following build warnings:
[auto build test WARNING on net-next/main]
url: https://github.com/intel-lab-lkp/linux/commits/Jiawen-Wu/net-wangxun-Replace-the-judgement-of-MAC-type-with-flags/20250115-180916
base: net-next/main
patch link: https://lore.kernel.org/r/20250115102408.2225055-1-jiawenwu%40trustnetic.com
patch subject: [PATCH net-next v3 1/2] net: txgbe: Add basic support for new AML devices
config: powerpc-randconfig-001-20250116 (https://download.01.org/0day-ci/archive/20250116/202501162038.zXreDkFM-lkp@intel.com/config)
compiler: clang version 20.0.0git (https://github.com/llvm/llvm-project c23f2417dc5f6dc371afb07af5627ec2a9d373a0)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250116/202501162038.zXreDkFM-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202501162038.zXreDkFM-lkp@intel.com/
All warnings (new ones prefixed by >>):
>> drivers/net/ethernet/wangxun/libwx/wx_hw.c:451:12: warning: variable 'recv_hdr' is uninitialized when used here [-Wuninitialized]
451 | buf_len = recv_hdr->buf_len;
| ^~~~~~~~
drivers/net/ethernet/wangxun/libwx/wx_hw.c:406:29: note: initialize the variable 'recv_hdr' to silence this warning
406 | struct wx_hic_hdr *recv_hdr;
| ^
| = NULL
1 warning generated.
vim +/recv_hdr +451 drivers/net/ethernet/wangxun/libwx/wx_hw.c
400
401 static int wx_host_interface_command_r(struct wx *wx, u32 *buffer,
402 u32 length, u32 timeout, bool return_data)
403 {
404 struct wx_hic_hdr *send_hdr = (struct wx_hic_hdr *)buffer;
405 u32 hdr_size = sizeof(struct wx_hic_hdr);
406 struct wx_hic_hdr *recv_hdr;
407 bool busy, reply;
408 u32 dword_len;
409 u16 buf_len;
410 int err = 0;
411 u8 send_cmd;
412 u32 i;
413
414 /* wait to get lock */
415 might_sleep();
416 err = read_poll_timeout(test_and_set_bit, busy, !busy, 1000, timeout * 1000,
417 false, WX_STATE_SWFW_BUSY, wx->state);
418 if (err)
419 return err;
420
421 /* index to unique seq id for each mbox message */
422 send_hdr->index = wx->swfw_index;
423 send_cmd = send_hdr->cmd;
424
425 dword_len = length >> 2;
426 /* write data to SW-FW mbox array */
427 for (i = 0; i < dword_len; i++) {
428 wr32a(wx, WX_SW2FW_MBOX, i, (__force u32)cpu_to_le32(buffer[i]));
429 /* write flush */
430 rd32a(wx, WX_SW2FW_MBOX, i);
431 }
432
433 /* generate interrupt to notify FW */
434 wr32m(wx, WX_SW2FW_MBOX_CMD, WX_SW2FW_MBOX_CMD_VLD, 0);
435 wr32m(wx, WX_SW2FW_MBOX_CMD, WX_SW2FW_MBOX_CMD_VLD, WX_SW2FW_MBOX_CMD_VLD);
436
437 /* polling reply from FW */
438 err = read_poll_timeout(wx_poll_fw_reply, reply, reply, 1000, 50000,
439 true, wx, buffer, recv_hdr, send_cmd);
440 if (err) {
441 wx_err(wx, "Polling from FW messages timeout, cmd: 0x%x, index: %d\n",
442 send_cmd, wx->swfw_index);
443 goto rel_out;
444 }
445
446 /* expect no reply from FW then return */
447 if (!return_data)
448 goto rel_out;
449
450 /* If there is any thing in data position pull it in */
> 451 buf_len = recv_hdr->buf_len;
452 if (buf_len == 0)
453 goto rel_out;
454
455 if (length < buf_len + hdr_size) {
456 wx_err(wx, "Buffer not large enough for reply message.\n");
457 err = -EFAULT;
458 goto rel_out;
459 }
460
461 /* Calculate length in DWORDs, add 3 for odd lengths */
462 dword_len = (buf_len + 3) >> 2;
463 for (i = hdr_size >> 2; i <= dword_len; i++) {
464 buffer[i] = rd32a(wx, WX_FW2SW_MBOX, i);
465 le32_to_cpus(&buffer[i]);
466 }
467
468 rel_out:
469 /* index++, index replace wx_hic_hdr.checksum */
470 if (send_hdr->index == WX_HIC_HDR_INDEX_MAX)
471 wx->swfw_index = 0;
472 else
473 wx->swfw_index = send_hdr->index + 1;
474
475 clear_bit(WX_STATE_SWFW_BUSY, wx->state);
476 return err;
477 }
478
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2025-01-16 12:33 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-01-15 10:24 [PATCH net-next v3 1/2] net: txgbe: Add basic support for new AML devices Jiawen Wu
2025-01-15 10:24 ` [PATCH net-next v3 2/2] net: wangxun: Replace the judgement of MAC type with flags Jiawen Wu
2025-01-15 15:29 ` [PATCH net-next v3 1/2] net: txgbe: Add basic support for new AML devices Simon Horman
2025-01-16 6:57 ` Jiawen Wu
2025-01-16 12:33 ` kernel test robot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).