Search code examples
dpdk

Is it possible to set a link speed for a port?


I would like to know if it's possible to start links with link speeds of my choosing. I believe I saw a topic not unlike this one on the website before, but I cannot find it anymore.

To my understanding, one would need to set the "link_speeds" field in the rte_eth_conf struct to some value that isn't RTE_ETH_LINK_SPEED_AUTONEG, but regardless of what I choose, checking the link in rte_eth_link_get always gives me 1000M and autoneg. Now, I also tried to look into the code from rte_eth_dev_configure to see how it does what it does, but it doesn't seem to take the link_speeds parameter into account. Keep in mind, I'm rather new to all this. Anyway, I have yet to attempt this outside of my VM, so perhaps it's due to the e1000 driver but if I had to guess it is something else entirely. Also, I did see on some website that interfaces had forced speeds and duplex (https://www.ibm.com/support/pages/forced-speedduplex-interface-settings-not-working-xgs-firmware-53), though the post dates a bit so I'm still hoping things are different now. Thanks in advance.


Solution

  • You're on the right track with setting link_speeds in rte_eth_conf before it's used in the call to rte_eth_dev_configure. Note that the documentation says you must set the RTE_ETH_LINK_SPEED_FIXED bit of link_speeds in addition to setting one link speed. Perhaps that's the step you're missing?

    The link_speeds field is used in the drivers/net/* files and not in rte_eth_dev_configure directly, because it is a hardware-specific request. For instance, if I look at drivers/net/e1000/igb_ethdev.c, I see usage of link_speeds in eth_igb_start

    To investigate speed capabilities of a device, you'd make a call to rte_eth_dev_info_get, e.g. rte_eth_dev_info_get(port_id, &dev_info) and look at dev_info.speed_capa.

    test-pmd prints them nicely:

    static void
    device_infos_display_speeds(uint32_t speed_capa)
    {
            printf("\n\tDevice speed capability:");
            if (speed_capa == RTE_ETH_LINK_SPEED_AUTONEG)
                    printf(" Autonegotiate (all speeds)");
            if (speed_capa & RTE_ETH_LINK_SPEED_FIXED)
                    printf(" Disable autonegotiate (fixed speed)  ");
            if (speed_capa & RTE_ETH_LINK_SPEED_10M_HD)
                    printf(" 10 Mbps half-duplex  ");
            if (speed_capa & RTE_ETH_LINK_SPEED_10M)
                    printf(" 10 Mbps full-duplex  ");
            if (speed_capa & RTE_ETH_LINK_SPEED_100M_HD)
                    printf(" 100 Mbps half-duplex  ");
            if (speed_capa & RTE_ETH_LINK_SPEED_100M)
                    printf(" 100 Mbps full-duplex  ");
            if (speed_capa & RTE_ETH_LINK_SPEED_1G)
                    printf(" 1 Gbps  ");
            if (speed_capa & RTE_ETH_LINK_SPEED_2_5G)
                    printf(" 2.5 Gbps  ");
            if (speed_capa & RTE_ETH_LINK_SPEED_5G)
                    printf(" 5 Gbps  ");
            if (speed_capa & RTE_ETH_LINK_SPEED_10G)
                    printf(" 10 Gbps  ");
            if (speed_capa & RTE_ETH_LINK_SPEED_20G)
                    printf(" 20 Gbps  ");
            if (speed_capa & RTE_ETH_LINK_SPEED_25G)
                    printf(" 25 Gbps  ");
            if (speed_capa & RTE_ETH_LINK_SPEED_40G)
                    printf(" 40 Gbps  ");
            if (speed_capa & RTE_ETH_LINK_SPEED_50G)
                    printf(" 50 Gbps  ");
            if (speed_capa & RTE_ETH_LINK_SPEED_56G)
                    printf(" 56 Gbps  ");
            if (speed_capa & RTE_ETH_LINK_SPEED_100G)
                    printf(" 100 Gbps  ");
            if (speed_capa & RTE_ETH_LINK_SPEED_200G)
                    printf(" 200 Gbps  ");
    }