Re: [PATCH net] ethtool: do not print warning for applications using legacy API

2017-12-30 Thread David Decotigny
Signed-off-by: David Decotigny <de...@googlers.com>


On Fri, Dec 29, 2017 at 10:02 AM, Stephen Hemminger
<step...@networkplumber.org> wrote:
> From: Stephen Hemminger <step...@networkplumber.org>
>
> In kernel log ths message appears on every boot:
>  "warning: `NetworkChangeNo' uses legacy ethtool link settings API,
>   link modes are only partially reported"
>
> When ethtool link settings API changed, it started complaining about
> usages of old API. Ironically, the original patch was from google but
> the application using the legacy API is chrome.
>
> Linux ABI is fixed as much as possible. The kernel must not break it
> and should not complain about applications using legacy API's.
> This patch just removes the warning since using legacy API's
> in Linux is perfectly acceptable.
>
> Fixes: 3f1ac7a700d0 ("net: ethtool: add new ETHTOOL_xLINKSETTINGS API")
> Signed-off-by: Stephen Hemminger <step...@networkplumber.org>
> ---
>  net/core/ethtool.c | 15 ++-
>  1 file changed, 2 insertions(+), 13 deletions(-)
>
> diff --git a/net/core/ethtool.c b/net/core/ethtool.c
> index f8fcf450a36e..8225416911ae 100644
> --- a/net/core/ethtool.c
> +++ b/net/core/ethtool.c
> @@ -770,15 +770,6 @@ static int ethtool_set_link_ksettings(struct net_device 
> *dev,
> return dev->ethtool_ops->set_link_ksettings(dev, _ksettings);
>  }
>
> -static void
> -warn_incomplete_ethtool_legacy_settings_conversion(const char *details)
> -{
> -   char name[sizeof(current->comm)];
> -
> -   pr_info_once("warning: `%s' uses legacy ethtool link settings API, 
> %s\n",
> -get_task_comm(name, current), details);
> -}
> -
>  /* Query device for its ethtool_cmd settings.
>   *
>   * Backward compatibility note: for compatibility with legacy ethtool,
> @@ -805,10 +796,8 @@ static int ethtool_get_settings(struct net_device *dev, 
> void __user *useraddr)
>_ksettings);
> if (err < 0)
> return err;
> -   if (!convert_link_ksettings_to_legacy_settings(,
> -  
> _ksettings))
> -   warn_incomplete_ethtool_legacy_settings_conversion(
> -   "link modes are only partially reported");
> +   convert_link_ksettings_to_legacy_settings(,
> + _ksettings);
>
> /* send a sensible cmd tag back to user */
> cmd.cmd = ETHTOOL_GSET;
> --
> 2.11.0
>


[PATCH iproute2 v1 1/2] iproute2: avoid exit in case of error.

2016-11-11 Thread David Decotigny
Be consistent with how non-0 print_route() return values are handled
elesewhere: return -1.


---
 ip/iproute.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/ip/iproute.c b/ip/iproute.c
index 98bfad6..dae793b 100644
--- a/ip/iproute.c
+++ b/ip/iproute.c
@@ -1743,7 +1743,7 @@ static int iproute_get(int argc, char **argv)
 
if (print_route(NULL, , (void *)stdout) < 0) {
fprintf(stderr, "An error :-)\n");
-   exit(1);
+   return -1;
}
 
if (req.n.nlmsg_type != RTM_NEWROUTE) {
-- 
2.8.0.rc3.226.g39d4020



[PATCH iproute2 v1 2/2] iproute2: a non-expected rtnl message is an error

2016-11-11 Thread David Decotigny

---
 ip/iproute.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/ip/iproute.c b/ip/iproute.c
index dae793b..10d0afe 100644
--- a/ip/iproute.c
+++ b/ip/iproute.c
@@ -320,7 +320,7 @@ int print_route(const struct sockaddr_nl *who, struct 
nlmsghdr *n, void *arg)
if (n->nlmsg_type != RTM_NEWROUTE && n->nlmsg_type != RTM_DELROUTE) {
fprintf(stderr, "Not a route: %08x %08x %08x\n",
n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags);
-   return 0;
+   return -1;
}
if (filter.flushb && n->nlmsg_type != RTM_NEWROUTE)
return 0;
-- 
2.8.0.rc3.226.g39d4020



[PATCH v1] mlx4: remove unused fields

2016-09-28 Thread David Decotigny
From: David Decotigny <de...@googlers.com>

This also can address following UBSAN warnings:
[   36.640343] 

[   36.648772] UBSAN: Undefined behaviour in 
drivers/net/ethernet/mellanox/mlx4/fw.c:857:26
[   36.656853] shift exponent 64 is too large for 32-bit type 'int'
[   36.663348] 

[   36.671783] 

[   36.680213] UBSAN: Undefined behaviour in 
drivers/net/ethernet/mellanox/mlx4/fw.c:861:27
[   36.688297] shift exponent 35 is too large for 32-bit type 'int'
[   36.694702] 


Tested:
  reboot with UBSAN, no warning.

Signed-off-by: David Decotigny <de...@googlers.com>
---
 drivers/net/ethernet/mellanox/mlx4/fw.c | 4 
 drivers/net/ethernet/mellanox/mlx4/fw.h | 2 --
 2 files changed, 6 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c 
b/drivers/net/ethernet/mellanox/mlx4/fw.c
index 090bf81..f9cbc67 100644
--- a/drivers/net/ethernet/mellanox/mlx4/fw.c
+++ b/drivers/net/ethernet/mellanox/mlx4/fw.c
@@ -853,12 +853,8 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct 
mlx4_dev_cap *dev_cap)
dev_cap->max_eqs = 1 << (field & 0xf);
MLX4_GET(field, outbox, QUERY_DEV_CAP_RSVD_MTT_OFFSET);
dev_cap->reserved_mtts = 1 << (field >> 4);
-   MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_MRW_SZ_OFFSET);
-   dev_cap->max_mrw_sz = 1 << field;
MLX4_GET(field, outbox, QUERY_DEV_CAP_RSVD_MRW_OFFSET);
dev_cap->reserved_mrws = 1 << (field & 0xf);
-   MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_MTT_SEG_OFFSET);
-   dev_cap->max_mtt_seg = 1 << (field & 0x3f);
MLX4_GET(size, outbox, QUERY_DEV_CAP_NUM_SYS_EQ_OFFSET);
dev_cap->num_sys_eqs = size & 0xfff;
MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_REQ_QP_OFFSET);
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.h 
b/drivers/net/ethernet/mellanox/mlx4/fw.h
index f11614f..5343a05 100644
--- a/drivers/net/ethernet/mellanox/mlx4/fw.h
+++ b/drivers/net/ethernet/mellanox/mlx4/fw.h
@@ -80,9 +80,7 @@ struct mlx4_dev_cap {
int max_eqs;
int num_sys_eqs;
int reserved_mtts;
-   int max_mrw_sz;
int reserved_mrws;
-   int max_mtt_seg;
int max_requester_per_qp;
int max_responder_per_qp;
int max_rdma_global;
-- 
2.8.0.rc3.226.g39d4020



Re: [ethtool PATCH v4 4/4] ethtool: Enhancing link mode bits to support 25G/50G/100G

2016-08-23 Thread David Decotigny
On Tue, Aug 23, 2016 at 6:30 AM, Vidya Sagar Ravipati
<vi...@cumulusnetworks.com> wrote:
> From: Vidya Sagar Ravipati <vi...@cumulusnetworks.com>
>
> Enhancing link mode bits to support 25G/50G/100G
> for supported and advertised speed mode bits
>
> Signed-off-by: Vidya Sagar Ravipati <vi...@cumulusnetworks.com>
> Acked-By: David Decotigny <de...@googlers.com>
> ---
>  ethtool.c | 30 ++
>  1 file changed, 30 insertions(+)
>
> diff --git a/ethtool.c b/ethtool.c
> index 1d6564e..ab58c7f 100644
> --- a/ethtool.c
> +++ b/ethtool.c
> @@ -512,6 +512,16 @@ static void init_global_link_mode_masks(void)
> ETHTOOL_LINK_MODE_56000baseCR4_Full_BIT,
> ETHTOOL_LINK_MODE_56000baseSR4_Full_BIT,
> ETHTOOL_LINK_MODE_56000baseLR4_Full_BIT,
> +   ETHTOOL_LINK_MODE_25000baseCR_Full_BIT,
> +   ETHTOOL_LINK_MODE_25000baseKR_Full_BIT,
> +   ETHTOOL_LINK_MODE_25000baseSR_Full_BIT,
> +   ETHTOOL_LINK_MODE_5baseCR2_Full_BIT,
> +   ETHTOOL_LINK_MODE_5baseKR2_Full_BIT,
> +   ETHTOOL_LINK_MODE_10baseKR4_Full_BIT,
> +   ETHTOOL_LINK_MODE_10baseSR4_Full_BIT,
> +   ETHTOOL_LINK_MODE_10baseCR4_Full_BIT,
> +   ETHTOOL_LINK_MODE_10baseLR4_ER4_Full_BIT,
> +   ETHTOOL_LINK_MODE_5baseSR2_Full_BIT,
> };
> static const enum ethtool_link_mode_bit_indices
> additional_advertised_flags_bits[] = {
> @@ -632,6 +642,26 @@ static void dump_link_caps(const char *prefix, const 
> char *an_prefix,
>   "56000baseSR4/Full" },
> { 0, ETHTOOL_LINK_MODE_56000baseLR4_Full_BIT,
>   "56000baseLR4/Full" },
> +   { 0, ETHTOOL_LINK_MODE_25000baseCR_Full_BIT,
> + "25000baseCR/Full" },
> +   { 0, ETHTOOL_LINK_MODE_25000baseKR_Full_BIT,
> + "25000baseKR/Full" },
> +   { 0, ETHTOOL_LINK_MODE_25000baseSR_Full_BIT,
> + "25000baseSR/Full" },
> +   { 0, ETHTOOL_LINK_MODE_5baseCR2_Full_BIT,
> + "5baseCR2/Full" },
> +   { 0, ETHTOOL_LINK_MODE_5baseKR2_Full_BIT,
> + "5baseKR2/Full" },
> +   { 0, ETHTOOL_LINK_MODE_10baseKR4_Full_BIT,
> + "10baseKR4/Full" },
> +   { 0, ETHTOOL_LINK_MODE_10baseSR4_Full_BIT,
> + "10baseSR4/Full" },
> +   { 0, ETHTOOL_LINK_MODE_10baseCR4_Full_BIT,
> + "10baseCR4/Full" },
> +   { 0, ETHTOOL_LINK_MODE_10baseLR4_ER4_Full_BIT,
> + "10baseLR4_ER4/Full" },
> +   { 0, ETHTOOL_LINK_MODE_5baseSR2_Full_BIT,
> + "5baseSR2/Full" },
> };
> int indent;
> int did1, new_line_pend, i;
> --
> 2.1.4
>

Acked-By: David Decotigny <de...@googlers.com>


Re: [ethtool PATCH v2 4/4] ethtool: Enhancing link mode bits to support 25G/50G/100G

2016-06-27 Thread David Decotigny
On Sun, Jun 26, 2016 at 12:45 PM, Vidya Sagar Ravipati
<vi...@cumulusnetworks.com> wrote:
> From: Vidya Sagar Ravipati <vi...@cumulusnetworks.com>
>
> Enhancing link mode bits to support 25G/50G/100G
> for supported and advertised speed mode bits
>
> Signed-off-by: Vidya Sagar Ravipati <vi...@cumulusnetworks.com>
> ---
>  ethtool.c | 27 +++
>  1 file changed, 27 insertions(+)
>
> diff --git a/ethtool.c b/ethtool.c
> index 1d6564e..5c3c765 100644
> --- a/ethtool.c
> +++ b/ethtool.c
> @@ -512,6 +512,15 @@ static void init_global_link_mode_masks(void)
> ETHTOOL_LINK_MODE_56000baseCR4_Full_BIT,
> ETHTOOL_LINK_MODE_56000baseSR4_Full_BIT,
> ETHTOOL_LINK_MODE_56000baseLR4_Full_BIT,
> +   ETHTOOL_LINK_MODE_25000baseCR_Full_BIT,
> +   ETHTOOL_LINK_MODE_25000baseKR_Full_BIT,
> +   ETHTOOL_LINK_MODE_25000baseSR_Full_BIT,
> +   ETHTOOL_LINK_MODE_5baseCR2_Full_BIT,
> +   ETHTOOL_LINK_MODE_5baseKR2_Full_BIT,
> +   ETHTOOL_LINK_MODE_10baseKR4_Full_BIT,
> +   ETHTOOL_LINK_MODE_10baseSR4_Full_BIT,
> +   ETHTOOL_LINK_MODE_10baseCR4_Full_BIT,
> +   ETHTOOL_LINK_MODE_10baseLR4_ER4_Full_BIT,
> };
> static const enum ethtool_link_mode_bit_indices
> additional_advertised_flags_bits[] = {
> @@ -632,6 +641,24 @@ static void dump_link_caps(const char *prefix, const 
> char *an_prefix,
>   "56000baseSR4/Full" },
> { 0, ETHTOOL_LINK_MODE_56000baseLR4_Full_BIT,
>   "56000baseLR4/Full" },
> +   { 0, ETHTOOL_LINK_MODE_25000baseCR_Full_BIT,
> + "25000baseCR/Full" },
> +   { 0, ETHTOOL_LINK_MODE_25000baseKR_Full_BIT,
> + "25000baseKR/Full" },
> +   { 0, ETHTOOL_LINK_MODE_25000baseSR_Full_BIT,
> + "25000baseSR/Full" },
> +   { 0, ETHTOOL_LINK_MODE_5baseCR2_Full_BIT,
> + "5baseCR2/Full" },
> +   { 0, ETHTOOL_LINK_MODE_5baseKR2_Full_BIT,
> + "5baseKR2/Full" },
> +   { 0, ETHTOOL_LINK_MODE_10baseKR4_Full_BIT,
> + "10baseKR4/Full" },
> +   { 0, ETHTOOL_LINK_MODE_10baseSR4_Full_BIT,
> + "10baseSR4/Full" },
> +   { 0, ETHTOOL_LINK_MODE_10baseCR4_Full_BIT,
> +     "10baseCR4/Full" },
> +   { 0, ETHTOOL_LINK_MODE_10baseLR4_ER4_Full_BIT,
> + "10baseLR4_ER4/Full" },
> };
> int indent;
> int did1, new_line_pend, i;
> --
> 2.1.4
>

Acked-By: David Decotigny <de...@googlers.com>


Re: [PATCH net-next V2 07/10] ethtool: Add 50G baseSR2 link mode

2016-06-23 Thread David Decotigny
On Thu, Jun 23, 2016 at 7:02 AM, Saeed Mahameed <sae...@mellanox.com> wrote:
> From: Gal Pressman <g...@mellanox.com>
>
> Add ETHTOOL_LINK_MODE_5baseSR2_Full_BIT bit.
>
> Signed-off-by: Gal Pressman <g...@mellanox.com>
> Signed-off-by: Saeed Mahameed <sae...@mellanox.com>
> Cc: Ben Hutchings <b...@kernel.org>
> Cc: David Decotigny <de...@googlers.com>
> ---
>  include/uapi/linux/ethtool.h | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/include/uapi/linux/ethtool.h b/include/uapi/linux/ethtool.h
> index 5f030b4..b8f38e8 100644
> --- a/include/uapi/linux/ethtool.h
> +++ b/include/uapi/linux/ethtool.h
> @@ -1362,6 +1362,7 @@ enum ethtool_link_mode_bit_indices {
> ETHTOOL_LINK_MODE_10baseSR4_Full_BIT= 37,
> ETHTOOL_LINK_MODE_10baseCR4_Full_BIT= 38,
> ETHTOOL_LINK_MODE_10baseLR4_ER4_Full_BIT= 39,
> +   ETHTOOL_LINK_MODE_5baseSR2_Full_BIT = 40,
>
> /* Last allowed bit for __ETHTOOL_LINK_MODE_LEGACY_MASK is bit
>  * 31. Please do NOT define any SUPPORTED_* or ADVERTISED_*
> @@ -1370,7 +1371,7 @@ enum ethtool_link_mode_bit_indices {
>  */
>
> __ETHTOOL_LINK_MODE_LAST
> - = ETHTOOL_LINK_MODE_10baseLR4_ER4_Full_BIT,
> + = ETHTOOL_LINK_MODE_5baseSR2_Full_BIT,
>  };
>
>  #define __ETHTOOL_LINK_MODE_LEGACY_MASK(base_name) \
> --
> 2.8.0
>

Acked-By: David Decotigny <de...@googlers.com>


Re: [PATCH net-next 7/9] net/mlx5e: Add 50G missing link mode to ethtool and mlx5 driver

2016-06-22 Thread David Decotigny
maybe split this into 2 separate patches?

On Wed, Jun 22, 2016 at 9:33 AM, Saeed Mahameed <sae...@mellanox.com> wrote:
> From: Gal Pressman <g...@mellanox.com>
>
> Add ETHTOOL_LINK_MODE_5baseSR2_Full_BIT and MLX5E_50GBASE_SR2
> bits.
>
> Signed-off-by: Gal Pressman <g...@mellanox.com>
> CC: Ben Hutchings <b...@kernel.org>
> CC: David Decotigny <de...@googlers.com>
> Signed-off-by: Saeed Mahameed <sae...@mellanox.com>
> ---
>  drivers/net/ethernet/mellanox/mlx5/core/en.h | 1 +
>  include/uapi/linux/ethtool.h | 3 ++-
>  2 files changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h 
> b/drivers/net/ethernet/mellanox/mlx5/core/en.h
> index aa36a3a..b8732e6 100644
> --- a/drivers/net/ethernet/mellanox/mlx5/core/en.h
> +++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h
> @@ -616,6 +616,7 @@ enum mlx5e_link_mode {
> MLX5E_10GBASE_ER = 14,
> MLX5E_40GBASE_SR4= 15,
> MLX5E_40GBASE_LR4= 16,
> +   MLX5E_50GBASE_SR2= 18,
> MLX5E_100GBASE_CR4   = 20,
> MLX5E_100GBASE_SR4   = 21,
> MLX5E_100GBASE_KR4   = 22,
> diff --git a/include/uapi/linux/ethtool.h b/include/uapi/linux/ethtool.h
> index 5f030b4..b8f38e8 100644
> --- a/include/uapi/linux/ethtool.h
> +++ b/include/uapi/linux/ethtool.h
> @@ -1362,6 +1362,7 @@ enum ethtool_link_mode_bit_indices {
> ETHTOOL_LINK_MODE_10baseSR4_Full_BIT= 37,
> ETHTOOL_LINK_MODE_10baseCR4_Full_BIT= 38,
> ETHTOOL_LINK_MODE_10baseLR4_ER4_Full_BIT= 39,
> +   ETHTOOL_LINK_MODE_5baseSR2_Full_BIT = 40,
>
> /* Last allowed bit for __ETHTOOL_LINK_MODE_LEGACY_MASK is bit
>  * 31. Please do NOT define any SUPPORTED_* or ADVERTISED_*
> @@ -1370,7 +1371,7 @@ enum ethtool_link_mode_bit_indices {
>  */
>
> __ETHTOOL_LINK_MODE_LAST
> - = ETHTOOL_LINK_MODE_10baseLR4_ER4_Full_BIT,
> + = ETHTOOL_LINK_MODE_5baseSR2_Full_BIT,
>  };
>
>  #define __ETHTOOL_LINK_MODE_LEGACY_MASK(base_name) \
> --
> 2.8.0
>


[ethtool PATCH v7 0/2] add support for new ETHTOOL_xLINKSETTINGS ioctls

2016-06-09 Thread David Decotigny
From: David Decotigny <de...@googlers.com>

[ this is a plain re-post, same v7 as the ones previously sent ]

History:
  v7
added ref to related kernel commit in netlink ioctl patch description
  v6
re-added last patch, to use AF_NETLINK when AF_INET not available
  v5
rebased main patch, removed last patch "use AF_LOCAL when AF_INET
not available"
  v4
review Ben Hutchings:
  using AF_UNIX instead of INET6 in the absence of v4 sockets
  use stdbool.h
  do_seeprom always fails when offset/length out of bounds
  sync to latest ethtool.h + kernel.h from net-next
  __SANE_USERSPACE_TYPES__ always defined
  cosmetic updates for var == const tests
  cosmetic updates for associativity in tests
  v3
TRUE/FALSE obvious-ification
  v2
added do_seeprom patch
added netdev   as recipient
  v1
initial submission


# Patch Set Summary:

David Decotigny (2):
  ethtool.c: add support for ETHTOOL_xLINKSETTINGS ioctls
  ethtool: use netlink socket when AF_INET not available

 configure.ac   |   2 +-
 ethtool.c  | 688 -
 internal.h |  67 ++
 test-cmdline.c |  13 ++
 4 files changed, 611 insertions(+), 159 deletions(-)

-- 
2.8.0.rc3.226.g39d4020



[ethtool PATCH v7 2/2] ethtool: use netlink socket when AF_INET not available

2016-06-09 Thread David Decotigny
From: David Decotigny <de...@googlers.com>

To benefit from this, kernel commit 025c68186e07 ("netlink: add support
for NIC driver ioctls") is needed.


Signed-off-by: David Decotigny <de...@googlers.com>
---
 configure.ac | 2 +-
 ethtool.c| 7 +++
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/configure.ac b/configure.ac
index 3105415..47d2a0f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -15,7 +15,7 @@ AM_PROG_CC_C_O
 dnl Checks for libraries.
 
 dnl Checks for header files.
-AC_CHECK_HEADERS(sys/ioctl.h)
+AC_CHECK_HEADERS(sys/ioctl.h linux/netlink.h)
 
 dnl Checks for typedefs, structures, and compiler characteristics.
 AC_MSG_CHECKING([whether  defines big-endian types])
diff --git a/ethtool.c b/ethtool.c
index cb3d971..314b1b8 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -42,6 +42,9 @@
 #include 
 
 #include 
+#ifdef HAVE_LINUX_NETLINK_H
+# include 
+#endif
 
 #ifndef MAX_ADDR_LEN
 #define MAX_ADDR_LEN   32
@@ -4645,6 +4648,10 @@ opt_found:
 
/* Open control socket. */
ctx.fd = socket(AF_INET, SOCK_DGRAM, 0);
+#ifdef HAVE_LINUX_NETLINK_H
+   if (ctx.fd < 0)
+   ctx.fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
+#endif
if (ctx.fd < 0) {
perror("Cannot get control socket");
return 70;
-- 
2.8.0.rc3.226.g39d4020



[ethtool PATCH v7 1/2] ethtool.c: add support for ETHTOOL_xLINKSETTINGS ioctls

2016-06-09 Thread David Decotigny
From: David Decotigny <de...@googlers.com>

More info with kernel commit 8d3f2806f8fb ("Merge branch
'ethtool-ksettings'").

Note: The new features implemented in this patch depend on kernel
commit 793cf87de9d1 ("Set cmd field in ETHTOOL_GLINKSETTINGS response to
wrong nwords").


Signed-off-by: David Decotigny <de...@googlers.com>
---
 ethtool.c  | 681 -
 internal.h |  67 ++
 test-cmdline.c |  13 ++
 3 files changed, 603 insertions(+), 158 deletions(-)

diff --git a/ethtool.c b/ethtool.c
index 0cd0d4f..cb3d971 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -47,42 +47,6 @@
 #define MAX_ADDR_LEN   32
 #endif
 
-#define ALL_ADVERTISED_MODES   \
-   (ADVERTISED_10baseT_Half |  \
-ADVERTISED_10baseT_Full |  \
-ADVERTISED_100baseT_Half | \
-ADVERTISED_100baseT_Full | \
-ADVERTISED_1000baseT_Half |\
-ADVERTISED_1000baseT_Full |\
-ADVERTISED_1000baseKX_Full|\
-ADVERTISED_2500baseX_Full |\
-ADVERTISED_1baseT_Full |   \
-ADVERTISED_1baseKX4_Full | \
-ADVERTISED_1baseKR_Full |  \
-ADVERTISED_1baseR_FEC |\
-ADVERTISED_2baseMLD2_Full |\
-ADVERTISED_2baseKR2_Full | \
-ADVERTISED_4baseKR4_Full | \
-ADVERTISED_4baseCR4_Full | \
-ADVERTISED_4baseSR4_Full | \
-ADVERTISED_4baseLR4_Full | \
-ADVERTISED_56000baseKR4_Full | \
-ADVERTISED_56000baseCR4_Full | \
-ADVERTISED_56000baseSR4_Full | \
-ADVERTISED_56000baseLR4_Full)
-
-#define ALL_ADVERTISED_FLAGS   \
-   (ADVERTISED_Autoneg |   \
-ADVERTISED_TP |\
-ADVERTISED_AUI |   \
-ADVERTISED_MII |   \
-ADVERTISED_FIBRE | \
-ADVERTISED_BNC |   \
-ADVERTISED_Pause | \
-ADVERTISED_Asym_Pause |\
-ADVERTISED_Backplane | \
-ALL_ADVERTISED_MODES)
-
 #ifndef HAVE_NETIF_MSG
 enum {
NETIF_MSG_DRV   = 0x0001,
@@ -293,6 +257,43 @@ static void get_mac_addr(char *src, unsigned char *dest)
}
 }
 
+static int parse_hex_u32_bitmap(const char *s,
+   unsigned int nbits, u32 *result)
+{
+   const unsigned int nwords = __KERNEL_DIV_ROUND_UP(nbits, 32);
+   size_t slen = strlen(s);
+   size_t i;
+
+   /* ignore optional '0x' prefix */
+   if ((slen > 2) && (strncasecmp(s, "0x", 2) == 0)) {
+   slen -= 2;
+   s += 2;
+   }
+
+   if (slen > 8 * nwords)  /* up to 2 digits per byte */
+   return -1;
+
+   memset(result, 0, 4 * nwords);
+   for (i = 0 ; i < slen ; ++i) {
+   const unsigned int shift = (slen - 1 - i) * 4;
+   u32 *dest = [shift / 32];
+   u32 nibble;
+
+   if ('a' <= s[i] && s[i] <= 'f')
+   nibble = 0xa + (s[i] - 'a');
+   else if ('A' <= s[i] && s[i] <= 'F')
+   nibble = 0xa + (s[i] - 'A');
+   else if ('0' <= s[i] && s[i] <= '9')
+   nibble = (s[i] - '0');
+   else
+   return -1;
+
+   *dest |= (nibble << (shift % 32));
+   }
+
+   return 0;
+}
+
 static void parse_generic_cmdline(struct cmd_context *ctx,
  int *changed,
  struct cmdline_info *info,
@@ -472,64 +473,157 @@ static int do_version(struct cmd_context *ctx)
return 0;
 }
 
-static void dump_link_caps(const char *prefix, const char *an_prefix, u32 mask,
-  int link_mode_only);
+/* link mode routines */
 
-static void dump_supported(struct ethtool_cmd *ep)
+static __ETHTOOL_DECLARE_LINK_MODE_MASK(all_advertised_modes);
+static __ETHTOOL_DECLARE_LINK_MODE_MASK(all_advertised_flags);
+
+static void init_global_link_mode_masks(void)
 {
-   u32 mask = ep->supported;
+   static const enum ethtool_link_mode_bit_indices
+   all_advertised_modes_bits[] = {
+   ETHTOOL_LINK_MODE_10baseT_Half_BIT,
+   ETHTOOL_LINK_MODE_10baseT_Full_BIT,
+   ETHTOOL_LINK_MODE_100baseT_Half_BIT,
+   ETHTOOL_LINK_MODE_100baseT_Full_BIT,
+   ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
+   ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
+   ETHTOOL_LINK_MODE_1000baseKX_Full_BI

Re: [PATCH v3 1/3] net: phy: add phy_ethtool_{get|set}_link_ksettings

2016-05-09 Thread David Decotigny
On Mon, May 9, 2016 at 3:19 PM, Philippe Reynes <trem...@gmail.com> wrote:
> Ethtool callbacks {get|set}_link_ksettings are often the same, so
> we add two generics functions phy_ethtool_{get|set}_link_ksettings
> to avoid writing severals times the same function.
>
> Signed-off-by: Philippe Reynes <trem...@gmail.com>
> ---
>  drivers/net/phy/phy.c |   24 
>  include/linux/phy.h   |4 
>  2 files changed, 28 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
> index 6f221c8..603e8db 100644
> --- a/drivers/net/phy/phy.c
> +++ b/drivers/net/phy/phy.c
> @@ -1347,3 +1347,27 @@ void phy_ethtool_get_wol(struct phy_device *phydev, 
> struct ethtool_wolinfo *wol)
> phydev->drv->get_wol(phydev, wol);
>  }
>  EXPORT_SYMBOL(phy_ethtool_get_wol);
> +
> +int phy_ethtool_get_link_ksettings(struct net_device *ndev,
> +  struct ethtool_link_ksettings *cmd)
> +{
> +   struct phy_device *phydev = ndev->phydev;
> +
> +   if (!phydev)
> +   return -ENODEV;
> +
> +   return phy_ethtool_ksettings_get(phydev, cmd);
> +}
> +EXPORT_SYMBOL(phy_ethtool_get_link_ksettings);
> +
> +int phy_ethtool_set_link_ksettings(struct net_device *ndev,
> +  const struct ethtool_link_ksettings *cmd)
> +{
> +   struct phy_device *phydev = ndev->phydev;
> +
> +   if (!phydev)
> +   return -ENODEV;
> +
> +   return phy_ethtool_ksettings_set(phydev, cmd);
> +}
> +EXPORT_SYMBOL(phy_ethtool_set_link_ksettings);
> diff --git a/include/linux/phy.h b/include/linux/phy.h
> index be3f83b..2d24b28 100644
> --- a/include/linux/phy.h
> +++ b/include/linux/phy.h
> @@ -829,6 +829,10 @@ int phy_ethtool_get_eee(struct phy_device *phydev, 
> struct ethtool_eee *data);
>  int phy_ethtool_set_wol(struct phy_device *phydev, struct ethtool_wolinfo 
> *wol);
>  void phy_ethtool_get_wol(struct phy_device *phydev,
>  struct ethtool_wolinfo *wol);
> +int phy_ethtool_get_link_ksettings(struct net_device *ndev,
> +  struct ethtool_link_ksettings *cmd);
> +int phy_ethtool_set_link_ksettings(struct net_device *ndev,
> +  const struct ethtool_link_ksettings *cmd);
>
>  int __init mdio_bus_init(void);
>  void mdio_bus_exit(void);
> --
> 1.7.4.4
>

Acked-By: David Decotigny <de...@googlers.com>


[ethtool PATCH v7 0/2] add support for new ETHTOOL_xLINKSETTINGS ioctls

2016-05-09 Thread David Decotigny
From: David Decotigny <de...@googlers.com>

[ this is a plain re-post, same v7 as the ones previously sent ]

History:
  v7
added ref to related kernel commit in netlink ioctl patch description
  v6
re-added last patch, to use AF_NETLINK when AF_INET not available
  v5
rebased main patch, removed last patch "use AF_LOCAL when AF_INET
not available"
  v4
review Ben Hutchings:
  using AF_UNIX instead of INET6 in the absence of v4 sockets
  use stdbool.h
  do_seeprom always fails when offset/length out of bounds
  sync to latest ethtool.h + kernel.h from net-next
  __SANE_USERSPACE_TYPES__ always defined
  cosmetic updates for var == const tests
  cosmetic updates for associativity in tests
  v3
TRUE/FALSE obvious-ification
  v2
added do_seeprom patch
added netdev   as recipient
  v1
initial submission


# Patch Set Summary:

David Decotigny (2):
  ethtool.c: add support for ETHTOOL_xLINKSETTINGS ioctls
  ethtool: use netlink socket when AF_INET not available

 configure.ac   |   2 +-
 ethtool.c  | 688 -
 internal.h |  67 ++
 test-cmdline.c |  13 ++
 4 files changed, 611 insertions(+), 159 deletions(-)

-- 
2.8.0.rc3.226.g39d4020



[ethtool PATCH v7 1/2] ethtool.c: add support for ETHTOOL_xLINKSETTINGS ioctls

2016-05-09 Thread David Decotigny
From: David Decotigny <de...@googlers.com>

More info with kernel commit 8d3f2806f8fb ("Merge branch
'ethtool-ksettings'").

Note: The new features implemented in this patch depend on kernel
commit 793cf87de9d1 ("Set cmd field in ETHTOOL_GLINKSETTINGS response to
wrong nwords").


Signed-off-by: David Decotigny <de...@googlers.com>
---
 ethtool.c  | 681 -
 internal.h |  67 ++
 test-cmdline.c |  13 ++
 3 files changed, 603 insertions(+), 158 deletions(-)

diff --git a/ethtool.c b/ethtool.c
index 0cd0d4f..cb3d971 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -47,42 +47,6 @@
 #define MAX_ADDR_LEN   32
 #endif
 
-#define ALL_ADVERTISED_MODES   \
-   (ADVERTISED_10baseT_Half |  \
-ADVERTISED_10baseT_Full |  \
-ADVERTISED_100baseT_Half | \
-ADVERTISED_100baseT_Full | \
-ADVERTISED_1000baseT_Half |\
-ADVERTISED_1000baseT_Full |\
-ADVERTISED_1000baseKX_Full|\
-ADVERTISED_2500baseX_Full |\
-ADVERTISED_1baseT_Full |   \
-ADVERTISED_1baseKX4_Full | \
-ADVERTISED_1baseKR_Full |  \
-ADVERTISED_1baseR_FEC |\
-ADVERTISED_2baseMLD2_Full |\
-ADVERTISED_2baseKR2_Full | \
-ADVERTISED_4baseKR4_Full | \
-ADVERTISED_4baseCR4_Full | \
-ADVERTISED_4baseSR4_Full | \
-ADVERTISED_4baseLR4_Full | \
-ADVERTISED_56000baseKR4_Full | \
-ADVERTISED_56000baseCR4_Full | \
-ADVERTISED_56000baseSR4_Full | \
-ADVERTISED_56000baseLR4_Full)
-
-#define ALL_ADVERTISED_FLAGS   \
-   (ADVERTISED_Autoneg |   \
-ADVERTISED_TP |\
-ADVERTISED_AUI |   \
-ADVERTISED_MII |   \
-ADVERTISED_FIBRE | \
-ADVERTISED_BNC |   \
-ADVERTISED_Pause | \
-ADVERTISED_Asym_Pause |\
-ADVERTISED_Backplane | \
-ALL_ADVERTISED_MODES)
-
 #ifndef HAVE_NETIF_MSG
 enum {
NETIF_MSG_DRV   = 0x0001,
@@ -293,6 +257,43 @@ static void get_mac_addr(char *src, unsigned char *dest)
}
 }
 
+static int parse_hex_u32_bitmap(const char *s,
+   unsigned int nbits, u32 *result)
+{
+   const unsigned int nwords = __KERNEL_DIV_ROUND_UP(nbits, 32);
+   size_t slen = strlen(s);
+   size_t i;
+
+   /* ignore optional '0x' prefix */
+   if ((slen > 2) && (strncasecmp(s, "0x", 2) == 0)) {
+   slen -= 2;
+   s += 2;
+   }
+
+   if (slen > 8 * nwords)  /* up to 2 digits per byte */
+   return -1;
+
+   memset(result, 0, 4 * nwords);
+   for (i = 0 ; i < slen ; ++i) {
+   const unsigned int shift = (slen - 1 - i) * 4;
+   u32 *dest = [shift / 32];
+   u32 nibble;
+
+   if ('a' <= s[i] && s[i] <= 'f')
+   nibble = 0xa + (s[i] - 'a');
+   else if ('A' <= s[i] && s[i] <= 'F')
+   nibble = 0xa + (s[i] - 'A');
+   else if ('0' <= s[i] && s[i] <= '9')
+   nibble = (s[i] - '0');
+   else
+   return -1;
+
+   *dest |= (nibble << (shift % 32));
+   }
+
+   return 0;
+}
+
 static void parse_generic_cmdline(struct cmd_context *ctx,
  int *changed,
  struct cmdline_info *info,
@@ -472,64 +473,157 @@ static int do_version(struct cmd_context *ctx)
return 0;
 }
 
-static void dump_link_caps(const char *prefix, const char *an_prefix, u32 mask,
-  int link_mode_only);
+/* link mode routines */
 
-static void dump_supported(struct ethtool_cmd *ep)
+static __ETHTOOL_DECLARE_LINK_MODE_MASK(all_advertised_modes);
+static __ETHTOOL_DECLARE_LINK_MODE_MASK(all_advertised_flags);
+
+static void init_global_link_mode_masks(void)
 {
-   u32 mask = ep->supported;
+   static const enum ethtool_link_mode_bit_indices
+   all_advertised_modes_bits[] = {
+   ETHTOOL_LINK_MODE_10baseT_Half_BIT,
+   ETHTOOL_LINK_MODE_10baseT_Full_BIT,
+   ETHTOOL_LINK_MODE_100baseT_Half_BIT,
+   ETHTOOL_LINK_MODE_100baseT_Full_BIT,
+   ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
+   ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
+   ETHTOOL_LINK_MODE_1000baseKX_Full_BI

[ethtool PATCH v7 2/2] ethtool: use netlink socket when AF_INET not available

2016-05-09 Thread David Decotigny
From: David Decotigny <de...@googlers.com>

To benefit from this, kernel commit 025c68186e07 ("netlink: add support
for NIC driver ioctls") is needed.


Signed-off-by: David Decotigny <de...@googlers.com>
---
 configure.ac | 2 +-
 ethtool.c| 7 +++
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/configure.ac b/configure.ac
index 3105415..47d2a0f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -15,7 +15,7 @@ AM_PROG_CC_C_O
 dnl Checks for libraries.
 
 dnl Checks for header files.
-AC_CHECK_HEADERS(sys/ioctl.h)
+AC_CHECK_HEADERS(sys/ioctl.h linux/netlink.h)
 
 dnl Checks for typedefs, structures, and compiler characteristics.
 AC_MSG_CHECKING([whether  defines big-endian types])
diff --git a/ethtool.c b/ethtool.c
index cb3d971..314b1b8 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -42,6 +42,9 @@
 #include 
 
 #include 
+#ifdef HAVE_LINUX_NETLINK_H
+# include 
+#endif
 
 #ifndef MAX_ADDR_LEN
 #define MAX_ADDR_LEN   32
@@ -4645,6 +4648,10 @@ opt_found:
 
/* Open control socket. */
ctx.fd = socket(AF_INET, SOCK_DGRAM, 0);
+#ifdef HAVE_LINUX_NETLINK_H
+   if (ctx.fd < 0)
+   ctx.fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
+#endif
if (ctx.fd < 0) {
perror("Cannot get control socket");
return 70;
-- 
2.8.0.rc3.226.g39d4020



Re: [PATCH v2 1/3] net: core: ethtool: add ethtool_op_{get|set}_link_ksettings

2016-05-09 Thread David Decotigny
Are you sure this belongs to ethtool.h? For one, I believe you need an
#include phy.h somewhere. I would suggest instead to keep this in
phy.h, presumably with a more explicit name suggesting that phydev is
involved.

On Sun, May 8, 2016 at 2:44 PM, Philippe Reynes  wrote:
> Ethtool callbacks {get|set}_link_ksettings are often the same, so
> we add two generics functions ethtool_op_{get|set}_link_ksettings
> to avoid writing severals times the same function.
>
> Signed-off-by: Philippe Reynes 
> ---
>  include/linux/ethtool.h |5 +
>  net/core/ethtool.c  |   24 
>  2 files changed, 29 insertions(+), 0 deletions(-)
>
> diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
> index 9ded8c6..9a55836 100644
> --- a/include/linux/ethtool.h
> +++ b/include/linux/ethtool.h
> @@ -157,6 +157,11 @@ void ethtool_convert_legacy_u32_to_link_mode(unsigned 
> long *dst,
>  bool ethtool_convert_link_mode_to_legacy_u32(u32 *legacy_u32,
>  const unsigned long *src);
>
> +int ethtool_op_get_link_ksettings(struct net_device *ndev,
> + struct ethtool_link_ksettings *cmd);
> +int ethtool_op_set_link_ksettings(struct net_device *ndev,
> + const struct ethtool_link_ksettings *cmd);
> +
>  /**
>   * struct ethtool_ops - optional netdev operations
>   * @get_settings: DEPRECATED, use %get_link_ksettings/%set_link_ksettings
> diff --git a/net/core/ethtool.c b/net/core/ethtool.c
> index bdb4013..b605fb1 100644
> --- a/net/core/ethtool.c
> +++ b/net/core/ethtool.c
> @@ -852,6 +852,30 @@ static int ethtool_set_settings(struct net_device *dev, 
> void __user *useraddr)
> return dev->ethtool_ops->set_settings(dev, );
>  }
>
> +int ethtool_op_get_link_ksettings(struct net_device *ndev,
> + struct ethtool_link_ksettings *cmd)
> +{
> +   struct phy_device *phydev = ndev->phydev;
> +
> +   if (!phydev)
> +   return -ENODEV;
> +
> +   return phy_ethtool_ksettings_get(phydev, cmd);
> +}
> +EXPORT_SYMBOL(ethtool_op_get_link_ksettings);
> +
> +int ethtool_op_set_link_ksettings(struct net_device *ndev,
> + const struct ethtool_link_ksettings *cmd)
> +{
> +   struct phy_device *phydev = ndev->phydev;
> +
> +   if (!phydev)
> +   return -ENODEV;
> +
> +   return phy_ethtool_ksettings_set(phydev, cmd);
> +}
> +EXPORT_SYMBOL(ethtool_op_set_link_ksettings);
> +
>  static noinline_for_stack int ethtool_get_drvinfo(struct net_device *dev,
>   void __user *useraddr)
>  {
> --
> 1.7.4.4
>


[ethtool PATCH v7 2/2] ethtool: use netlink socket when AF_INET not available

2016-05-02 Thread David Decotigny
From: David Decotigny <de...@googlers.com>

To benefit from this, kernel commit 025c68186e07 ("netlink: add support
for NIC driver ioctls") is needed.


Signed-off-by: David Decotigny <de...@googlers.com>
---
 configure.ac | 2 +-
 ethtool.c| 7 +++
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/configure.ac b/configure.ac
index 3105415..47d2a0f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -15,7 +15,7 @@ AM_PROG_CC_C_O
 dnl Checks for libraries.
 
 dnl Checks for header files.
-AC_CHECK_HEADERS(sys/ioctl.h)
+AC_CHECK_HEADERS(sys/ioctl.h linux/netlink.h)
 
 dnl Checks for typedefs, structures, and compiler characteristics.
 AC_MSG_CHECKING([whether  defines big-endian types])
diff --git a/ethtool.c b/ethtool.c
index cb3d971..314b1b8 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -42,6 +42,9 @@
 #include 
 
 #include 
+#ifdef HAVE_LINUX_NETLINK_H
+# include 
+#endif
 
 #ifndef MAX_ADDR_LEN
 #define MAX_ADDR_LEN   32
@@ -4645,6 +4648,10 @@ opt_found:
 
/* Open control socket. */
ctx.fd = socket(AF_INET, SOCK_DGRAM, 0);
+#ifdef HAVE_LINUX_NETLINK_H
+   if (ctx.fd < 0)
+   ctx.fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
+#endif
if (ctx.fd < 0) {
perror("Cannot get control socket");
return 70;
-- 
2.8.0.rc3.226.g39d4020



[ethtool PATCH v7 1/2] ethtool.c: add support for ETHTOOL_xLINKSETTINGS ioctls

2016-05-02 Thread David Decotigny
From: David Decotigny <de...@googlers.com>

More info with kernel commit 8d3f2806f8fb ("Merge branch
'ethtool-ksettings'").

Note: The new features implemented in this patch depend on kernel
commit 793cf87de9d1 ("Set cmd field in ETHTOOL_GLINKSETTINGS response to
wrong nwords").


Signed-off-by: David Decotigny <de...@googlers.com>
---
 ethtool.c  | 681 -
 internal.h |  67 ++
 test-cmdline.c |  13 ++
 3 files changed, 603 insertions(+), 158 deletions(-)

diff --git a/ethtool.c b/ethtool.c
index 0cd0d4f..cb3d971 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -47,42 +47,6 @@
 #define MAX_ADDR_LEN   32
 #endif
 
-#define ALL_ADVERTISED_MODES   \
-   (ADVERTISED_10baseT_Half |  \
-ADVERTISED_10baseT_Full |  \
-ADVERTISED_100baseT_Half | \
-ADVERTISED_100baseT_Full | \
-ADVERTISED_1000baseT_Half |\
-ADVERTISED_1000baseT_Full |\
-ADVERTISED_1000baseKX_Full|\
-ADVERTISED_2500baseX_Full |\
-ADVERTISED_1baseT_Full |   \
-ADVERTISED_1baseKX4_Full | \
-ADVERTISED_1baseKR_Full |  \
-ADVERTISED_1baseR_FEC |\
-ADVERTISED_2baseMLD2_Full |\
-ADVERTISED_2baseKR2_Full | \
-ADVERTISED_4baseKR4_Full | \
-ADVERTISED_4baseCR4_Full | \
-ADVERTISED_4baseSR4_Full | \
-ADVERTISED_4baseLR4_Full | \
-ADVERTISED_56000baseKR4_Full | \
-ADVERTISED_56000baseCR4_Full | \
-ADVERTISED_56000baseSR4_Full | \
-ADVERTISED_56000baseLR4_Full)
-
-#define ALL_ADVERTISED_FLAGS   \
-   (ADVERTISED_Autoneg |   \
-ADVERTISED_TP |\
-ADVERTISED_AUI |   \
-ADVERTISED_MII |   \
-ADVERTISED_FIBRE | \
-ADVERTISED_BNC |   \
-ADVERTISED_Pause | \
-ADVERTISED_Asym_Pause |\
-ADVERTISED_Backplane | \
-ALL_ADVERTISED_MODES)
-
 #ifndef HAVE_NETIF_MSG
 enum {
NETIF_MSG_DRV   = 0x0001,
@@ -293,6 +257,43 @@ static void get_mac_addr(char *src, unsigned char *dest)
}
 }
 
+static int parse_hex_u32_bitmap(const char *s,
+   unsigned int nbits, u32 *result)
+{
+   const unsigned int nwords = __KERNEL_DIV_ROUND_UP(nbits, 32);
+   size_t slen = strlen(s);
+   size_t i;
+
+   /* ignore optional '0x' prefix */
+   if ((slen > 2) && (strncasecmp(s, "0x", 2) == 0)) {
+   slen -= 2;
+   s += 2;
+   }
+
+   if (slen > 8 * nwords)  /* up to 2 digits per byte */
+   return -1;
+
+   memset(result, 0, 4 * nwords);
+   for (i = 0 ; i < slen ; ++i) {
+   const unsigned int shift = (slen - 1 - i) * 4;
+   u32 *dest = [shift / 32];
+   u32 nibble;
+
+   if ('a' <= s[i] && s[i] <= 'f')
+   nibble = 0xa + (s[i] - 'a');
+   else if ('A' <= s[i] && s[i] <= 'F')
+   nibble = 0xa + (s[i] - 'A');
+   else if ('0' <= s[i] && s[i] <= '9')
+   nibble = (s[i] - '0');
+   else
+   return -1;
+
+   *dest |= (nibble << (shift % 32));
+   }
+
+   return 0;
+}
+
 static void parse_generic_cmdline(struct cmd_context *ctx,
  int *changed,
  struct cmdline_info *info,
@@ -472,64 +473,157 @@ static int do_version(struct cmd_context *ctx)
return 0;
 }
 
-static void dump_link_caps(const char *prefix, const char *an_prefix, u32 mask,
-  int link_mode_only);
+/* link mode routines */
 
-static void dump_supported(struct ethtool_cmd *ep)
+static __ETHTOOL_DECLARE_LINK_MODE_MASK(all_advertised_modes);
+static __ETHTOOL_DECLARE_LINK_MODE_MASK(all_advertised_flags);
+
+static void init_global_link_mode_masks(void)
 {
-   u32 mask = ep->supported;
+   static const enum ethtool_link_mode_bit_indices
+   all_advertised_modes_bits[] = {
+   ETHTOOL_LINK_MODE_10baseT_Half_BIT,
+   ETHTOOL_LINK_MODE_10baseT_Full_BIT,
+   ETHTOOL_LINK_MODE_100baseT_Half_BIT,
+   ETHTOOL_LINK_MODE_100baseT_Full_BIT,
+   ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
+   ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
+   ETHTOOL_LINK_MODE_1000baseKX_Full_BI

[ethtool PATCH v7 0/2] add support for new ETHTOOL_xLINKSETTINGS ioctls

2016-05-02 Thread David Decotigny
From: David Decotigny <de...@googlers.com>

[ this is a plain re-post, same v7 as the ones previously sent ]

History:
  v7
added ref to related kernel commit in netlink ioctl patch description
  v6
re-added last patch, to use AF_NETLINK when AF_INET not available
  v5
rebased main patch, removed last patch "use AF_LOCAL when AF_INET
not available"
  v4
review Ben Hutchings:
  using AF_UNIX instead of INET6 in the absence of v4 sockets
  use stdbool.h
  do_seeprom always fails when offset/length out of bounds
  sync to latest ethtool.h + kernel.h from net-next
  __SANE_USERSPACE_TYPES__ always defined
  cosmetic updates for var == const tests
  cosmetic updates for associativity in tests
  v3
TRUE/FALSE obvious-ification
  v2
added do_seeprom patch
added netdev   as recipient
  v1
initial submission


# Patch Set Summary:

David Decotigny (2):
  ethtool.c: add support for ETHTOOL_xLINKSETTINGS ioctls
  ethtool: use netlink socket when AF_INET not available

 configure.ac   |   2 +-
 ethtool.c  | 688 -
 internal.h |  67 ++
 test-cmdline.c |  13 ++
 4 files changed, 611 insertions(+), 159 deletions(-)

-- 
2.8.0.rc3.226.g39d4020



[ethtool PATCH v7 0/2] add support for new ETHTOOL_xLINKSETTINGS ioctls

2016-04-22 Thread David Decotigny
From: David Decotigny <de...@googlers.com>

[ re-sending this series, same v7 as the one previously sent ]

History:
  v7
added ref to related kernel commit in netlink ioctl patch description
  v6
re-added last patch, to use AF_NETLINK when AF_INET not available
  v5
rebased main patch, removed last patch "use AF_LOCAL when AF_INET
not available"
  v4
review Ben Hutchings:
  using AF_UNIX instead of INET6 in the absence of v4 sockets
  use stdbool.h
  do_seeprom always fails when offset/length out of bounds
  sync to latest ethtool.h + kernel.h from net-next
  __SANE_USERSPACE_TYPES__ always defined
  cosmetic updates for var == const tests
  cosmetic updates for associativity in tests
  v3
TRUE/FALSE obvious-ification
  v2
added do_seeprom patch
added netdev   as recipient
  v1
initial submission


# Patch Set Summary:

David Decotigny (2):
  ethtool.c: add support for ETHTOOL_xLINKSETTINGS ioctls
  ethtool: use netlink socket when AF_INET not available

 configure.ac   |   2 +-
 ethtool.c  | 688 -
 internal.h |  67 ++
 test-cmdline.c |  13 ++
 4 files changed, 611 insertions(+), 159 deletions(-)

-- 
2.8.0.rc3.226.g39d4020



[ethtool PATCH v7 1/2] ethtool.c: add support for ETHTOOL_xLINKSETTINGS ioctls

2016-04-22 Thread David Decotigny
From: David Decotigny <de...@googlers.com>

More info with kernel commit 8d3f2806f8fb ("Merge branch
'ethtool-ksettings'").

Note: The new features implemented in this patch depend on kernel
commit 793cf87de9d1 ("Set cmd field in ETHTOOL_GLINKSETTINGS response to
wrong nwords").


Signed-off-by: David Decotigny <de...@googlers.com>
---
 ethtool.c  | 681 -
 internal.h |  67 ++
 test-cmdline.c |  13 ++
 3 files changed, 603 insertions(+), 158 deletions(-)

diff --git a/ethtool.c b/ethtool.c
index 0cd0d4f..cb3d971 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -47,42 +47,6 @@
 #define MAX_ADDR_LEN   32
 #endif
 
-#define ALL_ADVERTISED_MODES   \
-   (ADVERTISED_10baseT_Half |  \
-ADVERTISED_10baseT_Full |  \
-ADVERTISED_100baseT_Half | \
-ADVERTISED_100baseT_Full | \
-ADVERTISED_1000baseT_Half |\
-ADVERTISED_1000baseT_Full |\
-ADVERTISED_1000baseKX_Full|\
-ADVERTISED_2500baseX_Full |\
-ADVERTISED_1baseT_Full |   \
-ADVERTISED_1baseKX4_Full | \
-ADVERTISED_1baseKR_Full |  \
-ADVERTISED_1baseR_FEC |\
-ADVERTISED_2baseMLD2_Full |\
-ADVERTISED_2baseKR2_Full | \
-ADVERTISED_4baseKR4_Full | \
-ADVERTISED_4baseCR4_Full | \
-ADVERTISED_4baseSR4_Full | \
-ADVERTISED_4baseLR4_Full | \
-ADVERTISED_56000baseKR4_Full | \
-ADVERTISED_56000baseCR4_Full | \
-ADVERTISED_56000baseSR4_Full | \
-ADVERTISED_56000baseLR4_Full)
-
-#define ALL_ADVERTISED_FLAGS   \
-   (ADVERTISED_Autoneg |   \
-ADVERTISED_TP |\
-ADVERTISED_AUI |   \
-ADVERTISED_MII |   \
-ADVERTISED_FIBRE | \
-ADVERTISED_BNC |   \
-ADVERTISED_Pause | \
-ADVERTISED_Asym_Pause |\
-ADVERTISED_Backplane | \
-ALL_ADVERTISED_MODES)
-
 #ifndef HAVE_NETIF_MSG
 enum {
NETIF_MSG_DRV   = 0x0001,
@@ -293,6 +257,43 @@ static void get_mac_addr(char *src, unsigned char *dest)
}
 }
 
+static int parse_hex_u32_bitmap(const char *s,
+   unsigned int nbits, u32 *result)
+{
+   const unsigned int nwords = __KERNEL_DIV_ROUND_UP(nbits, 32);
+   size_t slen = strlen(s);
+   size_t i;
+
+   /* ignore optional '0x' prefix */
+   if ((slen > 2) && (strncasecmp(s, "0x", 2) == 0)) {
+   slen -= 2;
+   s += 2;
+   }
+
+   if (slen > 8 * nwords)  /* up to 2 digits per byte */
+   return -1;
+
+   memset(result, 0, 4 * nwords);
+   for (i = 0 ; i < slen ; ++i) {
+   const unsigned int shift = (slen - 1 - i) * 4;
+   u32 *dest = [shift / 32];
+   u32 nibble;
+
+   if ('a' <= s[i] && s[i] <= 'f')
+   nibble = 0xa + (s[i] - 'a');
+   else if ('A' <= s[i] && s[i] <= 'F')
+   nibble = 0xa + (s[i] - 'A');
+   else if ('0' <= s[i] && s[i] <= '9')
+   nibble = (s[i] - '0');
+   else
+   return -1;
+
+   *dest |= (nibble << (shift % 32));
+   }
+
+   return 0;
+}
+
 static void parse_generic_cmdline(struct cmd_context *ctx,
  int *changed,
  struct cmdline_info *info,
@@ -472,64 +473,157 @@ static int do_version(struct cmd_context *ctx)
return 0;
 }
 
-static void dump_link_caps(const char *prefix, const char *an_prefix, u32 mask,
-  int link_mode_only);
+/* link mode routines */
 
-static void dump_supported(struct ethtool_cmd *ep)
+static __ETHTOOL_DECLARE_LINK_MODE_MASK(all_advertised_modes);
+static __ETHTOOL_DECLARE_LINK_MODE_MASK(all_advertised_flags);
+
+static void init_global_link_mode_masks(void)
 {
-   u32 mask = ep->supported;
+   static const enum ethtool_link_mode_bit_indices
+   all_advertised_modes_bits[] = {
+   ETHTOOL_LINK_MODE_10baseT_Half_BIT,
+   ETHTOOL_LINK_MODE_10baseT_Full_BIT,
+   ETHTOOL_LINK_MODE_100baseT_Half_BIT,
+   ETHTOOL_LINK_MODE_100baseT_Full_BIT,
+   ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
+   ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
+   ETHTOOL_LINK_MODE_1000baseKX_Full_BI

[ethtool PATCH v7 2/2] ethtool: use netlink socket when AF_INET not available

2016-04-22 Thread David Decotigny
From: David Decotigny <de...@googlers.com>

To benefit from this, kernel commit 025c68186e07 ("netlink: add support
for NIC driver ioctls") is needed.


Signed-off-by: David Decotigny <de...@googlers.com>
---
 configure.ac | 2 +-
 ethtool.c| 7 +++
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/configure.ac b/configure.ac
index 3105415..47d2a0f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -15,7 +15,7 @@ AM_PROG_CC_C_O
 dnl Checks for libraries.
 
 dnl Checks for header files.
-AC_CHECK_HEADERS(sys/ioctl.h)
+AC_CHECK_HEADERS(sys/ioctl.h linux/netlink.h)
 
 dnl Checks for typedefs, structures, and compiler characteristics.
 AC_MSG_CHECKING([whether  defines big-endian types])
diff --git a/ethtool.c b/ethtool.c
index cb3d971..314b1b8 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -42,6 +42,9 @@
 #include 
 
 #include 
+#ifdef HAVE_LINUX_NETLINK_H
+# include 
+#endif
 
 #ifndef MAX_ADDR_LEN
 #define MAX_ADDR_LEN   32
@@ -4645,6 +4648,10 @@ opt_found:
 
/* Open control socket. */
ctx.fd = socket(AF_INET, SOCK_DGRAM, 0);
+#ifdef HAVE_LINUX_NETLINK_H
+   if (ctx.fd < 0)
+   ctx.fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
+#endif
if (ctx.fd < 0) {
perror("Cannot get control socket");
return 70;
-- 
2.8.0.rc3.226.g39d4020



[ethtool PATCH v7 0/2] add support for new ETHTOOL_xLINKSETTINGS ioctls

2016-03-25 Thread David Decotigny
From: David Decotigny <de...@googlers.com>

History:
  v7
added ref to related kernel commit in netlink ioctl patch description
  v6
re-added last patch, to use AF_NETLINK when AF_INET not available
  v5
rebased main patch, removed last patch "use AF_LOCAL when AF_INET
not available"
  v4
review Ben Hutchings:
  using AF_UNIX instead of INET6 in the absence of v4 sockets
  use stdbool.h
  do_seeprom always fails when offset/length out of bounds
  sync to latest ethtool.h + kernel.h from net-next
  __SANE_USERSPACE_TYPES__ always defined
  cosmetic updates for var == const tests
  cosmetic updates for associativity in tests
  v3
TRUE/FALSE obvious-ification
  v2
added do_seeprom patch
added netdev   as recipient
  v1
initial submission


# Patch Set Summary:

David Decotigny (2):
  ethtool.c: add support for ETHTOOL_xLINKSETTINGS ioctls
  ethtool: use netlink socket when AF_INET not available

 configure.ac   |   2 +-
 ethtool.c  | 688 -
 internal.h |  67 ++
 test-cmdline.c |  13 ++
 4 files changed, 611 insertions(+), 159 deletions(-)

-- 
2.8.0.rc3.226.g39d4020



[ethtool PATCH v7 2/2] ethtool: use netlink socket when AF_INET not available

2016-03-25 Thread David Decotigny
From: David Decotigny <de...@googlers.com>

To benefit from this, kernel commit 025c68186e07 ("netlink: add support
for NIC driver ioctls") is needed.


Signed-off-by: David Decotigny <de...@googlers.com>
---
 configure.ac | 2 +-
 ethtool.c| 7 +++
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/configure.ac b/configure.ac
index 3105415..47d2a0f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -15,7 +15,7 @@ AM_PROG_CC_C_O
 dnl Checks for libraries.
 
 dnl Checks for header files.
-AC_CHECK_HEADERS(sys/ioctl.h)
+AC_CHECK_HEADERS(sys/ioctl.h linux/netlink.h)
 
 dnl Checks for typedefs, structures, and compiler characteristics.
 AC_MSG_CHECKING([whether  defines big-endian types])
diff --git a/ethtool.c b/ethtool.c
index cb3d971..314b1b8 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -42,6 +42,9 @@
 #include 
 
 #include 
+#ifdef HAVE_LINUX_NETLINK_H
+# include 
+#endif
 
 #ifndef MAX_ADDR_LEN
 #define MAX_ADDR_LEN   32
@@ -4645,6 +4648,10 @@ opt_found:
 
/* Open control socket. */
ctx.fd = socket(AF_INET, SOCK_DGRAM, 0);
+#ifdef HAVE_LINUX_NETLINK_H
+   if (ctx.fd < 0)
+   ctx.fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
+#endif
if (ctx.fd < 0) {
perror("Cannot get control socket");
return 70;
-- 
2.8.0.rc3.226.g39d4020



[ethtool PATCH v7 1/2] ethtool.c: add support for ETHTOOL_xLINKSETTINGS ioctls

2016-03-25 Thread David Decotigny
From: David Decotigny <de...@googlers.com>

More info with kernel commit 8d3f2806f8fb ("Merge branch
'ethtool-ksettings'").

Note: The new features implemented in this patch depend on kernel
commit 793cf87de9d1 ("Set cmd field in ETHTOOL_GLINKSETTINGS response to
wrong nwords").


Signed-off-by: David Decotigny <de...@googlers.com>
---
 ethtool.c  | 681 -
 internal.h |  67 ++
 test-cmdline.c |  13 ++
 3 files changed, 603 insertions(+), 158 deletions(-)

diff --git a/ethtool.c b/ethtool.c
index 0cd0d4f..cb3d971 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -47,42 +47,6 @@
 #define MAX_ADDR_LEN   32
 #endif
 
-#define ALL_ADVERTISED_MODES   \
-   (ADVERTISED_10baseT_Half |  \
-ADVERTISED_10baseT_Full |  \
-ADVERTISED_100baseT_Half | \
-ADVERTISED_100baseT_Full | \
-ADVERTISED_1000baseT_Half |\
-ADVERTISED_1000baseT_Full |\
-ADVERTISED_1000baseKX_Full|\
-ADVERTISED_2500baseX_Full |\
-ADVERTISED_1baseT_Full |   \
-ADVERTISED_1baseKX4_Full | \
-ADVERTISED_1baseKR_Full |  \
-ADVERTISED_1baseR_FEC |\
-ADVERTISED_2baseMLD2_Full |\
-ADVERTISED_2baseKR2_Full | \
-ADVERTISED_4baseKR4_Full | \
-ADVERTISED_4baseCR4_Full | \
-ADVERTISED_4baseSR4_Full | \
-ADVERTISED_4baseLR4_Full | \
-ADVERTISED_56000baseKR4_Full | \
-ADVERTISED_56000baseCR4_Full | \
-ADVERTISED_56000baseSR4_Full | \
-ADVERTISED_56000baseLR4_Full)
-
-#define ALL_ADVERTISED_FLAGS   \
-   (ADVERTISED_Autoneg |   \
-ADVERTISED_TP |\
-ADVERTISED_AUI |   \
-ADVERTISED_MII |   \
-ADVERTISED_FIBRE | \
-ADVERTISED_BNC |   \
-ADVERTISED_Pause | \
-ADVERTISED_Asym_Pause |\
-ADVERTISED_Backplane | \
-ALL_ADVERTISED_MODES)
-
 #ifndef HAVE_NETIF_MSG
 enum {
NETIF_MSG_DRV   = 0x0001,
@@ -293,6 +257,43 @@ static void get_mac_addr(char *src, unsigned char *dest)
}
 }
 
+static int parse_hex_u32_bitmap(const char *s,
+   unsigned int nbits, u32 *result)
+{
+   const unsigned int nwords = __KERNEL_DIV_ROUND_UP(nbits, 32);
+   size_t slen = strlen(s);
+   size_t i;
+
+   /* ignore optional '0x' prefix */
+   if ((slen > 2) && (strncasecmp(s, "0x", 2) == 0)) {
+   slen -= 2;
+   s += 2;
+   }
+
+   if (slen > 8 * nwords)  /* up to 2 digits per byte */
+   return -1;
+
+   memset(result, 0, 4 * nwords);
+   for (i = 0 ; i < slen ; ++i) {
+   const unsigned int shift = (slen - 1 - i) * 4;
+   u32 *dest = [shift / 32];
+   u32 nibble;
+
+   if ('a' <= s[i] && s[i] <= 'f')
+   nibble = 0xa + (s[i] - 'a');
+   else if ('A' <= s[i] && s[i] <= 'F')
+   nibble = 0xa + (s[i] - 'A');
+   else if ('0' <= s[i] && s[i] <= '9')
+   nibble = (s[i] - '0');
+   else
+   return -1;
+
+   *dest |= (nibble << (shift % 32));
+   }
+
+   return 0;
+}
+
 static void parse_generic_cmdline(struct cmd_context *ctx,
  int *changed,
  struct cmdline_info *info,
@@ -472,64 +473,157 @@ static int do_version(struct cmd_context *ctx)
return 0;
 }
 
-static void dump_link_caps(const char *prefix, const char *an_prefix, u32 mask,
-  int link_mode_only);
+/* link mode routines */
 
-static void dump_supported(struct ethtool_cmd *ep)
+static __ETHTOOL_DECLARE_LINK_MODE_MASK(all_advertised_modes);
+static __ETHTOOL_DECLARE_LINK_MODE_MASK(all_advertised_flags);
+
+static void init_global_link_mode_masks(void)
 {
-   u32 mask = ep->supported;
+   static const enum ethtool_link_mode_bit_indices
+   all_advertised_modes_bits[] = {
+   ETHTOOL_LINK_MODE_10baseT_Half_BIT,
+   ETHTOOL_LINK_MODE_10baseT_Full_BIT,
+   ETHTOOL_LINK_MODE_100baseT_Half_BIT,
+   ETHTOOL_LINK_MODE_100baseT_Full_BIT,
+   ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
+   ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
+   ETHTOOL_LINK_MODE_1000baseKX_Full_BI

[ethtool PATCH v6 1/2] ethtool.c: add support for ETHTOOL_xLINKSETTINGS ioctls

2016-03-21 Thread David Decotigny
From: David Decotigny <de...@googlers.com>

More info with kernel commit 8d3f2806f8fb ("Merge branch
'ethtool-ksettings'").

Note: The new features implemented in this patch depend on kernel
commit 793cf87de9d1 ("Set cmd field in ETHTOOL_GLINKSETTINGS response to
wrong nwords").


Signed-off-by: David Decotigny <de...@googlers.com>
---
 ethtool.c  | 681 -
 internal.h |  67 ++
 test-cmdline.c |  13 ++
 3 files changed, 603 insertions(+), 158 deletions(-)

diff --git a/ethtool.c b/ethtool.c
index 0cd0d4f..cb3d971 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -47,42 +47,6 @@
 #define MAX_ADDR_LEN   32
 #endif
 
-#define ALL_ADVERTISED_MODES   \
-   (ADVERTISED_10baseT_Half |  \
-ADVERTISED_10baseT_Full |  \
-ADVERTISED_100baseT_Half | \
-ADVERTISED_100baseT_Full | \
-ADVERTISED_1000baseT_Half |\
-ADVERTISED_1000baseT_Full |\
-ADVERTISED_1000baseKX_Full|\
-ADVERTISED_2500baseX_Full |\
-ADVERTISED_1baseT_Full |   \
-ADVERTISED_1baseKX4_Full | \
-ADVERTISED_1baseKR_Full |  \
-ADVERTISED_1baseR_FEC |\
-ADVERTISED_2baseMLD2_Full |\
-ADVERTISED_2baseKR2_Full | \
-ADVERTISED_4baseKR4_Full | \
-ADVERTISED_4baseCR4_Full | \
-ADVERTISED_4baseSR4_Full | \
-ADVERTISED_4baseLR4_Full | \
-ADVERTISED_56000baseKR4_Full | \
-ADVERTISED_56000baseCR4_Full | \
-ADVERTISED_56000baseSR4_Full | \
-ADVERTISED_56000baseLR4_Full)
-
-#define ALL_ADVERTISED_FLAGS   \
-   (ADVERTISED_Autoneg |   \
-ADVERTISED_TP |\
-ADVERTISED_AUI |   \
-ADVERTISED_MII |   \
-ADVERTISED_FIBRE | \
-ADVERTISED_BNC |   \
-ADVERTISED_Pause | \
-ADVERTISED_Asym_Pause |\
-ADVERTISED_Backplane | \
-ALL_ADVERTISED_MODES)
-
 #ifndef HAVE_NETIF_MSG
 enum {
NETIF_MSG_DRV   = 0x0001,
@@ -293,6 +257,43 @@ static void get_mac_addr(char *src, unsigned char *dest)
}
 }
 
+static int parse_hex_u32_bitmap(const char *s,
+   unsigned int nbits, u32 *result)
+{
+   const unsigned int nwords = __KERNEL_DIV_ROUND_UP(nbits, 32);
+   size_t slen = strlen(s);
+   size_t i;
+
+   /* ignore optional '0x' prefix */
+   if ((slen > 2) && (strncasecmp(s, "0x", 2) == 0)) {
+   slen -= 2;
+   s += 2;
+   }
+
+   if (slen > 8 * nwords)  /* up to 2 digits per byte */
+   return -1;
+
+   memset(result, 0, 4 * nwords);
+   for (i = 0 ; i < slen ; ++i) {
+   const unsigned int shift = (slen - 1 - i) * 4;
+   u32 *dest = [shift / 32];
+   u32 nibble;
+
+   if ('a' <= s[i] && s[i] <= 'f')
+   nibble = 0xa + (s[i] - 'a');
+   else if ('A' <= s[i] && s[i] <= 'F')
+   nibble = 0xa + (s[i] - 'A');
+   else if ('0' <= s[i] && s[i] <= '9')
+   nibble = (s[i] - '0');
+   else
+   return -1;
+
+   *dest |= (nibble << (shift % 32));
+   }
+
+   return 0;
+}
+
 static void parse_generic_cmdline(struct cmd_context *ctx,
  int *changed,
  struct cmdline_info *info,
@@ -472,64 +473,157 @@ static int do_version(struct cmd_context *ctx)
return 0;
 }
 
-static void dump_link_caps(const char *prefix, const char *an_prefix, u32 mask,
-  int link_mode_only);
+/* link mode routines */
 
-static void dump_supported(struct ethtool_cmd *ep)
+static __ETHTOOL_DECLARE_LINK_MODE_MASK(all_advertised_modes);
+static __ETHTOOL_DECLARE_LINK_MODE_MASK(all_advertised_flags);
+
+static void init_global_link_mode_masks(void)
 {
-   u32 mask = ep->supported;
+   static const enum ethtool_link_mode_bit_indices
+   all_advertised_modes_bits[] = {
+   ETHTOOL_LINK_MODE_10baseT_Half_BIT,
+   ETHTOOL_LINK_MODE_10baseT_Full_BIT,
+   ETHTOOL_LINK_MODE_100baseT_Half_BIT,
+   ETHTOOL_LINK_MODE_100baseT_Full_BIT,
+   ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
+   ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
+   ETHTOOL_LINK_MODE_1000baseKX_Full_BI

[ethtool PATCH v6 2/2] ethtool: use netlink socket when AF_INET not available

2016-03-21 Thread David Decotigny
From: David Decotigny <de...@googlers.com>


Signed-off-by: David Decotigny <de...@googlers.com>
---
 configure.ac | 2 +-
 ethtool.c| 7 +++
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/configure.ac b/configure.ac
index 3105415..47d2a0f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -15,7 +15,7 @@ AM_PROG_CC_C_O
 dnl Checks for libraries.
 
 dnl Checks for header files.
-AC_CHECK_HEADERS(sys/ioctl.h)
+AC_CHECK_HEADERS(sys/ioctl.h linux/netlink.h)
 
 dnl Checks for typedefs, structures, and compiler characteristics.
 AC_MSG_CHECKING([whether  defines big-endian types])
diff --git a/ethtool.c b/ethtool.c
index cb3d971..314b1b8 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -42,6 +42,9 @@
 #include 
 
 #include 
+#ifdef HAVE_LINUX_NETLINK_H
+# include 
+#endif
 
 #ifndef MAX_ADDR_LEN
 #define MAX_ADDR_LEN   32
@@ -4645,6 +4648,10 @@ opt_found:
 
/* Open control socket. */
ctx.fd = socket(AF_INET, SOCK_DGRAM, 0);
+#ifdef HAVE_LINUX_NETLINK_H
+   if (ctx.fd < 0)
+   ctx.fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
+#endif
if (ctx.fd < 0) {
perror("Cannot get control socket");
return 70;
-- 
2.8.0.rc3.226.g39d4020



[PATCH net-next v2 0/2] basic ioctl support for netlink sockets

2016-03-21 Thread David Decotigny
From: David Decotigny <de...@googlers.com>

This removes the requirement that ethtool be tied to the support
of a specific L3 protocol, also updates a comment.

History:
  v2
updated commit description for the netlink ioctl patch
  v1
initial submission


# Patch Set Summary:

David Decotigny (2):
  ethtool: minor doc update
  netlink: add support for NIC driver ioctls

 include/uapi/linux/ethtool.h |  6 +++---
 net/netlink/af_netlink.c | 10 +-
 2 files changed, 12 insertions(+), 4 deletions(-)

-- 
2.8.0.rc3.226.g39d4020



[PATCH net-next v2 1/2] ethtool: minor doc update

2016-03-21 Thread David Decotigny
From: David Decotigny <de...@googlers.com>

Updates: commit 793cf87de9d1 ("ethtool: Set cmd field in
 ETHTOOL_GLINKSETTINGS response to wrong nwords")

Signed-off-by: David Decotigny <de...@googlers.com>
---
 include/uapi/linux/ethtool.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/include/uapi/linux/ethtool.h b/include/uapi/linux/ethtool.h
index 2835b07..9222db8 100644
--- a/include/uapi/linux/ethtool.h
+++ b/include/uapi/linux/ethtool.h
@@ -1648,9 +1648,9 @@ enum ethtool_reset_flags {
  * %ETHTOOL_GLINKSETTINGS: on entry, number of words passed by user
  * (>= 0); on return, if handshake in progress, negative if
  * request size unsupported by kernel: absolute value indicates
- * kernel recommended size and cmd field is 0, as well as all the
- * other fields; otherwise (handshake completed), strictly
- * positive to indicate size used by kernel and cmd field is
+ * kernel expected size and all the other fields but cmd
+ * are 0; otherwise (handshake completed), strictly positive
+ * to indicate size used by kernel and cmd field stays
  * %ETHTOOL_GLINKSETTINGS, all other fields populated by driver. For
  * %ETHTOOL_SLINKSETTINGS: must be valid on entry, ie. a positive
  * value returned previously by %ETHTOOL_GLINKSETTINGS, otherwise
-- 
2.8.0.rc3.226.g39d4020



[PATCH net-next v2 2/2] netlink: add support for NIC driver ioctls

2016-03-21 Thread David Decotigny
From: David Decotigny <de...@googlers.com>

By returning -ENOIOCTLCMD, sock_do_ioctl() falls back to calling
dev_ioctl(), which provides support for NIC driver ioctls, which
includes ethtool support. This is similar to the way ioctls are handled
in udp.c or tcp.c.

This removes the requirement that ethtool for example be tied to the
support of a specific L3 protocol (ethtool uses an AF_INET socket
today).

Signed-off-by: David Decotigny <de...@googlers.com>
---
 net/netlink/af_netlink.c | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index c841679..215fc08 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -1033,6 +1033,14 @@ static int netlink_getname(struct socket *sock, struct 
sockaddr *addr,
return 0;
 }
 
+static int netlink_ioctl(struct socket *sock, unsigned int cmd,
+unsigned long arg)
+{
+   /* try to hand this ioctl down to the NIC drivers.
+*/
+   return -ENOIOCTLCMD;
+}
+
 static struct sock *netlink_getsockbyportid(struct sock *ssk, u32 portid)
 {
struct sock *sock;
@@ -2494,7 +2502,7 @@ static const struct proto_ops netlink_ops = {
.accept =   sock_no_accept,
.getname =  netlink_getname,
.poll = datagram_poll,
-   .ioctl =sock_no_ioctl,
+   .ioctl =netlink_ioctl,
.listen =   sock_no_listen,
.shutdown = sock_no_shutdown,
.setsockopt =   netlink_setsockopt,
-- 
2.8.0.rc3.226.g39d4020



[PATCH v1 2/2] netlink: add support for NIC driver ioctls

2016-03-19 Thread David Decotigny
From: David Decotigny <de...@googlers.com>

This patch removes the requirement that ethtool be tied to the support
of a specific L3 protocol (ethtool uses an AF_INET socket today).

Signed-off-by: David Decotigny <de...@googlers.com>
---
 net/netlink/af_netlink.c | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index c841679..215fc08 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -1033,6 +1033,14 @@ static int netlink_getname(struct socket *sock, struct 
sockaddr *addr,
return 0;
 }
 
+static int netlink_ioctl(struct socket *sock, unsigned int cmd,
+unsigned long arg)
+{
+   /* try to hand this ioctl down to the NIC drivers.
+*/
+   return -ENOIOCTLCMD;
+}
+
 static struct sock *netlink_getsockbyportid(struct sock *ssk, u32 portid)
 {
struct sock *sock;
@@ -2494,7 +2502,7 @@ static const struct proto_ops netlink_ops = {
.accept =   sock_no_accept,
.getname =  netlink_getname,
.poll = datagram_poll,
-   .ioctl =sock_no_ioctl,
+   .ioctl =netlink_ioctl,
.listen =   sock_no_listen,
.shutdown = sock_no_shutdown,
.setsockopt =   netlink_setsockopt,
-- 
2.8.0.rc3.226.g39d4020



[PATCH v1 0/2] basic ioctl support for netlink sockets

2016-03-19 Thread David Decotigny
From: David Decotigny <de...@googlers.com>

This removes the requirement that ethtool be tied to the support
of a specific L3 protocol, also updates a comment.


# Patch Set Summary:

David Decotigny (2):
  ethtool: minor doc update
  netlink: add support for NIC driver ioctls

 include/uapi/linux/ethtool.h |  6 +++---
 net/netlink/af_netlink.c | 10 +-
 2 files changed, 12 insertions(+), 4 deletions(-)

-- 
2.8.0.rc3.226.g39d4020



[PATCH v1 1/2] ethtool: minor doc update

2016-03-19 Thread David Decotigny
From: David Decotigny <de...@googlers.com>

Updates: commit 793cf87de9d1 ("ethtool: Set cmd field in
 ETHTOOL_GLINKSETTINGS response to wrong nwords")

Signed-off-by: David Decotigny <de...@googlers.com>
---
 include/uapi/linux/ethtool.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/include/uapi/linux/ethtool.h b/include/uapi/linux/ethtool.h
index 2835b07..9222db8 100644
--- a/include/uapi/linux/ethtool.h
+++ b/include/uapi/linux/ethtool.h
@@ -1648,9 +1648,9 @@ enum ethtool_reset_flags {
  * %ETHTOOL_GLINKSETTINGS: on entry, number of words passed by user
  * (>= 0); on return, if handshake in progress, negative if
  * request size unsupported by kernel: absolute value indicates
- * kernel recommended size and cmd field is 0, as well as all the
- * other fields; otherwise (handshake completed), strictly
- * positive to indicate size used by kernel and cmd field is
+ * kernel expected size and all the other fields but cmd
+ * are 0; otherwise (handshake completed), strictly positive
+ * to indicate size used by kernel and cmd field stays
  * %ETHTOOL_GLINKSETTINGS, all other fields populated by driver. For
  * %ETHTOOL_SLINKSETTINGS: must be valid on entry, ie. a positive
  * value returned previously by %ETHTOOL_GLINKSETTINGS, otherwise
-- 
2.8.0.rc3.226.g39d4020



Re: [ethtool PATCH v4 10/11] ethtool.c: add support for ETHTOOL_xLINKSETTINGS ioctls

2016-03-15 Thread David Decotigny
Please note that v5 patch depends on Ben Hutchings'
http://patchwork.ozlabs.org/patch/596879/ to make any sense.

On Tue, Mar 15, 2016 at 4:42 PM, David Decotigny <ddeco...@gmail.com> wrote:
> Just sent v5 of the series: now only this patch left. Applied all your
> suggestions.
>
> Many thanks for the 2 bugs you caught, path was not covered by my
> tests. v5 was tested on a 10G nic with: ethtool -s eth1 msglvl 0x15
> speed 1 duplex full
>
> On Sun, Mar 13, 2016 at 6:32 PM, Ben Hutchings <b...@decadent.org.uk> wrote:
>> On Fri, 2016-03-11 at 09:58 -0800, David Decotigny wrote:
>> [...]
>>> +static int parse_hex_u32_bitmap(const char *s,
>>> + unsigned int nbits, u32 *result)
>>> +{
>>> + const unsigned nwords = __KERNEL_DIV_ROUND_UP(nbits, 32);
>>> + size_t slen = strlen(s);
>>> + size_t i;
>>> +
>>> + /* ignore optional '0x' prefix */
>>> + if ((slen > 2) && (
>>> + (0 == memcmp(s, "0x", 2)
>>> +  || (0 == memcmp(s, "0X", 2) {
>>
>> memcmp() is a really poor tool for comparing strings.  You should use
>> strncasecmp() here.
>
> done.
>
>>
>>> + slen -= 2;
>>> + s += 2;
>>> + }
>>> +
>>> + if (slen > 8*nwords)  /* up to 2 digits per byte */
>>
>> The '*' operator should have spaces around it.  Please run
>> checkpatch.pl over your ethtool patches to catch style errors like this
>> (there are many others in this one).
>
> both done. a few new lines over 80 chars that I prefer to keep,
> otherwise line break would make code harder to read imho.
>
>>
>> [...]
>>> +static void dump_link_caps(const char *prefix, const char *an_prefix,
>>> +const u32 *mask, int link_mode_only)
>>>  {
>>>   static const struct {
>>>   int same_line; /* print on same line as previous */
>>> - u32 value;
>>> + unsigned bit_indice;
>>
>> bit_index
>
> done.
>
>>
>> [...]
>>> @@ -558,51 +655,57 @@ dump_link_caps(const char *prefix, const char 
>>> *an_prefix, u32 mask,
>>>   }
>>>   }
>>>   if (did1 == 0)
>>> -  fprintf(stdout, "Not reported");
>>> + fprintf(stdout, "Not reported");
>>
>> Good catch, but whitespace fixes belong in another patch.
>
> removed for now.
>
>>
>> [...]
>>
>>> @@ -2248,10 +2360,219 @@ static int do_sfeatures(struct cmd_context *ctx)
>>>   return 0;
>>>  }
>>>
>>> -static int do_gset(struct cmd_context *ctx)
>>> +static struct ethtool_link_usettings *
>>> +__do_ioctl_glinksettings(struct cmd_context * ctx)
>>> +{
>>> + int err;
>>> + struct {
>>> + struct ethtool_link_settings req;
>>> + __u32 
>>> link_mode_data[3*__ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NU32];
>>> + } ecmd;
>>> + struct ethtool_link_usettings *link_usettings;
>>> + unsigned u32_offs;
>>> +
>>> + /* handshake with kernel to determine number of words for link
>>> +  * mode bitmaps */
>>> + memset(, 0, sizeof(ecmd));
>>> + ecmd.req.cmd = ETHTOOL_GLINKSETTINGS;
>>> + err = send_ioctl(ctx, );
>>> + if (err < 0)
>>> + return NULL;
>>> +
>>> + if (ecmd.req.link_mode_masks_nwords >= 0 || ecmd.req.cmd)
>>> + return NULL;
>>
>> Oops, I missed the kernel side of this.  Clearing the cmd field is a
>> very strange thing to do and inconsistent with every other ethtool
>> command, so I've just sent a patch to change the kernel side of that.
>> You'll need to change this to match.
>>
>> (I also think the negative size is a bit weird, but don't feel so
>> strongly about it.)
>
> updated based on your patch. sent a suggestion
> http://marc.info/?l=linux-netdev=145806871332416 , looks like it was
> not added properly to the thread, because I don't see it as a reply to
> your patch in patchwork. sorry about this.
>
>>
>> [...]
>>> + link_usettings = malloc(sizeof(*link_usettings));
>>> + if (NULL == link_usettings)
>>
>> Comparison is the wrong way round.
>
> done.
>
>>
>>> + return NULL;
>>> +
>>> + mem

Re: [ethtool PATCH v4 10/11] ethtool.c: add support for ETHTOOL_xLINKSETTINGS ioctls

2016-03-15 Thread David Decotigny
Just sent v5 of the series: now only this patch left. Applied all your
suggestions.

Many thanks for the 2 bugs you caught, path was not covered by my
tests. v5 was tested on a 10G nic with: ethtool -s eth1 msglvl 0x15
speed 1 duplex full

On Sun, Mar 13, 2016 at 6:32 PM, Ben Hutchings <b...@decadent.org.uk> wrote:
> On Fri, 2016-03-11 at 09:58 -0800, David Decotigny wrote:
> [...]
>> +static int parse_hex_u32_bitmap(const char *s,
>> + unsigned int nbits, u32 *result)
>> +{
>> + const unsigned nwords = __KERNEL_DIV_ROUND_UP(nbits, 32);
>> + size_t slen = strlen(s);
>> + size_t i;
>> +
>> + /* ignore optional '0x' prefix */
>> + if ((slen > 2) && (
>> + (0 == memcmp(s, "0x", 2)
>> +  || (0 == memcmp(s, "0X", 2) {
>
> memcmp() is a really poor tool for comparing strings.  You should use
> strncasecmp() here.

done.

>
>> + slen -= 2;
>> + s += 2;
>> + }
>> +
>> + if (slen > 8*nwords)  /* up to 2 digits per byte */
>
> The '*' operator should have spaces around it.  Please run
> checkpatch.pl over your ethtool patches to catch style errors like this
> (there are many others in this one).

both done. a few new lines over 80 chars that I prefer to keep,
otherwise line break would make code harder to read imho.

>
> [...]
>> +static void dump_link_caps(const char *prefix, const char *an_prefix,
>> +const u32 *mask, int link_mode_only)
>>  {
>>   static const struct {
>>   int same_line; /* print on same line as previous */
>> - u32 value;
>> + unsigned bit_indice;
>
> bit_index

done.

>
> [...]
>> @@ -558,51 +655,57 @@ dump_link_caps(const char *prefix, const char 
>> *an_prefix, u32 mask,
>>   }
>>   }
>>   if (did1 == 0)
>> -  fprintf(stdout, "Not reported");
>> + fprintf(stdout, "Not reported");
>
> Good catch, but whitespace fixes belong in another patch.

removed for now.

>
> [...]
>
>> @@ -2248,10 +2360,219 @@ static int do_sfeatures(struct cmd_context *ctx)
>>   return 0;
>>  }
>>
>> -static int do_gset(struct cmd_context *ctx)
>> +static struct ethtool_link_usettings *
>> +__do_ioctl_glinksettings(struct cmd_context * ctx)
>> +{
>> + int err;
>> + struct {
>> + struct ethtool_link_settings req;
>> + __u32 
>> link_mode_data[3*__ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NU32];
>> + } ecmd;
>> + struct ethtool_link_usettings *link_usettings;
>> + unsigned u32_offs;
>> +
>> + /* handshake with kernel to determine number of words for link
>> +  * mode bitmaps */
>> + memset(, 0, sizeof(ecmd));
>> + ecmd.req.cmd = ETHTOOL_GLINKSETTINGS;
>> + err = send_ioctl(ctx, );
>> + if (err < 0)
>> + return NULL;
>> +
>> + if (ecmd.req.link_mode_masks_nwords >= 0 || ecmd.req.cmd)
>> + return NULL;
>
> Oops, I missed the kernel side of this.  Clearing the cmd field is a
> very strange thing to do and inconsistent with every other ethtool
> command, so I've just sent a patch to change the kernel side of that.
> You'll need to change this to match.
>
> (I also think the negative size is a bit weird, but don't feel so
> strongly about it.)

updated based on your patch. sent a suggestion
http://marc.info/?l=linux-netdev=145806871332416 , looks like it was
not added properly to the thread, because I don't see it as a reply to
your patch in patchwork. sorry about this.

>
> [...]
>> + link_usettings = malloc(sizeof(*link_usettings));
>> + if (NULL == link_usettings)
>
> Comparison is the wrong way round.

done.

>
>> + return NULL;
>> +
>> + memset(link_usettings, 0, sizeof(*link_usettings));
>
> Could use calloc() instead of malloc() + memset().

done.

>
>> + /* keep transceiver 0 */
>> + memcpy(_usettings->base, , sizeof(link_usettings->base));
>> + /* remember that ETHTOOL_GLINKSETTINGS was used */
>> + link_usettings->base.cmd = ETHTOOL_GLINKSETTINGS;
>
> This is redundant as we know that ecmd.req.cmd ==
> ETHTOOL_GLINKSETTINGS.

done.

>
> [...]
>> +static struct ethtool_link_usettings *
>> +__do_ioctl_gset(struct cmd_context * ctx)
>>  {
> [...]
>> + link_usettings->base.link_mode_masks_nwords = 1;
>> + link_usettings->link_mode

[ethtool PATCH v5] ethtool.c: add support for ETHTOOL_xLINKSETTINGS ioctls

2016-03-15 Thread David Decotigny
From: David Decotigny <de...@googlers.com>

More info with kernel commit 8d3f2806f8fb ("Merge branch
'ethtool-ksettings'").


Signed-off-by: David Decotigny <de...@googlers.com>
---
 ethtool.c  | 681 -
 internal.h |  67 ++
 test-cmdline.c |  13 ++
 3 files changed, 603 insertions(+), 158 deletions(-)

diff --git a/ethtool.c b/ethtool.c
index 0cd0d4f..dbe4a6a 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -47,42 +47,6 @@
 #define MAX_ADDR_LEN   32
 #endif
 
-#define ALL_ADVERTISED_MODES   \
-   (ADVERTISED_10baseT_Half |  \
-ADVERTISED_10baseT_Full |  \
-ADVERTISED_100baseT_Half | \
-ADVERTISED_100baseT_Full | \
-ADVERTISED_1000baseT_Half |\
-ADVERTISED_1000baseT_Full |\
-ADVERTISED_1000baseKX_Full|\
-ADVERTISED_2500baseX_Full |\
-ADVERTISED_1baseT_Full |   \
-ADVERTISED_1baseKX4_Full | \
-ADVERTISED_1baseKR_Full |  \
-ADVERTISED_1baseR_FEC |\
-ADVERTISED_2baseMLD2_Full |\
-ADVERTISED_2baseKR2_Full | \
-ADVERTISED_4baseKR4_Full | \
-ADVERTISED_4baseCR4_Full | \
-ADVERTISED_4baseSR4_Full | \
-ADVERTISED_4baseLR4_Full | \
-ADVERTISED_56000baseKR4_Full | \
-ADVERTISED_56000baseCR4_Full | \
-ADVERTISED_56000baseSR4_Full | \
-ADVERTISED_56000baseLR4_Full)
-
-#define ALL_ADVERTISED_FLAGS   \
-   (ADVERTISED_Autoneg |   \
-ADVERTISED_TP |\
-ADVERTISED_AUI |   \
-ADVERTISED_MII |   \
-ADVERTISED_FIBRE | \
-ADVERTISED_BNC |   \
-ADVERTISED_Pause | \
-ADVERTISED_Asym_Pause |\
-ADVERTISED_Backplane | \
-ALL_ADVERTISED_MODES)
-
 #ifndef HAVE_NETIF_MSG
 enum {
NETIF_MSG_DRV   = 0x0001,
@@ -293,6 +257,43 @@ static void get_mac_addr(char *src, unsigned char *dest)
}
 }
 
+static int parse_hex_u32_bitmap(const char *s,
+   unsigned int nbits, u32 *result)
+{
+   const unsigned nwords = __KERNEL_DIV_ROUND_UP(nbits, 32);
+   size_t slen = strlen(s);
+   size_t i;
+
+   /* ignore optional '0x' prefix */
+   if ((slen > 2) && (strncasecmp(s, "0x", 2) == 0)) {
+   slen -= 2;
+   s += 2;
+   }
+
+   if (slen > 8 * nwords)  /* up to 2 digits per byte */
+   return -1;
+
+   memset(result, 0, 4 * nwords);
+   for (i = 0 ; i < slen ; ++i) {
+   const unsigned shift = (slen - 1 - i) * 4;
+   u32 *dest = [shift / 32];
+   u32 nibble;
+
+   if ('a' <= s[i] && s[i] <= 'f')
+   nibble = 0xa + (s[i] - 'a');
+   else if ('A' <= s[i] && s[i] <= 'F')
+   nibble = 0xa + (s[i] - 'A');
+   else if ('0' <= s[i] && s[i] <= '9')
+   nibble = (s[i] - '0');
+   else
+   return -1;
+
+   *dest |= (nibble << (shift % 32));
+   }
+
+   return 0;
+}
+
 static void parse_generic_cmdline(struct cmd_context *ctx,
  int *changed,
  struct cmdline_info *info,
@@ -472,64 +473,157 @@ static int do_version(struct cmd_context *ctx)
return 0;
 }
 
-static void dump_link_caps(const char *prefix, const char *an_prefix, u32 mask,
-  int link_mode_only);
+/* link mode routines */
 
-static void dump_supported(struct ethtool_cmd *ep)
+static __ETHTOOL_DECLARE_LINK_MODE_MASK(all_advertised_modes);
+static __ETHTOOL_DECLARE_LINK_MODE_MASK(all_advertised_flags);
+
+static void init_global_link_mode_masks(void)
 {
-   u32 mask = ep->supported;
+   static const enum ethtool_link_mode_bit_indices
+   all_advertised_modes_bits[] = {
+   ETHTOOL_LINK_MODE_10baseT_Half_BIT,
+   ETHTOOL_LINK_MODE_10baseT_Full_BIT,
+   ETHTOOL_LINK_MODE_100baseT_Half_BIT,
+   ETHTOOL_LINK_MODE_100baseT_Full_BIT,
+   ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
+   ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
+   ETHTOOL_LINK_MODE_1000baseKX_Full_BIT,
+   ETHTOOL_LINK_MODE_2500baseX_Full_BIT,
+   ETHTOOL_LINK_MODE_1baseT_Full_BIT,
+   ETHTOOL_LINK_MODE_1baseKX4_Full_BIT,
+   

Re: [ethtool PATCH v4 11/11] ethtool.c: support absence of v4 sockets

2016-03-15 Thread David Decotigny
will send a v5 shortly without this patch: question below.

about this patch: this is in prevision of a world where INET can be
compiled out. So it is not something that matters today with current
kernels.

Now, as you mentioned in another patch, the only socket that survives
various reasonable CONFIG_* gymnastics is netlink. So even though
non-IPv4 kernels with IP support is not feasible today, I believe
there is some logic to using netlink sockets for ethtool purposes,
instead of IPv4 or IPv6 sockets. Shall I propose a patch to add
ethtool support on AF_NETLINK sockets, and update the tool to try
AF_INET first for backward compatibility reasons, then fallback to
AF_NETLINK?

On Sun, Mar 13, 2016 at 10:24 AM, Ben Hutchings <b...@decadent.org.uk> wrote:
> On Fri, 2016-03-11 at 09:58 -0800, David Decotigny wrote:
>> From: David Decotigny <de...@googlers.com>
>>
>>
>> Signed-off-by: David Decotigny <de...@googlers.com>
>> ---
>>  ethtool.c | 3 +++
>>  1 file changed, 3 insertions(+)
>>
>> diff --git a/ethtool.c b/ethtool.c
>> index 761252f..f9336e3 100644
>> --- a/ethtool.c
>> +++ b/ethtool.c
>> @@ -4615,6 +4615,9 @@ opt_found:
>>   /* Open control socket. */
>>   ctx.fd = socket(AF_INET, SOCK_DGRAM, 0);
>>   if (ctx.fd < 0) {
>> + ctx.fd = socket(AF_UNIX, SOCK_DGRAM, 0);
>> + }
>
> You still haven't answered whether this is a real problem on Linux.
>
> Ben.
>
>> + if (ctx.fd < 0) {
>>   perror("Cannot get control socket");
>>   return 70;
>>   }
> --
> Ben Hutchings
> If at first you don't succeed, you're doing about average.


Re: [PATCH net-next] ethtool: Set cmd field in ETHTOOL_GLINKSETTINGS response to wrong nwords

2016-03-15 Thread david decotigny
Ben Hutchings  decadent.org.uk> writes:
> 
> When the ETHTOOL_GLINKSETTINGS implementation finds that userland is
> using the wrong number of words of link mode bitmaps (or is trying to
> find out the right numbers) it sets the cmd field to 0 in the response
> structure.
> 
> This is inconsistent with the implementation of every other ethtool
> command, so let's remove that inconsistency before it gets into a
> stable release.
> 
> Fixes: 3f1ac7a700d03 ("net: ethtool: add new ETHTOOL_xLINKSETTINGS API")
> Signed-off-by: Ben Hutchings  decadent.org.uk>
> ---
> David, please can you include this in changes for 4.6?
> 
> Ben.
> 
>  net/core/ethtool.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/net/core/ethtool.c b/net/core/ethtool.c
> index 2966cd0d7c93..f426c5ad6149 100644
> --- a/net/core/ethtool.c
> +++ b/net/core/ethtool.c
>  -655,7 +655,7  static int 
ethtool_get_link_ksettings(struct net_device *dev,
>   != link_ksettings.base.link_mode_masks_nwords) {
>   /* wrong link mode nbits requested */
>   memset(_ksettings, 0, sizeof(link_ksettings));
> - /* keep cmd field reset to 0 */
> + link_ksettings.base.cmd = ETHTOOL_GLINKSETTINGS;
>   /* send back number of words required as negative val */
>   compiletime_assert(__ETHTOOL_LINK_MODE_MASK_NU32 <= S8_MAX,
>  "need too many bits for link modes!");
> 

thanks!

Please also update the comments in ethtool.h, proposed change below:

diff --git a/include/uapi/linux/ethtool.h b/include/uapi/linux/ethtool.h
index 2835b07..9222db8 100644
--- a/include/uapi/linux/ethtool.h
+++ b/include/uapi/linux/ethtool.h
@@ -1648,9 +1648,9 @@ enum ethtool_reset_flags {
  * %ETHTOOL_GLINKSETTINGS: on entry, number of words passed by user
  * (>= 0); on return, if handshake in progress, negative if
  * request size unsupported by kernel: absolute value indicates
- * kernel recommended size and cmd field is 0, as well as all the
- * other fields; otherwise (handshake completed), strictly
- * positive to indicate size used by kernel and cmd field is
+ * kernel expected size and all the other fields but cmd
+ * are 0; otherwise (handshake completed), strictly positive
+ * to indicate size used by kernel and cmd field stays
  * %ETHTOOL_GLINKSETTINGS, all other fields populated by driver. For
  * %ETHTOOL_SLINKSETTINGS: must be valid on entry, ie. a positive
  * value returned previously by %ETHTOOL_GLINKSETTINGS, otherwise




[ethtool PATCH v4 04/11] ethtool.c: do_seeprom checks for params & stdin sanity

2016-03-11 Thread David Decotigny
From: David Decotigny <de...@googlers.com>

Tested:
  On qemu e1000:
  $ dd if=/dev/zero bs=2 count=5 | /mnt/ethtool -E eth0 length 9
  too much data from stdin
  $ dd if=/dev/zero bs=2 count=5 | /mnt/ethtool -E eth0 length 11
  not enough data from stdin
  $ dd if=/dev/zero bs=2 count=5 | /mnt/ethtool -E eth0 length 10
  Cannot set EEPROM data: Bad address


Signed-off-by: David Decotigny <de...@googlers.com>
---
 ethtool.c | 20 
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/ethtool.c b/ethtool.c
index 7c2b5cb..d349bee 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -2828,8 +2828,10 @@ static int do_seeprom(struct cmd_context *ctx)
if (seeprom_length == -1)
seeprom_length = drvinfo.eedump_len;
 
-   if (drvinfo.eedump_len < seeprom_offset + seeprom_length)
-   seeprom_length = drvinfo.eedump_len - seeprom_offset;
+   if (drvinfo.eedump_len < seeprom_offset + seeprom_length) {
+   fprintf(stderr, "offset & length out of bounds\n");
+   return 1;
+   }
 
eeprom = calloc(1, sizeof(*eeprom)+seeprom_length);
if (!eeprom) {
@@ -2844,8 +2846,18 @@ static int do_seeprom(struct cmd_context *ctx)
eeprom->data[0] = seeprom_value;
 
/* Multi-byte write: read input from stdin */
-   if (!seeprom_value_seen)
-   eeprom->len = fread(eeprom->data, 1, eeprom->len, stdin);
+   if (!seeprom_value_seen) {
+   if (1 != fread(eeprom->data, eeprom->len, 1, stdin)) {
+   fprintf(stderr, "not enough data from stdin\n");
+   free(eeprom);
+   return 75;
+   }
+   if ((fgetc(stdin) != EOF) || !feof(stdin)) {
+   fprintf(stderr, "too much data from stdin\n");
+   free(eeprom);
+   return 75;
+   }
+   }
 
err = send_ioctl(ctx, eeprom);
if (err < 0) {
-- 
2.7.0.rc3.207.g0ac5344



[ethtool PATCH v4 02/11] ethtool.c: don't ignore fread() return value

2016-03-11 Thread David Decotigny
From: David Decotigny <de...@googlers.com>

This addresses:
  ethtool.c:1116:8: warning: ignoring return value of ‘fread’, declared with 
attribute warn_unused_result [-Wunused-result]


Signed-off-by: David Decotigny <de...@googlers.com>
---
 ethtool.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/ethtool.c b/ethtool.c
index 92c40b8..9f80d5f 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -1007,6 +1007,7 @@ static int dump_regs(int gregs_dump_raw, int 
gregs_dump_hex,
if (gregs_dump_file) {
FILE *f = fopen(gregs_dump_file, "r");
struct stat st;
+   size_t nread;
 
if (!f || fstat(fileno(f), ) < 0) {
fprintf(stderr, "Can't open '%s': %s\n",
@@ -1016,8 +1017,10 @@ static int dump_regs(int gregs_dump_raw, int 
gregs_dump_hex,
 
regs = realloc(regs, sizeof(*regs) + st.st_size);
regs->len = st.st_size;
-   fread(regs->data, regs->len, 1, f);
+   nread = fread(regs->data, regs->len, 1, f);
fclose(f);
+   if (nread != 1)
+   return -1;
}
 
if (!gregs_dump_hex)
-- 
2.7.0.rc3.207.g0ac5344



[ethtool PATCH v4 10/11] ethtool.c: add support for ETHTOOL_xLINKSETTINGS ioctls

2016-03-11 Thread David Decotigny
From: David Decotigny <de...@googlers.com>

More info with kernel SHA1: 8d3f2806f8fbd9b22 "Merge branch
'ethtool-ksettings'".


Signed-off-by: David Decotigny <de...@googlers.com>
---
 ethtool.c  | 682 +++--
 internal.h |  67 ++
 test-cmdline.c |  12 +
 3 files changed, 602 insertions(+), 159 deletions(-)

diff --git a/ethtool.c b/ethtool.c
index 47f0259..761252f 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -47,42 +47,6 @@
 #define MAX_ADDR_LEN   32
 #endif
 
-#define ALL_ADVERTISED_MODES   \
-   (ADVERTISED_10baseT_Half |  \
-ADVERTISED_10baseT_Full |  \
-ADVERTISED_100baseT_Half | \
-ADVERTISED_100baseT_Full | \
-ADVERTISED_1000baseT_Half |\
-ADVERTISED_1000baseT_Full |\
-ADVERTISED_1000baseKX_Full|\
-ADVERTISED_2500baseX_Full |\
-ADVERTISED_1baseT_Full |   \
-ADVERTISED_1baseKX4_Full | \
-ADVERTISED_1baseKR_Full |  \
-ADVERTISED_1baseR_FEC |\
-ADVERTISED_2baseMLD2_Full |\
-ADVERTISED_2baseKR2_Full | \
-ADVERTISED_4baseKR4_Full | \
-ADVERTISED_4baseCR4_Full | \
-ADVERTISED_4baseSR4_Full | \
-ADVERTISED_4baseLR4_Full | \
-ADVERTISED_56000baseKR4_Full | \
-ADVERTISED_56000baseCR4_Full | \
-ADVERTISED_56000baseSR4_Full | \
-ADVERTISED_56000baseLR4_Full)
-
-#define ALL_ADVERTISED_FLAGS   \
-   (ADVERTISED_Autoneg |   \
-ADVERTISED_TP |\
-ADVERTISED_AUI |   \
-ADVERTISED_MII |   \
-ADVERTISED_FIBRE | \
-ADVERTISED_BNC |   \
-ADVERTISED_Pause | \
-ADVERTISED_Asym_Pause |\
-ADVERTISED_Backplane | \
-ALL_ADVERTISED_MODES)
-
 #ifndef HAVE_NETIF_MSG
 enum {
NETIF_MSG_DRV   = 0x0001,
@@ -294,6 +258,45 @@ static void get_mac_addr(char *src, unsigned char *dest)
}
 }
 
+static int parse_hex_u32_bitmap(const char *s,
+   unsigned int nbits, u32 *result)
+{
+   const unsigned nwords = __KERNEL_DIV_ROUND_UP(nbits, 32);
+   size_t slen = strlen(s);
+   size_t i;
+
+   /* ignore optional '0x' prefix */
+   if ((slen > 2) && (
+   (0 == memcmp(s, "0x", 2)
+|| (0 == memcmp(s, "0X", 2) {
+   slen -= 2;
+   s += 2;
+   }
+
+   if (slen > 8*nwords)  /* up to 2 digits per byte */
+   return -1;
+
+   memset(result, 0, 4*nwords);
+   for (i = 0 ; i < slen ; ++i) {
+   const unsigned shift = (slen - 1 - i)*4;
+   u32 *dest = [shift / 32];
+   u32 nibble;
+
+   if ('a' <= s[i] && s[i] <= 'f')
+   nibble = 0xa + (s[i] - 'a');
+   else if ('A' <= s[i] && s[i] <= 'F')
+   nibble = 0xa + (s[i] - 'A');
+   else if ('0' <= s[i] && s[i] <= '9')
+   nibble = (s[i] - '0');
+   else
+   return -1;
+
+   *dest |= (nibble << (shift % 32));
+   }
+
+   return 0;
+}
+
 static void parse_generic_cmdline(struct cmd_context *ctx,
  int *changed,
  struct cmdline_info *info,
@@ -473,64 +476,157 @@ static int do_version(struct cmd_context *ctx)
return 0;
 }
 
-static void dump_link_caps(const char *prefix, const char *an_prefix, u32 mask,
-  int link_mode_only);
+/* link mode routines */
+
+static __ETHTOOL_DECLARE_LINK_MODE_MASK(all_advertised_modes);
+static __ETHTOOL_DECLARE_LINK_MODE_MASK(all_advertised_flags);
 
-static void dump_supported(struct ethtool_cmd *ep)
+static void init_global_link_mode_masks()
 {
-   u32 mask = ep->supported;
+   static const enum ethtool_link_mode_bit_indices
+   all_advertised_modes_bits[] = {
+   ETHTOOL_LINK_MODE_10baseT_Half_BIT,
+   ETHTOOL_LINK_MODE_10baseT_Full_BIT,
+   ETHTOOL_LINK_MODE_100baseT_Half_BIT,
+   ETHTOOL_LINK_MODE_100baseT_Full_BIT,
+   ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
+   ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
+   ETHTOOL_LINK_MODE_1000baseKX_Full_BIT,
+   ETHTOOL_LINK_MODE_2500baseX_Full_BIT,
+   ETHTOOL_LINK_MODE_1baseT_Full_BIT,
+

[ethtool PATCH v4 09/11] ethtool-copy.h: sync with net-next

2016-03-11 Thread David Decotigny
From: David Decotigny <de...@googlers.com>

This cover changes up to:

  commit 14e2037902d65213842b4e40305ff54a64abbcb6
  Author: Nicolas Dichtel <nicolas.dich...@6wind.com>
  Date:   Fri Mar 4 11:52:19 2016 +0100

  ethtool.h: define INT_MAX for userland


Signed-off-by: David Decotigny <de...@googlers.com>
---
 ethtool-copy.h | 478 -
 1 file changed, 403 insertions(+), 75 deletions(-)

diff --git a/ethtool-copy.h b/ethtool-copy.h
index d23ffc4..7c581ea 100644
--- a/ethtool-copy.h
+++ b/ethtool-copy.h
@@ -13,15 +13,19 @@
 #ifndef _LINUX_ETHTOOL_H
 #define _LINUX_ETHTOOL_H
 
+#include 
 #include 
 #include 
 
+#include  /* for INT_MAX */
+
 /* All structures exposed to userland should be defined such that they
  * have the same layout for 32-bit and 64-bit userland.
  */
 
 /**
- * struct ethtool_cmd - link control and status
+ * struct ethtool_cmd - DEPRECATED, link control and status
+ * This structure is DEPRECATED, please use struct ethtool_link_settings.
  * @cmd: Command number = %ETHTOOL_GSET or %ETHTOOL_SSET
  * @supported: Bitmask of %SUPPORTED_* flags for the link modes,
  * physical connectors and other link features for which the
@@ -31,7 +35,7 @@
  * physical connectors and other link features that are
  * advertised through autonegotiation or enabled for
  * auto-detection.
- * @speed: Low bits of the speed
+ * @speed: Low bits of the speed, 1Mb units, 0 to INT_MAX or SPEED_UNKNOWN
  * @duplex: Duplex mode; one of %DUPLEX_*
  * @port: Physical connector type; one of %PORT_*
  * @phy_address: MDIO address of PHY (transceiver); 0 or 255 if not
@@ -47,7 +51,7 @@
  * obsoleted by  ethtool_coalesce.  Read-only; deprecated.
  * @maxrxpkt: Historically used to report RX IRQ coalescing; now
  * obsoleted by  ethtool_coalesce.  Read-only; deprecated.
- * @speed_hi: High bits of the speed
+ * @speed_hi: High bits of the speed, 1Mb units, 0 to INT_MAX or SPEED_UNKNOWN
  * @eth_tp_mdix: Ethernet twisted-pair MDI(-X) status; one of
  * %ETH_TP_MDI_*.  If the status is unknown or not applicable, the
  * value will be %ETH_TP_MDI_INVALID.  Read-only.
@@ -215,6 +219,11 @@ enum tunable_id {
ETHTOOL_ID_UNSPEC,
ETHTOOL_RX_COPYBREAK,
ETHTOOL_TX_COPYBREAK,
+   /*
+* Add your fresh new tubale attribute above and remember to update
+* tunable_strings[] in net/core/ethtool.c
+*/
+   __ETHTOOL_TUNABLE_COUNT,
 };
 
 enum tunable_type_id {
@@ -537,6 +546,7 @@ struct ethtool_pauseparam {
  * now deprecated
  * @ETH_SS_FEATURES: Device feature names
  * @ETH_SS_RSS_HASH_FUNCS: RSS hush function names
+ * @ETH_SS_PHY_STATS: Statistic names, for use with %ETHTOOL_GPHYSTATS
  */
 enum ethtool_stringset {
ETH_SS_TEST = 0,
@@ -545,6 +555,8 @@ enum ethtool_stringset {
ETH_SS_NTUPLE_FILTERS,
ETH_SS_FEATURES,
ETH_SS_RSS_HASH_FUNCS,
+   ETH_SS_TUNABLES,
+   ETH_SS_PHY_STATS,
 };
 
 /**
@@ -740,6 +752,56 @@ struct ethtool_usrip4_spec {
__u8proto;
 };
 
+/**
+ * struct ethtool_tcpip6_spec - flow specification for TCP/IPv6 etc.
+ * @ip6src: Source host
+ * @ip6dst: Destination host
+ * @psrc: Source port
+ * @pdst: Destination port
+ * @tclass: Traffic Class
+ *
+ * This can be used to specify a TCP/IPv6, UDP/IPv6 or SCTP/IPv6 flow.
+ */
+struct ethtool_tcpip6_spec {
+   __be32  ip6src[4];
+   __be32  ip6dst[4];
+   __be16  psrc;
+   __be16  pdst;
+   __u8tclass;
+};
+
+/**
+ * struct ethtool_ah_espip6_spec - flow specification for IPsec/IPv6
+ * @ip6src: Source host
+ * @ip6dst: Destination host
+ * @spi: Security parameters index
+ * @tclass: Traffic Class
+ *
+ * This can be used to specify an IPsec transport or tunnel over IPv6.
+ */
+struct ethtool_ah_espip6_spec {
+   __be32  ip6src[4];
+   __be32  ip6dst[4];
+   __be32  spi;
+   __u8tclass;
+};
+
+/**
+ * struct ethtool_usrip6_spec - general flow specification for IPv6
+ * @ip6src: Source host
+ * @ip6dst: Destination host
+ * @l4_4_bytes: First 4 bytes of transport (layer 4) header
+ * @tclass: Traffic Class
+ * @l4_proto: Transport protocol number (nexthdr after any Extension Headers)
+ */
+struct ethtool_usrip6_spec {
+   __be32  ip6src[4];
+   __be32  ip6dst[4];
+   __be32  l4_4_bytes;
+   __u8tclass;
+   __u8l4_proto;
+};
+
 union ethtool_flow_union {
struct ethtool_tcpip4_spec  tcp_ip4_spec;
struct ethtool_tcpip4_spec  udp_ip4_spec;
@@ -747,6 +809,12 @@ union ethtool_flow_union {
struct ethtool_ah_espip4_spec   ah_ip4_spec;
struct ethtool_ah_espip4_spec   esp_ip4_spec;
struct ethtool_usrip4_spec  usr_ip4_spec;
+   struct ethtool_tcpip6_spec  tcp_ip6_spec;
+   struct ethtool_tcpip6_spec  udp_ip6_spec;
+   struct ethtool_tcpip6_spec 

[ethtool PATCH v4 08/11] kernel-copy.h: import kernel.h from net-next and use it

2016-03-11 Thread David Decotigny
From: David Decotigny <de...@googlers.com>

This is required for recent version of ethtool.h .

This covers kernel.h up to:

  commit b5d3755a22e0cc4c369c0985aef0c52c2477c1e7
  Author: Nicolas Dichtel <nicolas.dich...@6wind.com>
  Date:   Fri Mar 4 11:52:16 2016 +0100

  uapi: define DIV_ROUND_UP for userland


Signed-off-by: David Decotigny <de...@googlers.com>
---
 ethtool.c |  3 ++-
 internal.h|  4 ++--
 kernel-copy.h | 14 ++
 3 files changed, 18 insertions(+), 3 deletions(-)
 create mode 100644 kernel-copy.h

diff --git a/ethtool.c b/ethtool.c
index d349bee..47f0259 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -227,7 +227,8 @@ struct feature_defs {
struct feature_def def[0];
 };
 
-#define FEATURE_BITS_TO_BLOCKS(n_bits) DIV_ROUND_UP(n_bits, 32U)
+#define FEATURE_BITS_TO_BLOCKS(n_bits) \
+   __KERNEL_DIV_ROUND_UP(n_bits, 32U)
 #define FEATURE_WORD(blocks, index, field) ((blocks)[(index) / 32U].field)
 #define FEATURE_FIELD_FLAG(index)  (1U << (index) % 32U)
 #define FEATURE_BIT_SET(blocks, index, field)  \
diff --git a/internal.h b/internal.h
index e38d305..1c64306 100644
--- a/internal.h
+++ b/internal.h
@@ -35,6 +35,7 @@ typedef uint16_t u16;
 typedef uint8_t u8;
 typedef int32_t s32;
 
+#include "kernel-copy.h"
 #include "ethtool-copy.h"
 #include "net_tstamp-copy.h"
 
@@ -71,8 +72,7 @@ static inline u64 cpu_to_be64(u64 value)
 
 #define BITS_PER_BYTE  8
 #define BITS_PER_LONG  (BITS_PER_BYTE * sizeof(long))
-#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
-#define BITS_TO_LONGS(nr)  DIV_ROUND_UP(nr, BITS_PER_LONG)
+#define BITS_TO_LONGS(nr)  __KERNEL_DIV_ROUND_UP(nr, BITS_PER_LONG)
 
 static inline void set_bit(unsigned int nr, unsigned long *addr)
 {
diff --git a/kernel-copy.h b/kernel-copy.h
new file mode 100644
index 000..527549f
--- /dev/null
+++ b/kernel-copy.h
@@ -0,0 +1,14 @@
+#ifndef _LINUX_KERNEL_H
+#define _LINUX_KERNEL_H
+
+#include 
+
+/*
+ * 'kernel.h' contains some often-used function prototypes etc
+ */
+#define __ALIGN_KERNEL(x, a)   __ALIGN_KERNEL_MASK(x, (typeof(x))(a) - 
1)
+#define __ALIGN_KERNEL_MASK(x, mask)   (((x) + (mask)) & ~(mask))
+
+#define __KERNEL_DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
+
+#endif /* _LINUX_KERNEL_H */
-- 
2.7.0.rc3.207.g0ac5344



[ethtool PATCH v4 11/11] ethtool.c: support absence of v4 sockets

2016-03-11 Thread David Decotigny
From: David Decotigny <de...@googlers.com>


Signed-off-by: David Decotigny <de...@googlers.com>
---
 ethtool.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/ethtool.c b/ethtool.c
index 761252f..f9336e3 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -4615,6 +4615,9 @@ opt_found:
/* Open control socket. */
ctx.fd = socket(AF_INET, SOCK_DGRAM, 0);
if (ctx.fd < 0) {
+   ctx.fd = socket(AF_UNIX, SOCK_DGRAM, 0);
+   }
+   if (ctx.fd < 0) {
perror("Cannot get control socket");
return 70;
}
-- 
2.7.0.rc3.207.g0ac5344



[ethtool PATCH v4 03/11] ethtool.c: fix dump_regs heap corruption

2016-03-11 Thread David Decotigny
From: David Decotigny <de...@googlers.com>

The 'regs' pointer is owned by do_gregs(), but updated internally inside
dump_regs() without propagating it back to do_gregs(): later free(regs)
in do_gregs() reclaims the wrong area. This commit moves the realloc()
inside do_gregs().


Signed-off-by: David Decotigny <de...@googlers.com>
---
 ethtool.c | 46 +-
 1 file changed, 25 insertions(+), 21 deletions(-)

diff --git a/ethtool.c b/ethtool.c
index 9f80d5f..7c2b5cb 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -994,7 +994,6 @@ void dump_hex(FILE *file, const u8 *data, int len, int 
offset)
 }
 
 static int dump_regs(int gregs_dump_raw, int gregs_dump_hex,
-const char *gregs_dump_file,
 struct ethtool_drvinfo *info, struct ethtool_regs *regs)
 {
int i;
@@ -1004,25 +1003,6 @@ static int dump_regs(int gregs_dump_raw, int 
gregs_dump_hex,
return 0;
}
 
-   if (gregs_dump_file) {
-   FILE *f = fopen(gregs_dump_file, "r");
-   struct stat st;
-   size_t nread;
-
-   if (!f || fstat(fileno(f), ) < 0) {
-   fprintf(stderr, "Can't open '%s': %s\n",
-   gregs_dump_file, strerror(errno));
-   return -1;
-   }
-
-   regs = realloc(regs, sizeof(*regs) + st.st_size);
-   regs->len = st.st_size;
-   nread = fread(regs->data, regs->len, 1, f);
-   fclose(f);
-   if (nread != 1)
-   return -1;
-   }
-
if (!gregs_dump_hex)
for (i = 0; i < ARRAY_SIZE(driver_list); i++)
if (!strncmp(driver_list[i].name, info->driver,
@@ -2711,7 +2691,31 @@ static int do_gregs(struct cmd_context *ctx)
free(regs);
return 74;
}
-   if (dump_regs(gregs_dump_raw, gregs_dump_hex, gregs_dump_file,
+
+   if (!gregs_dump_raw && gregs_dump_file != NULL) {
+   /* overwrite reg values from file dump */
+   FILE *f = fopen(gregs_dump_file, "r");
+   struct stat st;
+   size_t nread;
+
+   if (!f || fstat(fileno(f), ) < 0) {
+   fprintf(stderr, "Can't open '%s': %s\n",
+   gregs_dump_file, strerror(errno));
+   free(regs);
+   return 75;
+   }
+
+   regs = realloc(regs, sizeof(*regs) + st.st_size);
+   regs->len = st.st_size;
+   nread = fread(regs->data, regs->len, 1, f);
+   fclose(f);
+   if (nread != 1) {
+   free(regs);
+   return 75;
+   }
+}
+
+   if (dump_regs(gregs_dump_raw, gregs_dump_hex,
  , regs) < 0) {
fprintf(stderr, "Cannot dump registers\n");
free(regs);
-- 
2.7.0.rc3.207.g0ac5344



[ethtool PATCH v4 06/11] test-common.c: fix test_realloc(NULL, ...)

2016-03-11 Thread David Decotigny
From: Maciej Żenczykowski <m...@google.com>

This fixes:
  test-common.c: In function 'test_realloc':
  test-common.c:109:8: error: 'block' may be used uninitialized in this 
function [-Werror=maybe-uninitialized]
block = realloc(block, sizeof(*block) + size);
  ^


Signed-off-by: Maciej Żenczykowski <m...@google.com>
Signed-off-by: David Decotigny <de...@googlers.com>
---
 test-common.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/test-common.c b/test-common.c
index adc3cd4..cd63d1d 100644
--- a/test-common.c
+++ b/test-common.c
@@ -100,7 +100,7 @@ void test_free(void *ptr)
 
 void *test_realloc(void *ptr, size_t size)
 {
-   struct list_head *block;
+   struct list_head *block = NULL;
 
if (ptr) {
block = (struct list_head *)ptr - 1;
-- 
2.7.0.rc3.207.g0ac5344



[ethtool PATCH v4 05/11] marvell.c: fix strict alias warnings

2016-03-11 Thread David Decotigny
From: Maciej Żenczykowski <m...@google.com>

Addresses the following warnings:
  marvell.c:426:2: error: dereferencing type-punned pointer will break 
strict-aliasing rules [-Werror=strict-aliasing]
  marvell.c:427:2: error: dereferencing type-punned pointer will break 
strict-aliasing rules [-Werror=strict-aliasing]
  marvell.c:428:2: error: dereferencing type-punned pointer will break 
strict-aliasing rules [-Werror=strict-aliasing]

Note: code appears endian-dependent, not fixed by this commit.


Signed-off-by: Maciej Żenczykowski <m...@google.com>
Signed-off-by: David Decotigny <de...@googlers.com>
---
 marvell.c | 21 +++--
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/marvell.c b/marvell.c
index e583c82..af21188 100644
--- a/marvell.c
+++ b/marvell.c
@@ -381,7 +381,8 @@ static void dump_prefetch(const char *name, const void *r)
 
 int sky2_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs)
 {
-   const u32 *r = (const u32 *) regs->data;
+   const u16 *r16 = (const u16 *) regs->data;
+   const u32 *r32 = (const u32 *) regs->data;
int dual;
 
dump_pci(regs->data + 0x1c00);
@@ -390,15 +391,15 @@ int sky2_dump_regs(struct ethtool_drvinfo *info, struct 
ethtool_regs *regs)
 
printf("\nBus Management Unit\n");
printf("---\n");
-   printf("CSR Receive Queue 1  0x%08X\n", r[24]);
-   printf("CSR Sync Queue 1 0x%08X\n", r[26]);
-   printf("CSR Async Queue 10x%08X\n", r[27]);
+   printf("CSR Receive Queue 1  0x%08X\n", r32[24]);
+   printf("CSR Sync Queue 1 0x%08X\n", r32[26]);
+   printf("CSR Async Queue 10x%08X\n", r32[27]);
 
dual = (regs->data[0x11e] & 2) != 0;
if (dual) {
-   printf("CSR Receive Queue 2  0x%08X\n", r[25]);
-   printf("CSR Async Queue 20x%08X\n", r[29]);
-   printf("CSR Sync Queue 2 0x%08X\n", r[28]);
+   printf("CSR Receive Queue 2  0x%08X\n", r32[25]);
+   printf("CSR Async Queue 20x%08X\n", r32[29]);
+   printf("CSR Sync Queue 2 0x%08X\n", r32[28]);
}
 
dump_mac(regs->data);
@@ -423,9 +424,9 @@ int sky2_dump_regs(struct ethtool_drvinfo *info, struct 
ethtool_regs *regs)
dump_timer("TX status", regs->data + 0xec0);
dump_timer("ISR", regs->data + 0xed0);
 
-   printf("\nGMAC control 0x%04X\n", *(u32 *)(regs->data + 
0xf00));
-   printf("GPHY control 0x%04X\n", *(u32 *)(regs->data + 
0xf04));
-   printf("LINK control 0x%02hX\n", *(u16 *)(regs->data + 
0xf10));
+   printf("\nGMAC control 0x%04X\n", r32[0xf00 >> 2]);
+   printf("GPHY control 0x%04X\n", r32[0xf04 >> 2]);
+   printf("LINK control 0x%02hX\n", r16[0xf10 >> 1]);
 
dump_gmac("GMAC 1", regs->data + 0x2800);
dump_gmac_fifo("Rx GMAC 1", regs->data + 0xc40);
-- 
2.7.0.rc3.207.g0ac5344



[ethtool PATCH v4 07/11] test-features.c: add braces around array initialization

2016-03-11 Thread David Decotigny
From: Maciej Żenczykowski <m...@google.com>

This fixes:
  test-features.c:21:1: error: missing braces around initializer 
[-Werror=missing-braces]
   cmd_gssetinfo = { { ETHTOOL_GSSET_INFO, 0, 1ULL << ETH_SS_FEATURES }, 34 };
   ^


Signed-off-by: Maciej Żenczykowski <m...@google.com>
Signed-off-by: David Decotigny <de...@googlers.com>
---
 test-features.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/test-features.c b/test-features.c
index d7bd994..6ebb364 100644
--- a/test-features.c
+++ b/test-features.c
@@ -18,7 +18,7 @@ static const struct {
struct ethtool_sset_info cmd;
u32 data[1];
 }
-cmd_gssetinfo = { { ETHTOOL_GSSET_INFO, 0, 1ULL << ETH_SS_FEATURES }, 34 };
+cmd_gssetinfo = { { ETHTOOL_GSSET_INFO, 0, 1ULL << ETH_SS_FEATURES }, { 34 } };
 
 static const struct ethtool_value
 cmd_grxcsum_off = { ETHTOOL_GRXCSUM, 0 },
-- 
2.7.0.rc3.207.g0ac5344



[ethtool PATCH v4 00/11] add support for new ETHTOOL_xLINKSETTINGS ioctls

2016-03-11 Thread David Decotigny
From: David Decotigny <de...@googlers.com>

This adds support for the new ETHTOOL_xLINKSETTINGS ioctls. This also
fixes a few compilation warnings as well as a heap corruption bug.

History:
  v4
review Ben Hutchings:
  using AF_UNIX instead of INET6 in the absence of v4 sockets
  use stdbool.h
  do_seeprom always fails when offset/length out of bounds
  sync to latest ethtool.h + kernel.h from net-next
  __SANE_USERSPACE_TYPES__ always defined
  cosmetic updates for var == const tests
  cosmetic updates for associativity in tests
  v3
TRUE/FALSE obvious-ification
  v2
added do_seeprom patch
added netdev@ as recipient
  v1
initial submission


# Patch Set Summary:

David Decotigny (7):
  ethtool.c: don't ignore fread() return value
  ethtool.c: fix dump_regs heap corruption
  ethtool.c: do_seeprom checks for params & stdin sanity
  kernel-copy.h: import kernel.h from net-next and use it
  ethtool-copy.h: sync with net-next
  ethtool.c: add support for ETHTOOL_xLINKSETTINGS ioctls
  ethtool.c: support absence of v4 sockets

Maciej Żenczykowski (4):
  internal.h: change to new sane kernel headers on 64-bit archs
  marvell.c: fix strict alias warnings
  test-common.c: fix test_realloc(NULL, ...)
  test-features.c: add braces around array initialization

 ethtool-copy.h  | 478 ++--
 ethtool.c   | 751 ++--
 internal.h  |  77 +-
 kernel-copy.h   |  14 ++
 marvell.c   |  21 +-
 test-cmdline.c  |  12 +
 test-common.c   |   2 +-
 test-features.c |   2 +-
 8 files changed, 1086 insertions(+), 271 deletions(-)
 create mode 100644 kernel-copy.h

-- 
2.7.0.rc3.207.g0ac5344



[ethtool PATCH v4 01/11] internal.h: change to new sane kernel headers on 64-bit archs

2016-03-11 Thread David Decotigny
From: Maciej Żenczykowski <m...@google.com>

On ppc64, this fixes:
  In file included from ethtool-copy.h:22:0,
   from internal.h:32,
   from ethtool.c:29:
  .../include/linux/types.h:32:25: error: conflicting types for '__be64'
   typedef __u64 __bitwise __be64;
   ^
  In file included from ethtool.c:29:0:
  internal.h:23:28: note: previous declaration of '__be64' was here
   typedef unsigned long long __be64;
  ^
  ethtool.c: In function 'do_gstats':
  ethtool.c:3166:4: error: format '%llu' expects argument of type 'long long 
unsigned int', but argument 5 has type '__u64' [-Werror=format=]
  stats->data[i]);
  ^
  ethtool.c: In function 'print_indir_table':
  ethtool.c:3293:9: error: format '%llu' expects argument of type 'long long 
unsigned int', but argument 3 has type '__u64' [-Werror=format=]
   ctx->devname, ring_count->data);
   ^


Signed-off-by: Maciej Żenczykowski <m...@google.com>
Signed-off-by: David Decotigny <de...@googlers.com>
---
 internal.h | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/internal.h b/internal.h
index b5ef646..e38d305 100644
--- a/internal.h
+++ b/internal.h
@@ -3,6 +3,12 @@
 #ifndef ETHTOOL_INTERNAL_H__
 #define ETHTOOL_INTERNAL_H__
 
+/* Some platforms (eg. ppc64) need __SANE_USERSPACE_TYPES__ before
+ *  to select 'int-ll64.h' and avoid compile warnings
+ * when printing __u64 with %llu.
+ */
+#define __SANE_USERSPACE_TYPES__
+
 #ifdef HAVE_CONFIG_H
 #include "ethtool-config.h"
 #endif
-- 
2.7.0.rc3.207.g0ac5344



[ethtool PATCH v4 08/11] kernel-copy.h: import kernel.h from net-next and use it

2016-03-07 Thread David Decotigny
From: David Decotigny <de...@googlers.com>

This is required for recent version of ethtool.h .

This covers kernel.h up to:

  commit b5d3755a22e0cc4c369c0985aef0c52c2477c1e7
  Author: Nicolas Dichtel <nicolas.dich...@6wind.com>
  Date:   Fri Mar 4 11:52:16 2016 +0100

  uapi: define DIV_ROUND_UP for userland


Signed-off-by: David Decotigny <de...@googlers.com>
---
 ethtool.c |  3 ++-
 internal.h|  4 ++--
 kernel-copy.h | 14 ++
 3 files changed, 18 insertions(+), 3 deletions(-)
 create mode 100644 kernel-copy.h

diff --git a/ethtool.c b/ethtool.c
index d349bee..47f0259 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -227,7 +227,8 @@ struct feature_defs {
struct feature_def def[0];
 };
 
-#define FEATURE_BITS_TO_BLOCKS(n_bits) DIV_ROUND_UP(n_bits, 32U)
+#define FEATURE_BITS_TO_BLOCKS(n_bits) \
+   __KERNEL_DIV_ROUND_UP(n_bits, 32U)
 #define FEATURE_WORD(blocks, index, field) ((blocks)[(index) / 32U].field)
 #define FEATURE_FIELD_FLAG(index)  (1U << (index) % 32U)
 #define FEATURE_BIT_SET(blocks, index, field)  \
diff --git a/internal.h b/internal.h
index e38d305..1c64306 100644
--- a/internal.h
+++ b/internal.h
@@ -35,6 +35,7 @@ typedef uint16_t u16;
 typedef uint8_t u8;
 typedef int32_t s32;
 
+#include "kernel-copy.h"
 #include "ethtool-copy.h"
 #include "net_tstamp-copy.h"
 
@@ -71,8 +72,7 @@ static inline u64 cpu_to_be64(u64 value)
 
 #define BITS_PER_BYTE  8
 #define BITS_PER_LONG  (BITS_PER_BYTE * sizeof(long))
-#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
-#define BITS_TO_LONGS(nr)  DIV_ROUND_UP(nr, BITS_PER_LONG)
+#define BITS_TO_LONGS(nr)  __KERNEL_DIV_ROUND_UP(nr, BITS_PER_LONG)
 
 static inline void set_bit(unsigned int nr, unsigned long *addr)
 {
diff --git a/kernel-copy.h b/kernel-copy.h
new file mode 100644
index 000..527549f
--- /dev/null
+++ b/kernel-copy.h
@@ -0,0 +1,14 @@
+#ifndef _LINUX_KERNEL_H
+#define _LINUX_KERNEL_H
+
+#include 
+
+/*
+ * 'kernel.h' contains some often-used function prototypes etc
+ */
+#define __ALIGN_KERNEL(x, a)   __ALIGN_KERNEL_MASK(x, (typeof(x))(a) - 
1)
+#define __ALIGN_KERNEL_MASK(x, mask)   (((x) + (mask)) & ~(mask))
+
+#define __KERNEL_DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
+
+#endif /* _LINUX_KERNEL_H */
-- 
2.7.0.rc3.207.g0ac5344



[ethtool PATCH v4 10/11] ethtool.c: add support for ETHTOOL_xLINKSETTINGS ioctls

2016-03-07 Thread David Decotigny
From: David Decotigny <de...@googlers.com>

More info with kernel SHA1: 8d3f2806f8fbd9b22 "Merge branch
'ethtool-ksettings'".


Signed-off-by: David Decotigny <de...@googlers.com>
---
 ethtool.c  | 682 +++--
 internal.h |  67 ++
 test-cmdline.c |  12 +
 3 files changed, 602 insertions(+), 159 deletions(-)

diff --git a/ethtool.c b/ethtool.c
index 47f0259..761252f 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -47,42 +47,6 @@
 #define MAX_ADDR_LEN   32
 #endif
 
-#define ALL_ADVERTISED_MODES   \
-   (ADVERTISED_10baseT_Half |  \
-ADVERTISED_10baseT_Full |  \
-ADVERTISED_100baseT_Half | \
-ADVERTISED_100baseT_Full | \
-ADVERTISED_1000baseT_Half |\
-ADVERTISED_1000baseT_Full |\
-ADVERTISED_1000baseKX_Full|\
-ADVERTISED_2500baseX_Full |\
-ADVERTISED_1baseT_Full |   \
-ADVERTISED_1baseKX4_Full | \
-ADVERTISED_1baseKR_Full |  \
-ADVERTISED_1baseR_FEC |\
-ADVERTISED_2baseMLD2_Full |\
-ADVERTISED_2baseKR2_Full | \
-ADVERTISED_4baseKR4_Full | \
-ADVERTISED_4baseCR4_Full | \
-ADVERTISED_4baseSR4_Full | \
-ADVERTISED_4baseLR4_Full | \
-ADVERTISED_56000baseKR4_Full | \
-ADVERTISED_56000baseCR4_Full | \
-ADVERTISED_56000baseSR4_Full | \
-ADVERTISED_56000baseLR4_Full)
-
-#define ALL_ADVERTISED_FLAGS   \
-   (ADVERTISED_Autoneg |   \
-ADVERTISED_TP |\
-ADVERTISED_AUI |   \
-ADVERTISED_MII |   \
-ADVERTISED_FIBRE | \
-ADVERTISED_BNC |   \
-ADVERTISED_Pause | \
-ADVERTISED_Asym_Pause |\
-ADVERTISED_Backplane | \
-ALL_ADVERTISED_MODES)
-
 #ifndef HAVE_NETIF_MSG
 enum {
NETIF_MSG_DRV   = 0x0001,
@@ -294,6 +258,45 @@ static void get_mac_addr(char *src, unsigned char *dest)
}
 }
 
+static int parse_hex_u32_bitmap(const char *s,
+   unsigned int nbits, u32 *result)
+{
+   const unsigned nwords = __KERNEL_DIV_ROUND_UP(nbits, 32);
+   size_t slen = strlen(s);
+   size_t i;
+
+   /* ignore optional '0x' prefix */
+   if ((slen > 2) && (
+   (0 == memcmp(s, "0x", 2)
+|| (0 == memcmp(s, "0X", 2) {
+   slen -= 2;
+   s += 2;
+   }
+
+   if (slen > 8*nwords)  /* up to 2 digits per byte */
+   return -1;
+
+   memset(result, 0, 4*nwords);
+   for (i = 0 ; i < slen ; ++i) {
+   const unsigned shift = (slen - 1 - i)*4;
+   u32 *dest = [shift / 32];
+   u32 nibble;
+
+   if ('a' <= s[i] && s[i] <= 'f')
+   nibble = 0xa + (s[i] - 'a');
+   else if ('A' <= s[i] && s[i] <= 'F')
+   nibble = 0xa + (s[i] - 'A');
+   else if ('0' <= s[i] && s[i] <= '9')
+   nibble = (s[i] - '0');
+   else
+   return -1;
+
+   *dest |= (nibble << (shift % 32));
+   }
+
+   return 0;
+}
+
 static void parse_generic_cmdline(struct cmd_context *ctx,
  int *changed,
  struct cmdline_info *info,
@@ -473,64 +476,157 @@ static int do_version(struct cmd_context *ctx)
return 0;
 }
 
-static void dump_link_caps(const char *prefix, const char *an_prefix, u32 mask,
-  int link_mode_only);
+/* link mode routines */
+
+static __ETHTOOL_DECLARE_LINK_MODE_MASK(all_advertised_modes);
+static __ETHTOOL_DECLARE_LINK_MODE_MASK(all_advertised_flags);
 
-static void dump_supported(struct ethtool_cmd *ep)
+static void init_global_link_mode_masks()
 {
-   u32 mask = ep->supported;
+   static const enum ethtool_link_mode_bit_indices
+   all_advertised_modes_bits[] = {
+   ETHTOOL_LINK_MODE_10baseT_Half_BIT,
+   ETHTOOL_LINK_MODE_10baseT_Full_BIT,
+   ETHTOOL_LINK_MODE_100baseT_Half_BIT,
+   ETHTOOL_LINK_MODE_100baseT_Full_BIT,
+   ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
+   ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
+   ETHTOOL_LINK_MODE_1000baseKX_Full_BIT,
+   ETHTOOL_LINK_MODE_2500baseX_Full_BIT,
+   ETHTOOL_LINK_MODE_1baseT_Full_BIT,
+

[ethtool PATCH v4 07/11] test-features.c: add braces around array initialization

2016-03-07 Thread David Decotigny
From: Maciej Żenczykowski <m...@google.com>

This fixes:
  test-features.c:21:1: error: missing braces around initializer 
[-Werror=missing-braces]
   cmd_gssetinfo = { { ETHTOOL_GSSET_INFO, 0, 1ULL << ETH_SS_FEATURES }, 34 };
   ^


Signed-off-by: Maciej Żenczykowski <m...@google.com>
Signed-off-by: David Decotigny <de...@googlers.com>
---
 test-features.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/test-features.c b/test-features.c
index d7bd994..6ebb364 100644
--- a/test-features.c
+++ b/test-features.c
@@ -18,7 +18,7 @@ static const struct {
struct ethtool_sset_info cmd;
u32 data[1];
 }
-cmd_gssetinfo = { { ETHTOOL_GSSET_INFO, 0, 1ULL << ETH_SS_FEATURES }, 34 };
+cmd_gssetinfo = { { ETHTOOL_GSSET_INFO, 0, 1ULL << ETH_SS_FEATURES }, { 34 } };
 
 static const struct ethtool_value
 cmd_grxcsum_off = { ETHTOOL_GRXCSUM, 0 },
-- 
2.7.0.rc3.207.g0ac5344



[ethtool PATCH v4 06/11] test-common.c: fix test_realloc(NULL, ...)

2016-03-07 Thread David Decotigny
From: Maciej Żenczykowski <m...@google.com>

This fixes:
  test-common.c: In function 'test_realloc':
  test-common.c:109:8: error: 'block' may be used uninitialized in this 
function [-Werror=maybe-uninitialized]
block = realloc(block, sizeof(*block) + size);
  ^


Signed-off-by: Maciej Żenczykowski <m...@google.com>
Signed-off-by: David Decotigny <de...@googlers.com>
---
 test-common.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/test-common.c b/test-common.c
index adc3cd4..cd63d1d 100644
--- a/test-common.c
+++ b/test-common.c
@@ -100,7 +100,7 @@ void test_free(void *ptr)
 
 void *test_realloc(void *ptr, size_t size)
 {
-   struct list_head *block;
+   struct list_head *block = NULL;
 
if (ptr) {
block = (struct list_head *)ptr - 1;
-- 
2.7.0.rc3.207.g0ac5344



[ethtool PATCH v4 09/11] ethtool-copy.h: sync with net-next

2016-03-07 Thread David Decotigny
From: David Decotigny <de...@googlers.com>

This cover changes up to:

  commit 14e2037902d65213842b4e40305ff54a64abbcb6
  Author: Nicolas Dichtel <nicolas.dich...@6wind.com>
  Date:   Fri Mar 4 11:52:19 2016 +0100

  ethtool.h: define INT_MAX for userland


Signed-off-by: David Decotigny <de...@googlers.com>
---
 ethtool-copy.h | 478 -
 1 file changed, 403 insertions(+), 75 deletions(-)

diff --git a/ethtool-copy.h b/ethtool-copy.h
index d23ffc4..7c581ea 100644
--- a/ethtool-copy.h
+++ b/ethtool-copy.h
@@ -13,15 +13,19 @@
 #ifndef _LINUX_ETHTOOL_H
 #define _LINUX_ETHTOOL_H
 
+#include 
 #include 
 #include 
 
+#include  /* for INT_MAX */
+
 /* All structures exposed to userland should be defined such that they
  * have the same layout for 32-bit and 64-bit userland.
  */
 
 /**
- * struct ethtool_cmd - link control and status
+ * struct ethtool_cmd - DEPRECATED, link control and status
+ * This structure is DEPRECATED, please use struct ethtool_link_settings.
  * @cmd: Command number = %ETHTOOL_GSET or %ETHTOOL_SSET
  * @supported: Bitmask of %SUPPORTED_* flags for the link modes,
  * physical connectors and other link features for which the
@@ -31,7 +35,7 @@
  * physical connectors and other link features that are
  * advertised through autonegotiation or enabled for
  * auto-detection.
- * @speed: Low bits of the speed
+ * @speed: Low bits of the speed, 1Mb units, 0 to INT_MAX or SPEED_UNKNOWN
  * @duplex: Duplex mode; one of %DUPLEX_*
  * @port: Physical connector type; one of %PORT_*
  * @phy_address: MDIO address of PHY (transceiver); 0 or 255 if not
@@ -47,7 +51,7 @@
  * obsoleted by  ethtool_coalesce.  Read-only; deprecated.
  * @maxrxpkt: Historically used to report RX IRQ coalescing; now
  * obsoleted by  ethtool_coalesce.  Read-only; deprecated.
- * @speed_hi: High bits of the speed
+ * @speed_hi: High bits of the speed, 1Mb units, 0 to INT_MAX or SPEED_UNKNOWN
  * @eth_tp_mdix: Ethernet twisted-pair MDI(-X) status; one of
  * %ETH_TP_MDI_*.  If the status is unknown or not applicable, the
  * value will be %ETH_TP_MDI_INVALID.  Read-only.
@@ -215,6 +219,11 @@ enum tunable_id {
ETHTOOL_ID_UNSPEC,
ETHTOOL_RX_COPYBREAK,
ETHTOOL_TX_COPYBREAK,
+   /*
+* Add your fresh new tubale attribute above and remember to update
+* tunable_strings[] in net/core/ethtool.c
+*/
+   __ETHTOOL_TUNABLE_COUNT,
 };
 
 enum tunable_type_id {
@@ -537,6 +546,7 @@ struct ethtool_pauseparam {
  * now deprecated
  * @ETH_SS_FEATURES: Device feature names
  * @ETH_SS_RSS_HASH_FUNCS: RSS hush function names
+ * @ETH_SS_PHY_STATS: Statistic names, for use with %ETHTOOL_GPHYSTATS
  */
 enum ethtool_stringset {
ETH_SS_TEST = 0,
@@ -545,6 +555,8 @@ enum ethtool_stringset {
ETH_SS_NTUPLE_FILTERS,
ETH_SS_FEATURES,
ETH_SS_RSS_HASH_FUNCS,
+   ETH_SS_TUNABLES,
+   ETH_SS_PHY_STATS,
 };
 
 /**
@@ -740,6 +752,56 @@ struct ethtool_usrip4_spec {
__u8proto;
 };
 
+/**
+ * struct ethtool_tcpip6_spec - flow specification for TCP/IPv6 etc.
+ * @ip6src: Source host
+ * @ip6dst: Destination host
+ * @psrc: Source port
+ * @pdst: Destination port
+ * @tclass: Traffic Class
+ *
+ * This can be used to specify a TCP/IPv6, UDP/IPv6 or SCTP/IPv6 flow.
+ */
+struct ethtool_tcpip6_spec {
+   __be32  ip6src[4];
+   __be32  ip6dst[4];
+   __be16  psrc;
+   __be16  pdst;
+   __u8tclass;
+};
+
+/**
+ * struct ethtool_ah_espip6_spec - flow specification for IPsec/IPv6
+ * @ip6src: Source host
+ * @ip6dst: Destination host
+ * @spi: Security parameters index
+ * @tclass: Traffic Class
+ *
+ * This can be used to specify an IPsec transport or tunnel over IPv6.
+ */
+struct ethtool_ah_espip6_spec {
+   __be32  ip6src[4];
+   __be32  ip6dst[4];
+   __be32  spi;
+   __u8tclass;
+};
+
+/**
+ * struct ethtool_usrip6_spec - general flow specification for IPv6
+ * @ip6src: Source host
+ * @ip6dst: Destination host
+ * @l4_4_bytes: First 4 bytes of transport (layer 4) header
+ * @tclass: Traffic Class
+ * @l4_proto: Transport protocol number (nexthdr after any Extension Headers)
+ */
+struct ethtool_usrip6_spec {
+   __be32  ip6src[4];
+   __be32  ip6dst[4];
+   __be32  l4_4_bytes;
+   __u8tclass;
+   __u8l4_proto;
+};
+
 union ethtool_flow_union {
struct ethtool_tcpip4_spec  tcp_ip4_spec;
struct ethtool_tcpip4_spec  udp_ip4_spec;
@@ -747,6 +809,12 @@ union ethtool_flow_union {
struct ethtool_ah_espip4_spec   ah_ip4_spec;
struct ethtool_ah_espip4_spec   esp_ip4_spec;
struct ethtool_usrip4_spec  usr_ip4_spec;
+   struct ethtool_tcpip6_spec  tcp_ip6_spec;
+   struct ethtool_tcpip6_spec  udp_ip6_spec;
+   struct ethtool_tcpip6_spec 

[ethtool PATCH v4 03/11] ethtool.c: fix dump_regs heap corruption

2016-03-07 Thread David Decotigny
From: David Decotigny <de...@googlers.com>

The 'regs' pointer is owned by do_gregs(), but updated internally inside
dump_regs() without propagating it back to do_gregs(): later free(regs)
in do_gregs() reclaims the wrong area. This commit moves the realloc()
inside do_gregs().


Signed-off-by: David Decotigny <de...@googlers.com>
---
 ethtool.c | 46 +-
 1 file changed, 25 insertions(+), 21 deletions(-)

diff --git a/ethtool.c b/ethtool.c
index 9f80d5f..7c2b5cb 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -994,7 +994,6 @@ void dump_hex(FILE *file, const u8 *data, int len, int 
offset)
 }
 
 static int dump_regs(int gregs_dump_raw, int gregs_dump_hex,
-const char *gregs_dump_file,
 struct ethtool_drvinfo *info, struct ethtool_regs *regs)
 {
int i;
@@ -1004,25 +1003,6 @@ static int dump_regs(int gregs_dump_raw, int 
gregs_dump_hex,
return 0;
}
 
-   if (gregs_dump_file) {
-   FILE *f = fopen(gregs_dump_file, "r");
-   struct stat st;
-   size_t nread;
-
-   if (!f || fstat(fileno(f), ) < 0) {
-   fprintf(stderr, "Can't open '%s': %s\n",
-   gregs_dump_file, strerror(errno));
-   return -1;
-   }
-
-   regs = realloc(regs, sizeof(*regs) + st.st_size);
-   regs->len = st.st_size;
-   nread = fread(regs->data, regs->len, 1, f);
-   fclose(f);
-   if (nread != 1)
-   return -1;
-   }
-
if (!gregs_dump_hex)
for (i = 0; i < ARRAY_SIZE(driver_list); i++)
if (!strncmp(driver_list[i].name, info->driver,
@@ -2711,7 +2691,31 @@ static int do_gregs(struct cmd_context *ctx)
free(regs);
return 74;
}
-   if (dump_regs(gregs_dump_raw, gregs_dump_hex, gregs_dump_file,
+
+   if (!gregs_dump_raw && gregs_dump_file != NULL) {
+   /* overwrite reg values from file dump */
+   FILE *f = fopen(gregs_dump_file, "r");
+   struct stat st;
+   size_t nread;
+
+   if (!f || fstat(fileno(f), ) < 0) {
+   fprintf(stderr, "Can't open '%s': %s\n",
+   gregs_dump_file, strerror(errno));
+   free(regs);
+   return 75;
+   }
+
+   regs = realloc(regs, sizeof(*regs) + st.st_size);
+   regs->len = st.st_size;
+   nread = fread(regs->data, regs->len, 1, f);
+   fclose(f);
+   if (nread != 1) {
+   free(regs);
+   return 75;
+   }
+}
+
+   if (dump_regs(gregs_dump_raw, gregs_dump_hex,
  , regs) < 0) {
fprintf(stderr, "Cannot dump registers\n");
free(regs);
-- 
2.7.0.rc3.207.g0ac5344



[ethtool PATCH v4 05/11] marvell.c: fix strict alias warnings

2016-03-07 Thread David Decotigny
From: Maciej Żenczykowski <m...@google.com>

Addresses the following warnings:
  marvell.c:426:2: error: dereferencing type-punned pointer will break 
strict-aliasing rules [-Werror=strict-aliasing]
  marvell.c:427:2: error: dereferencing type-punned pointer will break 
strict-aliasing rules [-Werror=strict-aliasing]
  marvell.c:428:2: error: dereferencing type-punned pointer will break 
strict-aliasing rules [-Werror=strict-aliasing]

Note: code appears endian-dependent, not fixed by this commit.


Signed-off-by: Maciej Żenczykowski <m...@google.com>
Signed-off-by: David Decotigny <de...@googlers.com>
---
 marvell.c | 21 +++--
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/marvell.c b/marvell.c
index e583c82..af21188 100644
--- a/marvell.c
+++ b/marvell.c
@@ -381,7 +381,8 @@ static void dump_prefetch(const char *name, const void *r)
 
 int sky2_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs)
 {
-   const u32 *r = (const u32 *) regs->data;
+   const u16 *r16 = (const u16 *) regs->data;
+   const u32 *r32 = (const u32 *) regs->data;
int dual;
 
dump_pci(regs->data + 0x1c00);
@@ -390,15 +391,15 @@ int sky2_dump_regs(struct ethtool_drvinfo *info, struct 
ethtool_regs *regs)
 
printf("\nBus Management Unit\n");
printf("---\n");
-   printf("CSR Receive Queue 1  0x%08X\n", r[24]);
-   printf("CSR Sync Queue 1 0x%08X\n", r[26]);
-   printf("CSR Async Queue 10x%08X\n", r[27]);
+   printf("CSR Receive Queue 1  0x%08X\n", r32[24]);
+   printf("CSR Sync Queue 1 0x%08X\n", r32[26]);
+   printf("CSR Async Queue 10x%08X\n", r32[27]);
 
dual = (regs->data[0x11e] & 2) != 0;
if (dual) {
-   printf("CSR Receive Queue 2  0x%08X\n", r[25]);
-   printf("CSR Async Queue 20x%08X\n", r[29]);
-   printf("CSR Sync Queue 2 0x%08X\n", r[28]);
+   printf("CSR Receive Queue 2  0x%08X\n", r32[25]);
+   printf("CSR Async Queue 20x%08X\n", r32[29]);
+   printf("CSR Sync Queue 2 0x%08X\n", r32[28]);
}
 
dump_mac(regs->data);
@@ -423,9 +424,9 @@ int sky2_dump_regs(struct ethtool_drvinfo *info, struct 
ethtool_regs *regs)
dump_timer("TX status", regs->data + 0xec0);
dump_timer("ISR", regs->data + 0xed0);
 
-   printf("\nGMAC control 0x%04X\n", *(u32 *)(regs->data + 
0xf00));
-   printf("GPHY control 0x%04X\n", *(u32 *)(regs->data + 
0xf04));
-   printf("LINK control 0x%02hX\n", *(u16 *)(regs->data + 
0xf10));
+   printf("\nGMAC control 0x%04X\n", r32[0xf00 >> 2]);
+   printf("GPHY control 0x%04X\n", r32[0xf04 >> 2]);
+   printf("LINK control 0x%02hX\n", r16[0xf10 >> 1]);
 
dump_gmac("GMAC 1", regs->data + 0x2800);
dump_gmac_fifo("Rx GMAC 1", regs->data + 0xc40);
-- 
2.7.0.rc3.207.g0ac5344



[ethtool PATCH v4 02/11] ethtool.c: don't ignore fread() return value

2016-03-07 Thread David Decotigny
From: David Decotigny <de...@googlers.com>

This addresses:
  ethtool.c:1116:8: warning: ignoring return value of ‘fread’, declared with 
attribute warn_unused_result [-Wunused-result]


Signed-off-by: David Decotigny <de...@googlers.com>
---
 ethtool.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/ethtool.c b/ethtool.c
index 92c40b8..9f80d5f 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -1007,6 +1007,7 @@ static int dump_regs(int gregs_dump_raw, int 
gregs_dump_hex,
if (gregs_dump_file) {
FILE *f = fopen(gregs_dump_file, "r");
struct stat st;
+   size_t nread;
 
if (!f || fstat(fileno(f), ) < 0) {
fprintf(stderr, "Can't open '%s': %s\n",
@@ -1016,8 +1017,10 @@ static int dump_regs(int gregs_dump_raw, int 
gregs_dump_hex,
 
regs = realloc(regs, sizeof(*regs) + st.st_size);
regs->len = st.st_size;
-   fread(regs->data, regs->len, 1, f);
+   nread = fread(regs->data, regs->len, 1, f);
fclose(f);
+   if (nread != 1)
+   return -1;
}
 
if (!gregs_dump_hex)
-- 
2.7.0.rc3.207.g0ac5344



[ethtool PATCH v4 04/11] ethtool.c: do_seeprom checks for params & stdin sanity

2016-03-07 Thread David Decotigny
From: David Decotigny <de...@googlers.com>

Tested:
  On qemu e1000:
  $ dd if=/dev/zero bs=2 count=5 | /mnt/ethtool -E eth0 length 9
  too much data from stdin
  $ dd if=/dev/zero bs=2 count=5 | /mnt/ethtool -E eth0 length 11
  not enough data from stdin
  $ dd if=/dev/zero bs=2 count=5 | /mnt/ethtool -E eth0 length 10
  Cannot set EEPROM data: Bad address


Signed-off-by: David Decotigny <de...@googlers.com>
---
 ethtool.c | 20 
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/ethtool.c b/ethtool.c
index 7c2b5cb..d349bee 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -2828,8 +2828,10 @@ static int do_seeprom(struct cmd_context *ctx)
if (seeprom_length == -1)
seeprom_length = drvinfo.eedump_len;
 
-   if (drvinfo.eedump_len < seeprom_offset + seeprom_length)
-   seeprom_length = drvinfo.eedump_len - seeprom_offset;
+   if (drvinfo.eedump_len < seeprom_offset + seeprom_length) {
+   fprintf(stderr, "offset & length out of bounds\n");
+   return 1;
+   }
 
eeprom = calloc(1, sizeof(*eeprom)+seeprom_length);
if (!eeprom) {
@@ -2844,8 +2846,18 @@ static int do_seeprom(struct cmd_context *ctx)
eeprom->data[0] = seeprom_value;
 
/* Multi-byte write: read input from stdin */
-   if (!seeprom_value_seen)
-   eeprom->len = fread(eeprom->data, 1, eeprom->len, stdin);
+   if (!seeprom_value_seen) {
+   if (1 != fread(eeprom->data, eeprom->len, 1, stdin)) {
+   fprintf(stderr, "not enough data from stdin\n");
+   free(eeprom);
+   return 75;
+   }
+   if ((fgetc(stdin) != EOF) || !feof(stdin)) {
+   fprintf(stderr, "too much data from stdin\n");
+   free(eeprom);
+   return 75;
+   }
+   }
 
err = send_ioctl(ctx, eeprom);
if (err < 0) {
-- 
2.7.0.rc3.207.g0ac5344



[ethtool PATCH v4 11/11] ethtool.c: support absence of v4 sockets

2016-03-07 Thread David Decotigny
From: David Decotigny <de...@googlers.com>


Signed-off-by: David Decotigny <de...@googlers.com>
---
 ethtool.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/ethtool.c b/ethtool.c
index 761252f..f9336e3 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -4615,6 +4615,9 @@ opt_found:
/* Open control socket. */
ctx.fd = socket(AF_INET, SOCK_DGRAM, 0);
if (ctx.fd < 0) {
+   ctx.fd = socket(AF_UNIX, SOCK_DGRAM, 0);
+   }
+   if (ctx.fd < 0) {
perror("Cannot get control socket");
return 70;
}
-- 
2.7.0.rc3.207.g0ac5344



[ethtool PATCH v4 00/11] add support for new ETHTOOL_xLINKSETTINGS ioctls

2016-03-07 Thread David Decotigny
From: David Decotigny <de...@googlers.com>

This adds support for the new ETHTOOL_xLINKSETTINGS ioctls. This also
fixes a few compilation warnings as well as a heap corruption bug.

History:
  v4
review Ben Hutchings:
  using AF_UNIX instead of INET6 in the absence of v4 sockets
  use stdbool.h
  do_seeprom always fails when offset/length out of bounds
  sync to latest ethtool.h + kernel.h from net-next
  __SANE_USERSPACE_TYPES__ always defined
  cosmetic updates for var == const tests
  cosmetic updates for associativity in tests
  v3
TRUE/FALSE obvious-ification
  v2
added do_seeprom patch
added netdev@ as recipient
  v1
initial submission


# Patch Set Summary:

David Decotigny (7):
  ethtool.c: don't ignore fread() return value
  ethtool.c: fix dump_regs heap corruption
  ethtool.c: do_seeprom checks for params & stdin sanity
  kernel-copy.h: import kernel.h from net-next and use it
  ethtool-copy.h: sync with net-next
  ethtool.c: add support for ETHTOOL_xLINKSETTINGS ioctls
  ethtool.c: support absence of v4 sockets

Maciej Żenczykowski (4):
  internal.h: change to new sane kernel headers on 64-bit archs
  marvell.c: fix strict alias warnings
  test-common.c: fix test_realloc(NULL, ...)
  test-features.c: add braces around array initialization

 ethtool-copy.h  | 478 ++--
 ethtool.c   | 751 ++--
 internal.h  |  77 +-
 kernel-copy.h   |  14 ++
 marvell.c   |  21 +-
 test-cmdline.c  |  12 +
 test-common.c   |   2 +-
 test-features.c |   2 +-
 8 files changed, 1086 insertions(+), 271 deletions(-)
 create mode 100644 kernel-copy.h

-- 
2.7.0.rc3.207.g0ac5344



[ethtool PATCH v4 01/11] internal.h: change to new sane kernel headers on 64-bit archs

2016-03-07 Thread David Decotigny
From: Maciej Żenczykowski <m...@google.com>

On ppc64, this fixes:
  In file included from ethtool-copy.h:22:0,
   from internal.h:32,
   from ethtool.c:29:
  .../include/linux/types.h:32:25: error: conflicting types for '__be64'
   typedef __u64 __bitwise __be64;
   ^
  In file included from ethtool.c:29:0:
  internal.h:23:28: note: previous declaration of '__be64' was here
   typedef unsigned long long __be64;
  ^
  ethtool.c: In function 'do_gstats':
  ethtool.c:3166:4: error: format '%llu' expects argument of type 'long long 
unsigned int', but argument 5 has type '__u64' [-Werror=format=]
  stats->data[i]);
  ^
  ethtool.c: In function 'print_indir_table':
  ethtool.c:3293:9: error: format '%llu' expects argument of type 'long long 
unsigned int', but argument 3 has type '__u64' [-Werror=format=]
   ctx->devname, ring_count->data);
   ^


Signed-off-by: Maciej Żenczykowski <m...@google.com>
Signed-off-by: David Decotigny <de...@googlers.com>
---
 internal.h | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/internal.h b/internal.h
index b5ef646..e38d305 100644
--- a/internal.h
+++ b/internal.h
@@ -3,6 +3,12 @@
 #ifndef ETHTOOL_INTERNAL_H__
 #define ETHTOOL_INTERNAL_H__
 
+/* Some platforms (eg. ppc64) need __SANE_USERSPACE_TYPES__ before
+ *  to select 'int-ll64.h' and avoid compile warnings
+ * when printing __u64 with %llu.
+ */
+#define __SANE_USERSPACE_TYPES__
+
 #ifdef HAVE_CONFIG_H
 #include "ethtool-config.h"
 #endif
-- 
2.7.0.rc3.207.g0ac5344



[ethtool PATCH v3 02/12] ethtool.c: don't ignore fread() return value

2016-03-04 Thread David Decotigny
From: David Decotigny <de...@googlers.com>

This addresses:
  ethtool.c:1116:8: warning: ignoring return value of ‘fread’, declared with 
attribute warn_unused_result [-Wunused-result]


Signed-off-by: David Decotigny <de...@googlers.com>
---
 ethtool.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/ethtool.c b/ethtool.c
index 92c40b8..8a93dd1 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -1007,6 +1007,7 @@ static int dump_regs(int gregs_dump_raw, int 
gregs_dump_hex,
if (gregs_dump_file) {
FILE *f = fopen(gregs_dump_file, "r");
struct stat st;
+   size_t nread;
 
if (!f || fstat(fileno(f), ) < 0) {
fprintf(stderr, "Can't open '%s': %s\n",
@@ -1016,8 +1017,10 @@ static int dump_regs(int gregs_dump_raw, int 
gregs_dump_hex,
 
regs = realloc(regs, sizeof(*regs) + st.st_size);
regs->len = st.st_size;
-   fread(regs->data, regs->len, 1, f);
+   nread = fread(regs->data, regs->len, 1, f);
fclose(f);
+   if (1 != nread)
+   return -1;
}
 
if (!gregs_dump_hex)
-- 
2.7.0.rc3.207.g0ac5344



[ethtool PATCH v3 08/12] ethtool-copy.h: sync with net-next

2016-03-04 Thread David Decotigny
From: David Decotigny <de...@googlers.com>

This cover changes up to:

  commit 3f1ac7a700d039c61d8d8b99f28d605d489a60cf
  Author: David Decotigny <de...@googlers.com>
  Date:   Wed Feb 24 10:57:59 2016 -0800

  net: ethtool: add new ETHTOOL_xLINKSETTINGS API


Signed-off-by: David Decotigny <de...@googlers.com>
---
 ethtool-copy.h | 485 +++--
 1 file changed, 405 insertions(+), 80 deletions(-)

diff --git a/ethtool-copy.h b/ethtool-copy.h
index d23ffc4..37fd6dc 100644
--- a/ethtool-copy.h
+++ b/ethtool-copy.h
@@ -10,8 +10,8 @@
  * Portions Copyright (C) Sun Microsystems 2008
  */
 
-#ifndef _LINUX_ETHTOOL_H
-#define _LINUX_ETHTOOL_H
+#ifndef _UAPI_LINUX_ETHTOOL_H
+#define _UAPI_LINUX_ETHTOOL_H
 
 #include 
 #include 
@@ -21,7 +21,8 @@
  */
 
 /**
- * struct ethtool_cmd - link control and status
+ * struct ethtool_cmd - DEPRECATED, link control and status
+ * This structure is DEPRECATED, please use struct ethtool_link_settings.
  * @cmd: Command number = %ETHTOOL_GSET or %ETHTOOL_SSET
  * @supported: Bitmask of %SUPPORTED_* flags for the link modes,
  * physical connectors and other link features for which the
@@ -31,7 +32,7 @@
  * physical connectors and other link features that are
  * advertised through autonegotiation or enabled for
  * auto-detection.
- * @speed: Low bits of the speed
+ * @speed: Low bits of the speed, 1Mb units, 0 to INT_MAX or SPEED_UNKNOWN
  * @duplex: Duplex mode; one of %DUPLEX_*
  * @port: Physical connector type; one of %PORT_*
  * @phy_address: MDIO address of PHY (transceiver); 0 or 255 if not
@@ -47,7 +48,7 @@
  * obsoleted by  ethtool_coalesce.  Read-only; deprecated.
  * @maxrxpkt: Historically used to report RX IRQ coalescing; now
  * obsoleted by  ethtool_coalesce.  Read-only; deprecated.
- * @speed_hi: High bits of the speed
+ * @speed_hi: High bits of the speed, 1Mb units, 0 to INT_MAX or SPEED_UNKNOWN
  * @eth_tp_mdix: Ethernet twisted-pair MDI(-X) status; one of
  * %ETH_TP_MDI_*.  If the status is unknown or not applicable, the
  * value will be %ETH_TP_MDI_INVALID.  Read-only.
@@ -110,7 +111,7 @@ struct ethtool_cmd {
__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)
 {
 
@@ -118,7 +119,7 @@ static __inline__ void ethtool_cmd_speed_set(struct 
ethtool_cmd *ep,
ep->speed_hi = (__u16)(speed >> 16);
 }
 
-static __inline__ __u32 ethtool_cmd_speed(const struct ethtool_cmd *ep)
+static inline __u32 ethtool_cmd_speed(const struct ethtool_cmd *ep)
 {
return (ep->speed_hi << 16) | ep->speed;
 }
@@ -215,6 +216,11 @@ enum tunable_id {
ETHTOOL_ID_UNSPEC,
ETHTOOL_RX_COPYBREAK,
ETHTOOL_TX_COPYBREAK,
+   /*
+* Add your fresh new tubale attribute above and remember to update
+* tunable_strings[] in net/core/ethtool.c
+*/
+   __ETHTOOL_TUNABLE_COUNT,
 };
 
 enum tunable_type_id {
@@ -537,6 +543,7 @@ struct ethtool_pauseparam {
  * now deprecated
  * @ETH_SS_FEATURES: Device feature names
  * @ETH_SS_RSS_HASH_FUNCS: RSS hush function names
+ * @ETH_SS_PHY_STATS: Statistic names, for use with %ETHTOOL_GPHYSTATS
  */
 enum ethtool_stringset {
ETH_SS_TEST = 0,
@@ -545,6 +552,8 @@ enum ethtool_stringset {
ETH_SS_NTUPLE_FILTERS,
ETH_SS_FEATURES,
ETH_SS_RSS_HASH_FUNCS,
+   ETH_SS_TUNABLES,
+   ETH_SS_PHY_STATS,
 };
 
 /**
@@ -740,6 +749,56 @@ struct ethtool_usrip4_spec {
__u8proto;
 };
 
+/**
+ * struct ethtool_tcpip6_spec - flow specification for TCP/IPv6 etc.
+ * @ip6src: Source host
+ * @ip6dst: Destination host
+ * @psrc: Source port
+ * @pdst: Destination port
+ * @tclass: Traffic Class
+ *
+ * This can be used to specify a TCP/IPv6, UDP/IPv6 or SCTP/IPv6 flow.
+ */
+struct ethtool_tcpip6_spec {
+   __be32  ip6src[4];
+   __be32  ip6dst[4];
+   __be16  psrc;
+   __be16  pdst;
+   __u8tclass;
+};
+
+/**
+ * struct ethtool_ah_espip6_spec - flow specification for IPsec/IPv6
+ * @ip6src: Source host
+ * @ip6dst: Destination host
+ * @spi: Security parameters index
+ * @tclass: Traffic Class
+ *
+ * This can be used to specify an IPsec transport or tunnel over IPv6.
+ */
+struct ethtool_ah_espip6_spec {
+   __be32  ip6src[4];
+   __be32  ip6dst[4];
+   __be32  spi;
+   __u8tclass;
+};
+
+/**
+ * struct ethtool_usrip6_spec - general flow specification for IPv6
+ * @ip6src: Source host
+ * @ip6dst: Destination host
+ * @l4_4_bytes: First 4 bytes of transport (layer 4) header
+ * @tclass: Traffic Class
+ * @l4_proto: Transport protocol number (nexthdr after any Extension Headers)
+ */
+struct ethtool_usrip6_spec {
+   __be32  ip6src[4];
+   __be32  ip6dst[4];
+   __be32  l4_4_bytes;
+   _

[ethtool PATCH v3 05/12] marvell.c: fix strict alias warnings

2016-03-04 Thread David Decotigny
From: Maciej Żenczykowski <m...@google.com>

Addresses the following warnings:
  marvell.c:426:2: error: dereferencing type-punned pointer will break 
strict-aliasing rules [-Werror=strict-aliasing]
  marvell.c:427:2: error: dereferencing type-punned pointer will break 
strict-aliasing rules [-Werror=strict-aliasing]
  marvell.c:428:2: error: dereferencing type-punned pointer will break 
strict-aliasing rules [-Werror=strict-aliasing]

Note: code appears endian-dependent, not fixed by this commit.


Signed-off-by: Maciej Żenczykowski <m...@google.com>
Signed-off-by: David Decotigny <de...@googlers.com>
---
 marvell.c | 21 +++--
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/marvell.c b/marvell.c
index e583c82..af21188 100644
--- a/marvell.c
+++ b/marvell.c
@@ -381,7 +381,8 @@ static void dump_prefetch(const char *name, const void *r)
 
 int sky2_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs)
 {
-   const u32 *r = (const u32 *) regs->data;
+   const u16 *r16 = (const u16 *) regs->data;
+   const u32 *r32 = (const u32 *) regs->data;
int dual;
 
dump_pci(regs->data + 0x1c00);
@@ -390,15 +391,15 @@ int sky2_dump_regs(struct ethtool_drvinfo *info, struct 
ethtool_regs *regs)
 
printf("\nBus Management Unit\n");
printf("---\n");
-   printf("CSR Receive Queue 1  0x%08X\n", r[24]);
-   printf("CSR Sync Queue 1 0x%08X\n", r[26]);
-   printf("CSR Async Queue 10x%08X\n", r[27]);
+   printf("CSR Receive Queue 1  0x%08X\n", r32[24]);
+   printf("CSR Sync Queue 1 0x%08X\n", r32[26]);
+   printf("CSR Async Queue 10x%08X\n", r32[27]);
 
dual = (regs->data[0x11e] & 2) != 0;
if (dual) {
-   printf("CSR Receive Queue 2  0x%08X\n", r[25]);
-   printf("CSR Async Queue 20x%08X\n", r[29]);
-   printf("CSR Sync Queue 2 0x%08X\n", r[28]);
+   printf("CSR Receive Queue 2  0x%08X\n", r32[25]);
+   printf("CSR Async Queue 20x%08X\n", r32[29]);
+   printf("CSR Sync Queue 2 0x%08X\n", r32[28]);
}
 
dump_mac(regs->data);
@@ -423,9 +424,9 @@ int sky2_dump_regs(struct ethtool_drvinfo *info, struct 
ethtool_regs *regs)
dump_timer("TX status", regs->data + 0xec0);
dump_timer("ISR", regs->data + 0xed0);
 
-   printf("\nGMAC control 0x%04X\n", *(u32 *)(regs->data + 
0xf00));
-   printf("GPHY control 0x%04X\n", *(u32 *)(regs->data + 
0xf04));
-   printf("LINK control 0x%02hX\n", *(u16 *)(regs->data + 
0xf10));
+   printf("\nGMAC control 0x%04X\n", r32[0xf00 >> 2]);
+   printf("GPHY control 0x%04X\n", r32[0xf04 >> 2]);
+   printf("LINK control 0x%02hX\n", r16[0xf10 >> 1]);
 
dump_gmac("GMAC 1", regs->data + 0x2800);
dump_gmac_fifo("Rx GMAC 1", regs->data + 0xc40);
-- 
2.7.0.rc3.207.g0ac5344



[ethtool PATCH v3 07/12] test-features.c: add braces around array initialization

2016-03-04 Thread David Decotigny
From: Maciej Żenczykowski <m...@google.com>

This fixes:
  test-features.c:21:1: error: missing braces around initializer 
[-Werror=missing-braces]
   cmd_gssetinfo = { { ETHTOOL_GSSET_INFO, 0, 1ULL << ETH_SS_FEATURES }, 34 };
   ^


Signed-off-by: Maciej Żenczykowski <m...@google.com>
Signed-off-by: David Decotigny <de...@googlers.com>
---
 test-features.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/test-features.c b/test-features.c
index d7bd994..6ebb364 100644
--- a/test-features.c
+++ b/test-features.c
@@ -18,7 +18,7 @@ static const struct {
struct ethtool_sset_info cmd;
u32 data[1];
 }
-cmd_gssetinfo = { { ETHTOOL_GSSET_INFO, 0, 1ULL << ETH_SS_FEATURES }, 34 };
+cmd_gssetinfo = { { ETHTOOL_GSSET_INFO, 0, 1ULL << ETH_SS_FEATURES }, { 34 } };
 
 static const struct ethtool_value
 cmd_grxcsum_off = { ETHTOOL_GRXCSUM, 0 },
-- 
2.7.0.rc3.207.g0ac5344



[ethtool PATCH v3 12/12] ethtool.c: use v6 socket when v4 is not available

2016-03-04 Thread David Decotigny
From: David Decotigny <de...@googlers.com>


Signed-off-by: David Decotigny <de...@googlers.com>
---
 ethtool.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/ethtool.c b/ethtool.c
index e1acf09..4daf538 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -4618,6 +4618,9 @@ opt_found:
/* Open control socket. */
ctx.fd = socket(AF_INET, SOCK_DGRAM, 0);
if (ctx.fd < 0) {
+   ctx.fd = socket(AF_INET6, SOCK_DGRAM, 0);
+   }
+   if (ctx.fd < 0) {
perror("Cannot get control socket");
return 70;
}
-- 
2.7.0.rc3.207.g0ac5344



[ethtool PATCH v3 09/12] internal.h: fix build for latest ethtool-copy.h

2016-03-04 Thread David Decotigny
From: David Decotigny <de...@googlers.com>


Signed-off-by: David Decotigny <de...@googlers.com>
---
 internal.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/internal.h b/internal.h
index 5f8504d..5df8124 100644
--- a/internal.h
+++ b/internal.h
@@ -13,6 +13,7 @@
 #ifdef HAVE_CONFIG_H
 #include "ethtool-config.h"
 #endif
+#include 
 #include 
 #include 
 #include 
@@ -36,6 +37,8 @@ typedef uint16_t u16;
 typedef uint8_t u8;
 typedef int32_t s32;
 
+#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
+
 #include "ethtool-copy.h"
 #include "net_tstamp-copy.h"
 
@@ -72,7 +75,6 @@ static inline u64 cpu_to_be64(u64 value)
 
 #define BITS_PER_BYTE  8
 #define BITS_PER_LONG  (BITS_PER_BYTE * sizeof(long))
-#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
 #define BITS_TO_LONGS(nr)  DIV_ROUND_UP(nr, BITS_PER_LONG)
 
 static inline void set_bit(unsigned int nr, unsigned long *addr)
-- 
2.7.0.rc3.207.g0ac5344



[ethtool PATCH v3 10/12] internal.h: TRUE/FALSE macros

2016-03-04 Thread David Decotigny
From: David Decotigny <de...@googlers.com>


Signed-off-by: David Decotigny <de...@googlers.com>
---
 internal.h | 8 
 1 file changed, 8 insertions(+)

diff --git a/internal.h b/internal.h
index 5df8124..7c44d0e 100644
--- a/internal.h
+++ b/internal.h
@@ -42,6 +42,14 @@ typedef int32_t s32;
 #include "ethtool-copy.h"
 #include "net_tstamp-copy.h"
 
+#ifndef TRUE
+#  define TRUE 1
+#endif
+
+#ifndef FALSE
+#  define FALSE 0
+#endif
+
 #if __BYTE_ORDER == __BIG_ENDIAN
 static inline u16 cpu_to_be16(u16 value)
 {
-- 
2.7.0.rc3.207.g0ac5344



[ethtool PATCH v3 11/12] ethtool.c: add support for ETHTOOL_xLINKSETTINGS ioctls

2016-03-04 Thread David Decotigny
From: David Decotigny <de...@googlers.com>

More info with kernel SHA1: 8d3f2806f8fbd9b22 "Merge branch
'ethtool-ksettings'".


Signed-off-by: David Decotigny <de...@googlers.com>
---
 ethtool.c  | 682 +++--
 internal.h |  66 ++
 test-cmdline.c |  12 +
 3 files changed, 601 insertions(+), 159 deletions(-)

diff --git a/ethtool.c b/ethtool.c
index 19f479c..e1acf09 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -47,42 +47,6 @@
 #define MAX_ADDR_LEN   32
 #endif
 
-#define ALL_ADVERTISED_MODES   \
-   (ADVERTISED_10baseT_Half |  \
-ADVERTISED_10baseT_Full |  \
-ADVERTISED_100baseT_Half | \
-ADVERTISED_100baseT_Full | \
-ADVERTISED_1000baseT_Half |\
-ADVERTISED_1000baseT_Full |\
-ADVERTISED_1000baseKX_Full|\
-ADVERTISED_2500baseX_Full |\
-ADVERTISED_1baseT_Full |   \
-ADVERTISED_1baseKX4_Full | \
-ADVERTISED_1baseKR_Full |  \
-ADVERTISED_1baseR_FEC |\
-ADVERTISED_2baseMLD2_Full |\
-ADVERTISED_2baseKR2_Full | \
-ADVERTISED_4baseKR4_Full | \
-ADVERTISED_4baseCR4_Full | \
-ADVERTISED_4baseSR4_Full | \
-ADVERTISED_4baseLR4_Full | \
-ADVERTISED_56000baseKR4_Full | \
-ADVERTISED_56000baseCR4_Full | \
-ADVERTISED_56000baseSR4_Full | \
-ADVERTISED_56000baseLR4_Full)
-
-#define ALL_ADVERTISED_FLAGS   \
-   (ADVERTISED_Autoneg |   \
-ADVERTISED_TP |\
-ADVERTISED_AUI |   \
-ADVERTISED_MII |   \
-ADVERTISED_FIBRE | \
-ADVERTISED_BNC |   \
-ADVERTISED_Pause | \
-ADVERTISED_Asym_Pause |\
-ADVERTISED_Backplane | \
-ALL_ADVERTISED_MODES)
-
 #ifndef HAVE_NETIF_MSG
 enum {
NETIF_MSG_DRV   = 0x0001,
@@ -293,6 +257,45 @@ static void get_mac_addr(char *src, unsigned char *dest)
}
 }
 
+static int parse_hex_u32_bitmap(const char *s,
+   unsigned int nbits, u32 *result)
+{
+   const unsigned nwords = DIV_ROUND_UP(nbits, 32);
+   size_t slen = strlen(s);
+   size_t i;
+
+   /* ignore optional '0x' prefix */
+   if ((slen > 2) && (
+   (0 == memcmp(s, "0x", 2)
+|| (0 == memcmp(s, "0X", 2) {
+   slen -= 2;
+   s += 2;
+   }
+
+   if (slen > 8*nwords)  /* up to 2 digits per byte */
+   return -1;
+
+   memset(result, 0, 4*nwords);
+   for (i = 0 ; i < slen ; ++i) {
+   const unsigned shift = (slen - 1 - i)*4;
+   u32 *dest = [shift / 32];
+   u32 nibble;
+
+   if ('a' <= s[i] && s[i] <= 'f')
+   nibble = 0xa + (s[i] - 'a');
+   else if ('A' <= s[i] && s[i] <= 'F')
+   nibble = 0xa + (s[i] - 'A');
+   else if ('0' <= s[i] && s[i] <= '9')
+   nibble = (s[i] - '0');
+   else
+   return -1;
+
+   *dest |= (nibble << (shift % 32));
+   }
+
+   return 0;
+}
+
 static void parse_generic_cmdline(struct cmd_context *ctx,
  int *changed,
  struct cmdline_info *info,
@@ -472,64 +475,157 @@ static int do_version(struct cmd_context *ctx)
return 0;
 }
 
-static void dump_link_caps(const char *prefix, const char *an_prefix, u32 mask,
-  int link_mode_only);
+/* link mode routines */
+
+static __ETHTOOL_DECLARE_LINK_MODE_MASK(all_advertised_modes);
+static __ETHTOOL_DECLARE_LINK_MODE_MASK(all_advertised_flags);
 
-static void dump_supported(struct ethtool_cmd *ep)
+static void init_global_link_mode_masks()
 {
-   u32 mask = ep->supported;
+   static const enum ethtool_link_mode_bit_indices
+   all_advertised_modes_bits[] = {
+   ETHTOOL_LINK_MODE_10baseT_Half_BIT,
+   ETHTOOL_LINK_MODE_10baseT_Full_BIT,
+   ETHTOOL_LINK_MODE_100baseT_Half_BIT,
+   ETHTOOL_LINK_MODE_100baseT_Full_BIT,
+   ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
+   ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
+   ETHTOOL_LINK_MODE_1000baseKX_Full_BIT,
+   ETHTOOL_LINK_MODE_2500baseX_Full_BIT,
+   ETHTOOL_LINK_MODE_1baseT_Full_BIT,
+

[ethtool PATCH v3 04/12] ethtool.c: do_seeprom checks for params & stdin sanity

2016-03-04 Thread David Decotigny
From: David Decotigny <de...@googlers.com>

Tested:
  On qemu e1000:
  $ dd if=/dev/zero bs=2 count=5 | /mnt/ethtool -E eth0 length 9
  too much data from stdin
  $ dd if=/dev/zero bs=2 count=5 | /mnt/ethtool -E eth0 length 11
  not enough data from stdin
  $ dd if=/dev/zero bs=2 count=5 | /mnt/ethtool -E eth0 length 10
  Cannot set EEPROM data: Bad address


Signed-off-by: David Decotigny <de...@googlers.com>
---
 ethtool.c | 24 
 1 file changed, 20 insertions(+), 4 deletions(-)

diff --git a/ethtool.c b/ethtool.c
index c64b962..19f479c 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -2828,8 +2828,14 @@ static int do_seeprom(struct cmd_context *ctx)
if (seeprom_length == -1)
seeprom_length = drvinfo.eedump_len;
 
-   if (drvinfo.eedump_len < seeprom_offset + seeprom_length)
-   seeprom_length = drvinfo.eedump_len - seeprom_offset;
+   if (drvinfo.eedump_len < seeprom_offset + seeprom_length) {
+   if (drvinfo.eedump_len > seeprom_offset)
+   seeprom_length = drvinfo.eedump_len - seeprom_offset;
+   else {
+   fprintf(stderr, "offset & length out of bounds\n");
+   return 75;
+   }
+   }
 
eeprom = calloc(1, sizeof(*eeprom)+seeprom_length);
if (!eeprom) {
@@ -2844,8 +2850,18 @@ static int do_seeprom(struct cmd_context *ctx)
eeprom->data[0] = seeprom_value;
 
/* Multi-byte write: read input from stdin */
-   if (!seeprom_value_seen)
-   eeprom->len = fread(eeprom->data, 1, eeprom->len, stdin);
+   if (!seeprom_value_seen) {
+   if (1 != fread(eeprom->data, eeprom->len, 1, stdin)) {
+   fprintf(stderr, "not enough data from stdin\n");
+   free(eeprom);
+   return 75;
+   }
+   if ((EOF != fgetc(stdin)) || !feof(stdin)) {
+   fprintf(stderr, "too much data from stdin\n");
+   free(eeprom);
+   return 75;
+   }
+   }
 
err = send_ioctl(ctx, eeprom);
if (err < 0) {
-- 
2.7.0.rc3.207.g0ac5344



[ethtool PATCH v3 06/12] test-common.c: fix test_realloc(NULL, ...)

2016-03-04 Thread David Decotigny
From: Maciej Żenczykowski <m...@google.com>

This fixes:
  test-common.c: In function 'test_realloc':
  test-common.c:109:8: error: 'block' may be used uninitialized in this 
function [-Werror=maybe-uninitialized]
block = realloc(block, sizeof(*block) + size);
  ^


Signed-off-by: Maciej Żenczykowski <m...@google.com>
Signed-off-by: David Decotigny <de...@googlers.com>
---
 test-common.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/test-common.c b/test-common.c
index adc3cd4..cd63d1d 100644
--- a/test-common.c
+++ b/test-common.c
@@ -100,7 +100,7 @@ void test_free(void *ptr)
 
 void *test_realloc(void *ptr, size_t size)
 {
-   struct list_head *block;
+   struct list_head *block = NULL;
 
if (ptr) {
block = (struct list_head *)ptr - 1;
-- 
2.7.0.rc3.207.g0ac5344



[ethtool PATCH v3 03/12] ethtool.c: fix dump_regs heap corruption

2016-03-04 Thread David Decotigny
From: David Decotigny <de...@googlers.com>

The 'regs' pointer is owned by do_gregs(), but updated internally inside
dump_regs() without propagating it back to do_gregs(): later free(regs)
in do_gregs() reclaims the wrong area. This commit moves the realloc()
inside do_gregs().


Signed-off-by: David Decotigny <de...@googlers.com>
---
 ethtool.c | 46 +-
 1 file changed, 25 insertions(+), 21 deletions(-)

diff --git a/ethtool.c b/ethtool.c
index 8a93dd1..c64b962 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -994,7 +994,6 @@ void dump_hex(FILE *file, const u8 *data, int len, int 
offset)
 }
 
 static int dump_regs(int gregs_dump_raw, int gregs_dump_hex,
-const char *gregs_dump_file,
 struct ethtool_drvinfo *info, struct ethtool_regs *regs)
 {
int i;
@@ -1004,25 +1003,6 @@ static int dump_regs(int gregs_dump_raw, int 
gregs_dump_hex,
return 0;
}
 
-   if (gregs_dump_file) {
-   FILE *f = fopen(gregs_dump_file, "r");
-   struct stat st;
-   size_t nread;
-
-   if (!f || fstat(fileno(f), ) < 0) {
-   fprintf(stderr, "Can't open '%s': %s\n",
-   gregs_dump_file, strerror(errno));
-   return -1;
-   }
-
-   regs = realloc(regs, sizeof(*regs) + st.st_size);
-   regs->len = st.st_size;
-   nread = fread(regs->data, regs->len, 1, f);
-   fclose(f);
-   if (1 != nread)
-   return -1;
-   }
-
if (!gregs_dump_hex)
for (i = 0; i < ARRAY_SIZE(driver_list); i++)
if (!strncmp(driver_list[i].name, info->driver,
@@ -2711,7 +2691,31 @@ static int do_gregs(struct cmd_context *ctx)
free(regs);
return 74;
}
-   if (dump_regs(gregs_dump_raw, gregs_dump_hex, gregs_dump_file,
+
+   if ((!gregs_dump_raw) && (NULL != gregs_dump_file)) {
+   /* overwrite reg values from file dump */
+   FILE *f = fopen(gregs_dump_file, "r");
+   struct stat st;
+   size_t nread;
+
+   if (!f || fstat(fileno(f), ) < 0) {
+   fprintf(stderr, "Can't open '%s': %s\n",
+   gregs_dump_file, strerror(errno));
+   free(regs);
+   return 75;
+   }
+
+   regs = realloc(regs, sizeof(*regs) + st.st_size);
+   regs->len = st.st_size;
+   nread = fread(regs->data, regs->len, 1, f);
+   fclose(f);
+   if (1 != nread) {
+   free(regs);
+   return 75;
+   }
+}
+
+   if (dump_regs(gregs_dump_raw, gregs_dump_hex,
  , regs) < 0) {
fprintf(stderr, "Cannot dump registers\n");
free(regs);
-- 
2.7.0.rc3.207.g0ac5344



[ethtool PATCH v3 01/12] internal.h: change to new sane powerpc64 kernel headers

2016-03-04 Thread David Decotigny
From: Maciej Żenczykowski <m...@google.com>

This fixes:
  In file included from ethtool-copy.h:22:0,
   from internal.h:32,
   from ethtool.c:29:
  .../include/linux/types.h:32:25: error: conflicting types for '__be64'
   typedef __u64 __bitwise __be64;
   ^
  In file included from ethtool.c:29:0:
  internal.h:23:28: note: previous declaration of '__be64' was here
   typedef unsigned long long __be64;
  ^
  ethtool.c: In function 'do_gstats':
  ethtool.c:3166:4: error: format '%llu' expects argument of type 'long long 
unsigned int', but argument 5 has type '__u64' [-Werror=format=]
  stats->data[i]);
  ^
  ethtool.c: In function 'print_indir_table':
  ethtool.c:3293:9: error: format '%llu' expects argument of type 'long long 
unsigned int', but argument 3 has type '__u64' [-Werror=format=]
   ctx->devname, ring_count->data);
   ^


Signed-off-by: Maciej Żenczykowski <m...@google.com>
Signed-off-by: David Decotigny <de...@googlers.com>
---
 internal.h | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/internal.h b/internal.h
index b5ef646..5f8504d 100644
--- a/internal.h
+++ b/internal.h
@@ -3,6 +3,13 @@
 #ifndef ETHTOOL_INTERNAL_H__
 #define ETHTOOL_INTERNAL_H__
 
+#ifdef __powerpc64__
+/* Powerpc needs __SANE_USERSPACE_TYPES__ before  to select
+ * 'int-ll64.h' and avoid compile warnings when printing __u64 with %llu.
+ */
+#define __SANE_USERSPACE_TYPES__
+#endif
+
 #ifdef HAVE_CONFIG_H
 #include "ethtool-config.h"
 #endif
-- 
2.7.0.rc3.207.g0ac5344



[ethtool PATCH v3 00/12] add support for new ETHTOOL_xLINKSETTINGS ioctls

2016-03-04 Thread David Decotigny
From: David Decotigny <de...@googlers.com>

This adds support for the new ETHTOOL_xLINKSETTINGS ioctls. This also
fixes a few compilation warnings as well as a heap corruption bug.

History:
  v3
TRUE/FALSE obvious-ification
  v2
added do_seeprom patch
added netdev@ as recipient
  v1
initial submission


# Patch Set Summary:

David Decotigny (8):
  ethtool.c: don't ignore fread() return value
  ethtool.c: fix dump_regs heap corruption
  ethtool.c: do_seeprom checks for params & stdin sanity
  ethtool-copy.h: sync with net-next
  internal.h: fix build for latest ethtool-copy.h
  internal.h: TRUE/FALSE macros
  ethtool.c: add support for ETHTOOL_xLINKSETTINGS ioctls
  ethtool.c: use v6 socket when v4 is not available

Maciej Żenczykowski (4):
  internal.h: change to new sane powerpc64 kernel headers
  marvell.c: fix strict alias warnings
  test-common.c: fix test_realloc(NULL, ...)
  test-features.c: add braces around array initialization

 ethtool-copy.h  | 485 ++--
 ethtool.c   | 752 ++--
 internal.h  |  85 ++-
 marvell.c   |  21 +-
 test-cmdline.c  |  12 +
 test-common.c   |   2 +-
 test-features.c |   2 +-
 7 files changed, 1085 insertions(+), 274 deletions(-)

-- 
2.7.0.rc3.207.g0ac5344



[ethtool PATCH v2 07/12] test-features.c: add braces around array initialization

2016-03-03 Thread David Decotigny
From: Maciej Żenczykowski <m...@google.com>

This fixes:
  test-features.c:21:1: error: missing braces around initializer 
[-Werror=missing-braces]
   cmd_gssetinfo = { { ETHTOOL_GSSET_INFO, 0, 1ULL << ETH_SS_FEATURES }, 34 };
   ^


Signed-off-by: David Decotigny <de...@googlers.com>
---
 test-features.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/test-features.c b/test-features.c
index d7bd994..6ebb364 100644
--- a/test-features.c
+++ b/test-features.c
@@ -18,7 +18,7 @@ static const struct {
struct ethtool_sset_info cmd;
u32 data[1];
 }
-cmd_gssetinfo = { { ETHTOOL_GSSET_INFO, 0, 1ULL << ETH_SS_FEATURES }, 34 };
+cmd_gssetinfo = { { ETHTOOL_GSSET_INFO, 0, 1ULL << ETH_SS_FEATURES }, { 34 } };
 
 static const struct ethtool_value
 cmd_grxcsum_off = { ETHTOOL_GRXCSUM, 0 },
-- 
2.7.0.rc3.207.g0ac5344



[ethtool PATCH v2 03/12] ethtool.c: fix dump_regs heap corruption

2016-03-03 Thread David Decotigny
From: David Decotigny <de...@googlers.com>

The 'regs' pointer is owned by do_gregs(), but updated internally inside
dump_regs() without propagating it back to do_gregs(): later free(regs)
in do_gregs() reclaims the wrong area. This commit moves the realloc()
inside do_gregs().


Signed-off-by: David Decotigny <de...@googlers.com>
---
 ethtool.c | 46 +-
 1 file changed, 25 insertions(+), 21 deletions(-)

diff --git a/ethtool.c b/ethtool.c
index 8a93dd1..c64b962 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -994,7 +994,6 @@ void dump_hex(FILE *file, const u8 *data, int len, int 
offset)
 }
 
 static int dump_regs(int gregs_dump_raw, int gregs_dump_hex,
-const char *gregs_dump_file,
 struct ethtool_drvinfo *info, struct ethtool_regs *regs)
 {
int i;
@@ -1004,25 +1003,6 @@ static int dump_regs(int gregs_dump_raw, int 
gregs_dump_hex,
return 0;
}
 
-   if (gregs_dump_file) {
-   FILE *f = fopen(gregs_dump_file, "r");
-   struct stat st;
-   size_t nread;
-
-   if (!f || fstat(fileno(f), ) < 0) {
-   fprintf(stderr, "Can't open '%s': %s\n",
-   gregs_dump_file, strerror(errno));
-   return -1;
-   }
-
-   regs = realloc(regs, sizeof(*regs) + st.st_size);
-   regs->len = st.st_size;
-   nread = fread(regs->data, regs->len, 1, f);
-   fclose(f);
-   if (1 != nread)
-   return -1;
-   }
-
if (!gregs_dump_hex)
for (i = 0; i < ARRAY_SIZE(driver_list); i++)
if (!strncmp(driver_list[i].name, info->driver,
@@ -2711,7 +2691,31 @@ static int do_gregs(struct cmd_context *ctx)
free(regs);
return 74;
}
-   if (dump_regs(gregs_dump_raw, gregs_dump_hex, gregs_dump_file,
+
+   if ((!gregs_dump_raw) && (NULL != gregs_dump_file)) {
+   /* overwrite reg values from file dump */
+   FILE *f = fopen(gregs_dump_file, "r");
+   struct stat st;
+   size_t nread;
+
+   if (!f || fstat(fileno(f), ) < 0) {
+   fprintf(stderr, "Can't open '%s': %s\n",
+   gregs_dump_file, strerror(errno));
+   free(regs);
+   return 75;
+   }
+
+   regs = realloc(regs, sizeof(*regs) + st.st_size);
+   regs->len = st.st_size;
+   nread = fread(regs->data, regs->len, 1, f);
+   fclose(f);
+   if (1 != nread) {
+   free(regs);
+   return 75;
+   }
+}
+
+   if (dump_regs(gregs_dump_raw, gregs_dump_hex,
  , regs) < 0) {
fprintf(stderr, "Cannot dump registers\n");
free(regs);
-- 
2.7.0.rc3.207.g0ac5344



[ethtool PATCH v2 08/12] ethtool-copy.h: sync with net-next

2016-03-03 Thread David Decotigny
From: David Decotigny <de...@googlers.com>

This cover changes up to:

  commit 3f1ac7a700d039c61d8d8b99f28d605d489a60cf
  Author: David Decotigny <de...@googlers.com>
  Date:   Wed Feb 24 10:57:59 2016 -0800

  net: ethtool: add new ETHTOOL_xLINKSETTINGS API


Signed-off-by: David Decotigny <de...@googlers.com>
---
 ethtool-copy.h | 485 +++--
 1 file changed, 405 insertions(+), 80 deletions(-)

diff --git a/ethtool-copy.h b/ethtool-copy.h
index d23ffc4..37fd6dc 100644
--- a/ethtool-copy.h
+++ b/ethtool-copy.h
@@ -10,8 +10,8 @@
  * Portions Copyright (C) Sun Microsystems 2008
  */
 
-#ifndef _LINUX_ETHTOOL_H
-#define _LINUX_ETHTOOL_H
+#ifndef _UAPI_LINUX_ETHTOOL_H
+#define _UAPI_LINUX_ETHTOOL_H
 
 #include 
 #include 
@@ -21,7 +21,8 @@
  */
 
 /**
- * struct ethtool_cmd - link control and status
+ * struct ethtool_cmd - DEPRECATED, link control and status
+ * This structure is DEPRECATED, please use struct ethtool_link_settings.
  * @cmd: Command number = %ETHTOOL_GSET or %ETHTOOL_SSET
  * @supported: Bitmask of %SUPPORTED_* flags for the link modes,
  * physical connectors and other link features for which the
@@ -31,7 +32,7 @@
  * physical connectors and other link features that are
  * advertised through autonegotiation or enabled for
  * auto-detection.
- * @speed: Low bits of the speed
+ * @speed: Low bits of the speed, 1Mb units, 0 to INT_MAX or SPEED_UNKNOWN
  * @duplex: Duplex mode; one of %DUPLEX_*
  * @port: Physical connector type; one of %PORT_*
  * @phy_address: MDIO address of PHY (transceiver); 0 or 255 if not
@@ -47,7 +48,7 @@
  * obsoleted by  ethtool_coalesce.  Read-only; deprecated.
  * @maxrxpkt: Historically used to report RX IRQ coalescing; now
  * obsoleted by  ethtool_coalesce.  Read-only; deprecated.
- * @speed_hi: High bits of the speed
+ * @speed_hi: High bits of the speed, 1Mb units, 0 to INT_MAX or SPEED_UNKNOWN
  * @eth_tp_mdix: Ethernet twisted-pair MDI(-X) status; one of
  * %ETH_TP_MDI_*.  If the status is unknown or not applicable, the
  * value will be %ETH_TP_MDI_INVALID.  Read-only.
@@ -110,7 +111,7 @@ struct ethtool_cmd {
__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)
 {
 
@@ -118,7 +119,7 @@ static __inline__ void ethtool_cmd_speed_set(struct 
ethtool_cmd *ep,
ep->speed_hi = (__u16)(speed >> 16);
 }
 
-static __inline__ __u32 ethtool_cmd_speed(const struct ethtool_cmd *ep)
+static inline __u32 ethtool_cmd_speed(const struct ethtool_cmd *ep)
 {
return (ep->speed_hi << 16) | ep->speed;
 }
@@ -215,6 +216,11 @@ enum tunable_id {
ETHTOOL_ID_UNSPEC,
ETHTOOL_RX_COPYBREAK,
ETHTOOL_TX_COPYBREAK,
+   /*
+* Add your fresh new tubale attribute above and remember to update
+* tunable_strings[] in net/core/ethtool.c
+*/
+   __ETHTOOL_TUNABLE_COUNT,
 };
 
 enum tunable_type_id {
@@ -537,6 +543,7 @@ struct ethtool_pauseparam {
  * now deprecated
  * @ETH_SS_FEATURES: Device feature names
  * @ETH_SS_RSS_HASH_FUNCS: RSS hush function names
+ * @ETH_SS_PHY_STATS: Statistic names, for use with %ETHTOOL_GPHYSTATS
  */
 enum ethtool_stringset {
ETH_SS_TEST = 0,
@@ -545,6 +552,8 @@ enum ethtool_stringset {
ETH_SS_NTUPLE_FILTERS,
ETH_SS_FEATURES,
ETH_SS_RSS_HASH_FUNCS,
+   ETH_SS_TUNABLES,
+   ETH_SS_PHY_STATS,
 };
 
 /**
@@ -740,6 +749,56 @@ struct ethtool_usrip4_spec {
__u8proto;
 };
 
+/**
+ * struct ethtool_tcpip6_spec - flow specification for TCP/IPv6 etc.
+ * @ip6src: Source host
+ * @ip6dst: Destination host
+ * @psrc: Source port
+ * @pdst: Destination port
+ * @tclass: Traffic Class
+ *
+ * This can be used to specify a TCP/IPv6, UDP/IPv6 or SCTP/IPv6 flow.
+ */
+struct ethtool_tcpip6_spec {
+   __be32  ip6src[4];
+   __be32  ip6dst[4];
+   __be16  psrc;
+   __be16  pdst;
+   __u8tclass;
+};
+
+/**
+ * struct ethtool_ah_espip6_spec - flow specification for IPsec/IPv6
+ * @ip6src: Source host
+ * @ip6dst: Destination host
+ * @spi: Security parameters index
+ * @tclass: Traffic Class
+ *
+ * This can be used to specify an IPsec transport or tunnel over IPv6.
+ */
+struct ethtool_ah_espip6_spec {
+   __be32  ip6src[4];
+   __be32  ip6dst[4];
+   __be32  spi;
+   __u8tclass;
+};
+
+/**
+ * struct ethtool_usrip6_spec - general flow specification for IPv6
+ * @ip6src: Source host
+ * @ip6dst: Destination host
+ * @l4_4_bytes: First 4 bytes of transport (layer 4) header
+ * @tclass: Traffic Class
+ * @l4_proto: Transport protocol number (nexthdr after any Extension Headers)
+ */
+struct ethtool_usrip6_spec {
+   __be32  ip6src[4];
+   __be32  ip6dst[4];
+   __be32  l4_4_bytes;
+   _

[ethtool PATCH v2 10/12] internal.h: TRUE/FALSE macros

2016-03-03 Thread David Decotigny
From: David Decotigny <de...@googlers.com>


Signed-off-by: David Decotigny <de...@googlers.com>
---
 internal.h | 8 
 1 file changed, 8 insertions(+)

diff --git a/internal.h b/internal.h
index 5df8124..5fd87f1 100644
--- a/internal.h
+++ b/internal.h
@@ -42,6 +42,14 @@ typedef int32_t s32;
 #include "ethtool-copy.h"
 #include "net_tstamp-copy.h"
 
+#ifndef TRUE
+#  define TRUE (!0)
+#endif
+
+#ifndef FALSE
+#  define FALSE (!!0)
+#endif
+
 #if __BYTE_ORDER == __BIG_ENDIAN
 static inline u16 cpu_to_be16(u16 value)
 {
-- 
2.7.0.rc3.207.g0ac5344



[ethtool PATCH v2 11/12] ethtool.c: add support for ETHTOOL_xLINKSETTINGS ioctls

2016-03-03 Thread David Decotigny
From: David Decotigny <de...@googlers.com>

More info with kernel SHA1: 8d3f2806f8fbd9b22 "Merge branch
'ethtool-ksettings'".


Signed-off-by: David Decotigny <de...@googlers.com>
---
 ethtool.c  | 682 +++--
 internal.h |  66 ++
 test-cmdline.c |  12 +
 3 files changed, 601 insertions(+), 159 deletions(-)

diff --git a/ethtool.c b/ethtool.c
index 19f479c..e1acf09 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -47,42 +47,6 @@
 #define MAX_ADDR_LEN   32
 #endif
 
-#define ALL_ADVERTISED_MODES   \
-   (ADVERTISED_10baseT_Half |  \
-ADVERTISED_10baseT_Full |  \
-ADVERTISED_100baseT_Half | \
-ADVERTISED_100baseT_Full | \
-ADVERTISED_1000baseT_Half |\
-ADVERTISED_1000baseT_Full |\
-ADVERTISED_1000baseKX_Full|\
-ADVERTISED_2500baseX_Full |\
-ADVERTISED_1baseT_Full |   \
-ADVERTISED_1baseKX4_Full | \
-ADVERTISED_1baseKR_Full |  \
-ADVERTISED_1baseR_FEC |\
-ADVERTISED_2baseMLD2_Full |\
-ADVERTISED_2baseKR2_Full | \
-ADVERTISED_4baseKR4_Full | \
-ADVERTISED_4baseCR4_Full | \
-ADVERTISED_4baseSR4_Full | \
-ADVERTISED_4baseLR4_Full | \
-ADVERTISED_56000baseKR4_Full | \
-ADVERTISED_56000baseCR4_Full | \
-ADVERTISED_56000baseSR4_Full | \
-ADVERTISED_56000baseLR4_Full)
-
-#define ALL_ADVERTISED_FLAGS   \
-   (ADVERTISED_Autoneg |   \
-ADVERTISED_TP |\
-ADVERTISED_AUI |   \
-ADVERTISED_MII |   \
-ADVERTISED_FIBRE | \
-ADVERTISED_BNC |   \
-ADVERTISED_Pause | \
-ADVERTISED_Asym_Pause |\
-ADVERTISED_Backplane | \
-ALL_ADVERTISED_MODES)
-
 #ifndef HAVE_NETIF_MSG
 enum {
NETIF_MSG_DRV   = 0x0001,
@@ -293,6 +257,45 @@ static void get_mac_addr(char *src, unsigned char *dest)
}
 }
 
+static int parse_hex_u32_bitmap(const char *s,
+   unsigned int nbits, u32 *result)
+{
+   const unsigned nwords = DIV_ROUND_UP(nbits, 32);
+   size_t slen = strlen(s);
+   size_t i;
+
+   /* ignore optional '0x' prefix */
+   if ((slen > 2) && (
+   (0 == memcmp(s, "0x", 2)
+|| (0 == memcmp(s, "0X", 2) {
+   slen -= 2;
+   s += 2;
+   }
+
+   if (slen > 8*nwords)  /* up to 2 digits per byte */
+   return -1;
+
+   memset(result, 0, 4*nwords);
+   for (i = 0 ; i < slen ; ++i) {
+   const unsigned shift = (slen - 1 - i)*4;
+   u32 *dest = [shift / 32];
+   u32 nibble;
+
+   if ('a' <= s[i] && s[i] <= 'f')
+   nibble = 0xa + (s[i] - 'a');
+   else if ('A' <= s[i] && s[i] <= 'F')
+   nibble = 0xa + (s[i] - 'A');
+   else if ('0' <= s[i] && s[i] <= '9')
+   nibble = (s[i] - '0');
+   else
+   return -1;
+
+   *dest |= (nibble << (shift % 32));
+   }
+
+   return 0;
+}
+
 static void parse_generic_cmdline(struct cmd_context *ctx,
  int *changed,
  struct cmdline_info *info,
@@ -472,64 +475,157 @@ static int do_version(struct cmd_context *ctx)
return 0;
 }
 
-static void dump_link_caps(const char *prefix, const char *an_prefix, u32 mask,
-  int link_mode_only);
+/* link mode routines */
+
+static __ETHTOOL_DECLARE_LINK_MODE_MASK(all_advertised_modes);
+static __ETHTOOL_DECLARE_LINK_MODE_MASK(all_advertised_flags);
 
-static void dump_supported(struct ethtool_cmd *ep)
+static void init_global_link_mode_masks()
 {
-   u32 mask = ep->supported;
+   static const enum ethtool_link_mode_bit_indices
+   all_advertised_modes_bits[] = {
+   ETHTOOL_LINK_MODE_10baseT_Half_BIT,
+   ETHTOOL_LINK_MODE_10baseT_Full_BIT,
+   ETHTOOL_LINK_MODE_100baseT_Half_BIT,
+   ETHTOOL_LINK_MODE_100baseT_Full_BIT,
+   ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
+   ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
+   ETHTOOL_LINK_MODE_1000baseKX_Full_BIT,
+   ETHTOOL_LINK_MODE_2500baseX_Full_BIT,
+   ETHTOOL_LINK_MODE_1baseT_Full_BIT,
+

[ethtool PATCH v2 04/12] ethtool.c: do_seeprom checks for params & stdin sanity

2016-03-03 Thread David Decotigny
From: David Decotigny <de...@googlers.com>

Tested:
  On qemu e1000:
  $ dd if=/dev/zero bs=2 count=5 | /mnt/ethtool -E eth0 length 9
  too much data from stdin
  $ dd if=/dev/zero bs=2 count=5 | /mnt/ethtool -E eth0 length 11
  not enough data from stdin
  $ dd if=/dev/zero bs=2 count=5 | /mnt/ethtool -E eth0 length 10
  Cannot set EEPROM data: Bad address


Signed-off-by: David Decotigny <de...@googlers.com>
---
 ethtool.c | 24 
 1 file changed, 20 insertions(+), 4 deletions(-)

diff --git a/ethtool.c b/ethtool.c
index c64b962..19f479c 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -2828,8 +2828,14 @@ static int do_seeprom(struct cmd_context *ctx)
if (seeprom_length == -1)
seeprom_length = drvinfo.eedump_len;
 
-   if (drvinfo.eedump_len < seeprom_offset + seeprom_length)
-   seeprom_length = drvinfo.eedump_len - seeprom_offset;
+   if (drvinfo.eedump_len < seeprom_offset + seeprom_length) {
+   if (drvinfo.eedump_len > seeprom_offset)
+   seeprom_length = drvinfo.eedump_len - seeprom_offset;
+   else {
+   fprintf(stderr, "offset & length out of bounds\n");
+   return 75;
+   }
+   }
 
eeprom = calloc(1, sizeof(*eeprom)+seeprom_length);
if (!eeprom) {
@@ -2844,8 +2850,18 @@ static int do_seeprom(struct cmd_context *ctx)
eeprom->data[0] = seeprom_value;
 
/* Multi-byte write: read input from stdin */
-   if (!seeprom_value_seen)
-   eeprom->len = fread(eeprom->data, 1, eeprom->len, stdin);
+   if (!seeprom_value_seen) {
+   if (1 != fread(eeprom->data, eeprom->len, 1, stdin)) {
+   fprintf(stderr, "not enough data from stdin\n");
+   free(eeprom);
+   return 75;
+   }
+   if ((EOF != fgetc(stdin)) || !feof(stdin)) {
+   fprintf(stderr, "too much data from stdin\n");
+   free(eeprom);
+   return 75;
+   }
+   }
 
err = send_ioctl(ctx, eeprom);
if (err < 0) {
-- 
2.7.0.rc3.207.g0ac5344



[ethtool PATCH v2 05/12] marvell.c: fix strict alias warnings

2016-03-03 Thread David Decotigny
From: Maciej Żenczykowski <m...@google.com>

Addresses the following warnings:
  marvell.c:426:2: error: dereferencing type-punned pointer will break 
strict-aliasing rules [-Werror=strict-aliasing]
  marvell.c:427:2: error: dereferencing type-punned pointer will break 
strict-aliasing rules [-Werror=strict-aliasing]
  marvell.c:428:2: error: dereferencing type-punned pointer will break 
strict-aliasing rules [-Werror=strict-aliasing]

Note: code appears endian-dependent, not fixed by this commit.


Signed-off-by: David Decotigny <de...@googlers.com>
---
 marvell.c | 21 +++--
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/marvell.c b/marvell.c
index e583c82..af21188 100644
--- a/marvell.c
+++ b/marvell.c
@@ -381,7 +381,8 @@ static void dump_prefetch(const char *name, const void *r)
 
 int sky2_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs)
 {
-   const u32 *r = (const u32 *) regs->data;
+   const u16 *r16 = (const u16 *) regs->data;
+   const u32 *r32 = (const u32 *) regs->data;
int dual;
 
dump_pci(regs->data + 0x1c00);
@@ -390,15 +391,15 @@ int sky2_dump_regs(struct ethtool_drvinfo *info, struct 
ethtool_regs *regs)
 
printf("\nBus Management Unit\n");
printf("---\n");
-   printf("CSR Receive Queue 1  0x%08X\n", r[24]);
-   printf("CSR Sync Queue 1 0x%08X\n", r[26]);
-   printf("CSR Async Queue 10x%08X\n", r[27]);
+   printf("CSR Receive Queue 1  0x%08X\n", r32[24]);
+   printf("CSR Sync Queue 1 0x%08X\n", r32[26]);
+   printf("CSR Async Queue 10x%08X\n", r32[27]);
 
dual = (regs->data[0x11e] & 2) != 0;
if (dual) {
-   printf("CSR Receive Queue 2  0x%08X\n", r[25]);
-   printf("CSR Async Queue 20x%08X\n", r[29]);
-   printf("CSR Sync Queue 2 0x%08X\n", r[28]);
+   printf("CSR Receive Queue 2  0x%08X\n", r32[25]);
+   printf("CSR Async Queue 20x%08X\n", r32[29]);
+   printf("CSR Sync Queue 2 0x%08X\n", r32[28]);
}
 
dump_mac(regs->data);
@@ -423,9 +424,9 @@ int sky2_dump_regs(struct ethtool_drvinfo *info, struct 
ethtool_regs *regs)
dump_timer("TX status", regs->data + 0xec0);
dump_timer("ISR", regs->data + 0xed0);
 
-   printf("\nGMAC control 0x%04X\n", *(u32 *)(regs->data + 
0xf00));
-   printf("GPHY control 0x%04X\n", *(u32 *)(regs->data + 
0xf04));
-   printf("LINK control 0x%02hX\n", *(u16 *)(regs->data + 
0xf10));
+   printf("\nGMAC control 0x%04X\n", r32[0xf00 >> 2]);
+   printf("GPHY control 0x%04X\n", r32[0xf04 >> 2]);
+   printf("LINK control 0x%02hX\n", r16[0xf10 >> 1]);
 
dump_gmac("GMAC 1", regs->data + 0x2800);
dump_gmac_fifo("Rx GMAC 1", regs->data + 0xc40);
-- 
2.7.0.rc3.207.g0ac5344



[ethtool PATCH v2 09/12] internal.h: fix build for latest ethtool-copy.h

2016-03-03 Thread David Decotigny
From: David Decotigny <de...@googlers.com>


Signed-off-by: David Decotigny <de...@googlers.com>
---
 internal.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/internal.h b/internal.h
index 5f8504d..5df8124 100644
--- a/internal.h
+++ b/internal.h
@@ -13,6 +13,7 @@
 #ifdef HAVE_CONFIG_H
 #include "ethtool-config.h"
 #endif
+#include 
 #include 
 #include 
 #include 
@@ -36,6 +37,8 @@ typedef uint16_t u16;
 typedef uint8_t u8;
 typedef int32_t s32;
 
+#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
+
 #include "ethtool-copy.h"
 #include "net_tstamp-copy.h"
 
@@ -72,7 +75,6 @@ static inline u64 cpu_to_be64(u64 value)
 
 #define BITS_PER_BYTE  8
 #define BITS_PER_LONG  (BITS_PER_BYTE * sizeof(long))
-#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
 #define BITS_TO_LONGS(nr)  DIV_ROUND_UP(nr, BITS_PER_LONG)
 
 static inline void set_bit(unsigned int nr, unsigned long *addr)
-- 
2.7.0.rc3.207.g0ac5344



[ethtool PATCH v2 02/12] ethtool.c: don't ignore fread() return value

2016-03-03 Thread David Decotigny
From: David Decotigny <de...@googlers.com>

This addresses:
  ethtool.c:1116:8: warning: ignoring return value of ‘fread’, declared with 
attribute warn_unused_result [-Wunused-result]


Signed-off-by: David Decotigny <de...@googlers.com>
---
 ethtool.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/ethtool.c b/ethtool.c
index 92c40b8..8a93dd1 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -1007,6 +1007,7 @@ static int dump_regs(int gregs_dump_raw, int 
gregs_dump_hex,
if (gregs_dump_file) {
FILE *f = fopen(gregs_dump_file, "r");
struct stat st;
+   size_t nread;
 
if (!f || fstat(fileno(f), ) < 0) {
fprintf(stderr, "Can't open '%s': %s\n",
@@ -1016,8 +1017,10 @@ static int dump_regs(int gregs_dump_raw, int 
gregs_dump_hex,
 
regs = realloc(regs, sizeof(*regs) + st.st_size);
regs->len = st.st_size;
-   fread(regs->data, regs->len, 1, f);
+   nread = fread(regs->data, regs->len, 1, f);
fclose(f);
+   if (1 != nread)
+   return -1;
}
 
if (!gregs_dump_hex)
-- 
2.7.0.rc3.207.g0ac5344



[ethtool PATCH v2 12/12] ethtool.c: use v6 socket when v4 is not available

2016-03-03 Thread David Decotigny
From: David Decotigny <de...@googlers.com>


Signed-off-by: David Decotigny <de...@googlers.com>
---
 ethtool.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/ethtool.c b/ethtool.c
index e1acf09..4daf538 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -4618,6 +4618,9 @@ opt_found:
/* Open control socket. */
ctx.fd = socket(AF_INET, SOCK_DGRAM, 0);
if (ctx.fd < 0) {
+   ctx.fd = socket(AF_INET6, SOCK_DGRAM, 0);
+   }
+   if (ctx.fd < 0) {
perror("Cannot get control socket");
return 70;
}
-- 
2.7.0.rc3.207.g0ac5344



[ethtool PATCH v2 06/12] test-common.c: fix test_realloc(NULL, ...)

2016-03-03 Thread David Decotigny
From: Maciej Żenczykowski <m...@google.com>

This fixes:
  test-common.c: In function 'test_realloc':
  test-common.c:109:8: error: 'block' may be used uninitialized in this 
function [-Werror=maybe-uninitialized]
block = realloc(block, sizeof(*block) + size);
  ^


Signed-off-by: David Decotigny <de...@googlers.com>
---
 test-common.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/test-common.c b/test-common.c
index adc3cd4..cd63d1d 100644
--- a/test-common.c
+++ b/test-common.c
@@ -100,7 +100,7 @@ void test_free(void *ptr)
 
 void *test_realloc(void *ptr, size_t size)
 {
-   struct list_head *block;
+   struct list_head *block = NULL;
 
if (ptr) {
block = (struct list_head *)ptr - 1;
-- 
2.7.0.rc3.207.g0ac5344



[ethtool PATCH v2 01/12] internal.h: change to new sane powerpc64 kernel headers

2016-03-03 Thread David Decotigny
From: Maciej Żenczykowski <m...@google.com>

This fixes:
  In file included from ethtool-copy.h:22:0,
   from internal.h:32,
   from ethtool.c:29:
  .../include/linux/types.h:32:25: error: conflicting types for '__be64'
   typedef __u64 __bitwise __be64;
   ^
  In file included from ethtool.c:29:0:
  internal.h:23:28: note: previous declaration of '__be64' was here
   typedef unsigned long long __be64;
  ^
  ethtool.c: In function 'do_gstats':
  ethtool.c:3166:4: error: format '%llu' expects argument of type 'long long 
unsigned int', but argument 5 has type '__u64' [-Werror=format=]
  stats->data[i]);
  ^
  ethtool.c: In function 'print_indir_table':
  ethtool.c:3293:9: error: format '%llu' expects argument of type 'long long 
unsigned int', but argument 3 has type '__u64' [-Werror=format=]
   ctx->devname, ring_count->data);
   ^


Signed-off-by: David Decotigny <de...@googlers.com>
---
 internal.h | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/internal.h b/internal.h
index b5ef646..5f8504d 100644
--- a/internal.h
+++ b/internal.h
@@ -3,6 +3,13 @@
 #ifndef ETHTOOL_INTERNAL_H__
 #define ETHTOOL_INTERNAL_H__
 
+#ifdef __powerpc64__
+/* Powerpc needs __SANE_USERSPACE_TYPES__ before  to select
+ * 'int-ll64.h' and avoid compile warnings when printing __u64 with %llu.
+ */
+#define __SANE_USERSPACE_TYPES__
+#endif
+
 #ifdef HAVE_CONFIG_H
 #include "ethtool-config.h"
 #endif
-- 
2.7.0.rc3.207.g0ac5344



[ethtool PATCH v2 00/12] add support for new ETHTOOL_xLINKSETTINGS ioctls

2016-03-03 Thread David Decotigny
From: David Decotigny <de...@googlers.com>

This adds support for the new ETHTOOL_xLINKSETTINGS ioctls. This also
fixes a few compilation warnings as well as a heap corruption bug.

History:
  v2
added do_seeprom patch
added netdev@ as recipient
  v1
initial submission


# Patch Set Summary:

David Decotigny (8):
  ethtool.c: don't ignore fread() return value
  ethtool.c: fix dump_regs heap corruption
  ethtool.c: do_seeprom checks for params & stdin sanity
  ethtool-copy.h: sync with net-next
  internal.h: fix build for latest ethtool-copy.h
  internal.h: TRUE/FALSE macros
  ethtool.c: add support for ETHTOOL_xLINKSETTINGS ioctls
  ethtool.c: use v6 socket when v4 is not available

Maciej Żenczykowski (4):
  internal.h: change to new sane powerpc64 kernel headers
  marvell.c: fix strict alias warnings
  test-common.c: fix test_realloc(NULL, ...)
  test-features.c: add braces around array initialization

 ethtool-copy.h  | 485 ++--
 ethtool.c   | 752 ++--
 internal.h  |  85 ++-
 marvell.c   |  21 +-
 test-cmdline.c  |  12 +
 test-common.c   |   2 +-
 test-features.c |   2 +-
 7 files changed, 1085 insertions(+), 274 deletions(-)

-- 
2.7.0.rc3.207.g0ac5344



[PATCH net-next v9 03/16] net: ethtool: add new ETHTOOL_xLINKSETTINGS API

2016-02-24 Thread David Decotigny
From: David Decotigny <de...@googlers.com>

This patch defines a new ETHTOOL_GLINKSETTINGS/SLINKSETTINGS API,
handled by the new get_link_ksettings/set_link_ksettings callbacks.
This API provides support for most legacy ethtool_cmd fields, adds
support for larger link mode masks (up to 4064 bits, variable length),
and removes ethtool_cmd deprecated
fields (transceiver/maxrxpkt/maxtxpkt).

This API is deprecating the legacy ETHTOOL_GSET/SSET API and provides
the following backward compatibility properties:
 - legacy ethtool with legacy drivers: no change, still using the
   get_settings/set_settings callbacks.
 - legacy ethtool with new get/set_link_ksettings drivers: the new
   driver callbacks are used, data internally converted to legacy
   ethtool_cmd. ETHTOOL_GSET will return only the 1st 32b of each link
   mode mask. ETHTOOL_SSET will fail if user tries to set the
   ethtool_cmd deprecated fields to
   non-0 (transceiver/maxrxpkt/maxtxpkt). A kernel warning is logged if
   driver sets higher bits.
 - future ethtool with legacy drivers: no change, still using the
   get_settings/set_settings callbacks, internally converted to new data
   structure. Deprecated fields (transceiver/maxrxpkt/maxtxpkt) will be
   ignored and seen as 0 from user space. Note that that "future"
   ethtool tool will not allow changes to these deprecated fields.
 - future ethtool with new drivers: direct call to the new callbacks.

By "future" ethtool, what is meant is:
 - query: first try ETHTOOL_GLINKSETTINGS, and revert to ETHTOOL_GSET if
   fails
 - set: query first and remember which of ETHTOOL_GLINKSETTINGS or
   ETHTOOL_GSET was successful
   + if ETHTOOL_GLINKSETTINGS was successful, then change config with
 ETHTOOL_SLINKSETTINGS. A failure there is final (do not try
 ETHTOOL_SSET).
   + otherwise ETHTOOL_GSET was successful, change config with
 ETHTOOL_SSET. A failure there is final (do not try
 ETHTOOL_SLINKSETTINGS).

The interaction user/kernel via the new API requires a small
ETHTOOL_GLINKSETTINGS handshake first to agree on the length of the link
mode bitmaps. If kernel doesn't agree with user, it returns the bitmap
length it is expecting from user as a negative length (and cmd field is
0). When kernel and user agree, kernel returns valid info in all
fields (ie. link mode length > 0 and cmd is ETHTOOL_GLINKSETTINGS).

Data structure crossing user/kernel boundary is 32/64-bit
agnostic. Converted internally to a legal kernel bitmap.

The internal __ethtool_get_settings kernel helper will gradually be
replaced by __ethtool_get_link_ksettings by the time the first
"link_settings" drivers start to appear. So this patch doesn't change
it, it will be removed before it needs to be changed.

Signed-off-by: David Decotigny <de...@googlers.com>
---
 include/linux/ethtool.h  |  91 -
 include/uapi/linux/ethtool.h | 322 +++---
 net/core/ethtool.c   | 453 ++-
 3 files changed, 786 insertions(+), 80 deletions(-)

diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index 472d7d7..8a400a5 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -12,6 +12,7 @@
 #ifndef _LINUX_ETHTOOL_H
 #define _LINUX_ETHTOOL_H
 
+#include 
 #include 
 #include 
 
@@ -40,9 +41,6 @@ struct compat_ethtool_rxnfc {
 
 #include 
 
-extern int __ethtool_get_settings(struct net_device *dev,
- struct ethtool_cmd *cmd);
-
 /**
  * enum ethtool_phys_id_state - indicator state for physical identification
  * @ETHTOOL_ID_INACTIVE: Physical ID indicator should be deactivated
@@ -97,13 +95,74 @@ static inline u32 ethtool_rxfh_indir_default(u32 index, u32 
n_rx_rings)
return index % n_rx_rings;
 }
 
+/* number of link mode bits/ulongs handled internally by kernel */
+#define __ETHTOOL_LINK_MODE_MASK_NBITS \
+   (__ETHTOOL_LINK_MODE_LAST + 1)
+
+/* declare a link mode bitmap */
+#define __ETHTOOL_DECLARE_LINK_MODE_MASK(name) \
+   DECLARE_BITMAP(name, __ETHTOOL_LINK_MODE_MASK_NBITS)
+
+/* drivers must ignore base.cmd and base.link_mode_masks_nwords
+ * fields, but they are allowed to overwrite them (will be ignored).
+ */
+struct ethtool_link_ksettings {
+   struct ethtool_link_settings base;
+   struct {
+   __ETHTOOL_DECLARE_LINK_MODE_MASK(supported);
+   __ETHTOOL_DECLARE_LINK_MODE_MASK(advertising);
+   __ETHTOOL_DECLARE_LINK_MODE_MASK(lp_advertising);
+   } link_modes;
+};
+
+/**
+ * ethtool_link_ksettings_zero_link_mode - clear link_ksettings link mode mask
+ *   @ptr : pointer to struct ethtool_link_ksettings
+ *   @name : one of supported/advertising/lp_advertising
+ */
+#define ethtool_link_ksettings_zero_link_mode(ptr, name)   \
+   bitmap_zero((ptr)->link_modes.name, __ETHTOOL_LINK_MODE_MASK_NBITS)
+
+/**
+ * ethtool_link_ksettings_add_link_mod

[PATCH net-next v9 06/16] net: bonding: use __ethtool_get_ksettings

2016-02-24 Thread David Decotigny
From: David Decotigny <de...@googlers.com>

Signed-off-by: David Decotigny <de...@googlers.com>
---
 drivers/net/bonding/bond_main.c | 14 ++
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index a6527d5..b6236ff 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -376,22 +376,20 @@ down:
 static void bond_update_speed_duplex(struct slave *slave)
 {
struct net_device *slave_dev = slave->dev;
-   struct ethtool_cmd ecmd;
-   u32 slave_speed;
+   struct ethtool_link_ksettings ecmd;
int res;
 
slave->speed = SPEED_UNKNOWN;
slave->duplex = DUPLEX_UNKNOWN;
 
-   res = __ethtool_get_settings(slave_dev, );
+   res = __ethtool_get_link_ksettings(slave_dev, );
if (res < 0)
return;
 
-   slave_speed = ethtool_cmd_speed();
-   if (slave_speed == 0 || slave_speed == ((__u32) -1))
+   if (ecmd.base.speed == 0 || ecmd.base.speed == ((__u32)-1))
return;
 
-   switch (ecmd.duplex) {
+   switch (ecmd.base.duplex) {
case DUPLEX_FULL:
case DUPLEX_HALF:
break;
@@ -399,8 +397,8 @@ static void bond_update_speed_duplex(struct slave *slave)
return;
}
 
-   slave->speed = slave_speed;
-   slave->duplex = ecmd.duplex;
+   slave->speed = ecmd.base.speed;
+   slave->duplex = ecmd.base.duplex;
 
return;
 }
-- 
2.7.0.rc3.207.g0ac5344



[PATCH net-next v9 07/16] net: ipvlan: use __ethtool_get_ksettings

2016-02-24 Thread David Decotigny
From: David Decotigny <de...@googlers.com>

Signed-off-by: David Decotigny <de...@googlers.com>
---
 drivers/net/ipvlan/ipvlan_main.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ipvlan/ipvlan_main.c b/drivers/net/ipvlan/ipvlan_main.c
index a7ca1c5..5802b90 100644
--- a/drivers/net/ipvlan/ipvlan_main.c
+++ b/drivers/net/ipvlan/ipvlan_main.c
@@ -346,12 +346,12 @@ static const struct header_ops ipvlan_header_ops = {
.cache_update   = eth_header_cache_update,
 };
 
-static int ipvlan_ethtool_get_settings(struct net_device *dev,
-  struct ethtool_cmd *cmd)
+static int ipvlan_ethtool_get_link_ksettings(struct net_device *dev,
+struct ethtool_link_ksettings *cmd)
 {
const struct ipvl_dev *ipvlan = netdev_priv(dev);
 
-   return __ethtool_get_settings(ipvlan->phy_dev, cmd);
+   return __ethtool_get_link_ksettings(ipvlan->phy_dev, cmd);
 }
 
 static void ipvlan_ethtool_get_drvinfo(struct net_device *dev,
@@ -377,7 +377,7 @@ static void ipvlan_ethtool_set_msglevel(struct net_device 
*dev, u32 value)
 
 static const struct ethtool_ops ipvlan_ethtool_ops = {
.get_link   = ethtool_op_get_link,
-   .get_settings   = ipvlan_ethtool_get_settings,
+   .get_link_ksettings = ipvlan_ethtool_get_link_ksettings,
.get_drvinfo= ipvlan_ethtool_get_drvinfo,
.get_msglevel   = ipvlan_ethtool_get_msglevel,
.set_msglevel   = ipvlan_ethtool_set_msglevel,
-- 
2.7.0.rc3.207.g0ac5344



[PATCH net-next v9 02/16] net: usnic: use __ethtool_get_settings

2016-02-24 Thread David Decotigny
From: David Decotigny <de...@googlers.com>

Signed-off-by: David Decotigny <de...@googlers.com>
---
 drivers/infiniband/hw/usnic/usnic_ib_verbs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/infiniband/hw/usnic/usnic_ib_verbs.c 
b/drivers/infiniband/hw/usnic/usnic_ib_verbs.c
index ea003ec..1cf19a3 100644
--- a/drivers/infiniband/hw/usnic/usnic_ib_verbs.c
+++ b/drivers/infiniband/hw/usnic/usnic_ib_verbs.c
@@ -329,7 +329,7 @@ int usnic_ib_query_port(struct ib_device *ibdev, u8 port,
usnic_dbg("\n");
 
mutex_lock(_ibdev->usdev_lock);
-   us_ibdev->netdev->ethtool_ops->get_settings(us_ibdev->netdev, );
+   __ethtool_get_settings(us_ibdev->netdev, );
memset(props, 0, sizeof(*props));
 
props->lid = 0;
-- 
2.7.0.rc3.207.g0ac5344



[PATCH net-next v9 05/16] net: usnic: use __ethtool_get_ksettings

2016-02-24 Thread David Decotigny
From: David Decotigny <de...@googlers.com>

Signed-off-by: David Decotigny <de...@googlers.com>
---
 drivers/infiniband/hw/usnic/usnic_ib_verbs.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/infiniband/hw/usnic/usnic_ib_verbs.c 
b/drivers/infiniband/hw/usnic/usnic_ib_verbs.c
index 1cf19a3..a5bfbba 100644
--- a/drivers/infiniband/hw/usnic/usnic_ib_verbs.c
+++ b/drivers/infiniband/hw/usnic/usnic_ib_verbs.c
@@ -324,12 +324,12 @@ int usnic_ib_query_port(struct ib_device *ibdev, u8 port,
struct ib_port_attr *props)
 {
struct usnic_ib_dev *us_ibdev = to_usdev(ibdev);
-   struct ethtool_cmd cmd;
+   struct ethtool_link_ksettings cmd;
 
usnic_dbg("\n");
 
mutex_lock(_ibdev->usdev_lock);
-   __ethtool_get_settings(us_ibdev->netdev, );
+   __ethtool_get_link_ksettings(us_ibdev->netdev, );
memset(props, 0, sizeof(*props));
 
props->lid = 0;
@@ -353,8 +353,8 @@ int usnic_ib_query_port(struct ib_device *ibdev, u8 port,
props->pkey_tbl_len = 1;
props->bad_pkey_cntr = 0;
props->qkey_viol_cntr = 0;
-   eth_speed_to_ib_speed(cmd.speed, >active_speed,
-   >active_width);
+   eth_speed_to_ib_speed(cmd.base.speed, >active_speed,
+ >active_width);
props->max_mtu = IB_MTU_4096;
props->active_mtu = iboe_get_mtu(us_ibdev->ufdev->mtu);
/* Userspace will adjust for hdrs */
-- 
2.7.0.rc3.207.g0ac5344



[PATCH net-next v9 08/16] net: macvlan: use __ethtool_get_ksettings

2016-02-24 Thread David Decotigny
From: David Decotigny <de...@googlers.com>

Signed-off-by: David Decotigny <de...@googlers.com>
---
 drivers/net/macvlan.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 426a2cc..6e953e3 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -940,12 +940,12 @@ static void macvlan_ethtool_get_drvinfo(struct net_device 
*dev,
strlcpy(drvinfo->version, "0.1", sizeof(drvinfo->version));
 }
 
-static int macvlan_ethtool_get_settings(struct net_device *dev,
-   struct ethtool_cmd *cmd)
+static int macvlan_ethtool_get_link_ksettings(struct net_device *dev,
+ struct ethtool_link_ksettings 
*cmd)
 {
const struct macvlan_dev *vlan = netdev_priv(dev);
 
-   return __ethtool_get_settings(vlan->lowerdev, cmd);
+   return __ethtool_get_link_ksettings(vlan->lowerdev, cmd);
 }
 
 static netdev_features_t macvlan_fix_features(struct net_device *dev,
@@ -1020,7 +1020,7 @@ static int macvlan_dev_get_iflink(const struct net_device 
*dev)
 
 static const struct ethtool_ops macvlan_ethtool_ops = {
.get_link   = ethtool_op_get_link,
-   .get_settings   = macvlan_ethtool_get_settings,
+   .get_link_ksettings = macvlan_ethtool_get_link_ksettings,
.get_drvinfo= macvlan_ethtool_get_drvinfo,
 };
 
-- 
2.7.0.rc3.207.g0ac5344



[PATCH net-next v9 04/16] tx4939: use __ethtool_get_ksettings

2016-02-24 Thread David Decotigny
From: David Decotigny <de...@googlers.com>

Signed-off-by: David Decotigny <de...@googlers.com>
---
 arch/mips/txx9/generic/setup_tx4939.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/arch/mips/txx9/generic/setup_tx4939.c 
b/arch/mips/txx9/generic/setup_tx4939.c
index e3733cd..402ac2e 100644
--- a/arch/mips/txx9/generic/setup_tx4939.c
+++ b/arch/mips/txx9/generic/setup_tx4939.c
@@ -320,11 +320,12 @@ void __init tx4939_sio_init(unsigned int sclk, unsigned 
int cts_mask)
 #if IS_ENABLED(CONFIG_TC35815)
 static u32 tx4939_get_eth_speed(struct net_device *dev)
 {
-   struct ethtool_cmd cmd;
-   if (__ethtool_get_settings(dev, ))
+   struct ethtool_link_ksettings cmd;
+
+   if (__ethtool_get_link_ksettings(dev, ))
return 100; /* default 100Mbps */
 
-   return ethtool_cmd_speed();
+   return cmd.base.speed;
 }
 
 static int tx4939_netdev_event(struct notifier_block *this,
-- 
2.7.0.rc3.207.g0ac5344



[PATCH net-next v9 00/16] new ETHTOOL_GLINKSETTINGS/SLINKSETTINGS API

2016-02-24 Thread David Decotigny
From: David Decotigny <de...@googlers.com>


History:
 v9
 - add 'link' in macro, struct and function names
 - rename ethtool_link_ksettings::parent -> ::base
 - remove un-needed mlx4 en_dbg_enabled() companion patch
 - note: bitmap u32[] API patches were merged separately by Kan Liang
 v8
 - bitmap u32 API returns number of bits copied, unit tests updated
 v7
 - module_exit in test_bitmap
 v6
 - fix copy_from_user in user/kernel handshake
 v5
 note: please see v4 bullets for a question regarding bitmap.c
 - minor fix to make allyesconfig/allmodconfig
 v4
 - removed typedef for link mode bitmaps
 - moved bitmap<->u32[] conversion routines to bitmap.c . This is the
   naive implementation. I have an endian-aware version that uses
   memcpy/memset as much as possible, but I find it harder to follow
   (see http://paste.ubuntu.com/13863722/). Please let me know if I
   should use it instead.
 - fixes suggested by Ben Hutchings
 v3
 - rebased v2 on top of latest net-next, minor checkpatch/printf %*pb
   updates
 v2
 - keep return 0 in get_settings when successful, instead of
   propagating positive result from driver's get_settings callback.
 v1
 - original submission


The main goal of this series is to support ethtool link mode masks
larger than 32 bits. It implements a new ioctl pair
(ETHTOOL_GLINKSETTINGS/SLINKSETTINGS), its associated callbacks
(get/set_link_ksettings) and a new struct ethtool_link_settings, which
should eventually replace legacy ethtool_cmd. Internally, the kernel
uses fixed length link mode masks defined at compilation time in
ethtool.h (for now: 31 bits), that can be increased by changing
__ETHTOOL_LINK_MODE_LAST in ethtool.h (absolute max is 4064 bits,
checked at compile time), and the user/kernel interface allows this
length to be arbitrary within 1..4064. This should allow some
flexibility without using too much heap/stack space, at the cost of a
small kernel/user handshake for the user to determine the sizes of
those bitmaps.

Along the way, I chose to drop in the new structure the 3 ethtool_cmd
fields marked "deprecated" (transceiver/maxrxpkt/maxtxpkt). They are
still available for old drivers via the (old) ETHTOOL_GSET/SSET API,
but are not available to drivers that switch to new API. Of those 3
fields, ethtool_cmd::transceiver seems to be still actively used by
several drivers, maybe we should not consider this field deprecated?
The 2 other fields are basically not used. This transition requires
some care in the way old and new ethtool talk to the kernel.

More technical details provided in the description for main patch. In
particular details about backward compatibility properties.

Some open questions:
 - the kernel/interface multiplexes the "tell me the bitmap length"
   handshake and the "give me the settings" inside the new
   ETHTOOL_GLINKSETTINGS cmd. I was thinking of making this into 2
   separate cmds: 1 cmd ETHTOOL_GKERNELPROPERTIES which would be
   kernel-wide rather than device-specific, would return properties
   like "length of the link mode bitmaps", and possibly others. And
   ETHTOOL_GLINKSETTINGS would expect the proper bitmaps
 - the link mode bitmaps are piggybacked at tail of the new struct
   ethtool_link_settings. Since its user-visible definition does not
   assume specific bitmap width, I am using a 0-length array as the
   publicly visible placeholder. But then, the kernel needs to
   specialize it (struct ethtool_link_ksettings) to specify its
   current link mode masks. This means that kernel code is "littered"
   with "ksettings->base.field" to access "field" inside
   ethtool_settings:
   + I could use ethtool_link_settings everywhere (instead of a new
 ethtool_ksettings) and an container_of accessor (or a plain cast)
 to retrieve the link mode masks?
   + or: we could decide to make the link mode masks statically
 bounded again, ie. make their width public, but larger than
 current 32, and unchangeable forever. This would make everything
 straightforward, but we might hit limits later, or have an
 unneeded memory/stack usage for unused bits.
   any preference?
 - I foresee bugs where people use the legacy/deprecated SUPPORTED_x
   macros instead of the new ETHTOOL_LINK_MODE_x_BIT enums in the new
   get/set_link_ksettings callbacks. Not sure how to prevent problems
   with this.

The only driver which was converted for now is mlx4. I am not
considering fcoe as fully converted, but I updated it a minima to be
able to remove __ethtool_get_settings, now known as
__ethtool_get_link_ksettings.

Tested with legacy and "future" ethtool on 64b x86 kernel and 32+64b
ethtool, and on a 32b x86 kernel + 32b ethtool.


# Patch Set Summary:

David Decotigny (16):
  net: usnic: remove unused call to ethtool_ops::get_settings
  net: usnic: use __ethtool_get_settings
  net: ethtool: add new ETHTOOL

[PATCH net-next v9 01/16] net: usnic: remove unused call to ethtool_ops::get_settings

2016-02-24 Thread David Decotigny
From: David Decotigny <de...@googlers.com>

Signed-off-by: David Decotigny <de...@googlers.com>
---
 drivers/infiniband/hw/usnic/usnic_ib_verbs.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/infiniband/hw/usnic/usnic_ib_verbs.c 
b/drivers/infiniband/hw/usnic/usnic_ib_verbs.c
index 6cdb4d2..ea003ec 100644
--- a/drivers/infiniband/hw/usnic/usnic_ib_verbs.c
+++ b/drivers/infiniband/hw/usnic/usnic_ib_verbs.c
@@ -269,7 +269,6 @@ int usnic_ib_query_device(struct ib_device *ibdev,
struct usnic_ib_dev *us_ibdev = to_usdev(ibdev);
union ib_gid gid;
struct ethtool_drvinfo info;
-   struct ethtool_cmd cmd;
int qp_per_vf;
 
usnic_dbg("\n");
@@ -278,7 +277,6 @@ int usnic_ib_query_device(struct ib_device *ibdev,
 
mutex_lock(_ibdev->usdev_lock);
us_ibdev->netdev->ethtool_ops->get_drvinfo(us_ibdev->netdev, );
-   us_ibdev->netdev->ethtool_ops->get_settings(us_ibdev->netdev, );
memset(props, 0, sizeof(*props));
usnic_mac_ip_to_gid(us_ibdev->ufdev->mac, us_ibdev->ufdev->inaddr,
[0]);
-- 
2.7.0.rc3.207.g0ac5344



[PATCH net-next v9 10/16] net: fcoe: use __ethtool_get_ksettings

2016-02-24 Thread David Decotigny
From: David Decotigny <de...@googlers.com>

Signed-off-by: David Decotigny <de...@googlers.com>
---
 drivers/scsi/fcoe/fcoe_transport.c | 36 
 1 file changed, 20 insertions(+), 16 deletions(-)

diff --git a/drivers/scsi/fcoe/fcoe_transport.c 
b/drivers/scsi/fcoe/fcoe_transport.c
index d7597c0..641c60e 100644
--- a/drivers/scsi/fcoe/fcoe_transport.c
+++ b/drivers/scsi/fcoe/fcoe_transport.c
@@ -93,36 +93,40 @@ static struct notifier_block libfcoe_notifier = {
 int fcoe_link_speed_update(struct fc_lport *lport)
 {
struct net_device *netdev = fcoe_get_netdev(lport);
-   struct ethtool_cmd ecmd;
+   struct ethtool_link_ksettings ecmd;
 
-   if (!__ethtool_get_settings(netdev, )) {
+   if (!__ethtool_get_link_ksettings(netdev, )) {
lport->link_supported_speeds &= ~(FC_PORTSPEED_1GBIT  |
  FC_PORTSPEED_10GBIT |
  FC_PORTSPEED_20GBIT |
  FC_PORTSPEED_40GBIT);
 
-   if (ecmd.supported & (SUPPORTED_1000baseT_Half |
- SUPPORTED_1000baseT_Full |
- SUPPORTED_1000baseKX_Full))
+   if (ecmd.link_modes.supported[0] & (
+   SUPPORTED_1000baseT_Half |
+   SUPPORTED_1000baseT_Full |
+   SUPPORTED_1000baseKX_Full))
lport->link_supported_speeds |= FC_PORTSPEED_1GBIT;
 
-   if (ecmd.supported & (SUPPORTED_1baseT_Full   |
- SUPPORTED_1baseKX4_Full |
- SUPPORTED_1baseKR_Full  |
- SUPPORTED_1baseR_FEC))
+   if (ecmd.link_modes.supported[0] & (
+   SUPPORTED_1baseT_Full   |
+   SUPPORTED_1baseKX4_Full |
+   SUPPORTED_1baseKR_Full  |
+   SUPPORTED_1baseR_FEC))
lport->link_supported_speeds |= FC_PORTSPEED_10GBIT;
 
-   if (ecmd.supported & (SUPPORTED_2baseMLD2_Full |
- SUPPORTED_2baseKR2_Full))
+   if (ecmd.link_modes.supported[0] & (
+   SUPPORTED_2baseMLD2_Full |
+   SUPPORTED_2baseKR2_Full))
lport->link_supported_speeds |= FC_PORTSPEED_20GBIT;
 
-   if (ecmd.supported & (SUPPORTED_4baseKR4_Full |
- SUPPORTED_4baseCR4_Full |
- SUPPORTED_4baseSR4_Full |
- SUPPORTED_4baseLR4_Full))
+   if (ecmd.link_modes.supported[0] & (
+   SUPPORTED_4baseKR4_Full |
+   SUPPORTED_4baseCR4_Full |
+   SUPPORTED_4baseSR4_Full |
+   SUPPORTED_4baseLR4_Full))
lport->link_supported_speeds |= FC_PORTSPEED_40GBIT;
 
-   switch (ethtool_cmd_speed()) {
+   switch (ecmd.base.speed) {
case SPEED_1000:
lport->link_speed = FC_PORTSPEED_1GBIT;
break;
-- 
2.7.0.rc3.207.g0ac5344



[PATCH net-next v9 11/16] net: rdma: use __ethtool_get_ksettings

2016-02-24 Thread David Decotigny
From: David Decotigny <de...@googlers.com>

Signed-off-by: David Decotigny <de...@googlers.com>
---
 include/rdma/ib_addr.h | 14 ++
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/include/rdma/ib_addr.h b/include/rdma/ib_addr.h
index c34c900..931a47b 100644
--- a/include/rdma/ib_addr.h
+++ b/include/rdma/ib_addr.h
@@ -262,24 +262,22 @@ static inline enum ib_mtu iboe_get_mtu(int mtu)
 
 static inline int iboe_get_rate(struct net_device *dev)
 {
-   struct ethtool_cmd cmd;
-   u32 speed;
+   struct ethtool_link_ksettings cmd;
int err;
 
rtnl_lock();
-   err = __ethtool_get_settings(dev, );
+   err = __ethtool_get_link_ksettings(dev, );
rtnl_unlock();
if (err)
return IB_RATE_PORT_CURRENT;
 
-   speed = ethtool_cmd_speed();
-   if (speed >= 4)
+   if (cmd.base.speed >= 4)
return IB_RATE_40_GBPS;
-   else if (speed >= 3)
+   else if (cmd.base.speed >= 3)
return IB_RATE_30_GBPS;
-   else if (speed >= 2)
+   else if (cmd.base.speed >= 2)
return IB_RATE_20_GBPS;
-   else if (speed >= 1)
+   else if (cmd.base.speed >= 1)
return IB_RATE_10_GBPS;
else
return IB_RATE_PORT_CURRENT;
-- 
2.7.0.rc3.207.g0ac5344



[PATCH net-next v9 13/16] net: bridge: use __ethtool_get_ksettings

2016-02-24 Thread David Decotigny
From: David Decotigny <de...@googlers.com>

Signed-off-by: David Decotigny <de...@googlers.com>
---
 net/bridge/br_if.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index c367b3e..b37a1cc 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -36,10 +36,10 @@
  */
 static int port_cost(struct net_device *dev)
 {
-   struct ethtool_cmd ecmd;
+   struct ethtool_link_ksettings ecmd;
 
-   if (!__ethtool_get_settings(dev, )) {
-   switch (ethtool_cmd_speed()) {
+   if (!__ethtool_get_link_ksettings(dev, )) {
+   switch (ecmd.base.speed) {
case SPEED_1:
return 2;
case SPEED_1000:
-- 
2.7.0.rc3.207.g0ac5344



  1   2   3   >