Add LRO control to ethtool
Subsystems (2)
PATCH 1/1 Add LRO control to ethtool
The kernel-side ethtool code supports ETHTOOL_{G,S}FLAGS commands which can control various features; currently the only feature is LRO. I didn't see any code to use these in the ethtool git repository
<git://git.kernel.org/pub/scm/network/ethtool/ethtool.git>. So here's a patch that adds that. I tested this with the latest version of the sfc driver, which we should be re-posting later today.
Signed-off-by Ben Hutchings <[email protected]>
ethtool.c +34 -6
@@ -151,7 +151,8 @@ static struct option {" [ sg on|off ]\n" " [ tso on|off ]\n" " [ ufo on|off ]\n" - " [ gso on|off ]\n" }, +" [ gso on|off ]\n" + " [ lro on|off ]\n" }, { "-i", "--driver", MODE_GDRV, "Show driver information" }, { "-d", "--register-dump", MODE_GREGS, "Do a register dump"," [ raw on|off ]\n"
@@ -200,6 +201,7 @@ static int off_sg_wanted = -1;static int off_tso_wanted =-1 ;static int off_ufo_wanted =-1 ;static int off_gso_wanted =-1 ; +static int off_lro_wanted =-1 ;static struct ethtool_pauseparam epause;static int gpause_changed =0 ;
@@ -310,6 +312,7 @@ static struct cmdline_info cmdline_offload[] = { { "tso", CMDL_BOOL, &off_tso_wanted, NULL }, { "ufo", CMDL_BOOL, &off_ufo_wanted, NULL }, { "gso", CMDL_BOOL, &off_gso_wanted, NULL }, + { "lro", CMDL_BOOL, &off_lro_wanted, NULL }, }; static struct cmdline_info cmdline_pause[] = {
@@ -1217,7 +1220,8 @@ static int dump_coalesce(void)return 0 ; } -static int dump_offload (int rx,int tx,int sg,int tso,int ufo,int gso) +static int dump_offload (int rx,int tx,int sg,int tso,int ufo,int gso, +int lro) {fprintf (stdout, "rx-checksumming: %s\n"
@@ -1225,13 +1229,15 @@ static int dump_offload (int rx, int tx, int sg, int tso, int ufo, int gso)"scatter-gather: %s\n" "tcp segmentation offload: %s\n" "udp fragmentation offload: %s\n" -"generic segmentation offload: %s\n" , +"generic segmentation offload: %s\n" +"large receive offload: %s\n" , rx ?"on" :"off" , tx ?"on" :"off" , sg ?"on" :"off" , tso ?"on" :"off" , ufo ?"on" :"off" , - gso ? "on" : "off"); + gso ?"on" :"off" , + lro ? "on" : "off");return 0 ; }
@@ -1495,7 +1501,8 @@ static int do_scoalesce(int fd, struct ifreq *ifr)static int do_goffload (int fd,struct ifreq *ifr) {struct ethtool_value eval; -int err, allfail =1 , rx =0 , tx =0 , sg =0 , tso =0 , ufo =0 , gso =0 ; +int err, allfail =1 ; +int rx =0 , tx =0 , sg =0 , tso =0 , ufo =0 , gso =0 , lro =0 ;fprintf (stdout,"Offload parameters for %s:\n" , devname);
@@ -1559,12 +1566,22 @@ static int do_goffload(int fd, struct ifreq *ifr) allfail =0 ; } + eval.cmd =ETHTOOL_GFLAGS ; + ifr->ifr_data = (caddr_t)&eval; + err =ioctl (fd,SIOCETHTOOL , ifr); +if (err) +perror ("Cannot get device large receive offload settings" ); +else { + lro = (eval.data Ð_FLAG_LRO ) !=0 ; + allfail =0 ; + } +if (allfail) {fprintf (stdout,"no offload info available\n" );return 83 ; } -return dump_offload (rx, tx, sg, tso, ufo, gso); +return dump_offload (rx, tx, sg, tso, ufo, gso, lro); }static int do_soffload (int fd,struct ifreq *ifr)
@@ -1641,6 +1658,17 @@ static int do_soffload(int fd, struct ifreq *ifr)return 90 ; } } +if (off_lro_wanted >=0 ) { + changed =1 ; + eval.cmd =ETHTOOL_SFLAGS ; + eval.data = (off_lro_wanted ==1 ) ?ETH_FLAG_LRO :0 ; + ifr->ifr_data = (caddr_t)&eval; + err =ioctl (fd,SIOCETHTOOL , ifr); +if (err) { +perror ("Cannot set device large receive offload settings" ); +return 91 ; + } + }if (!changed) {fprintf (stdout,"no offload settings changed\n" ); }
Signature · 2 lines
Ben Hutchings, Senior Software Engineer, Solarflare Communications Not speaking for my employer; that's the marketing department's job.