Skip to content

Commit 4ef8e14

Browse files
ibirnbaumcfriedt
authored andcommitted
drivers: ethernet: xlnx_gem: invert RX/TX checksum offload behaviour
Invert the RX/TX checksum offloading to hardware behaviour so that hardware checksum generation / evaluation for TCP/UDP packets on either IPv4 or IPv6 is enabled by default, but can be disabled explicitly. This behaviour, which should optimize network performance, has become possible with the implementation of the device driver's get_config function, indicating to the network stack that HW checksum offloading is not supported for, e.g., ICMP packets. Before this implementation, enabling the HW checksum offloading resulted in invalid packets for any unsupported protocol and could therefore not be enabled by default. For QEMU, which does not support the emulation of the HW checksum offloading, automatically disable the offloading. Signed-off-by: Immo Birnbaum <[email protected]>
1 parent 9e52df0 commit 4ef8e14

File tree

2 files changed

+18
-20
lines changed

2 files changed

+18
-20
lines changed

drivers/ethernet/eth_xlnx_gem.c

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@
3737
#include <zephyr/logging/log.h>
3838
LOG_MODULE_REGISTER(LOG_MODULE_NAME);
3939

40+
#if CONFIG_QEMU_TARGET ||\
41+
DT_ANY_INST_HAS_BOOL_STATUS_OKAY(disable_rx_checksum_offload) ||\
42+
DT_ANY_INST_HAS_BOOL_STATUS_OKAY(disable_tx_checksum_offload)
43+
#warning "xlnx_gem: at least one instance has checksum offloading to hardware disabled"
44+
#endif
45+
4046
static int eth_xlnx_gem_dev_init(const struct device *dev);
4147
static void eth_xlnx_gem_iface_init(struct net_if *iface);
4248
static void eth_xlnx_gem_isr(const struct device *dev);
@@ -181,16 +187,6 @@ static int eth_xlnx_gem_dev_init(const struct device *dev)
181187
"must be 16380 bytes maximum.", dev->name,
182188
dev_conf->tx_buffer_size);
183189

184-
/* Checksum offloading limitations of the QEMU GEM implementation */
185-
#ifdef CONFIG_QEMU_TARGET
186-
__ASSERT(!dev_conf->enable_rx_chksum_offload,
187-
"TCP/UDP/IP hardware checksum offloading is not "
188-
"supported by the QEMU GEM implementation");
189-
__ASSERT(!dev_conf->enable_tx_chksum_offload,
190-
"TCP/UDP/IP hardware checksum offloading is not "
191-
"supported by the QEMU GEM implementation");
192-
#endif
193-
194190
/*
195191
* Initialization procedure as described in the Zynq-7000 TRM,
196192
* chapter 16.3.x.
@@ -641,11 +637,11 @@ static enum ethernet_hw_caps eth_xlnx_gem_get_capabilities(
641637
caps |= ETHERNET_LINK_10BASE;
642638
}
643639

644-
if (dev_conf->enable_rx_chksum_offload) {
640+
if (!dev_conf->disable_rx_chksum_offload) {
645641
caps |= ETHERNET_HW_RX_CHKSUM_OFFLOAD;
646642
}
647643

648-
if (dev_conf->enable_tx_chksum_offload) {
644+
if (!dev_conf->disable_tx_chksum_offload) {
649645
caps |= ETHERNET_HW_TX_CHKSUM_OFFLOAD;
650646
}
651647

@@ -682,7 +678,7 @@ static int eth_xlnx_gem_get_config(const struct device *dev,
682678

683679
switch (type) {
684680
case ETHERNET_CONFIG_TYPE_RX_CHECKSUM_SUPPORT:
685-
if (dev_conf->enable_rx_chksum_offload) {
681+
if (!dev_conf->disable_rx_chksum_offload) {
686682
config->chksum_support = ETHERNET_CHECKSUM_SUPPORT_IPV4_HEADER |
687683
ETHERNET_CHECKSUM_SUPPORT_IPV6_HEADER |
688684
ETHERNET_CHECKSUM_SUPPORT_TCP |
@@ -692,7 +688,7 @@ static int eth_xlnx_gem_get_config(const struct device *dev,
692688
}
693689
return 0;
694690
case ETHERNET_CONFIG_TYPE_TX_CHECKSUM_SUPPORT:
695-
if (dev_conf->enable_tx_chksum_offload) {
691+
if (!dev_conf->disable_tx_chksum_offload) {
696692
config->chksum_support = ETHERNET_CHECKSUM_SUPPORT_IPV4_HEADER |
697693
ETHERNET_CHECKSUM_SUPPORT_IPV6_HEADER |
698694
ETHERNET_CHECKSUM_SUPPORT_TCP |
@@ -975,7 +971,7 @@ static void eth_xlnx_gem_set_initial_nwcfg(const struct device *dev)
975971
/* [25] RX half duplex while TX enable */
976972
reg_val |= ETH_XLNX_GEM_NWCFG_HDRXEN_BIT;
977973
}
978-
if (dev_conf->enable_rx_chksum_offload) {
974+
if (!dev_conf->disable_rx_chksum_offload) {
979975
/* [24] enable RX IP/TCP/UDP checksum offload */
980976
reg_val |= ETH_XLNX_GEM_NWCFG_RXCHKSUMEN_BIT;
981977
}
@@ -1153,7 +1149,7 @@ static void eth_xlnx_gem_set_initial_dmacr(const struct device *dev)
11531149
reg_val |= (((dev_conf->rx_buffer_size / 64) &
11541150
ETH_XLNX_GEM_DMACR_RX_BUF_MASK) <<
11551151
ETH_XLNX_GEM_DMACR_RX_BUF_SHIFT);
1156-
if (dev_conf->enable_tx_chksum_offload) {
1152+
if (!dev_conf->disable_tx_chksum_offload) {
11571153
/* [11] TX TCP/UDP/IP checksum offload to GEM */
11581154
reg_val |= ETH_XLNX_GEM_DMACR_TCP_CHKSUM_BIT;
11591155
}

drivers/ethernet/eth_xlnx_gem_priv.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -453,7 +453,8 @@ static const struct eth_xlnx_gem_dev_cfg eth_xlnx_gem##port##_dev_cfg = {\
453453
.enable_sgmii_mode = DT_INST_PROP(port, sgmii_mode),\
454454
.disable_reject_fcs_crc_errors = DT_INST_PROP(port, disable_reject_fcs_crc_errors),\
455455
.enable_rx_halfdup_while_tx = DT_INST_PROP(port, rx_halfdup_while_tx),\
456-
.enable_rx_chksum_offload = DT_INST_PROP(port, rx_checksum_offload),\
456+
.disable_rx_chksum_offload = UTIL_OR(IS_ENABLED(CONFIG_QEMU_TARGET),\
457+
DT_INST_PROP(port, disable_rx_checksum_offload)),\
457458
.disable_pause_copy = DT_INST_PROP(port, disable_pause_copy),\
458459
.discard_rx_fcs = DT_INST_PROP(port, discard_rx_fcs),\
459460
.discard_rx_length_errors = DT_INST_PROP(port, discard_rx_length_errors),\
@@ -467,7 +468,8 @@ static const struct eth_xlnx_gem_dev_cfg eth_xlnx_gem##port##_dev_cfg = {\
467468
.discard_non_vlan = DT_INST_PROP(port, discard_non_vlan),\
468469
.enable_fdx = DT_INST_PROP(port, full_duplex),\
469470
.disc_rx_ahb_unavail = DT_INST_PROP(port, discard_rx_frame_ahb_unavail),\
470-
.enable_tx_chksum_offload = DT_INST_PROP(port, tx_checksum_offload),\
471+
.disable_tx_chksum_offload = UTIL_OR(IS_ENABLED(CONFIG_QEMU_TARGET),\
472+
DT_INST_PROP(port, disable_tx_checksum_offload)),\
471473
.tx_buffer_size_full = DT_INST_PROP(port, hw_tx_buffer_size_full),\
472474
.enable_ahb_packet_endian_swap = DT_INST_PROP(port, ahb_packet_endian_swap),\
473475
.enable_ahb_md_endian_swap = DT_INST_PROP(port, ahb_md_endian_swap)\
@@ -710,7 +712,7 @@ struct eth_xlnx_gem_dev_cfg {
710712
bool enable_sgmii_mode : 1;
711713
bool disable_reject_fcs_crc_errors : 1;
712714
bool enable_rx_halfdup_while_tx : 1;
713-
bool enable_rx_chksum_offload : 1;
715+
bool disable_rx_chksum_offload : 1;
714716
bool disable_pause_copy : 1;
715717
bool discard_rx_fcs : 1;
716718
bool discard_rx_length_errors : 1;
@@ -724,7 +726,7 @@ struct eth_xlnx_gem_dev_cfg {
724726
bool discard_non_vlan : 1;
725727
bool enable_fdx : 1;
726728
bool disc_rx_ahb_unavail : 1;
727-
bool enable_tx_chksum_offload : 1;
729+
bool disable_tx_chksum_offload : 1;
728730
bool tx_buffer_size_full : 1;
729731
bool enable_ahb_packet_endian_swap : 1;
730732
bool enable_ahb_md_endian_swap : 1;

0 commit comments

Comments
 (0)