* DPDK callback to change the MTU. * * Setting the MTU affects hardware MRU (packets larger than the MRU * will be dropped). * * @param dev * Pointer to Ethernet device structure. * @param mtu * New MTU. * * @return * 0 on success, negative error value otherwise. */
| 226 | * 0 on success, negative error value otherwise. |
| 227 | */ |
| 228 | static int |
| 229 | mvneta_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) |
| 230 | { |
| 231 | struct mvneta_priv *priv = dev->data->dev_private; |
| 232 | uint16_t mbuf_data_size = 0; /* SW buffer size */ |
| 233 | uint16_t mru; |
| 234 | int ret; |
| 235 | |
| 236 | mru = MRVL_NETA_MTU_TO_MRU(mtu); |
| 237 | /* |
| 238 | * min_rx_buf_size is equal to mbuf data size |
| 239 | * if pmd didn't set it differently |
| 240 | */ |
| 241 | mbuf_data_size = dev->data->min_rx_buf_size - RTE_PKTMBUF_HEADROOM; |
| 242 | /* Prevent PMD from: |
| 243 | * - setting mru greater than the mbuf size resulting in |
| 244 | * hw and sw buffer size mismatch |
| 245 | * - setting mtu that requires the support of scattered packets |
| 246 | * when this feature has not been enabled/supported so far. |
| 247 | */ |
| 248 | if (!dev->data->scattered_rx && |
| 249 | (mru + MRVL_NETA_PKT_OFFS > mbuf_data_size)) { |
| 250 | mru = mbuf_data_size - MRVL_NETA_PKT_OFFS; |
| 251 | mtu = MRVL_NETA_MRU_TO_MTU(mru); |
| 252 | MVNETA_LOG(WARNING, "MTU too big, max MTU possible limited by" |
| 253 | " current mbuf size: %u. Set MTU to %u, MRU to %u", |
| 254 | mbuf_data_size, mtu, mru); |
| 255 | } |
| 256 | |
| 257 | if (mtu < RTE_ETHER_MIN_MTU || mru > MVNETA_PKT_SIZE_MAX) { |
| 258 | MVNETA_LOG(ERR, "Invalid MTU [%u] or MRU [%u]", mtu, mru); |
| 259 | return -EINVAL; |
| 260 | } |
| 261 | |
| 262 | if (!priv->ppio) |
| 263 | /* It is OK. New MTU will be set later on mvneta_dev_start */ |
| 264 | return 0; |
| 265 | |
| 266 | ret = neta_ppio_set_mru(priv->ppio, mru); |
| 267 | if (ret) { |
| 268 | MVNETA_LOG(ERR, "Failed to change MRU"); |
| 269 | return ret; |
| 270 | } |
| 271 | |
| 272 | ret = neta_ppio_set_mtu(priv->ppio, mtu); |
| 273 | if (ret) { |
| 274 | MVNETA_LOG(ERR, "Failed to change MTU"); |
| 275 | return ret; |
| 276 | } |
| 277 | MVNETA_LOG(INFO, "MTU changed to %u, MRU = %u", mtu, mru); |
| 278 | |
| 279 | return 0; |
| 280 | } |
| 281 | |
| 282 | /** |
| 283 | * DPDK callback to bring the link up. |