* DPDK callback to retrieve physical link information. * * @param dev * Pointer to Ethernet device structure. * @param wait_to_complete * Wait for request completion (ignored). * * @return * 0 on success, negative errno value otherwise and rte_errno is set. */
| 791 | * 0 on success, negative errno value otherwise and rte_errno is set. |
| 792 | */ |
| 793 | int |
| 794 | mlx4_link_update(struct rte_eth_dev *dev, int wait_to_complete) |
| 795 | { |
| 796 | const struct mlx4_priv *priv = dev->data->dev_private; |
| 797 | struct ethtool_cmd edata = { |
| 798 | .cmd = ETHTOOL_GSET, |
| 799 | }; |
| 800 | struct ifreq ifr; |
| 801 | struct rte_eth_link dev_link; |
| 802 | int link_speed = 0; |
| 803 | |
| 804 | if (priv == NULL) { |
| 805 | rte_errno = EINVAL; |
| 806 | return -rte_errno; |
| 807 | } |
| 808 | (void)wait_to_complete; |
| 809 | if (mlx4_ifreq(priv, SIOCGIFFLAGS, &ifr)) { |
| 810 | WARN("ioctl(SIOCGIFFLAGS) failed: %s", strerror(rte_errno)); |
| 811 | return -rte_errno; |
| 812 | } |
| 813 | memset(&dev_link, 0, sizeof(dev_link)); |
| 814 | dev_link.link_status = ((ifr.ifr_flags & IFF_UP) && |
| 815 | (ifr.ifr_flags & IFF_RUNNING)); |
| 816 | ifr.ifr_data = (void *)&edata; |
| 817 | if (mlx4_ifreq(priv, SIOCETHTOOL, &ifr)) { |
| 818 | WARN("ioctl(SIOCETHTOOL, ETHTOOL_GSET) failed: %s", |
| 819 | strerror(rte_errno)); |
| 820 | return -rte_errno; |
| 821 | } |
| 822 | link_speed = ethtool_cmd_speed(&edata); |
| 823 | if (link_speed == -1) |
| 824 | dev_link.link_speed = RTE_ETH_SPEED_NUM_NONE; |
| 825 | else |
| 826 | dev_link.link_speed = link_speed; |
| 827 | dev_link.link_duplex = ((edata.duplex == DUPLEX_HALF) ? |
| 828 | RTE_ETH_LINK_HALF_DUPLEX : RTE_ETH_LINK_FULL_DUPLEX); |
| 829 | dev_link.link_autoneg = !(dev->data->dev_conf.link_speeds & |
| 830 | RTE_ETH_LINK_SPEED_FIXED); |
| 831 | dev->data->dev_link = dev_link; |
| 832 | return 0; |
| 833 | } |
| 834 | |
| 835 | /** |
| 836 | * DPDK callback to get flow control status. |
no test coverage detected