@@ -3638,6 +3638,7 @@ struct cmd_csum_result {
struct cmd_csum_result *res = parsed_result;
int hw = 0;
uint64_t csum_offloads = 0;
+ struct rte_eth_dev_info dev_info;
if (port_id_is_invalid(res->port_id, ENABLED_WARN)) {
printf("invalid port %d\n", res->port_id);
@@ -3648,21 +3649,53 @@ struct cmd_csum_result {
return;
}
+ rte_eth_dev_info_get(res->port_id, &dev_info);
if (!strcmp(res->mode, "set")) {
if (!strcmp(res->hwsw, "hw"))
hw = 1;
if (!strcmp(res->proto, "ip")) {
- csum_offloads |= DEV_TX_OFFLOAD_IPV4_CKSUM;
+ if (dev_info.tx_offload_capa &
+ DEV_TX_OFFLOAD_IPV4_CKSUM) {
+ csum_offloads |= DEV_TX_OFFLOAD_IPV4_CKSUM;
+ } else {
+ printf("IP checksum offload is not supported "
+ "by port %u\n", res->port_id);
+ }
} else if (!strcmp(res->proto, "udp")) {
- csum_offloads |= DEV_TX_OFFLOAD_UDP_CKSUM;
+ if (dev_info.tx_offload_capa &
+ DEV_TX_OFFLOAD_UDP_CKSUM) {
+ csum_offloads |= DEV_TX_OFFLOAD_UDP_CKSUM;
+ } else {
+ printf("UDP checksum offload is not supported "
+ "by port %u\n", res->port_id);
+ }
} else if (!strcmp(res->proto, "tcp")) {
- csum_offloads |= DEV_TX_OFFLOAD_TCP_CKSUM;
+ if (dev_info.tx_offload_capa &
+ DEV_TX_OFFLOAD_TCP_CKSUM) {
+ csum_offloads |= DEV_TX_OFFLOAD_TCP_CKSUM;
+ } else {
+ printf("TCP checksum offload is not supported "
+ "by port %u\n", res->port_id);
+ }
} else if (!strcmp(res->proto, "sctp")) {
- csum_offloads |= DEV_TX_OFFLOAD_SCTP_CKSUM;
+ if (dev_info.tx_offload_capa &
+ DEV_TX_OFFLOAD_SCTP_CKSUM) {
+ csum_offloads |= DEV_TX_OFFLOAD_SCTP_CKSUM;
+ } else {
+ printf("SCTP checksum offload is not supported "
+ "by port %u\n", res->port_id);
+ }
} else if (!strcmp(res->proto, "outer-ip")) {
- csum_offloads |= DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM;
+ if (dev_info.tx_offload_capa &
+ DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM) {
+ csum_offloads |=
+ DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM;
+ } else {
+ printf("Outer IP checksum offload is not "
+ "supported by port %u\n", res->port_id);
+ }
}
if (hw) {
@@ -3805,6 +3838,14 @@ struct cmd_tso_set_result {
if (!strcmp(res->mode, "set"))
ports[res->port_id].tso_segsz = res->tso_segsz;
+ rte_eth_dev_info_get(res->port_id, &dev_info);
+ if ((ports[res->port_id].tso_segsz != 0) &&
+ (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_TCP_TSO) == 0) {
+ printf("Error: TSO is not supported by port %d\n",
+ res->port_id);
+ return;
+ }
+
if (ports[res->port_id].tso_segsz == 0) {
ports[res->port_id].dev_conf.txmode.offloads &=
~DEV_TX_OFFLOAD_TCP_TSO;
@@ -3881,24 +3922,25 @@ struct cmd_tunnel_tso_set_result {
portid_t port_id;
};
-static void
+static struct rte_eth_dev_info
check_tunnel_tso_nic_support(portid_t port_id)
{
struct rte_eth_dev_info dev_info;
rte_eth_dev_info_get(port_id, &dev_info);
if (!(dev_info.tx_offload_capa & DEV_TX_OFFLOAD_VXLAN_TNL_TSO))
- printf("Warning: TSO enabled but VXLAN TUNNEL TSO not "
- "supported by port %d\n", port_id);
+ printf("Warning: VXLAN TUNNEL TSO not supported therefore "
+ "not enabled for port %d\n", port_id);
if (!(dev_info.tx_offload_capa & DEV_TX_OFFLOAD_GRE_TNL_TSO))
- printf("Warning: TSO enabled but GRE TUNNEL TSO not "
- "supported by port %d\n", port_id);
+ printf("Warning: GRE TUNNEL TSO not supported therefore "
+ "not enabled for port %d\n", port_id);
if (!(dev_info.tx_offload_capa & DEV_TX_OFFLOAD_IPIP_TNL_TSO))
- printf("Warning: TSO enabled but IPIP TUNNEL TSO not "
- "supported by port %d\n", port_id);
+ printf("Warning: IPIP TUNNEL TSO not supported therefore "
+ "not enabled for port %d\n", port_id);
if (!(dev_info.tx_offload_capa & DEV_TX_OFFLOAD_GENEVE_TNL_TSO))
- printf("Warning: TSO enabled but GENEVE TUNNEL TSO not "
- "supported by port %d\n", port_id);
+ printf("Warning: GENEVE TUNNEL TSO not supported therefore "
+ "not enabled for port %d\n", port_id);
+ return dev_info;
}
static void
@@ -3907,6 +3949,7 @@ struct cmd_tunnel_tso_set_result {
__attribute__((unused)) void *data)
{
struct cmd_tunnel_tso_set_result *res = parsed_result;
+ struct rte_eth_dev_info dev_info;
if (port_id_is_invalid(res->port_id, ENABLED_WARN))
return;
@@ -3918,6 +3961,7 @@ struct cmd_tunnel_tso_set_result {
if (!strcmp(res->mode, "set"))
ports[res->port_id].tunnel_tso_segsz = res->tso_segsz;
+ dev_info = check_tunnel_tso_nic_support(res->port_id);
if (ports[res->port_id].tunnel_tso_segsz == 0) {
ports[res->port_id].dev_conf.txmode.offloads &=
~(DEV_TX_OFFLOAD_VXLAN_TNL_TSO |
@@ -3926,11 +3970,13 @@ struct cmd_tunnel_tso_set_result {
DEV_TX_OFFLOAD_GENEVE_TNL_TSO);
printf("TSO for tunneled packets is disabled\n");
} else {
+ uint64_t tso_offloads = (DEV_TX_OFFLOAD_VXLAN_TNL_TSO |
+ DEV_TX_OFFLOAD_GRE_TNL_TSO |
+ DEV_TX_OFFLOAD_IPIP_TNL_TSO |
+ DEV_TX_OFFLOAD_GENEVE_TNL_TSO);
+
ports[res->port_id].dev_conf.txmode.offloads |=
- (DEV_TX_OFFLOAD_VXLAN_TNL_TSO |
- DEV_TX_OFFLOAD_GRE_TNL_TSO |
- DEV_TX_OFFLOAD_IPIP_TNL_TSO |
- DEV_TX_OFFLOAD_GENEVE_TNL_TSO);
+ (tso_offloads & dev_info.tx_offload_capa);
printf("TSO segment size for tunneled packets is %d\n",
ports[res->port_id].tunnel_tso_segsz);
@@ -3945,7 +3991,6 @@ struct cmd_tunnel_tso_set_result {
* is not necessary for IPv6 tunneled pkts because there's no
* checksum in IP header anymore.
*/
- check_tunnel_tso_nic_support(res->port_id);
if (!ports[res->port_id].parse_tunnel)
printf("Warning: csum parse_tunnel must be set "
@@ -12995,6 +13040,7 @@ struct cmd_macsec_offload_on_result {
portid_t port_id = res->port_id;
int en = (strcmp(res->en_on_off, "on") == 0) ? 1 : 0;
int rp = (strcmp(res->rp_on_off, "on") == 0) ? 1 : 0;
+ struct rte_eth_dev_info dev_info;
if (port_id_is_invalid(port_id, ENABLED_WARN))
return;
@@ -13003,15 +13049,19 @@ struct cmd_macsec_offload_on_result {
return;
}
- ports[port_id].dev_conf.txmode.offloads |= DEV_TX_OFFLOAD_MACSEC_INSERT;
+ rte_eth_dev_info_get(port_id, &dev_info);
+ if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MACSEC_INSERT) {
#ifdef RTE_LIBRTE_IXGBE_PMD
- ret = rte_pmd_ixgbe_macsec_enable(port_id, en, rp);
+ ret = rte_pmd_ixgbe_macsec_enable(port_id, en, rp);
#endif
+ }
RTE_SET_USED(en);
RTE_SET_USED(rp);
switch (ret) {
case 0:
+ ports[port_id].dev_conf.txmode.offloads |=
+ DEV_TX_OFFLOAD_MACSEC_INSERT;
cmd_reconfig_device_queue(port_id, 1, 1);
break;
case -ENODEV:
@@ -13083,6 +13133,7 @@ struct cmd_macsec_offload_off_result {
{
struct cmd_macsec_offload_off_result *res = parsed_result;
int ret = -ENOTSUP;
+ struct rte_eth_dev_info dev_info;
portid_t port_id = res->port_id;
if (port_id_is_invalid(port_id, ENABLED_WARN))
@@ -13092,14 +13143,16 @@ struct cmd_macsec_offload_off_result {
return;
}
- ports[port_id].dev_conf.txmode.offloads &=
- ~DEV_TX_OFFLOAD_MACSEC_INSERT;
+ rte_eth_dev_info_get(port_id, &dev_info);
+ if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MACSEC_INSERT) {
#ifdef RTE_LIBRTE_IXGBE_PMD
- ret = rte_pmd_ixgbe_macsec_disable(port_id);
+ ret = rte_pmd_ixgbe_macsec_disable(port_id);
#endif
-
+ }
switch (ret) {
case 0:
+ ports[port_id].dev_conf.txmode.offloads &=
+ ~DEV_TX_OFFLOAD_MACSEC_INSERT;
cmd_reconfig_device_queue(port_id, 1, 1);
break;
case -ENODEV:
@@ -2791,6 +2791,7 @@ struct igb_ring_desc_16_bytes {
tx_vlan_set(portid_t port_id, uint16_t vlan_id)
{
int vlan_offload;
+ struct rte_eth_dev_info dev_info;
if (port_id_is_invalid(port_id, ENABLED_WARN))
return;
@@ -2802,6 +2803,12 @@ struct igb_ring_desc_16_bytes {
printf("Error, as QinQ has been enabled.\n");
return;
}
+ rte_eth_dev_info_get(port_id, &dev_info);
+ if ((dev_info.tx_offload_capa & DEV_TX_OFFLOAD_VLAN_INSERT) == 0) {
+ printf("Error: vlan insert is not supported by port %d\n",
+ port_id);
+ return;
+ }
tx_vlan_reset(port_id);
ports[port_id].dev_conf.txmode.offloads |= DEV_TX_OFFLOAD_VLAN_INSERT;
@@ -2812,6 +2819,7 @@ struct igb_ring_desc_16_bytes {
tx_qinq_set(portid_t port_id, uint16_t vlan_id, uint16_t vlan_id_outer)
{
int vlan_offload;
+ struct rte_eth_dev_info dev_info;
if (port_id_is_invalid(port_id, ENABLED_WARN))
return;
@@ -2825,6 +2833,12 @@ struct igb_ring_desc_16_bytes {
printf("Error, as QinQ hasn't been enabled.\n");
return;
}
+ rte_eth_dev_info_get(port_id, &dev_info);
+ if ((dev_info.tx_offload_capa & DEV_TX_OFFLOAD_QINQ_INSERT) == 0) {
+ printf("Error: qinq insert not supported by port %d\n",
+ port_id);
+ return;
+ }
tx_vlan_reset(port_id);
ports[port_id].dev_conf.txmode.offloads |= DEV_TX_OFFLOAD_QINQ_INSERT;
@@ -1440,6 +1440,28 @@ static int eth_event_callback(portid_t port_id,
return 1;
}
+static void
+check_port_offloads_conf(portid_t pi, struct rte_eth_conf *port_conf)
+{
+ struct rte_eth_dev_info dev_info;
+
+ rte_eth_dev_info_get(pi, &dev_info);
+ if ((dev_info.tx_offload_capa & port_conf->txmode.offloads) !=
+ port_conf->txmode.offloads) {
+ printf("Some Tx offloads are not supported "
+ "by port %d: requested 0x%lx supported 0x%lx\n",
+ pi, port_conf->txmode.offloads,
+ dev_info.tx_offload_capa);
+ }
+ if ((dev_info.rx_offload_capa & port_conf->rxmode.offloads) !=
+ port_conf->rxmode.offloads) {
+ printf("Some Rx offloads are not supported "
+ "by port %d: requested 0x%lx supported 0x%lx\n",
+ pi, port_conf->rxmode.offloads,
+ dev_info.rx_offload_capa);
+ }
+}
+
int
start_port(portid_t pid)
{
@@ -1481,6 +1503,8 @@ static int eth_event_callback(portid_t port_id,
printf("Configuring Port %d (socket %u)\n", pi,
port->socket_id);
+ /* Check for unsupported offloads */
+ check_port_offloads_conf(pi, &port->dev_conf);
/* configure port */
diag = rte_eth_dev_configure(pi, nb_rxq, nb_txq,
&(port->dev_conf));
@@ -2263,6 +2287,7 @@ uint8_t port_is_bonding_slave(portid_t slave_pid)
* Set the numbers of RX & TX queues to 0, so
* the RX & TX queues will not be setup.
*/
+ check_port_offloads_conf(pid, &port_conf);
rte_eth_dev_configure(pid, 0, 0, &port_conf);
rte_eth_dev_info_get(pid, &rte_port->dev_info);