diff options
author | Ben Hutchings <bhutchings@solarflare.com> | 2011-10-19 20:52:12 +0100 |
---|---|---|
committer | Ben Hutchings <bhutchings@solarflare.com> | 2011-10-28 22:21:26 +0100 |
commit | 6e50ac01eec1d38d4ad7863c02c597c9f161327f (patch) | |
tree | ea345b762ac717460a6286459c7c5e42b6023107 | |
parent | ca910802b2ae25080560190028c1a8cb97b985e9 (diff) | |
download | ethtool-6e50ac01eec1d38d4ad7863c02c597c9f161327f.tar.gz |
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 <bhutchings@solarflare.com>
-rw-r--r-- | ethtool.c | 46 |
1 files changed, 40 insertions, 6 deletions
@@ -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; } |