openbmc/build/tmp/deploy/sdk/witherspoon-2019-08-08/sysroots/armv6-openbmc-linux-gnueabi/usr/src/debug/systemd/1_242+AUTOINC+db2e367bfc-r0/git/src/udev/net/ethtool-util.c
int ethtool_set_glinksettings(int* fd, const char* ifname,
                              struct link_config* link)
{
    _cleanup_free_ struct ethtool_link_usettings* u = NULL;
    struct ifreq ifr = {};
    int r;

    if (link->autonegotiation != AUTONEG_DISABLE && eqzero(link->advertise))
    {
        log_info("link_config: autonegotiation is unset or enabled, the speed "
                 "and duplex are not writable.");
        return 0;
    }

    if (*fd < 0)
    {
        r = ethtool_connect(fd);
        if (r < 0)
            return log_warning_errno(
                r, "link_config: could not connect to ethtool: %m");
    }

    strscpy(ifr.ifr_name, IFNAMSIZ, ifname);

    r = get_glinksettings(*fd, &ifr, &u);
    if (r < 0)
    {
        r = get_gset(*fd, &ifr, &u);
        if (r < 0)
            return log_warning_errno(
                r, "link_config: Cannot get device settings for %s : %m",
                ifname);
    }

    if (link->speed)
        u->base.speed = DIV_ROUND_UP(link->speed, 1000000);

    if (link->duplex != _DUP_INVALID)
        u->base.duplex = link->duplex;

    if (link->port != _NET_DEV_PORT_INVALID)
        u->base.port = link->port;

    if (link->autonegotiation >= 0)
        u->base.autoneg = link->autonegotiation;

    if (!eqzero(link->advertise))
    {
        u->base.autoneg = AUTONEG_ENABLE;
        memcpy(&u->link_modes.advertising, link->advertise,
               sizeof(link->advertise));
        memzero((uint8_t*)&u->link_modes.advertising + sizeof(link->advertise),
                ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NBYTES -
                    sizeof(link->advertise));
    }

    if (u->base.cmd == ETHTOOL_GLINKSETTINGS)
        r = set_slinksettings(*fd, &ifr, u);
    else
        r = set_sset(*fd, &ifr, u);
    if (r < 0)
        return log_warning_errno(
            r, "link_config: Cannot set device settings for %s : %m", ifname);

    return r;
}
/* If autonegotiation is disabled, the speed and duplex represent the fixed link
 * mode and are writable if the driver supports multiple link modes. If it is
 * enabled then they are read-only. If the link is up they represent the
 * negotiated link mode; if the link is down, the speed is 0, %SPEED_UNKNOWN or
 * the highest enabled speed and @duplex is %DUPLEX_UNKNOWN or the best enabled
 * duplex mode.
 */
If autonegotiation is disabled, the speed and duplex represent the fixed link
mode and are writable if the driver supports multiple link modes. If it is
enabled then they are read-only. If the link is up they represent the
negotiated link mode; if the link is down, the speed is 0, %SPEED_UNKNOWN or
the highest enabled speed and @duplex is %DUPLEX_UNKNOWN or the best enabled
duplex mode.
If autonegotiation is disabled the speed and duplex represent the fixed link mode and are writable if the driver supports multiple link modes . If it is enabled then they are read - only . If the link is up they represent the negotiated link mode ; if the link is down the speed is 0 %SPEED_UNKNOWN or the highest enabled speed and @duplex is %DUPLEX_UNKNOWN or the best enabled duplex mode .
int ethtool_set_glinksettings(int* fd, const char* ifname,
                              struct link_config* link)
{
    _cleanup_free_ struct ethtool_link_usettings* u = NULL;
    struct ifreq ifr = {};
    int r;
    if (link->autonegotiation != AUTONEG_DISABLE && eqzero(link->advertise))
    {
        log_info("link_config: autonegotiation is unset or enabled, the speed "
                 "and duplex are not writable.");
        return 0;
    }
    if (*fd < 0)
    {
        r = ethtool_connect(fd);
        if (r < 0)
            return log_warning_errno(
                r, "link_config: could not connect to ethtool: %m");
    }
    strscpy(ifr.ifr_name, IFNAMSIZ, ifname);
    r = get_glinksettings(*fd, &ifr, &u);
    if (r < 0)
    {
        r = get_gset(*fd, &ifr, &u);
        if (r < 0)
            return log_warning_errno(
                r, "link_config: Cannot get device settings for %s : %m",
                ifname);
    }
    if (link->speed)
        u->base.speed = DIV_ROUND_UP(link->speed, 1000000);
    if (link->duplex != _DUP_INVALID)
        u->base.duplex = link->duplex;
    if (link->port != _NET_DEV_PORT_INVALID)
        u->base.port = link->port;
    if (link->autonegotiation >= 0)
        u->base.autoneg = link->autonegotiation;
    if (!eqzero(link->advertise))
    {
        u->base.autoneg = AUTONEG_ENABLE;
        memcpy(&u->link_modes.advertising, link->advertise,
               sizeof(link->advertise));
        memzero((uint8_t*)&u->link_modes.advertising + sizeof(link->advertise),
                ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NBYTES -
                    sizeof(link->advertise));
    }
    if (u->base.cmd == ETHTOOL_GLINKSETTINGS)
        r = set_slinksettings(*fd, &ifr, u);
    else
        r = set_sset(*fd, &ifr, u);
    if (r < 0)
        return log_warning_errno(
            r, "link_config: Cannot set device settings for %s : %m", ifname);
    return r;
}
int ethtool_set_glinksettings ( int * fd , const char * ifname , struct link_config * link ) { _cleanup_free_ struct ethtool_link_usettings * u = NULL ; struct ifreq ifr = { } ; int r ; if ( link -> autonegotiation != AUTONEG_DISABLE && eqzero ( link -> advertise ) ) { log_info ( " " " " ) ; return 0 ; } if ( * fd < 0 ) { r = ethtool_connect ( fd ) ; if ( r < 0 ) return log_warning_errno ( r , " " ) ; } strscpy ( ifr . ifr_name , IFNAMSIZ , ifname ) ; r = get_glinksettings ( * fd , & ifr , & u ) ; if ( r < 0 ) { r = get_gset ( * fd , & ifr , & u ) ; if ( r < 0 ) return log_warning_errno ( r , " " , ifname ) ; } if ( link -> speed ) u -> base . speed = DIV_ROUND_UP ( link -> speed , 1000000 ) ; if ( link -> duplex != _DUP_INVALID ) u -> base . duplex = link -> duplex ; if ( link -> port != _NET_DEV_PORT_INVALID ) u -> base . port = link -> port ; if ( link -> autonegotiation >= 0 ) u -> base . autoneg = link -> autonegotiation ; if ( ! eqzero ( link -> advertise ) ) { u -> base . autoneg = AUTONEG_ENABLE ; memcpy ( & u -> link_modes . advertising , link -> advertise , sizeof ( link -> advertise ) ) ; memzero ( ( uint8_t * ) & u -> link_modes . advertising + sizeof ( link -> advertise ) , ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NBYTES - sizeof ( link -> advertise ) ) ; } if ( u -> base . cmd == ETHTOOL_GLINKSETTINGS ) r = set_slinksettings ( * fd , & ifr , u ) ; else r = set_sset ( * fd , & ifr , u ) ; if ( r < 0 ) return log_warning_errno ( r , " " , ifname ) ; return r ; }
If autonegotiation is disabled, the speed and duplex represent the fixed link
 mode and are writable if the driver supports multiple link modes.
If autonegotiation is disabled the speed and duplex represent the fixed link mode and are writable if the driver supports multiple link modes .