diff --git a/doc/guides/nics/features/octeontx.ini b/doc/guides/nics/features/octeontx.ini index 19caee61b6..e3ee79f0ff 100644 --- a/doc/guides/nics/features/octeontx.ini +++ b/doc/guides/nics/features/octeontx.ini @@ -8,6 +8,7 @@ Speed capabilities = Y Link status = Y Lock-free Tx queue = Y Queue start/stop = P +MTU update = Y Jumbo frame = Y Scattered Rx = Y Promiscuous mode = Y diff --git a/doc/guides/nics/octeontx.rst b/doc/guides/nics/octeontx.rst index 0c36e10cb6..ddb626bc39 100644 --- a/doc/guides/nics/octeontx.rst +++ b/doc/guides/nics/octeontx.rst @@ -22,6 +22,7 @@ Features of the OCTEON TX Ethdev PMD are: - Jumbo frames - Scatter-Gather IO support - Link state information +- MTU update - SR-IOV VF - Multiple queues for TX - Lock-free Tx queue diff --git a/drivers/net/octeontx/base/octeontx_bgx.c b/drivers/net/octeontx/base/octeontx_bgx.c index a2d615fb24..cc2bbd1043 100644 --- a/drivers/net/octeontx/base/octeontx_bgx.c +++ b/drivers/net/octeontx/base/octeontx_bgx.c @@ -226,6 +226,23 @@ octeontx_bgx_port_promisc_set(int port, int en) return res; } +int +octeontx_bgx_port_mtu_set(int port, int mtu) +{ + struct octeontx_mbox_hdr hdr; + int res; + + hdr.coproc = OCTEONTX_BGX_COPROC; + hdr.msg = MBOX_BGX_PORT_SET_MTU; + hdr.vfid = port; + + res = octeontx_mbox_send(&hdr, &mtu, sizeof(mtu), NULL, 0); + if (res < 0) + return -EACCES; + + return res; +} + int octeontx_bgx_port_mac_set(int port, uint8_t *mac_addr) { diff --git a/drivers/net/octeontx/base/octeontx_bgx.h b/drivers/net/octeontx/base/octeontx_bgx.h index 11c25db671..e385de42d7 100644 --- a/drivers/net/octeontx/base/octeontx_bgx.h +++ b/drivers/net/octeontx/base/octeontx_bgx.h @@ -131,6 +131,7 @@ int octeontx_bgx_port_mac_set(int port, uint8_t *mac_addr); int octeontx_bgx_port_mac_add(int port, uint8_t *mac_addr, int index); int octeontx_bgx_port_mac_del(int port, uint32_t index); int octeontx_bgx_port_mac_entries_get(int port); +int octeontx_bgx_port_mtu_set(int port, int mtu); #endif /* __OCTEONTX_BGX_H__ */ diff --git a/drivers/net/octeontx/base/octeontx_pkovf.c b/drivers/net/octeontx/base/octeontx_pkovf.c index dacbdd0b44..bf28bc7992 100644 --- a/drivers/net/octeontx/base/octeontx_pkovf.c +++ b/drivers/net/octeontx/base/octeontx_pkovf.c @@ -465,6 +465,27 @@ octeontx_pko_get_vfid(void) return SIZE_MAX; } +int +octeontx_pko_send_mtu(int port, int mtu) +{ + struct octeontx_mbox_hdr hdr; + int res; + mbox_pko_mtu_cfg_t cfg; + + cfg.mtu = mtu; + + hdr.coproc = OCTEONTX_PKO_COPROC; + hdr.msg = MBOX_PKO_MTU_CONFIG; + hdr.vfid = port; + + res = octeontx_mbox_send(&hdr, &cfg, sizeof(mbox_pko_mtu_cfg_t), + NULL, 0); + if (res < 0) + return -EACCES; + + return res; +} + int octeontx_pko_init_fc(const size_t pko_vf_count) { diff --git a/drivers/net/octeontx/base/octeontx_pkovf.h b/drivers/net/octeontx/base/octeontx_pkovf.h index 4e0bb7c2ed..7e1aba3e33 100644 --- a/drivers/net/octeontx/base/octeontx_pkovf.h +++ b/drivers/net/octeontx/base/octeontx_pkovf.h @@ -43,6 +43,13 @@ #define PKO_SEND_GATHER_LDTYPE(x) ((x) << 58) #define PKO_SEND_GATHER_GAUAR(x) ((x) << 24) +#define OCTEONTX_PKO_COPROC 4 +#define MBOX_PKO_MTU_CONFIG 1 + +typedef struct mbox_pko_mtu_cfg { + uint32_t mtu; +} mbox_pko_mtu_cfg_t; + typedef struct octeontx_dq_s { void *lmtline_va; void *ioreg_va; @@ -71,5 +78,6 @@ int octeontx_pko_vf_count(void); size_t octeontx_pko_get_vfid(void); int octeontx_pko_init_fc(const size_t pko_vf_count); void octeontx_pko_fc_free(void); +int octeontx_pko_send_mtu(int port, int mtu); #endif /* __OCTEONTX_PKO_H__ */ diff --git a/drivers/net/octeontx/octeontx_ethdev.c b/drivers/net/octeontx/octeontx_ethdev.c index 97b4298feb..91b9ea6454 100644 --- a/drivers/net/octeontx/octeontx_ethdev.c +++ b/drivers/net/octeontx/octeontx_ethdev.c @@ -139,7 +139,7 @@ octeontx_port_open(struct octeontx_nic *nic) nic->base_ochan = bgx_port_conf.base_chan; nic->num_ichans = bgx_port_conf.num_chans; nic->num_ochans = bgx_port_conf.num_chans; - nic->mtu = bgx_port_conf.mtu; + nic->bgx_mtu = bgx_port_conf.mtu; nic->bpen = bgx_port_conf.bpen; nic->fcs_strip = bgx_port_conf.fcs_strip; nic->bcast_mode = bgx_port_conf.bcast_mode; @@ -407,6 +407,55 @@ octeontx_dev_close(struct rte_eth_dev *dev) dev->rx_pkt_burst = NULL; } +static int +octeontx_dev_mtu_set(struct rte_eth_dev *eth_dev, uint16_t mtu) +{ + uint32_t buffsz, frame_size = mtu + OCCTX_L2_OVERHEAD; + struct octeontx_nic *nic = octeontx_pmd_priv(eth_dev); + struct rte_eth_dev_data *data = eth_dev->data; + int rc = 0; + + /* Check if MTU is within the allowed range */ + if (frame_size < OCCTX_MIN_FRS || frame_size > OCCTX_MAX_FRS) + return -EINVAL; + + buffsz = data->min_rx_buf_size - RTE_PKTMBUF_HEADROOM; + + /* Refuse MTU that requires the support of scattered packets + * when this feature has not been enabled before. + */ + if (data->dev_started && frame_size > buffsz && + !(nic->rx_offloads & DEV_RX_OFFLOAD_SCATTER)) { + octeontx_log_err("Scatter mode is disabled"); + return -EINVAL; + } + + /* Check * >= max_frame */ + if ((nic->rx_offloads & DEV_RX_OFFLOAD_SCATTER) && + (frame_size > buffsz * OCCTX_RX_NB_SEG_MAX)) + return -EINVAL; + + rc = octeontx_pko_send_mtu(nic->port_id, frame_size); + if (rc) + return rc; + + rc = octeontx_bgx_port_mtu_set(nic->port_id, frame_size); + if (rc) + return rc; + + if (frame_size > RTE_ETHER_MAX_LEN) + nic->rx_offloads |= DEV_RX_OFFLOAD_JUMBO_FRAME; + else + nic->rx_offloads &= ~DEV_RX_OFFLOAD_JUMBO_FRAME; + + /* Update max_rx_pkt_len */ + data->dev_conf.rxmode.max_rx_pkt_len = frame_size; + octeontx_log_info("Received pkt beyond maxlen %d will be dropped", + frame_size); + + return rc; +} + static int octeontx_recheck_rx_offloads(struct octeontx_rxq *rxq) { @@ -435,6 +484,9 @@ octeontx_recheck_rx_offloads(struct octeontx_rxq *rxq) evdev_priv->rx_offload_flags = nic->rx_offload_flags; evdev_priv->tx_offload_flags = nic->tx_offload_flags; + /* Setup MTU based on max_rx_pkt_len */ + nic->mtu = data->dev_conf.rxmode.max_rx_pkt_len - OCCTX_L2_OVERHEAD; + return 0; } @@ -445,6 +497,7 @@ octeontx_dev_start(struct rte_eth_dev *dev) struct octeontx_rxq *rxq; int ret = 0, i; + PMD_INIT_FUNC_TRACE(); /* Rechecking if any new offload set to update * rx/tx burst function pointer accordingly. */ @@ -453,7 +506,13 @@ octeontx_dev_start(struct rte_eth_dev *dev) octeontx_recheck_rx_offloads(rxq); } - PMD_INIT_FUNC_TRACE(); + /* Setting up the mtu based on max_rx_pkt_len */ + ret = octeontx_dev_mtu_set(dev, nic->mtu); + if (ret) { + octeontx_log_err("Failed to set default MTU size %d", ret); + goto error; + } + /* * Tx start */ @@ -713,6 +772,12 @@ octeontx_dev_info(struct rte_eth_dev *dev, ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G | ETH_LINK_SPEED_40G; + /* Min/Max MTU supported */ + dev_info->min_rx_bufsize = OCCTX_MIN_FRS; + dev_info->max_rx_pktlen = OCCTX_MAX_FRS; + dev_info->max_mtu = dev_info->max_rx_pktlen - OCCTX_L2_OVERHEAD; + dev_info->min_mtu = dev_info->min_rx_bufsize - OCCTX_L2_OVERHEAD; + dev_info->max_mac_addrs = octeontx_bgx_port_mac_entries_get(nic->port_id); dev_info->max_rx_pktlen = PKI_MAX_PKTLEN; @@ -1127,6 +1192,7 @@ static const struct eth_dev_ops octeontx_dev_ops = { .rx_queue_setup = octeontx_dev_rx_queue_setup, .rx_queue_release = octeontx_dev_rx_queue_release, .dev_supported_ptypes_get = octeontx_dev_supported_ptypes_get, + .mtu_set = octeontx_dev_mtu_set, .pool_ops_supported = octeontx_pool_ops, }; @@ -1256,7 +1322,7 @@ octeontx_create(struct rte_vdev_device *dev, int port, uint8_t evdev, nic->port_id, nic->port_ena, nic->base_ochan, nic->num_ochans, nic->num_tx_queues); - PMD_INIT_LOG(DEBUG, "speed %d mtu %d", nic->speed, nic->mtu); + PMD_INIT_LOG(DEBUG, "speed %d mtu %d", nic->speed, nic->bgx_mtu); rte_octeontx_pchan_map[(nic->base_ochan >> 8) & 0x7] [(nic->base_ochan >> 4) & 0xF] = data->port_id; diff --git a/drivers/net/octeontx/octeontx_ethdev.h b/drivers/net/octeontx/octeontx_ethdev.h index 1abe1703b9..27f6556dd9 100644 --- a/drivers/net/octeontx/octeontx_ethdev.h +++ b/drivers/net/octeontx/octeontx_ethdev.h @@ -29,6 +29,30 @@ #define OCTEONTX_MAX_BGX_PORTS 4 #define OCTEONTX_MAX_LMAC_PER_BGX 4 +#define OCCTX_RX_NB_SEG_MAX 6 + +/* VLAN tag inserted by OCCTX_TX_VTAG_ACTION. + * In Tx space is always reserved for this in FRS. + */ +#define OCCTX_MAX_VTAG_INS 2 +#define OCCTX_MAX_VTAG_ACT_SIZE (4 * OCCTX_MAX_VTAG_INS) + +/* HW config of frame size doesn't include FCS */ +#define OCCTX_MAX_HW_FRS 9212 +#define OCCTX_MIN_HW_FRS 60 + +/* ETH_HLEN+ETH_FCS+2*VLAN_HLEN */ +#define OCCTX_L2_OVERHEAD (RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN + \ + OCCTX_MAX_VTAG_ACT_SIZE) + +/* Since HW FRS includes NPC VTAG insertion space, user has reduced FRS */ +#define OCCTX_MAX_FRS \ + (OCCTX_MAX_HW_FRS + RTE_ETHER_CRC_LEN - OCCTX_MAX_VTAG_ACT_SIZE) + +#define OCCTX_MIN_FRS (OCCTX_MIN_HW_FRS + RTE_ETHER_CRC_LEN) + +#define OCCTX_MAX_MTU (OCCTX_MAX_FRS - OCCTX_L2_OVERHEAD) + #define OCTEONTX_RX_OFFLOADS (DEV_RX_OFFLOAD_CHECKSUM | \ DEV_RX_OFFLOAD_SCATTER | \ DEV_RX_OFFLOAD_JUMBO_FRAME) @@ -67,6 +91,7 @@ struct octeontx_nic { uint8_t link_up; uint8_t duplex; uint8_t speed; + uint16_t bgx_mtu; uint16_t mtu; uint8_t mac_addr[RTE_ETHER_ADDR_LEN]; /* Rx port parameters */ diff --git a/drivers/net/octeontx/octeontx_logs.h b/drivers/net/octeontx/octeontx_logs.h index ccb8a1b0ab..dec8042c67 100644 --- a/drivers/net/octeontx/octeontx_logs.h +++ b/drivers/net/octeontx/octeontx_logs.h @@ -19,6 +19,9 @@ rte_log(RTE_LOG_ ## level, otx_net_logtype_mbox, \ "%s(): " fmt "\n", __func__, ## args) +#define octeontx_log_info(fmt, args...) \ + RTE_LOG(INFO, PMD, fmt "\n", ## args) + #define octeontx_log_err(s, ...) PMD_INIT_LOG(ERR, s, ##__VA_ARGS__) #define octeontx_log_dbg(s, ...) PMD_DRV_LOG(DEBUG, s, ##__VA_ARGS__) #define octeontx_mbox_log(s, ...) PMD_MBOX_LOG(DEBUG, s, ##__VA_ARGS__)