summaryrefslogtreecommitdiff
path: root/ethtool.c
diff options
context:
space:
mode:
Diffstat (limited to 'ethtool.c')
-rw-r--r--ethtool.c46
1 files changed, 40 insertions, 6 deletions
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;
}