static int mthca_update_rate(struct mthca_dev *dev, u8 port_num) { struct ib_port_attr *tprops = NULL; int ret; tprops = kmalloc(sizeof *tprops, GFP_KERNEL); if (!tprops) return -ENOMEM; ret = ib_query_port(&dev->ib_dev, port_num, tprops); if (ret) { printk(KERN_WARNING "ib_query_port failed (%d) for %s port %d\n", ret, dev->ib_dev.name, port_num); goto out; } dev->rate[port_num - 1] = tprops->active_speed * ib_width_enum_to_int(tprops->active_width); out: kfree(tprops); return ret; }
static int ipoib_get_link_ksettings(struct net_device *netdev, struct ethtool_link_ksettings *cmd) { struct ipoib_dev_priv *priv = ipoib_priv(netdev); struct ib_port_attr attr; int ret, speed, width; if (!netif_carrier_ok(netdev)) { cmd->base.speed = SPEED_UNKNOWN; cmd->base.duplex = DUPLEX_UNKNOWN; return 0; } ret = ib_query_port(priv->ca, priv->port, &attr); if (ret < 0) return -EINVAL; speed = ib_speed_enum_to_int(attr.active_speed); width = ib_width_enum_to_int(attr.active_width); if (speed < 0 || width < 0) return -EINVAL; /* Except the following are set, the other members of * the struct ethtool_link_settings are initialized to * zero in the function __ethtool_get_link_ksettings. */ cmd->base.speed = speed * width; cmd->base.duplex = DUPLEX_FULL; cmd->base.phy_address = 0xFF; cmd->base.autoneg = AUTONEG_ENABLE; cmd->base.port = PORT_OTHER; return 0; }