From 6e50ac01eec1d38d4ad7863c02c597c9f161327f Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 19 Oct 2011 20:52:12 +0100 Subject: Report pause frame autonegotiation result If pause frame autonegotiation is enabled and the driver reports the link partner's advertising flags, report the result of autonegotiation. Signed-off-by: Ben Hutchings --- ethtool.c | 46 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 40 insertions(+), 6 deletions(-) (limited to 'ethtool.c') diff --git a/ethtool.c b/ethtool.c index a4e8b58..ad2d583 100644 --- a/ethtool.c +++ b/ethtool.c @@ -1745,7 +1745,7 @@ static int dump_test(struct ethtool_drvinfo *info, struct ethtool_test *test, return rc; } -static int dump_pause(void) +static int dump_pause(u32 advertising, u32 lp_advertising) { fprintf(stdout, "Autonegotiate: %s\n" @@ -1755,6 +1755,30 @@ static int dump_pause(void) epause.rx_pause ? "on" : "off", epause.tx_pause ? "on" : "off"); + if (lp_advertising) { + int an_rx = 0, an_tx = 0; + + /* Work out negotiated pause frame usage per + * IEEE 802.3-2005 table 28B-3. + */ + if (advertising & lp_advertising & ADVERTISED_Pause) { + an_tx = 1; + an_rx = 1; + } else if (advertising & lp_advertising & + ADVERTISED_Asym_Pause) { + if (advertising & ADVERTISED_Pause) + an_rx = 1; + else if (lp_advertising & ADVERTISED_Pause) + an_tx = 1; + } + + fprintf(stdout, + "RX negotiated: %s\n" + "TX negotiated: %s\n", + an_rx ? "on" : "off", + an_tx ? "on" : "off"); + } + fprintf(stdout, "\n"); return 0; } @@ -2051,6 +2075,7 @@ static int do_gdrv(int fd, struct ifreq *ifr) static int do_gpause(int fd, struct ifreq *ifr) { + struct ethtool_cmd ecmd; int err; fprintf(stdout, "Pause parameters for %s:\n", devname); @@ -2058,15 +2083,24 @@ static int do_gpause(int fd, struct ifreq *ifr) epause.cmd = ETHTOOL_GPAUSEPARAM; ifr->ifr_data = (caddr_t)&epause; err = send_ioctl(fd, ifr); - if (err == 0) { - err = dump_pause(); - if (err) - return err; - } else { + if (err) { perror("Cannot get device pause settings"); return 76; } + if (epause.autoneg) { + ecmd.cmd = ETHTOOL_GSET; + ifr->ifr_data = (caddr_t)&ecmd; + err = send_ioctl(fd, ifr); + if (err) { + perror("Cannot get device settings"); + return 1; + } + dump_pause(ecmd.advertising, ecmd.lp_advertising); + } else { + dump_pause(0, 0); + } + return 0; } -- cgit v1.2.1