summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ethtool-copy.h25
-rw-r--r--ethtool.815
-rw-r--r--ethtool.c55
3 files changed, 91 insertions, 4 deletions
diff --git a/ethtool-copy.h b/ethtool-copy.h
index d9bb957..dc1c089 100644
--- a/ethtool-copy.h
+++ b/ethtool-copy.h
@@ -30,12 +30,13 @@ struct ethtool_cmd {
__u32 maxtxpkt; /* Tx pkts before generating tx int */
__u32 maxrxpkt; /* Rx pkts before generating rx int */
__u16 speed_hi;
- __u16 reserved2;
+ __u8 eth_tp_mdix;
+ __u8 reserved2;
__u32 lp_advertising; /* Features the link partner advertises */
__u32 reserved[2];
};
-static __inline__ void ethtool_cmd_speed_set(struct ethtool_cmd *ep,
+static inline void ethtool_cmd_speed_set(struct ethtool_cmd *ep,
__u32 speed)
{
@@ -43,7 +44,7 @@ static __inline__ void ethtool_cmd_speed_set(struct ethtool_cmd *ep,
ep->speed_hi = (__u16)(speed >> 16);
}
-static __inline__ __u32 ethtool_cmd_speed(struct ethtool_cmd *ep)
+static inline __u32 ethtool_cmd_speed(struct ethtool_cmd *ep)
{
return (ep->speed_hi << 16) | ep->speed;
}
@@ -361,6 +362,18 @@ struct ethtool_rxnfc {
__u32 rule_locs[0];
};
+#define ETHTOOL_FLASH_MAX_FILENAME 128
+enum ethtool_flash_op_type {
+ ETHTOOL_FLASH_ALL_REGIONS = 0,
+};
+
+/* for passing firmware flashing related parameters */
+struct ethtool_flash {
+ __u32 cmd;
+ __u32 region;
+ char data[ETHTOOL_FLASH_MAX_FILENAME];
+};
+
/* CMDs currently supported */
#define ETHTOOL_GSET 0x00000001 /* Get settings. */
@@ -415,6 +428,7 @@ struct ethtool_rxnfc {
#define ETHTOOL_GRXCLSRLALL 0x00000030 /* Get all RX classification rule */
#define ETHTOOL_SRXCLSRLDEL 0x00000031 /* Delete RX classification rule */
#define ETHTOOL_SRXCLSRLINS 0x00000032 /* Insert RX classification rule */
+#define ETHTOOL_FLASHDEV 0x00000033 /* Flash firmware to device */
/* compatibility with older code */
#define SPARC_ETH_GSET ETHTOOL_GSET
@@ -504,6 +518,11 @@ struct ethtool_rxnfc {
#define AUTONEG_DISABLE 0x00
#define AUTONEG_ENABLE 0x01
+/* Mode MDI or MDI-X */
+#define ETH_TP_MDI_INVALID 0x00
+#define ETH_TP_MDI 0x01
+#define ETH_TP_MDI_X 0x02
+
/* Wake-On-Lan options. */
#define WAKE_PHY (1 << 0)
#define WAKE_UCAST (1 << 1)
diff --git a/ethtool.8 b/ethtool.8
index 7a6f52b..8921e45 100644
--- a/ethtool.8
+++ b/ethtool.8
@@ -207,6 +207,11 @@ ethtool \- Display or change ethernet card settings
.I ethX
.RB [ rx-flow-hash \ \*(FL
.RB \ \*(HO]
+
+.B ethtool \-f|\-\-flash
+.I ethX
+.RI FILE
+.RI [ N ]
.SH DESCRIPTION
.BI ethtool
is used for querying settings of an ethernet device and changing them.
@@ -498,6 +503,16 @@ Hash on bytes 2 and 3 of the Layer 4 header of the rx packet.
Discard all packets of this flow type. When this option is set, all other options are ignored.
.PD
.RE
+.TP
+.B \-f \-\-flash \ FILE
+Flash firmware image from the specified file to a region on the adapter.
+By default this will flash all the regions on the adapter.
+.TP
+.B N
+A number to identify flash region where the image should be flashed.
+Default region is 0 which denotes all regions in the flash.
+.PD
+.RE
.SH BUGS
Not supported (in part or whole) on all ethernet drivers.
.SH AUTHOR
diff --git a/ethtool.c b/ethtool.c
index a409e02..52915d6 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -77,6 +77,7 @@ static char *unparse_rxfhashopts(u64 opts);
static int dump_rxfhash(int fhash, u64 val);
static int do_srxclass(int fd, struct ifreq *ifr);
static int do_grxclass(int fd, struct ifreq *ifr);
+static int do_flash(int fd, struct ifreq *ifr);
static int send_ioctl(int fd, struct ifreq *ifr);
static enum {
@@ -101,6 +102,7 @@ static enum {
MODE_GSTATS,
MODE_GNFC,
MODE_SNFC,
+ MODE_FLASHDEV,
} mode = MODE_GSET;
static struct option {
@@ -188,6 +190,9 @@ static struct option {
"options",
" [ rx-flow-hash tcp4|udp4|ah4|sctp4|"
"tcp6|udp6|ah6|sctp6 ]\n" },
+ { "-f", "--flash", MODE_FLASHDEV, "FILENAME " "Flash firmware image "
+ "from the specified file to a region on the device",
+ " [ REGION-NUMBER-TO-FLASH ]\n" },
{ "-N", "--config-nfc", MODE_SNFC, "Configure Rx network flow "
"classification options",
" [ rx-flow-hash tcp4|udp4|ah4|sctp4|"
@@ -304,6 +309,9 @@ static int rx_fhash_get = 0;
static int rx_fhash_set = 0;
static u32 rx_fhash_val = 0;
static int rx_fhash_changed = 0;
+static char *flash_file = NULL;
+static int flash = -1;
+static int flash_region = -1;
static enum {
ONLINE=0,
OFFLINE,
@@ -496,7 +504,8 @@ static void parse_cmdline(int argc, char **argp)
(mode == MODE_GSTATS) ||
(mode == MODE_GNFC) ||
(mode == MODE_SNFC) ||
- (mode == MODE_PHYS_ID)) {
+ (mode == MODE_PHYS_ID) ||
+ (mode == MODE_FLASHDEV)) {
devname = argp[i];
break;
}
@@ -516,6 +525,10 @@ static void parse_cmdline(int argc, char **argp)
if (phys_id_time < 0)
show_usage(1);
break;
+ } else if (mode == MODE_FLASHDEV) {
+ flash_file = argp[i];
+ flash = 1;
+ break;
}
/* fallthrough */
default:
@@ -590,6 +603,12 @@ static void parse_cmdline(int argc, char **argp)
show_usage(1);
break;
}
+ if (mode == MODE_FLASHDEV) {
+ flash_region = strtol(argp[i], NULL, 0);
+ if ((flash_region < 0))
+ show_usage(1);
+ break;
+ }
if (mode == MODE_SNFC) {
if (!strcmp(argp[i], "rx-flow-hash")) {
i += 1;
@@ -1516,6 +1535,8 @@ static int doit(void)
return do_grxclass(fd, &ifr);
} else if (mode == MODE_SNFC) {
return do_srxclass(fd, &ifr);
+ } else if (mode == MODE_FLASHDEV) {
+ return do_flash(fd, &ifr);
}
return 69;
@@ -2410,6 +2431,38 @@ static int do_grxclass(int fd, struct ifreq *ifr)
return 0;
}
+static int do_flash(int fd, struct ifreq *ifr)
+{
+ struct ethtool_flash efl;
+ int err;
+
+ if (flash < 0) {
+ fprintf(stdout, "Missing filename argument\n");
+ show_usage(1);
+ return 98;
+ }
+
+ if (strlen(flash_file) > ETHTOOL_FLASH_MAX_FILENAME - 1) {
+ fprintf(stdout, "Filename too long\n");
+ return 99;
+ }
+
+ efl.cmd = ETHTOOL_FLASHDEV;
+ strcpy(efl.data, flash_file);
+
+ if (flash_region < 0)
+ efl.region = ETHTOOL_FLASH_ALL_REGIONS;
+ else
+ efl.region = flash_region;
+
+ ifr->ifr_data = (caddr_t)&efl;
+ err = send_ioctl(fd, ifr);
+ if (err < 0)
+ perror("Flashing failed");
+
+ return err;
+}
+
static int send_ioctl(int fd, struct ifreq *ifr)
{
return ioctl(fd, SIOCETHTOOL, ifr);