Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH net-next 2/5] net: phy: mscc: Add EEE init sequence
From: Florian Fainelli @ 2018-09-15  2:21 UTC (permalink / raw)
  To: Quentin Schulz, davem, andrew
  Cc: allan.nielsen, linux-kernel, netdev, thomas.petazzoni,
	Raju Lakkaraju
In-Reply-To: <64809c5f01f3c6407257553a286b82949cef1ac0.1536913944.git-series.quentin.schulz@bootlin.com>



On 09/14/18 01:33, Quentin Schulz wrote:
> From: Raju Lakkaraju <Raju.Lakkaraju@microchip.com>
> 
> Microsemi PHYs (VSC 8530/31/40/41) need to update the Energy Efficient
> Ethernet initialization sequence.
> In order to avoid certain link state errors that could result in link
> drops and packet loss, the physical coding sublayer (PCS) must be
> updated with settings related to EEE in order to improve performance.
> 
> Signed-off-by: Raju Lakkaraju <Raju.Lakkaraju@microchip.com>
> Signed-off-by: Quentin Schulz <quentin.schulz@bootlin.com>
> ---

[snip]

> +	vsc85xx_tr_write(phydev, 0x0f82, 0x0012b00a);

Can you just make this an array of register + value pair? That would be
less error prone in case you need to update that sequence in the future.

With that:

Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-- 
Florian

^ permalink raw reply

* Re: [net-next, RFC PATCH] net: sched: cls_range: Introduce Range classifier
From: Cong Wang @ 2018-09-14 21:06 UTC (permalink / raw)
  To: amritha.nambiar
  Cc: Linux Kernel Network Developers, David Miller, Alexander Duyck,
	Jakub Kicinski, sridhar.samudrala, Jamal Hadi Salim,
	Jesse Brandeburg, Jiri Pirko
In-Reply-To: <153687192654.43503.1433255216543560934.stgit@anamhost.jf.intel.com>

On Thu, Sep 13, 2018 at 6:53 PM Amritha Nambiar
<amritha.nambiar@intel.com> wrote:
>
> This patch introduces a range classifier to support filtering based
> on ranges. Only port-range filters are supported currently. This can
> be combined with flower classifier to support filters that are a
> combination of port-ranges and other parameters based on existing
> fields supported by cls_flower.

Why should we have a special-purpose filter just for ports here?

We have achieved almost the same goal with u32 filter:

https://github.com/apache/mesos/blob/master/src/slave/containerizer/mesos/isolators/network/port_mapping.cpp

There is a large overlap with other general purpose filters.

I don't see you provide any justification for the purpose of it. If
it is just for convenience, can't we just make it on top of other
general purpose header-matching filters?

^ permalink raw reply

* Re: [PATCH net-next v3 03/11] net: mscc: ocelot: get HSIO regmap from syscon
From: Florian Fainelli @ 2018-09-15  2:23 UTC (permalink / raw)
  To: Quentin Schulz, alexandre.belloni, ralf, paul.burton, jhogan,
	robh+dt, mark.rutland, davem, kishon, andrew
  Cc: allan.nielsen, linux-mips, devicetree, linux-kernel, netdev,
	thomas.petazzoni
In-Reply-To: <d9b23949e81272006e076e0b58d90e0541f80c7f.1536912834.git-series.quentin.schulz@bootlin.com>



On 09/14/18 01:16, Quentin Schulz wrote:
> HSIO address space was moved to a syscon, hence we need to get the
> regmap of this address space from there and no more from the device
> node.
> 
> Acked-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
> Signed-off-by: Quentin Schulz <quentin.schulz@bootlin.com>

Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-- 
Florian

^ permalink raw reply

* Re: [PATCH net-next v3 04/11] net: mscc: ocelot: move the HSIO header to include/soc
From: Florian Fainelli @ 2018-09-15  2:24 UTC (permalink / raw)
  To: Quentin Schulz, alexandre.belloni, ralf, paul.burton, jhogan,
	robh+dt, mark.rutland, davem, kishon, andrew
  Cc: allan.nielsen, linux-mips, devicetree, linux-kernel, netdev,
	thomas.petazzoni
In-Reply-To: <45bc0a8bd6a1dfc35adcedc3581124879fdb5a07.1536912834.git-series.quentin.schulz@bootlin.com>



On 09/14/18 01:16, Quentin Schulz wrote:
> Since HSIO address space can be used by different drivers (PLL, SerDes
> muxing, temperature sensor), let's move it somewhere it can be included
> by all drivers.
> 
> Acked-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
> Signed-off-by: Quentin Schulz <quentin.schulz@bootlin.com>

Nothing wrong with the patch, you likely would have wanted to use git
format-patch -M such that the diff would have been showing that the file
was renamed.

Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-- 
Florian

^ permalink raw reply

* Re: [net-next,RFC PATCH] Introduce TC Range classifier
From: Cong Wang @ 2018-09-14 21:09 UTC (permalink / raw)
  To: Jiri Pirko
  Cc: amritha.nambiar, Linux Kernel Network Developers, David Miller,
	Alexander Duyck, Jakub Kicinski, sridhar.samudrala,
	Jamal Hadi Salim, Jesse Brandeburg
In-Reply-To: <20180914094932.GK25110@nanopsycho>

On Fri, Sep 14, 2018 at 2:53 AM Jiri Pirko <jiri@resnulli.us> wrote:
>
> Thu, Sep 13, 2018 at 10:52:01PM CEST, amritha.nambiar@intel.com wrote:
> >This patch introduces a TC range classifier to support filtering based
> >on ranges. Only port-range filters are supported currently. This can
> >be combined with flower classifier to support filters that are a
> >combination of port-ranges and other parameters based on existing
> >fields supported by cls_flower. The 'goto chain' action can be used to
> >combine the flower and range filter.
> >The filter precedence is decided based on the 'prio' value.
>
> For example Spectrum ASIC supports mask-based and range-based matching
> in a single TCAM rule. No chains needed. Also, I don't really understand
> why is this a separate cls. I believe that this functionality should be
> put as an extension of existing cls_flower.

Exactly. u32 filters support range matching too with proper masks.

^ permalink raw reply

* Re: [PATCH net-next v3 05/11] net: mscc: ocelot: simplify register access for PLL5 configuration
From: Florian Fainelli @ 2018-09-15  2:26 UTC (permalink / raw)
  To: Quentin Schulz, alexandre.belloni, ralf, paul.burton, jhogan,
	robh+dt, mark.rutland, davem, kishon, andrew
  Cc: allan.nielsen, linux-mips, devicetree, linux-kernel, netdev,
	thomas.petazzoni
In-Reply-To: <b09eb1026a2870c6cc882997ac69e25fdf7a96d8.1536912834.git-series.quentin.schulz@bootlin.com>



On 09/14/18 01:16, Quentin Schulz wrote:
> Since HSIO address space can be accessed by different drivers, let's
> simplify the register address definitions so that it can be easily used
> by all drivers and put the register address definition in the
> include/soc/mscc/ocelot_hsio.h header file.
> 
> Acked-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
> Signed-off-by: Quentin Schulz <quentin.schulz@bootlin.com>

Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-- 
Florian

^ permalink raw reply

* Re: [PATCH net-next v3 06/11] phy: add QSGMII and PCIE modes
From: Florian Fainelli @ 2018-09-15  2:27 UTC (permalink / raw)
  To: Quentin Schulz, alexandre.belloni, ralf, paul.burton, jhogan,
	robh+dt, mark.rutland, davem, kishon, andrew
  Cc: allan.nielsen, linux-mips, devicetree, linux-kernel, netdev,
	thomas.petazzoni
In-Reply-To: <52d9c9444175911a8f6ee3dfec8946646907135b.1536912834.git-series.quentin.schulz@bootlin.com>



On 09/14/18 01:16, Quentin Schulz wrote:
> Prepare for upcoming phys that'll handle QSGMII or PCIe.
> 
> Signed-off-by: Quentin Schulz <quentin.schulz@bootlin.com>

Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-- 
Florian

^ permalink raw reply

* Re: [PATCH net-next v3 07/11] dt-bindings: phy: add DT binding for Microsemi Ocelot SerDes muxing
From: Florian Fainelli @ 2018-09-15  2:29 UTC (permalink / raw)
  To: Quentin Schulz, alexandre.belloni, ralf, paul.burton, jhogan,
	robh+dt, mark.rutland, davem, kishon, andrew
  Cc: allan.nielsen, linux-mips, devicetree, linux-kernel, netdev,
	thomas.petazzoni
In-Reply-To: <f392dafca9165800439fc09cd7d16e6a9506d457.1536912834.git-series.quentin.schulz@bootlin.com>



On 09/14/18 01:16, Quentin Schulz wrote:
> Signed-off-by: Quentin Schulz <quentin.schulz@bootlin.com>

Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-- 
Florian

^ permalink raw reply

* Re: [PATCH net-next v3 08/11] MIPS: mscc: ocelot: add SerDes mux DT node
From: Florian Fainelli @ 2018-09-15  2:30 UTC (permalink / raw)
  To: Quentin Schulz, alexandre.belloni, ralf, paul.burton, jhogan,
	robh+dt, mark.rutland, davem, kishon, andrew
  Cc: allan.nielsen, linux-mips, devicetree, linux-kernel, netdev,
	thomas.petazzoni
In-Reply-To: <ba95add3d931177ef55666e856164523903d1148.1536912834.git-series.quentin.schulz@bootlin.com>



On 09/14/18 01:16, Quentin Schulz wrote:
> The Microsemi Ocelot has a set of register for SerDes/switch port muxing
> as well as PCIe muxing for a specific SerDes, so let's add the device
> and all SerDes in the Device Tree.
> 
> Acked-by: Paul Burton <paul.burton@mips.com>
> Signed-off-by: Quentin Schulz <quentin.schulz@bootlin.com>

Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-- 
Florian

^ permalink raw reply

* Re: [PATCH net-next v3 09/11] dt-bindings: add constants for Microsemi Ocelot SerDes driver
From: Florian Fainelli @ 2018-09-15  2:31 UTC (permalink / raw)
  To: Quentin Schulz, alexandre.belloni, ralf, paul.burton, jhogan,
	robh+dt, mark.rutland, davem, kishon, andrew
  Cc: allan.nielsen, linux-mips, devicetree, linux-kernel, netdev,
	thomas.petazzoni
In-Reply-To: <73113ea4b3d8d34c05d88413b3d15cc1733cf25e.1536912834.git-series.quentin.schulz@bootlin.com>



On 09/14/18 01:16, Quentin Schulz wrote:
> The Microsemi Ocelot has multiple SerDes and requires that the SerDes be
> muxed accordingly to the hardware representation.
> 
> Let's add a constant for each SerDes available in the Microsemi Ocelot.
> 
> Signed-off-by: Quentin Schulz <quentin.schulz@bootlin.com>
> ---
>  include/dt-bindings/phy/phy-ocelot-serdes.h | 19 +++++++++++++++++++
>  1 file changed, 19 insertions(+)
>  create mode 100644 include/dt-bindings/phy/phy-ocelot-serdes.h
> 
> diff --git a/include/dt-bindings/phy/phy-ocelot-serdes.h b/include/dt-bindings/phy/phy-ocelot-serdes.h
> new file mode 100644
> index 0000000..cf111ba
> --- /dev/null
> +++ b/include/dt-bindings/phy/phy-ocelot-serdes.h
> @@ -0,0 +1,19 @@
> +/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */
> +/* Copyright (c) 2018 Microsemi Corporation */
> +#ifndef __PHY_OCELOT_SERDES_H__
> +#define __PHY_OCELOT_SERDES_H__
> +
> +#define SERDES1G_0	0
> +#define SERDES1G_1	1
> +#define SERDES1G_2	2
> +#define SERDES1G_3	3
> +#define SERDES1G_4	4
> +#define SERDES1G_5	5
> +#define SERDES1G_MAX	6

Given you use the C preprocessor you could have done something like:

#define SERDES1G(x)	(x)
#define SERDES1G_MAX	5
#define SERDES6G(x)	((x) + SERDES1G_MAX)

etc. but this works for me as well.

> +#define SERDES6G_0	SERDES1G_MAX
> +#define SERDES6G_1	(SERDES1G_MAX + 1)
> +#define SERDES6G_2	(SERDES1G_MAX + 2)
> +#define SERDES6G_MAX	(SERDES1G_MAX + 3)
> +#define SERDES_MAX	(SERDES1G_MAX + SERDES6G_MAX)
> +
> +#endif
> 

-- 
Florian

^ permalink raw reply

* mlx5_core: null pointer dereference in mlx5_accel_tls_device_caps() (net-next kernel)
From: Michal Kubecek @ 2018-09-14 21:20 UTC (permalink / raw)
  To: netdev; +Cc: Saeed Mahameed, Leon Romanovsky

I just encountered a null pointer dereference on mlx5_core module
initialization while booting net-next kernel (based on commit
ee4fccbee7d3) on an aarch64 machine:

[   12.021971] iommu: Adding device 0000:01:00.0 to group 3
[   12.022925] mlx5_core 0000:01:00.0: firmware version: 12.17.2020
[   12.022954] mlx5_core 0000:01:00.0: 63.008 Gb/s available PCIe bandwidth (8 GT/s x8 link)
[   12.068709] Adding 98830144k swap on /dev/sda4.  Priority:-2 extents:1 across:98830144k FS
[   12.347571] (0000:01:00.0): E-Switch: Total vports 9, per vport: max uc(1024) max mc(16384)
[   12.351962] mlx5_core 0000:01:00.0: Port module event: module 0, Cable plugged
[   12.366306] mlx5_core 0000:01:00.0: MLX5E: StrdRq(0) RqSz(1024) StrdSz(128) RxCqeCmprss(0)
[   12.366741] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000050
[   12.374603] Mem abort info:
[   12.377368]   ESR = 0x96000004
[   12.380406]   Exception class = DABT (current EL), IL = 32 bits
[   12.386357]   SET = 0, FnV = 0
[   12.389347]   EA = 0, S1PTW = 0
[   12.392471] Data abort info:
[   12.395343]   ISV = 0, ISS = 0x00000004
[   12.399156]   CM = 0, WnR = 0
[   12.402108] user pgtable: 4k pages, 48-bit VAs, pgdp = (____ptrval____)
[   12.408711] [0000000000000050] pgd=0000000000000000
[   12.413567] Internal error: Oops: 96000004 [#1] SMP
[   12.418427] Modules linked in: fat mlx5_core(+) ipmi_ssif(+) aes_ce_blk crypto_simd cryptd aes_ce_cipher crc32_ce crct10dif_ce ghash_ce aes_arm64 sha2_ce sha256_arm64 sha1_ce ipmi_devintf ipmi_msghandler sbsa_gwdt tls mlxfw devlink at803x qcom_emac btrfs libcrc32c xor zlib_deflate raid6_pq ahci_platform libahci_platform hdma hdma_mgmt i2c_qup sg dm_multipath dm_mod scsi_dh_rdac scsi_dh_emc scsi_dh_alua efivarfs
[   12.454800] CPU: 40 PID: 742 Comm: systemd-udevd Not tainted 4.19.0-rc3-ethnl.15-default #1
[   12.463131] Hardware name: To be filled by O.E.M. To be filled by O.E.M./To be filled by O.E.M., BIOS 5.13 12/12/2012
[   12.473722] pstate: 60400005 (nZCv daif +PAN -UAO)
[   12.478559] pc : mlx5_accel_tls_device_caps+0x28/0x38 [mlx5_core]
[   12.484598] lr : mlx5e_tls_build_netdev+0x24/0x98 [mlx5_core]
[   12.490301] sp : ffff000021873a30
[   12.493599] x29: ffff000021873a30 x28: ffff2a72560a7940 
[   12.498895] x27: ffff2a7256df6000 x26: ffff2a71a0fed650 
[   12.504190] x25: 0000000000000000 x24: ffff92c7f2b988c0 
[   12.509485] x23: ffff92c7fe01c0c0 x22: ffff2a71a0fcfa70 
[   12.514780] x21: ffff92c7f2b808c0 x20: ffff92c7f741c110 
[   12.520075] x19: ffff92c7f2b988c0 x18: ffff0000218739b0 
[   12.525370] x17: 0000000000000000 x16: ffff2a725625ade0 
[   12.530665] x15: 0000000029818ed4 x14: 00000000d47aab07 
[   12.535961] x13: 8a24000000000000 x12: 0000000000000000 
[   12.541256] x11: 0000000000000000 x10: 0000000000000000 
[   12.546551] x9 : 0000000000000000 x8 : 0000000000000000 
[   12.551846] x7 : 0000000000000000 x6 : ffff92c8159dc910 
[   12.557141] x5 : 0000000000000400 x4 : ffff7e4b205a20c7 
[   12.562436] x3 : 0000000000000000 x2 : ffff2a725625ae1c 
[   12.567731] x1 : 00000000ab078a24 x0 : 0000000000000000 
[   12.573027] Process systemd-udevd (pid: 742, stack limit = 0x(____ptrval____))
[   12.580232] Call trace:
[   12.582688]  mlx5_accel_tls_device_caps+0x28/0x38 [mlx5_core]
[   12.588419]  mlx5e_build_nic_netdev+0x27c/0x348 [mlx5_core]
[   12.593974]  mlx5e_nic_init+0x1a0/0x258 [mlx5_core]
[   12.598835]  mlx5e_create_netdev+0x74/0x118 [mlx5_core]
[   12.604043]  mlx5e_add+0xf0/0x2c0 [mlx5_core]
[   12.608384]  mlx5_add_device+0x88/0x1a8 [mlx5_core]
[   12.613246]  mlx5_register_interface+0x78/0xb0 [mlx5_core]
[   12.618713]  mlx5e_init+0x24/0x30 [mlx5_core]
[   12.623052]  init+0x88/0xa0 [mlx5_core]
[   12.626850]  do_one_initcall+0x54/0x200
[   12.630667]  do_init_module+0x64/0x1d8
[   12.634401]  load_module+0x1480/0x1510
[   12.638132]  __se_sys_finit_module+0xc8/0xd8
[   12.642385]  __arm64_sys_finit_module+0x24/0x30
[   12.646901]  el0_svc_common+0x7c/0x118
[   12.650631]  el0_svc_handler+0x38/0x78
[   12.654364]  el0_svc+0x8/0xc
[   12.657229] Code: d503201f f97c7e60 f9400bf3 a8c27bfd (f9402800) 
[   12.663306] ---[ end trace 57e772dd3cf718f1 ]---

The function looks like this:

------------------------------------------------------------------------
drivers/net/ethernet/mellanox/mlx5/core/accel/tls.c:
68      {
   0x0000000000058230 <+0>:     stp     x29, x30, [sp, #-32]!
   0x0000000000058234 <+4>:     mov     x29, sp
   0x0000000000058238 <+8>:     str     x19, [sp, #16]
   0x000000000005823c <+12>:    mov     x19, x0
   0x0000000000058240 <+16>:    mov     x0, x30

drivers/net/ethernet/mellanox/mlx5/core/fpga/tls.h:
68              return mdev->fpga->tls->caps;
   0x0000000000058244 <+20>:    add     x19, x19, #0x38, lsl #12

drivers/net/ethernet/mellanox/mlx5/core/accel/tls.c:
68      {
   0x0000000000058248 <+24>:    bl      0x58248
<mlx5_accel_tls_device_caps+24>

drivers/net/ethernet/mellanox/mlx5/core/fpga/tls.h:
68              return mdev->fpga->tls->caps;
   0x000000000005824c <+28>:    ldr     x0, [x19, #30968]

drivers/net/ethernet/mellanox/mlx5/core/accel/tls.c:
70      }
   0x0000000000058250 <+32>:    ldr     x19, [sp, #16]
   0x0000000000058254 <+36>:    ldp     x29, x30, [sp], #32

drivers/net/ethernet/mellanox/mlx5/core/fpga/tls.h:
68              return mdev->fpga->tls->caps;
   0x0000000000058258 <+40>:    ldr     x0, [x0, #80]

drivers/net/ethernet/mellanox/mlx5/core/accel/tls.c:
70      }
   0x000000000005825c <+44>:    ldr     w0, [x0, #20]
   0x0000000000058260 <+48>:    ret
------------------------------------------------------------------------

so IIUC mdev->fpga is null (offset of tls in struct mlx5_fpga_device is
indeed 80 = 0x50).

The NIC is

  Model: "Mellanox MT27700 Family [ConnectX-4]"
  Vendor: pci 0x15b3 "Mellanox Technologies"
  Device: pci 0x1013 "MT27700 Family [ConnectX-4]"
  SubVendor: pci 0x15b3 "Mellanox Technologies"
  SubDevice: pci 0x0003 

Michal Kubecek

^ permalink raw reply

* Re: [PATCH net-next v3 0/2] net: stmmac: Coalesce and tail addr fixes
From: David Miller @ 2018-09-14 21:27 UTC (permalink / raw)
  To: Jose.Abreu
  Cc: netdev, f.fainelli, narmstrong, jbrunet, martin.blumenstingl,
	Joao.Pinto, peppe.cavallaro, alexandre.torgue
In-Reply-To: <cover.1536762575.git.joabreu@synopsys.com>

From: Jose Abreu <Jose.Abreu@synopsys.com>
Date: Thu, 13 Sep 2018 09:02:21 +0100

> The fix for coalesce timer and a fix in tail address setting that impacts
> XGMAC2 operation.

This series is fixing bugs going all the way back to 4.7

There is no logical way that targetting net-next is valid.

net-next is always for new features and cleanups.

Bug fixes always go to 'net'.

Thank you.

^ permalink raw reply

* [PATH RFC net-next 5/8] net: phy: Add limkmode equivalents to some of the MII ethtool helpers
From: Andrew Lunn @ 2018-09-14 21:38 UTC (permalink / raw)
  To: netdev; +Cc: Florian Fainelli, Andrew Lunn
In-Reply-To: <1536961136-30453-1-git-send-email-andrew@lunn.ch>

Add helpers which take a linkmode rather than a u32 ethtool for
advertising settings.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 include/linux/mii.h | 50 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)

diff --git a/include/linux/mii.h b/include/linux/mii.h
index 9ed49c8261d0..2da85b02e1c0 100644
--- a/include/linux/mii.h
+++ b/include/linux/mii.h
@@ -132,6 +132,34 @@ static inline u32 ethtool_adv_to_mii_adv_t(u32 ethadv)
 	return result;
 }
 
+/**
+ * linkmode_adv_to_mii_adv_t
+ * @advertising: the linkmode advertisement settings
+ *
+ * A small helper function that translates linkmode advertisement
+ * settings to phy autonegotiation advertisements for the
+ * MII_ADVERTISE register.
+ */
+static inline u32 linkmode_adv_to_mii_adv_t(unsigned long *advertising)
+{
+	u32 result = 0;
+
+	if (linkmode_test_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT, advertising))
+		result |= ADVERTISE_10HALF;
+	if (linkmode_test_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT, advertising))
+		result |= ADVERTISE_10FULL;
+	if (linkmode_test_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, advertising))
+		result |= ADVERTISE_100HALF;
+	if (linkmode_test_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, advertising))
+		result |= ADVERTISE_100FULL;
+	if (linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT, advertising))
+		result |= ADVERTISE_PAUSE_CAP;
+	if (linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, advertising))
+		result |= ADVERTISE_PAUSE_ASYM;
+
+	return result;
+}
+
 /**
  * mii_adv_to_ethtool_adv_t
  * @adv: value of the MII_ADVERTISE register
@@ -179,6 +207,28 @@ static inline u32 ethtool_adv_to_mii_ctrl1000_t(u32 ethadv)
 	return result;
 }
 
+/**
+ * linkmode_adv_to_mii_ctrl1000_t
+ * advertising: the linkmode advertisement settings
+ *
+ * A small helper function that translates linkmode advertisement
+ * settings to phy autonegotiation advertisements for the
+ * MII_CTRL1000 register when in 1000T mode.
+ */
+static inline u32 linkmode_adv_to_mii_ctrl1000_t(unsigned long *advertising)
+{
+	u32 result = 0;
+
+	if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
+			      advertising))
+		result |= ADVERTISE_1000HALF;
+	if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
+			      advertising))
+		result |= ADVERTISE_1000FULL;
+
+	return result;
+}
+
 /**
  * mii_ctrl1000_to_ethtool_adv_t
  * @adv: value of the MII_CTRL1000 register
-- 
2.19.0.rc1

^ permalink raw reply related

* [PATH RFC net-next 2/8] net: phy: Add phydev_warn()
From: Andrew Lunn @ 2018-09-14 21:38 UTC (permalink / raw)
  To: netdev; +Cc: Florian Fainelli, Andrew Lunn
In-Reply-To: <1536961136-30453-1-git-send-email-andrew@lunn.ch>

Not all new style LINK_MODE bits can be converted into old style
SUPPORTED bits. We need to warn when such a conversion is attempted.
Add a helper for this.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 include/linux/phy.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/include/linux/phy.h b/include/linux/phy.h
index d24cc46748e2..0ab9f89773fd 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -968,6 +968,9 @@ static inline void phy_device_reset(struct phy_device *phydev, int value)
 #define phydev_err(_phydev, format, args...)	\
 	dev_err(&_phydev->mdio.dev, format, ##args)
 
+#define phydev_warn(_phydev, format, args...)	\
+	dev_warn(&_phydev->mdio.dev, format, ##args)
+
 #define phydev_dbg(_phydev, format, args...)	\
 	dev_dbg(&_phydev->mdio.dev, format, ##args)
 
-- 
2.19.0.rc1

^ permalink raw reply related

* [PATH RFC net-next 4/8] net: phy: Add helper for advertise to lcl value
From: Andrew Lunn @ 2018-09-14 21:38 UTC (permalink / raw)
  To: netdev; +Cc: Florian Fainelli, Andrew Lunn
In-Reply-To: <1536961136-30453-1-git-send-email-andrew@lunn.ch>

Add a helper to convert the local advertising to an LCL capabilities,
which is then used to resolve pause flow control settings.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 drivers/net/dsa/mt7530.c                      |  6 +-----
 drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c   |  5 +----
 drivers/net/ethernet/freescale/fman/mac.c     |  6 +-----
 drivers/net/ethernet/freescale/gianfar.c      |  7 +------
 .../hisilicon/hns3/hns3pf/hclge_main.c        |  6 +-----
 drivers/net/ethernet/mediatek/mtk_eth_soc.c   |  6 +-----
 drivers/net/ethernet/socionext/sni_ave.c      |  5 +----
 include/linux/mii.h                           | 19 +++++++++++++++++++
 8 files changed, 26 insertions(+), 34 deletions(-)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 62e486652e62..a5de9bffe5be 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -658,11 +658,7 @@ static void mt7530_adjust_link(struct dsa_switch *ds, int port,
 			if (phydev->asym_pause)
 				rmt_adv |= LPA_PAUSE_ASYM;
 
-			if (phydev->advertising & ADVERTISED_Pause)
-				lcl_adv |= ADVERTISE_PAUSE_CAP;
-			if (phydev->advertising & ADVERTISED_Asym_Pause)
-				lcl_adv |= ADVERTISE_PAUSE_ASYM;
-
+			lcl_adv = ethtool_adv_to_lcl_adv_t(phydev->advertising);
 			flowctrl = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv);
 
 			if (flowctrl & FLOW_CTRL_TX)
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c b/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c
index 289129011b9f..a7e03e3ecc93 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c
@@ -1495,10 +1495,7 @@ static void xgbe_phy_phydev_flowctrl(struct xgbe_prv_data *pdata)
 	if (!phy_data->phydev)
 		return;
 
-	if (phy_data->phydev->advertising & ADVERTISED_Pause)
-		lcl_adv |= ADVERTISE_PAUSE_CAP;
-	if (phy_data->phydev->advertising & ADVERTISED_Asym_Pause)
-		lcl_adv |= ADVERTISE_PAUSE_ASYM;
+	lcl_adv = ethtool_adv_to_lcl_adv_t(phy_data->phydev->advertising);
 
 	if (phy_data->phydev->pause) {
 		XGBE_SET_LP_ADV(lks, Pause);
diff --git a/drivers/net/ethernet/freescale/fman/mac.c b/drivers/net/ethernet/freescale/fman/mac.c
index a847b9c3b31a..d79e4e009d63 100644
--- a/drivers/net/ethernet/freescale/fman/mac.c
+++ b/drivers/net/ethernet/freescale/fman/mac.c
@@ -393,11 +393,7 @@ void fman_get_pause_cfg(struct mac_device *mac_dev, bool *rx_pause,
 	 */
 
 	/* get local capabilities */
-	lcl_adv = 0;
-	if (phy_dev->advertising & ADVERTISED_Pause)
-		lcl_adv |= ADVERTISE_PAUSE_CAP;
-	if (phy_dev->advertising & ADVERTISED_Asym_Pause)
-		lcl_adv |= ADVERTISE_PAUSE_ASYM;
+	lcl_adv = ethtool_adv_to_lcl_adv_t(phy_dev->advertising);
 
 	/* get link partner capabilities */
 	rmt_adv = 0;
diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c
index 40a1a87cd338..a24b242bf752 100644
--- a/drivers/net/ethernet/freescale/gianfar.c
+++ b/drivers/net/ethernet/freescale/gianfar.c
@@ -3658,12 +3658,7 @@ static u32 gfar_get_flowctrl_cfg(struct gfar_private *priv)
 		if (phydev->asym_pause)
 			rmt_adv |= LPA_PAUSE_ASYM;
 
-		lcl_adv = 0;
-		if (phydev->advertising & ADVERTISED_Pause)
-			lcl_adv |= ADVERTISE_PAUSE_CAP;
-		if (phydev->advertising & ADVERTISED_Asym_Pause)
-			lcl_adv |= ADVERTISE_PAUSE_ASYM;
-
+		lcl_adv = ethtool_adv_to_lcl_adv_t(phydev->advertising);
 		flowctrl = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv);
 		if (flowctrl & FLOW_CTRL_TX)
 			val |= MACCFG1_TX_FLOW;
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index cf18608669f5..a8088ba2ac9c 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -5270,11 +5270,7 @@ int hclge_cfg_flowctrl(struct hclge_dev *hdev)
 	if (!phydev->link || !phydev->autoneg)
 		return 0;
 
-	if (phydev->advertising & ADVERTISED_Pause)
-		local_advertising = ADVERTISE_PAUSE_CAP;
-
-	if (phydev->advertising & ADVERTISED_Asym_Pause)
-		local_advertising |= ADVERTISE_PAUSE_ASYM;
+	local_advertising = ethtool_adv_to_lcl_adv_t(phydev->advertising);
 
 	if (phydev->pause)
 		remote_advertising = LPA_PAUSE_CAP;
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index cc1e9a96a43b..7dbfdac4067a 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -243,11 +243,7 @@ static void mtk_phy_link_adjust(struct net_device *dev)
 		if (dev->phydev->asym_pause)
 			rmt_adv |= LPA_PAUSE_ASYM;
 
-		if (dev->phydev->advertising & ADVERTISED_Pause)
-			lcl_adv |= ADVERTISE_PAUSE_CAP;
-		if (dev->phydev->advertising & ADVERTISED_Asym_Pause)
-			lcl_adv |= ADVERTISE_PAUSE_ASYM;
-
+		lcl_adv = ethtool_adv_to_lcl_adv_t(dev->phydev->advertising);
 		flowctrl = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv);
 
 		if (flowctrl & FLOW_CTRL_TX)
diff --git a/drivers/net/ethernet/socionext/sni_ave.c b/drivers/net/ethernet/socionext/sni_ave.c
index 61e6abb966ac..6feecd4e23e9 100644
--- a/drivers/net/ethernet/socionext/sni_ave.c
+++ b/drivers/net/ethernet/socionext/sni_ave.c
@@ -1116,11 +1116,8 @@ static void ave_phy_adjust_link(struct net_device *ndev)
 			rmt_adv |= LPA_PAUSE_CAP;
 		if (phydev->asym_pause)
 			rmt_adv |= LPA_PAUSE_ASYM;
-		if (phydev->advertising & ADVERTISED_Pause)
-			lcl_adv |= ADVERTISE_PAUSE_CAP;
-		if (phydev->advertising & ADVERTISED_Asym_Pause)
-			lcl_adv |= ADVERTISE_PAUSE_ASYM;
 
+		lcl_adv = ethtool_adv_to_lcl_adv_t(phydev->advertising);
 		cap = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv);
 		if (cap & FLOW_CTRL_TX)
 			txcr |= AVE_TXCR_FLOCTR;
diff --git a/include/linux/mii.h b/include/linux/mii.h
index 8c7da9473ad9..9ed49c8261d0 100644
--- a/include/linux/mii.h
+++ b/include/linux/mii.h
@@ -334,6 +334,25 @@ static inline void mii_adv_to_linkmode_adv_t(unsigned long *advertising,
 		linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, advertising);
 }
 
+/**
+ * ethtool_adv_to_lcl_adv_t
+ * @advertising:pointer to ethtool advertising
+ *
+ * A small helper function that translates ethtool advertising to LVL
+ * pause capabilities.
+ */
+static inline u32 ethtool_adv_to_lcl_adv_t(u32 advertising)
+{
+	u32 lcl_adv = 0;
+
+	if (advertising & ADVERTISED_Pause)
+		lcl_adv |= ADVERTISE_PAUSE_CAP;
+	if (advertising & ADVERTISED_Asym_Pause)
+		lcl_adv |= ADVERTISE_PAUSE_ASYM;
+
+	return lcl_adv;
+}
+
 /**
  * mii_advertise_flowctrl - get flow control advertisement flags
  * @cap: Flow control capabilities (FLOW_CTRL_RX, FLOW_CTRL_TX or both)
-- 
2.19.0.rc1

^ permalink raw reply related

* [PATH RFC net-next 1/8] net: phy: Move linkmode helpers to somewhere public
From: Andrew Lunn @ 2018-09-14 21:38 UTC (permalink / raw)
  To: netdev; +Cc: Florian Fainelli, Andrew Lunn
In-Reply-To: <1536961136-30453-1-git-send-email-andrew@lunn.ch>

phylink has some useful helpers to working with linkmode bitmaps.
Move them to there own header so other code can use them.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 drivers/net/phy/phylink.c | 27 ----------------
 include/linux/linkmode.h  | 67 +++++++++++++++++++++++++++++++++++++++
 include/linux/mii.h       |  1 +
 include/linux/phy.h       |  1 +
 4 files changed, 69 insertions(+), 27 deletions(-)
 create mode 100644 include/linux/linkmode.h

diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
index 3ba5cf2a8a5f..95ab492089f2 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -68,33 +68,6 @@ struct phylink {
 	struct sfp_bus *sfp_bus;
 };
 
-static inline void linkmode_zero(unsigned long *dst)
-{
-	bitmap_zero(dst, __ETHTOOL_LINK_MODE_MASK_NBITS);
-}
-
-static inline void linkmode_copy(unsigned long *dst, const unsigned long *src)
-{
-	bitmap_copy(dst, src, __ETHTOOL_LINK_MODE_MASK_NBITS);
-}
-
-static inline void linkmode_and(unsigned long *dst, const unsigned long *a,
-				const unsigned long *b)
-{
-	bitmap_and(dst, a, b, __ETHTOOL_LINK_MODE_MASK_NBITS);
-}
-
-static inline void linkmode_or(unsigned long *dst, const unsigned long *a,
-				const unsigned long *b)
-{
-	bitmap_or(dst, a, b, __ETHTOOL_LINK_MODE_MASK_NBITS);
-}
-
-static inline bool linkmode_empty(const unsigned long *src)
-{
-	return bitmap_empty(src, __ETHTOOL_LINK_MODE_MASK_NBITS);
-}
-
 /**
  * phylink_set_port_modes() - set the port type modes in the ethtool mask
  * @mask: ethtool link mode mask
diff --git a/include/linux/linkmode.h b/include/linux/linkmode.h
new file mode 100644
index 000000000000..014fb86c7114
--- /dev/null
+++ b/include/linux/linkmode.h
@@ -0,0 +1,67 @@
+#ifndef __LINKMODE_H
+#define __LINKMODE_H
+
+#include <linux/bitmap.h>
+#include <linux/ethtool.h>
+#include <uapi/linux/ethtool.h>
+
+static inline void linkmode_zero(unsigned long *dst)
+{
+	bitmap_zero(dst, __ETHTOOL_LINK_MODE_MASK_NBITS);
+}
+
+static inline void linkmode_copy(unsigned long *dst, const unsigned long *src)
+{
+	bitmap_copy(dst, src, __ETHTOOL_LINK_MODE_MASK_NBITS);
+}
+
+static inline void linkmode_and(unsigned long *dst, const unsigned long *a,
+				const unsigned long *b)
+{
+	bitmap_and(dst, a, b, __ETHTOOL_LINK_MODE_MASK_NBITS);
+}
+
+static inline void linkmode_or(unsigned long *dst, const unsigned long *a,
+				const unsigned long *b)
+{
+	bitmap_or(dst, a, b, __ETHTOOL_LINK_MODE_MASK_NBITS);
+}
+
+static inline bool linkmode_empty(const unsigned long *src)
+{
+	return bitmap_empty(src, __ETHTOOL_LINK_MODE_MASK_NBITS);
+}
+
+static inline int linkmode_andnot(unsigned long *dst, const unsigned long *src1,
+				  const unsigned long *src2)
+{
+	return bitmap_andnot(dst, src1, src2,  __ETHTOOL_LINK_MODE_MASK_NBITS);
+}
+
+static inline void linkmode_set_bit(int nr, volatile unsigned long *addr)
+{
+	__set_bit(nr, addr);
+}
+
+static inline void linkmode_clear_bit(int nr, volatile unsigned long *addr)
+{
+	__clear_bit(nr, addr);
+}
+
+static inline void linkmode_change_bit(int nr, volatile unsigned long *addr)
+{
+	__change_bit(nr, addr);
+}
+
+static inline int linkmode_test_bit(int nr, volatile unsigned long *addr)
+{
+	return test_bit(nr, addr);
+}
+
+static inline int linkmode_equal(const unsigned long *src1,
+				 const unsigned long *src2)
+{
+	return bitmap_equal(src1, src2, __ETHTOOL_LINK_MODE_MASK_NBITS);
+}
+
+#endif /* __LINKMODE_H */
diff --git a/include/linux/mii.h b/include/linux/mii.h
index 55000ee5c6ad..567047ef0309 100644
--- a/include/linux/mii.h
+++ b/include/linux/mii.h
@@ -10,6 +10,7 @@
 
 
 #include <linux/if.h>
+#include <linux/linkmode.h>
 #include <uapi/linux/mii.h>
 
 struct ethtool_cmd;
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 192a1fa0c73b..d24cc46748e2 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -19,6 +19,7 @@
 #include <linux/compiler.h>
 #include <linux/spinlock.h>
 #include <linux/ethtool.h>
+#include <linux/linkmode.h>
 #include <linux/mdio.h>
 #include <linux/mii.h>
 #include <linux/module.h>
-- 
2.19.0.rc1

^ permalink raw reply related

* [PATH RFC net-next 6/8] net: ethernet xgbe expand PHY_GBIT_FEAUTRES
From: Andrew Lunn @ 2018-09-14 21:38 UTC (permalink / raw)
  To: netdev; +Cc: Florian Fainelli, Andrew Lunn
In-Reply-To: <1536961136-30453-1-git-send-email-andrew@lunn.ch>

The macro PHY_GBIT_FEAUTRES needs to change into a bitmap in order to
support link_modes. Remove its use from xgde by replacing it with its
definition.

Probably, the current behavior is wrong. It probably should be
ANDing not assigning.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c b/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c
index a7e03e3ecc93..d49e76982453 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c
@@ -878,8 +878,9 @@ static bool xgbe_phy_finisar_phy_quirks(struct xgbe_prv_data *pdata)
 	phy_write(phy_data->phydev, 0x04, 0x0d01);
 	phy_write(phy_data->phydev, 0x00, 0x9140);
 
-	phy_data->phydev->supported = PHY_GBIT_FEATURES;
-	phy_data->phydev->advertising = phy_data->phydev->supported;
+	phy_data->phydev->supported = (PHY_10BT_FEATURES |
+				       PHY_100BT_FEATURES |
+				       PHY_1000BT_FEATURES);
 	phy_support_asym_pause(phy_data->phydev);
 
 	netif_dbg(pdata, drv, pdata->netdev,
@@ -950,8 +951,9 @@ static bool xgbe_phy_belfuse_phy_quirks(struct xgbe_prv_data *pdata)
 	reg = phy_read(phy_data->phydev, 0x00);
 	phy_write(phy_data->phydev, 0x00, reg & ~0x00800);
 
-	phy_data->phydev->supported = PHY_GBIT_FEATURES;
-	phy_data->phydev->advertising = phy_data->phydev->supported;
+	phy_data->phydev->supported = (PHY_10BT_FEATURES |
+				       PHY_100BT_FEATURES |
+				       PHY_1000BT_FEATURES);
 	phy_support_asym_pause(phy_data->phydev);
 
 	netif_dbg(pdata, drv, pdata->netdev,
-- 
2.19.0.rc1

^ permalink raw reply related

* [PATH RFC net-next 3/8] net: phy: Add helper to convert MII ADV register to a linkmode
From: Andrew Lunn @ 2018-09-14 21:38 UTC (permalink / raw)
  To: netdev; +Cc: Florian Fainelli, Andrew Lunn
In-Reply-To: <1536961136-30453-1-git-send-email-andrew@lunn.ch>

The phy_mii_ioctl can be used to write a value into the MII_ADVERTISE
register in the PHY. Since this changes the state of the PHY, we need
to make the same change to phydev->advertising. Add a helper which can
convert the register value to a linkmode.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 include/linux/mii.h | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/include/linux/mii.h b/include/linux/mii.h
index 567047ef0309..8c7da9473ad9 100644
--- a/include/linux/mii.h
+++ b/include/linux/mii.h
@@ -303,6 +303,37 @@ static inline u32 mii_lpa_to_ethtool_lpa_x(u32 lpa)
 	return result | mii_adv_to_ethtool_adv_x(lpa);
 }
 
+/**
+ * mii_adv_to_linkmode_adv_t
+ * @advertising:pointer to destination link mode.
+ * @adv: value of the MII_ADVERTISE register
+ *
+ * A small helper function that translates MII_ADVERTISE bits
+ * to linkmode advertisement settings.
+ */
+static inline void mii_adv_to_linkmode_adv_t(unsigned long *advertising,
+					     u32 adv)
+{
+	linkmode_zero(advertising);
+
+	if (adv & ADVERTISE_10HALF)
+		linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT,
+				 advertising);
+	if (adv & ADVERTISE_10FULL)
+		linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT,
+				 advertising);
+	if (adv & ADVERTISE_100HALF)
+		linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT,
+				 advertising);
+	if (adv & ADVERTISE_100FULL)
+		linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT,
+				 advertising);
+	if (adv & ADVERTISE_PAUSE_CAP)
+		linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, advertising);
+	if (adv & ADVERTISE_PAUSE_ASYM)
+		linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, advertising);
+}
+
 /**
  * mii_advertise_flowctrl - get flow control advertisement flags
  * @cap: Flow control capabilities (FLOW_CTRL_RX, FLOW_CTRL_TX or both)
-- 
2.19.0.rc1

^ permalink raw reply related

* [PATH RFC net-next 7/8] net: phy: Replace phy driver features u32 with link_mode bitmap
From: Andrew Lunn @ 2018-09-14 21:38 UTC (permalink / raw)
  To: netdev; +Cc: Florian Fainelli, Andrew Lunn
In-Reply-To: <1536961136-30453-1-git-send-email-andrew@lunn.ch>

This is one step in allowing phylib to make use of link_mode bitmaps,
instead of u32 for supported and advertised features. Convert the phy
drivers to use bitmaps to indicates the features they support. This
requires some macro magic in order to construct constant bitmaps used
to initialise the driver structures.

Some new PHY_*_FEATURES are added, to indicate FIBRE is supported, and
that all media ports are supported. This is done since bitmaps cannot
be ORed together at compile time.

Within phylib, the features bitmap is currently turned back into a
u32.  The MAC API to phylib needs to be cleaned up before the core of
phylib can be converted to using bitmaps instead of u32.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 drivers/net/ethernet/marvell/pxa168_eth.c |   4 +-
 drivers/net/phy/aquantia.c                |  12 +-
 drivers/net/phy/bcm63xx.c                 |   9 +-
 drivers/net/phy/marvell.c                 |   2 +-
 drivers/net/phy/marvell10g.c              |  11 +-
 drivers/net/phy/microchip_t1.c            |   2 +-
 drivers/net/phy/phy_device.c              | 204 +++++++++++++++++++++-
 include/linux/phy.h                       |  24 ++-
 8 files changed, 229 insertions(+), 39 deletions(-)

diff --git a/drivers/net/ethernet/marvell/pxa168_eth.c b/drivers/net/ethernet/marvell/pxa168_eth.c
index 3a9730612a70..b406395bbb37 100644
--- a/drivers/net/ethernet/marvell/pxa168_eth.c
+++ b/drivers/net/ethernet/marvell/pxa168_eth.c
@@ -988,8 +988,8 @@ static int pxa168_init_phy(struct net_device *dev)
 	cmd.base.phy_address = pep->phy_addr;
 	cmd.base.speed = pep->phy_speed;
 	cmd.base.duplex = pep->phy_duplex;
-	ethtool_convert_legacy_u32_to_link_mode(cmd.link_modes.advertising,
-						PHY_BASIC_FEATURES);
+	bitmap_copy(cmd.link_modes.advertising, PHY_BASIC_FEATURES,
+		    __ETHTOOL_LINK_MODE_MASK_NBITS);
 	cmd.base.autoneg = AUTONEG_ENABLE;
 
 	if (cmd.base.speed != 0)
diff --git a/drivers/net/phy/aquantia.c b/drivers/net/phy/aquantia.c
index 319edc9c8ec7..632472cab3bb 100644
--- a/drivers/net/phy/aquantia.c
+++ b/drivers/net/phy/aquantia.c
@@ -115,7 +115,7 @@ static struct phy_driver aquantia_driver[] = {
 	.phy_id		= PHY_ID_AQ1202,
 	.phy_id_mask	= 0xfffffff0,
 	.name		= "Aquantia AQ1202",
-	.features	= PHY_AQUANTIA_FEATURES,
+	.features	= PHY_10GBIT_FULL_FEATURES,
 	.flags		= PHY_HAS_INTERRUPT,
 	.aneg_done	= genphy_c45_aneg_done,
 	.config_aneg    = aquantia_config_aneg,
@@ -127,7 +127,7 @@ static struct phy_driver aquantia_driver[] = {
 	.phy_id		= PHY_ID_AQ2104,
 	.phy_id_mask	= 0xfffffff0,
 	.name		= "Aquantia AQ2104",
-	.features	= PHY_AQUANTIA_FEATURES,
+	.features	= PHY_10GBIT_FULL_FEATURES,
 	.flags		= PHY_HAS_INTERRUPT,
 	.aneg_done	= genphy_c45_aneg_done,
 	.config_aneg    = aquantia_config_aneg,
@@ -139,7 +139,7 @@ static struct phy_driver aquantia_driver[] = {
 	.phy_id		= PHY_ID_AQR105,
 	.phy_id_mask	= 0xfffffff0,
 	.name		= "Aquantia AQR105",
-	.features	= PHY_AQUANTIA_FEATURES,
+	.features	= PHY_10GBIT_FULL_FEATURES,
 	.flags		= PHY_HAS_INTERRUPT,
 	.aneg_done	= genphy_c45_aneg_done,
 	.config_aneg    = aquantia_config_aneg,
@@ -151,7 +151,7 @@ static struct phy_driver aquantia_driver[] = {
 	.phy_id		= PHY_ID_AQR106,
 	.phy_id_mask	= 0xfffffff0,
 	.name		= "Aquantia AQR106",
-	.features	= PHY_AQUANTIA_FEATURES,
+	.features	= PHY_10GBIT_FULL_FEATURES,
 	.flags		= PHY_HAS_INTERRUPT,
 	.aneg_done	= genphy_c45_aneg_done,
 	.config_aneg    = aquantia_config_aneg,
@@ -163,7 +163,7 @@ static struct phy_driver aquantia_driver[] = {
 	.phy_id		= PHY_ID_AQR107,
 	.phy_id_mask	= 0xfffffff0,
 	.name		= "Aquantia AQR107",
-	.features	= PHY_AQUANTIA_FEATURES,
+	.features	= PHY_10GBIT_FULL_FEATURES,
 	.flags		= PHY_HAS_INTERRUPT,
 	.aneg_done	= genphy_c45_aneg_done,
 	.config_aneg    = aquantia_config_aneg,
@@ -175,7 +175,7 @@ static struct phy_driver aquantia_driver[] = {
 	.phy_id		= PHY_ID_AQR405,
 	.phy_id_mask	= 0xfffffff0,
 	.name		= "Aquantia AQR405",
-	.features	= PHY_AQUANTIA_FEATURES,
+	.features	= PHY_10GBIT_FULL_FEATURES,
 	.flags		= PHY_HAS_INTERRUPT,
 	.aneg_done	= genphy_c45_aneg_done,
 	.config_aneg    = aquantia_config_aneg,
diff --git a/drivers/net/phy/bcm63xx.c b/drivers/net/phy/bcm63xx.c
index cf14613745c9..ff5acf01b877 100644
--- a/drivers/net/phy/bcm63xx.c
+++ b/drivers/net/phy/bcm63xx.c
@@ -42,6 +42,9 @@ static int bcm63xx_config_init(struct phy_device *phydev)
 {
 	int reg, err;
 
+	/* ASYM_PAUSE bit is marked RO in datasheet, so don't cheat */
+	linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, phydev->supported),
+
 	reg = phy_read(phydev, MII_BCM63XX_IR);
 	if (reg < 0)
 		return reg;
@@ -65,8 +68,7 @@ static struct phy_driver bcm63xx_driver[] = {
 	.phy_id		= 0x00406000,
 	.phy_id_mask	= 0xfffffc00,
 	.name		= "Broadcom BCM63XX (1)",
-	/* ASYM_PAUSE bit is marked RO in datasheet, so don't cheat */
-	.features	= (PHY_BASIC_FEATURES | SUPPORTED_Pause),
+	.features	= PHY_BASIC_FEATURES,
 	.flags		= PHY_HAS_INTERRUPT | PHY_IS_INTERNAL,
 	.config_init	= bcm63xx_config_init,
 	.ack_interrupt	= bcm_phy_ack_intr,
@@ -75,8 +77,7 @@ static struct phy_driver bcm63xx_driver[] = {
 	/* same phy as above, with just a different OUI */
 	.phy_id		= 0x002bdc00,
 	.phy_id_mask	= 0xfffffc00,
-	.name		= "Broadcom BCM63XX (2)",
-	.features	= (PHY_BASIC_FEATURES | SUPPORTED_Pause),
+	.features	= PHY_BASIC_FEATURES,
 	.flags		= PHY_HAS_INTERRUPT | PHY_IS_INTERNAL,
 	.config_init	= bcm63xx_config_init,
 	.ack_interrupt	= bcm_phy_ack_intr,
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
index f7c69ca34056..de1e900f7253 100644
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@ -2222,7 +2222,7 @@ static struct phy_driver marvell_drivers[] = {
 		.phy_id = MARVELL_PHY_ID_88E1510,
 		.phy_id_mask = MARVELL_PHY_ID_MASK,
 		.name = "Marvell 88E1510",
-		.features = PHY_GBIT_FEATURES | SUPPORTED_FIBRE,
+		.features = PHY_GBIT_FIBRE_FEATURES,
 		.flags = PHY_HAS_INTERRUPT,
 		.probe = &m88e1510_probe,
 		.config_init = &m88e1510_config_init,
diff --git a/drivers/net/phy/marvell10g.c b/drivers/net/phy/marvell10g.c
index f77a2d9e7f9d..7f4a43c65da6 100644
--- a/drivers/net/phy/marvell10g.c
+++ b/drivers/net/phy/marvell10g.c
@@ -535,16 +535,7 @@ static struct phy_driver mv3310_drivers[] = {
 		.phy_id		= 0x002b09aa,
 		.phy_id_mask	= MARVELL_PHY_ID_MASK,
 		.name		= "mv88x3310",
-		.features	= SUPPORTED_10baseT_Full |
-				  SUPPORTED_10baseT_Half |
-				  SUPPORTED_100baseT_Full |
-				  SUPPORTED_100baseT_Half |
-				  SUPPORTED_1000baseT_Full |
-				  SUPPORTED_Autoneg |
-				  SUPPORTED_TP |
-				  SUPPORTED_FIBRE |
-				  SUPPORTED_10000baseT_Full |
-				  SUPPORTED_Backplane,
+		.features	= PHY_10GBIT_FEATURES,
 		.soft_reset	= gen10g_no_soft_reset,
 		.config_init	= mv3310_config_init,
 		.probe		= mv3310_probe,
diff --git a/drivers/net/phy/microchip_t1.c b/drivers/net/phy/microchip_t1.c
index b1917dd1978a..c600a8509d60 100644
--- a/drivers/net/phy/microchip_t1.c
+++ b/drivers/net/phy/microchip_t1.c
@@ -46,7 +46,7 @@ static struct phy_driver microchip_t1_phy_driver[] = {
 		.phy_id_mask    = 0xfffffff0,
 		.name           = "Microchip LAN87xx T1",
 
-		.features       = SUPPORTED_100baseT_Full,
+		.features       = PHY_BASIC_T1_FEATURES,
 		.flags          = PHY_HAS_INTERRUPT,
 
 		.config_init    = genphy_config_init,
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index af64a9320fb0..eed61ee1d394 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -29,6 +29,7 @@
 #include <linux/module.h>
 #include <linux/mii.h>
 #include <linux/ethtool.h>
+#include <linux/bitmap.h>
 #include <linux/phy.h>
 #include <linux/phy_led_triggers.h>
 #include <linux/mdio.h>
@@ -42,6 +43,191 @@ MODULE_DESCRIPTION("PHY library");
 MODULE_AUTHOR("Andy Fleming");
 MODULE_LICENSE("GPL");
 
+#define BIT_IN_RANGE(bit, lower, upper)			\
+	((bit) < (lower) ? 0 : ((bit) > (upper) ? 0 :	\
+				 BIT((bit) - (lower))))
+
+#define BIT_IN_LONG_ARRAY(bit, index)				\
+	BIT_IN_RANGE(bit, (BITS_PER_LONG * (index)),		\
+		     (BITS_PER_LONG * ((index) + 1)) - 1)
+
+#define BIT_IN_LONG_ARRAY_0(bit) BIT_IN_LONG_ARRAY(bit, 0)
+#define BIT_IN_LONG_ARRAY_1(bit) BIT_IN_LONG_ARRAY(bit, 1)
+#define BIT_IN_LONG_ARRAY_2(bit) BIT_IN_LONG_ARRAY(bit, 2)
+
+const __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_basic_features) = {
+	[0] = (BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_Autoneg_BIT)	|
+	       BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_TP_BIT)		|
+	       BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_MII_BIT)		|
+	       BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_10baseT_Half_BIT)	|
+	       BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_10baseT_Full_BIT)	|
+	       BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_100baseT_Half_BIT)	|
+	       BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_100baseT_Full_BIT)),
+#if BITS_PER_LONG == 32
+	[1] = (BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_Autoneg_BIT)	|
+	       BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_TP_BIT)		|
+	       BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_MII_BIT)		|
+	       BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_10baseT_Half_BIT)	|
+	       BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_10baseT_Full_BIT)	|
+	       BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_100baseT_Half_BIT)	|
+	       BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_100baseT_Full_BIT)),
+#endif
+};
+EXPORT_SYMBOL_GPL(phy_basic_features);
+
+const __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_basic_t1_features) = {
+	[0] = (BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_TP_BIT)		|
+	       BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_100baseT_Full_BIT)),
+#if BITS_PER_LONG == 32
+	[1] = (BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_TP_BIT)		|
+	       BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_100baseT_Full_BIT)),
+#endif
+};
+EXPORT_SYMBOL_GPL(phy_basic_t1_features);
+
+const __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_gbit_features) = {
+	[0] = (BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_Autoneg_BIT)	 |
+	       BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_TP_BIT)		 |
+	       BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_MII_BIT)		 |
+	       BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_10baseT_Half_BIT)	 |
+	       BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_10baseT_Full_BIT)	 |
+	       BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_100baseT_Half_BIT)	 |
+	       BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_100baseT_Full_BIT)	 |
+	       BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_1000baseT_Half_BIT) |
+	       BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_1000baseT_Full_BIT)),
+#if BITS_PER_LONG == 32
+	[1] = (BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_Autoneg_BIT)	 |
+	       BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_TP_BIT)		 |
+	       BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_MII_BIT)		 |
+	       BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_10baseT_Half_BIT)	 |
+	       BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_10baseT_Full_BIT)	 |
+	       BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_100baseT_Half_BIT)	 |
+	       BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_100baseT_Full_BIT)	 |
+	       BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_1000baseT_Half_BIT) |
+	       BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_1000baseT_Full_BIT)),
+#endif
+};
+EXPORT_SYMBOL_GPL(phy_gbit_features);
+
+const __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_gbit_fibre_features) = {
+	[0] = (BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_Autoneg_BIT)	 |
+	       BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_TP_BIT)		 |
+	       BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_MII_BIT)		 |
+	       BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_FIBRE_BIT)		 |
+	       BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_10baseT_Half_BIT)	 |
+	       BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_10baseT_Full_BIT)	 |
+	       BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_100baseT_Half_BIT)	 |
+	       BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_100baseT_Full_BIT)	 |
+	       BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_1000baseT_Half_BIT) |
+	       BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_1000baseT_Full_BIT)),
+#if BITS_PER_LONG == 32
+	[1] = (BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_Autoneg_BIT)	 |
+	       BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_TP_BIT)		 |
+	       BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_MII_BIT)		 |
+	       BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_FIBRE_BIT)		 |
+	       BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_10baseT_Half_BIT)	 |
+	       BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_10baseT_Full_BIT)	 |
+	       BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_100baseT_Half_BIT)	 |
+	       BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_100baseT_Full_BIT)	 |
+	       BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_1000baseT_Half_BIT) |
+	       BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_1000baseT_Full_BIT)),
+#endif
+};
+EXPORT_SYMBOL_GPL(phy_gbit_fibre_features);
+
+const __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_gbit_all_ports_features) = {
+	[0] = (BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_Autoneg_BIT)	 |
+	       BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_TP_BIT)		 |
+	       BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_MII_BIT)		 |
+	       BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_FIBRE_BIT)		 |
+	       BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_AUI_BIT)		 |
+	       BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_BNC_BIT)		 |
+	       BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_Backplane_BIT)	 |
+	       BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_10baseT_Half_BIT)	 |
+	       BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_10baseT_Full_BIT)	 |
+	       BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_100baseT_Half_BIT)	 |
+	       BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_100baseT_Full_BIT)	 |
+	       BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_1000baseT_Half_BIT) |
+	       BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_1000baseT_Full_BIT)),
+#if BITS_PER_LONG == 32
+	[1] = (BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_Autoneg_BIT)	 |
+	       BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_TP_BIT)		 |
+	       BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_MII_BIT)		 |
+	       BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_FIBRE_BIT)		 |
+	       BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_AUI_BIT)		 |
+	       BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_BNC_BIT)		 |
+	       BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_Backplane_BIT)	 |
+	       BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_10baseT_Half_BIT)	 |
+	       BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_10baseT_Full_BIT)	 |
+	       BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_100baseT_Half_BIT)	 |
+	       BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_100baseT_Full_BIT)	 |
+	       BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_1000baseT_Half_BIT) |
+	       BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_1000baseT_Full_BIT)),
+#endif
+};
+EXPORT_SYMBOL_GPL(phy_gbit_all_ports_features);
+
+const __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_10gbit_features) = {
+	[0] = (BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_Autoneg_BIT)	 |
+	       BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_TP_BIT)		 |
+	       BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_MII_BIT)		 |
+	       BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_FIBRE_BIT)		 |
+	       BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_AUI_BIT)		 |
+	       BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_BNC_BIT)		 |
+	       BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_Backplane_BIT)	 |
+	       BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_10baseT_Half_BIT)	 |
+	       BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_10baseT_Full_BIT)	 |
+	       BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_100baseT_Half_BIT)	 |
+	       BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_100baseT_Full_BIT)	 |
+	       BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_1000baseT_Half_BIT) |
+	       BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_1000baseT_Full_BIT) |
+	       BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_10000baseT_Full_BIT)),
+#if BITS_PER_LONG == 32
+	[1] = (BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_Autoneg_BIT)	 |
+	       BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_TP_BIT)		 |
+	       BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_MII_BIT)		 |
+	       BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_FIBRE_BIT)		 |
+	       BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_Backplane_BIT)	 |
+	       BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_10baseT_Half_BIT)	 |
+	       BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_10baseT_Full_BIT)	 |
+	       BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_100baseT_Half_BIT)	 |
+	       BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_100baseT_Full_BIT)	 |
+	       BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_1000baseT_Half_BIT) |
+	       BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_1000baseT_Full_BIT) |
+	       BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_10000baseT_Full_BIT)),
+#endif
+};
+EXPORT_SYMBOL_GPL(phy_10gbit_features);
+
+/* No half duplex support */
+const __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_10gbit_full_features) = {
+	[0] = (BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_Autoneg_BIT)	 |
+	       BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_TP_BIT)		 |
+	       BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_MII_BIT)		 |
+	       BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_FIBRE_BIT)		 |
+	       BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_AUI_BIT)		 |
+	       BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_BNC_BIT)		 |
+	       BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_Backplane_BIT)	 |
+	       BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_10baseT_Full_BIT)	 |
+	       BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_100baseT_Full_BIT)	 |
+	       BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_1000baseT_Full_BIT) |
+	       BIT_IN_LONG_ARRAY_0(ETHTOOL_LINK_MODE_10000baseT_Full_BIT)),
+#if BITS_PER_LONG == 32
+	[1] = (BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_Autoneg_BIT)	 |
+	       BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_TP_BIT)		 |
+	       BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_MII_BIT)		 |
+	       BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_AUI_BIT)		 |
+	       BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_BNC_BIT)		 |
+	       BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_FIBRE_BIT)		 |
+	       BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_Backplane_BIT)	 |
+	       BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_10baseT_Full_BIT)	 |
+	       BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_100baseT_Full_BIT)	 |
+	       BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_1000baseT_Full_BIT) |
+	       BIT_IN_LONG_ARRAY_1(ETHTOOL_LINK_MODE_10000baseT_Full_BIT)),
+#endif
+};
+EXPORT_SYMBOL_GPL(phy_10gbit_full_features);
+
 void phy_device_free(struct phy_device *phydev)
 {
 	put_device(&phydev->mdio.dev);
@@ -1938,6 +2124,7 @@ static int phy_probe(struct device *dev)
 	struct phy_device *phydev = to_phy_device(dev);
 	struct device_driver *drv = phydev->mdio.dev.driver;
 	struct phy_driver *phydrv = to_phy_driver(drv);
+	u32 features;
 	int err = 0;
 
 	phydev->drv = phydrv;
@@ -1958,7 +2145,8 @@ static int phy_probe(struct device *dev)
 	 * a controller will attach, and may modify one
 	 * or both of these values
 	 */
-	phydev->supported = phydrv->features;
+	ethtool_convert_link_mode_to_legacy_u32(&features, phydrv->features);
+	phydev->supported = features;
 	of_set_phy_supported(phydev);
 	phydev->advertising = phydev->supported;
 
@@ -1978,10 +2166,14 @@ static int phy_probe(struct device *dev)
 	 * (e.g. hardware erratum) where the driver wants to set only one
 	 * of these bits.
 	 */
-	if (phydrv->features & (SUPPORTED_Pause | SUPPORTED_Asym_Pause)) {
+	if (test_bit(ETHTOOL_LINK_MODE_Pause_BIT, phydrv->features) ||
+	    test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, phydrv->features)) {
 		phydev->supported &= ~(SUPPORTED_Pause | SUPPORTED_Asym_Pause);
-		phydev->supported |= phydrv->features &
-				     (SUPPORTED_Pause | SUPPORTED_Asym_Pause);
+		if (test_bit(ETHTOOL_LINK_MODE_Pause_BIT, phydrv->features))
+			phydev->supported |= SUPPORTED_Pause;
+		if (test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
+			     phydrv->features))
+			phydev->supported |= SUPPORTED_Asym_Pause;
 	} else {
 		phydev->supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
 	}
@@ -2094,9 +2286,7 @@ static struct phy_driver genphy_driver = {
 	.name		= "Generic PHY",
 	.soft_reset	= genphy_no_soft_reset,
 	.config_init	= genphy_config_init,
-	.features	= PHY_GBIT_FEATURES | SUPPORTED_MII |
-			  SUPPORTED_AUI | SUPPORTED_FIBRE |
-			  SUPPORTED_BNC,
+	.features	= PHY_GBIT_ALL_PORTS_FEATURES,
 	.aneg_done	= genphy_aneg_done,
 	.suspend	= genphy_suspend,
 	.resume		= genphy_resume,
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 0ab9f89773fd..8343a1999e1b 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -42,13 +42,21 @@
 #define PHY_1000BT_FEATURES	(SUPPORTED_1000baseT_Half | \
 				 SUPPORTED_1000baseT_Full)
 
-#define PHY_BASIC_FEATURES	(PHY_10BT_FEATURES | \
-				 PHY_100BT_FEATURES | \
-				 PHY_DEFAULT_FEATURES)
-
-#define PHY_GBIT_FEATURES	(PHY_BASIC_FEATURES | \
-				 PHY_1000BT_FEATURES)
-
+extern const __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_basic_features);
+extern const __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_basic_t1_features);
+extern const __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_gbit_features);
+extern const __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_gbit_fibre_features);
+extern const __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_gbit_all_ports_features);
+extern const __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_10gbit_features);
+extern const __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_10gbit_full_features);
+
+#define PHY_BASIC_FEATURES ((unsigned long *)&phy_basic_features)
+#define PHY_BASIC_T1_FEATURES ((unsigned long *)&phy_basic_t1_features)
+#define PHY_GBIT_FEATURES ((unsigned long *)&phy_gbit_features)
+#define PHY_GBIT_FIBRE_FEATURES ((unsigned long *)&phy_gbit_fibre_features)
+#define PHY_GBIT_ALL_PORTS_FEATURES ((unsigned long *)&phy_gbit_all_ports_features)
+#define PHY_10GBIT_FEATURES ((unsigned long *)&phy_10gbit_features)
+#define PHY_10GBIT_FULL_FEATURES ((unsigned long *)&phy_10gbit_full_features)
 
 /*
  * Set phydev->irq to PHY_POLL if interrupts are not supported,
@@ -510,7 +518,7 @@ struct phy_driver {
 	u32 phy_id;
 	char *name;
 	u32 phy_id_mask;
-	u32 features;
+	const unsigned long * const features;
 	u32 flags;
 	const void *driver_data;
 
-- 
2.19.0.rc1

^ permalink raw reply related

* [PATH RFC net-next 8/8] net: phy: Add build warning if assumptions get broken
From: Andrew Lunn @ 2018-09-14 21:38 UTC (permalink / raw)
  To: netdev; +Cc: Florian Fainelli, Andrew Lunn
In-Reply-To: <1536961136-30453-1-git-send-email-andrew@lunn.ch>

The macro magic to build constant bitmaps of supported PHY features
breaks when we have more than 63 ETHTOOL_LINK_MODE bits. Make the
breakage loud, not a subtle bug, when we get to that condition.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 drivers/net/phy/phy_device.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index eed61ee1d394..7bee59c7834b 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -2297,6 +2297,13 @@ static int __init phy_init(void)
 {
 	int rc;
 
+	/* The phy_basic_features, phy_gbit_features etc, above, only
+	 * work for values up to 63. Ensure we get a loud error if
+	 * this threshold is exceeded, and the necessary changes are
+	 * made.
+	 */
+	BUILD_BUG_ON(__ETHTOOL_LINK_MODE_LAST > 63);
+
 	rc = mdio_bus_init();
 	if (rc)
 		return rc;
-- 
2.19.0.rc1

^ permalink raw reply related

* [PATH RFC net-next 0/8] Continue towards using linkmode in phylib
From: Andrew Lunn @ 2018-09-14 21:38 UTC (permalink / raw)
  To: netdev; +Cc: Florian Fainelli, Andrew Lunn

These patches contain some further cleanup and helpers, and the first
real patch towards using linkmode bitmaps in phylink.

It is RFC because i don't like patch #7 and maybe somebody has a
better idea how to do this. Ideally, we want to initialise a linux
generic bitmap at compile time.

Thanks
	Andrew

Andrew Lunn (8):
  net: phy: Move linkmode helpers to somewhere public
  net: phy: Add phydev_warn()
  net: phy: Add helper to convert MII ADV register to a linkmode
  net: phy: Add helper for advertise to lcl value
  net: phy: Add limkmode equivalents to some of the MII ethtool helpers
  net: ethernet xgbe expand PHY_GBIT_FEAUTRES
  net: phy: Replace phy driver features u32 with link_mode bitmap
  net: phy: Add build warning if assumptions get broken

 drivers/net/dsa/mt7530.c                      |   6 +-
 drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c   |  15 +-
 drivers/net/ethernet/freescale/fman/mac.c     |   6 +-
 drivers/net/ethernet/freescale/gianfar.c      |   7 +-
 .../hisilicon/hns3/hns3pf/hclge_main.c        |   6 +-
 drivers/net/ethernet/marvell/pxa168_eth.c     |   4 +-
 drivers/net/ethernet/mediatek/mtk_eth_soc.c   |   6 +-
 drivers/net/ethernet/socionext/sni_ave.c      |   5 +-
 drivers/net/phy/aquantia.c                    |  12 +-
 drivers/net/phy/bcm63xx.c                     |   9 +-
 drivers/net/phy/marvell.c                     |   2 +-
 drivers/net/phy/marvell10g.c                  |  11 +-
 drivers/net/phy/microchip_t1.c                |   2 +-
 drivers/net/phy/phy_device.c                  | 211 +++++++++++++++++-
 drivers/net/phy/phylink.c                     |  27 ---
 include/linux/linkmode.h                      |  67 ++++++
 include/linux/mii.h                           | 101 +++++++++
 include/linux/phy.h                           |  28 ++-
 18 files changed, 421 insertions(+), 104 deletions(-)
 create mode 100644 include/linux/linkmode.h

-- 
2.19.0.rc1

^ permalink raw reply

* [PATCH net] net: dsa: mv88e6xxx: Fix ATU Miss Violation
From: Andrew Lunn @ 2018-09-14 21:46 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, Florian Fainelli, Andrew Lunn

Fix a cut/paste error and a typo which results in ATU miss violations
not being reported.

Fixes: 0977644c5005 ("net: dsa: mv88e6xxx: Decode ATU problem interrupt")
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 drivers/net/dsa/mv88e6xxx/global1.h     | 2 +-
 drivers/net/dsa/mv88e6xxx/global1_atu.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/dsa/mv88e6xxx/global1.h b/drivers/net/dsa/mv88e6xxx/global1.h
index 7c791c1da4b9..bef01331266f 100644
--- a/drivers/net/dsa/mv88e6xxx/global1.h
+++ b/drivers/net/dsa/mv88e6xxx/global1.h
@@ -128,7 +128,7 @@
 #define MV88E6XXX_G1_ATU_OP_GET_CLR_VIOLATION		0x7000
 #define MV88E6XXX_G1_ATU_OP_AGE_OUT_VIOLATION		BIT(7)
 #define MV88E6XXX_G1_ATU_OP_MEMBER_VIOLATION		BIT(6)
-#define MV88E6XXX_G1_ATU_OP_MISS_VIOLTATION		BIT(5)
+#define MV88E6XXX_G1_ATU_OP_MISS_VIOLATION		BIT(5)
 #define MV88E6XXX_G1_ATU_OP_FULL_VIOLATION		BIT(4)
 
 /* Offset 0x0C: ATU Data Register */
diff --git a/drivers/net/dsa/mv88e6xxx/global1_atu.c b/drivers/net/dsa/mv88e6xxx/global1_atu.c
index 307410898fc9..5200e4bdce93 100644
--- a/drivers/net/dsa/mv88e6xxx/global1_atu.c
+++ b/drivers/net/dsa/mv88e6xxx/global1_atu.c
@@ -349,7 +349,7 @@ static irqreturn_t mv88e6xxx_g1_atu_prob_irq_thread_fn(int irq, void *dev_id)
 		chip->ports[entry.portvec].atu_member_violation++;
 	}
 
-	if (val & MV88E6XXX_G1_ATU_OP_MEMBER_VIOLATION) {
+	if (val & MV88E6XXX_G1_ATU_OP_MISS_VIOLATION) {
 		dev_err_ratelimited(chip->dev,
 				    "ATU miss violation for %pM portvec %x\n",
 				    entry.mac, entry.portvec);
-- 
2.19.0.rc1

^ permalink raw reply related

* Re: [bpf-next, v4 0/5] Introduce eBPF flow dissector
From: Y Song @ 2018-09-14 21:47 UTC (permalink / raw)
  To: Alexei Starovoitov
  Cc: peterpenkov96, netdev, David Miller, Alexei Starovoitov,
	Daniel Borkmann, simon.horman, Edward Cree, songliubraving, tom,
	ppenkov
In-Reply-To: <20180914192225.oj22b7klqzyombcf@ast-mbp>

On Fri, Sep 14, 2018 at 12:24 PM Alexei Starovoitov
<alexei.starovoitov@gmail.com> wrote:
>
> On Fri, Sep 14, 2018 at 07:46:17AM -0700, Petar Penkov wrote:
> > From: Petar Penkov <ppenkov@google.com>
> >
> > This patch series hardens the RX stack by allowing flow dissection in BPF,
> > as previously discussed [1]. Because of the rigorous checks of the BPF
> > verifier, this provides significant security guarantees. In particular, the
> > BPF flow dissector cannot get inside of an infinite loop, as with
> > CVE-2013-4348, because BPF programs are guaranteed to terminate. It cannot
> > read outside of packet bounds, because all memory accesses are checked.
> > Also, with BPF the administrator can decide which protocols to support,
> > reducing potential attack surface. Rarely encountered protocols can be
> > excluded from dissection and the program can be updated without kernel
> > recompile or reboot if a bug is discovered.
> >
> > Patch 1 adds infrastructure to execute a BPF program in __skb_flow_dissect.
> > This includes a new BPF program and attach type.
> >
> > Patch 2 adds the new BPF flow dissector definitions to tools/uapi.
> >
> > Patch 3 adds support for the new BPF program type to libbpf and bpftool.
> >
> > Patch 4 adds a flow dissector program in BPF. This parses most protocols in
> > __skb_flow_dissect in BPF for a subset of flow keys (basic, control, ports,
> > and address types).
> >
> > Patch 5 adds a selftest that attaches the BPF program to the flow dissector
> > and sends traffic with different levels of encapsulation.
> >
> > Performance Evaluation:
> > The in-kernel implementation was compared against the demo program from
> > patch 4 using the test in patch 5 with IPv4/UDP traffic over 10 seconds.
> >       $perf record -a -C 4 taskset -c 4 ./test_flow_dissector -i 4 -f 8 \
> >               -t 10
>
> Looks great. Applied to bpf-next with one extra patch:
>  SEC("dissect")
> -int dissect(struct __sk_buff *skb)
> +int _dissect(struct __sk_buff *skb)
>
> otherwise the test doesn't build.
> I'm not sure how it builds for you. Which llvm did you use?

This is a known issue. IIRC, llvm <= 4 should be okay and llvm >= 5 would fail.

>
> Also above command works and ipv4 test in ./test_flow_dissector.sh
> is passing as well, but it still fails at the end for me:
> ./test_flow_dissector.sh
> bpffs not mounted. Mounting...
> 0: IP
> 1: IPV6
> 2: IPV6OP
> 3: IPV6FR
> 4: MPLS
> 5: VLAN
> Testing IPv4...
> inner.dest4: 127.0.0.1
> inner.source4: 127.0.0.3
> pkts: tx=10 rx=10
> inner.dest4: 127.0.0.1
> inner.source4: 127.0.0.3
> pkts: tx=10 rx=0
> inner.dest4: 127.0.0.1
> inner.source4: 127.0.0.3
> pkts: tx=10 rx=10
> Testing IPIP...
> tunnels before test:
> tunl0: any/ip remote any local any ttl inherit nopmtudisc
> sit_test_LV5N: any/ip remote 127.0.0.2 local 127.0.0.1 dev lo ttl inherit
> ipip_test_LV5N: any/ip remote 127.0.0.2 local 127.0.0.1 dev lo ttl inherit
> sit0: ipv6/ip remote any local any ttl 64 nopmtudisc
> gre_test_LV5N: gre/ip remote 127.0.0.2 local 127.0.0.1 dev lo ttl inherit
> gre0: gre/ip remote any local any ttl inherit nopmtudisc
> inner.dest4: 192.168.0.1
> inner.source4: 1.1.1.1
> encap proto:   4
> outer.dest4: 127.0.0.1
> outer.source4: 127.0.0.2
> pkts: tx=10 rx=0
> tunnels after test:
> tunl0: any/ip remote any local any ttl inherit nopmtudisc
> sit0: ipv6/ip remote any local any ttl 64 nopmtudisc
> gre0: gre/ip remote any local any ttl inherit nopmtudisc
> selftests: test_flow_dissector [FAILED]
>
> is it something in my setup or test is broken?
>

^ permalink raw reply

* Re: [bpf-next, v4 0/5] Introduce eBPF flow dissector
From: Petar Penkov @ 2018-09-14 21:49 UTC (permalink / raw)
  To: Y Song
  Cc: Alexei Starovoitov, Petar Penkov, netdev, David Miller,
	Alexei Starovoitov, Daniel Borkmann, simon.horman, Edward Cree,
	songliubraving, Tom Herbert
In-Reply-To: <CAH3MdRVxywbxT0WNg9NZMCRw6-cAzpQcFF-U2gdRAQAoHBOsww@mail.gmail.com>

On Fri, Sep 14, 2018 at 2:47 PM, Y Song <ys114321@gmail.com> wrote:
> On Fri, Sep 14, 2018 at 12:24 PM Alexei Starovoitov
> <alexei.starovoitov@gmail.com> wrote:
>>
>> On Fri, Sep 14, 2018 at 07:46:17AM -0700, Petar Penkov wrote:
>> > From: Petar Penkov <ppenkov@google.com>
>> >
>> > This patch series hardens the RX stack by allowing flow dissection in BPF,
>> > as previously discussed [1]. Because of the rigorous checks of the BPF
>> > verifier, this provides significant security guarantees. In particular, the
>> > BPF flow dissector cannot get inside of an infinite loop, as with
>> > CVE-2013-4348, because BPF programs are guaranteed to terminate. It cannot
>> > read outside of packet bounds, because all memory accesses are checked.
>> > Also, with BPF the administrator can decide which protocols to support,
>> > reducing potential attack surface. Rarely encountered protocols can be
>> > excluded from dissection and the program can be updated without kernel
>> > recompile or reboot if a bug is discovered.
>> >
>> > Patch 1 adds infrastructure to execute a BPF program in __skb_flow_dissect.
>> > This includes a new BPF program and attach type.
>> >
>> > Patch 2 adds the new BPF flow dissector definitions to tools/uapi.
>> >
>> > Patch 3 adds support for the new BPF program type to libbpf and bpftool.
>> >
>> > Patch 4 adds a flow dissector program in BPF. This parses most protocols in
>> > __skb_flow_dissect in BPF for a subset of flow keys (basic, control, ports,
>> > and address types).
>> >
>> > Patch 5 adds a selftest that attaches the BPF program to the flow dissector
>> > and sends traffic with different levels of encapsulation.
>> >
>> > Performance Evaluation:
>> > The in-kernel implementation was compared against the demo program from
>> > patch 4 using the test in patch 5 with IPv4/UDP traffic over 10 seconds.
>> >       $perf record -a -C 4 taskset -c 4 ./test_flow_dissector -i 4 -f 8 \
>> >               -t 10
>>
>> Looks great. Applied to bpf-next with one extra patch:
>>  SEC("dissect")
>> -int dissect(struct __sk_buff *skb)
>> +int _dissect(struct __sk_buff *skb)
>>
>> otherwise the test doesn't build.
>> I'm not sure how it builds for you. Which llvm did you use?
>
> This is a known issue. IIRC, llvm <= 4 should be okay and llvm >= 5 would fail.
>
I was running a much older version of llvm so I imagine this was the
issue. Thanks for the fix!
>>
>> Also above command works and ipv4 test in ./test_flow_dissector.sh
>> is passing as well, but it still fails at the end for me:
>> ./test_flow_dissector.sh
>> bpffs not mounted. Mounting...
>> 0: IP
>> 1: IPV6
>> 2: IPV6OP
>> 3: IPV6FR
>> 4: MPLS
>> 5: VLAN
>> Testing IPv4...
>> inner.dest4: 127.0.0.1
>> inner.source4: 127.0.0.3
>> pkts: tx=10 rx=10
>> inner.dest4: 127.0.0.1
>> inner.source4: 127.0.0.3
>> pkts: tx=10 rx=0
>> inner.dest4: 127.0.0.1
>> inner.source4: 127.0.0.3
>> pkts: tx=10 rx=10
>> Testing IPIP...
>> tunnels before test:
>> tunl0: any/ip remote any local any ttl inherit nopmtudisc
>> sit_test_LV5N: any/ip remote 127.0.0.2 local 127.0.0.1 dev lo ttl inherit
>> ipip_test_LV5N: any/ip remote 127.0.0.2 local 127.0.0.1 dev lo ttl inherit
>> sit0: ipv6/ip remote any local any ttl 64 nopmtudisc
>> gre_test_LV5N: gre/ip remote 127.0.0.2 local 127.0.0.1 dev lo ttl inherit
>> gre0: gre/ip remote any local any ttl inherit nopmtudisc
>> inner.dest4: 192.168.0.1
>> inner.source4: 1.1.1.1
>> encap proto:   4
>> outer.dest4: 127.0.0.1
>> outer.source4: 127.0.0.2
>> pkts: tx=10 rx=0
>> tunnels after test:
>> tunl0: any/ip remote any local any ttl inherit nopmtudisc
>> sit0: ipv6/ip remote any local any ttl 64 nopmtudisc
>> gre0: gre/ip remote any local any ttl inherit nopmtudisc
>> selftests: test_flow_dissector [FAILED]
>>
>> is it something in my setup or test is broken?
>>
I just reran the test and it is passing. We will investigate what
could be causing the issue.

^ permalink raw reply

* [PATCH bpf-next] tools/bpf: bpftool: improve output format for bpftool net
From: Yonghong Song @ 2018-09-14 21:49 UTC (permalink / raw)
  To: ast, daniel, netdev; +Cc: kernel-team

This is a followup patch for Commit f6f3bac08ff9
("tools/bpf: bpftool: add net support").
Some improvements are made for the bpftool net output.
Specially, plain output is more concise such that
per attachment should nicely fit in one line.
Compared to previous output, the prog tag is removed
since it can be easily obtained with program id.
Similar to xdp attachments, the device name is added
to tc_filters attachments.

The bpf program attached through shared block
mechanism is supported as well.
  $ ip link add dev v1 type veth peer name v2
  $ tc qdisc add dev v1 ingress_block 10 egress_block 20 clsact
  $ tc qdisc add dev v2 ingress_block 10 egress_block 20 clsact
  $ tc filter add block 10 protocol ip prio 25 bpf obj bpf_shared.o sec ingress flowid 1:1
  $ tc filter add block 20 protocol ip prio 30 bpf obj bpf_cyclic.o sec classifier flowid 1:1
  $ bpftool net
  xdp [
  ]
  tc_filters [
   v2(7) qdisc_clsact_ingress bpf_shared.o:[ingress] id 23
   v2(7) qdisc_clsact_egress bpf_cyclic.o:[classifier] id 24
   v1(8) qdisc_clsact_ingress bpf_shared.o:[ingress] id 23
   v1(8) qdisc_clsact_egress bpf_cyclic.o:[classifier] id 24
  ]

The documentation and "bpftool net help" are updated
to make it clear that current implementation only
supports xdp and tc attachments. For programs
attached to cgroups, "bpftool cgroup" can be used
to dump attachments. For other programs e.g.
sk_{filter,skb,msg,reuseport} and lwt/seg6,
iproute2 tools should be used.

The new output:
  $ bpftool net
  xdp [
   eth0(2) id/drv 198
  ]
  tc_filters [
   eth0(2) qdisc_clsact_ingress fbflow_icmp id 335 act [{icmp_action id 336}]
   eth0(2) qdisc_clsact_egress fbflow_egress id 334
  ]
  $ bpftool -jp net
  [{
        "xdp": [{
                "devname": "eth0",
                "ifindex": 2,
                "id/drv": 198
            }
        ],
        "tc_filters": [{
                "devname": "eth0",
                "ifindex": 2,
                "kind": "qdisc_clsact_ingress",
                "name": "fbflow_icmp",
                "id": 335,
                "act": [{
                        "name": "icmp_action",
                        "id": 336
                    }
                ]
            },{
                "devname": "eth0",
                "ifindex": 2,
                "kind": "qdisc_clsact_egress",
                "name": "fbflow_egress",
                "id": 334
            }
        ]
    }
  ]

Signed-off-by: Yonghong Song <yhs@fb.com>
---
 .../bpf/bpftool/Documentation/bpftool-net.rst |  58 +++++-----
 tools/bpf/bpftool/main.h                      |   3 +-
 tools/bpf/bpftool/net.c                       | 100 ++++++++++++------
 tools/bpf/bpftool/netlink_dumper.c            |  78 ++++++--------
 tools/bpf/bpftool/netlink_dumper.h            |  20 ++--
 5 files changed, 143 insertions(+), 116 deletions(-)

diff --git a/tools/bpf/bpftool/Documentation/bpftool-net.rst b/tools/bpf/bpftool/Documentation/bpftool-net.rst
index 48a61837a264..433581592c72 100644
--- a/tools/bpf/bpftool/Documentation/bpftool-net.rst
+++ b/tools/bpf/bpftool/Documentation/bpftool-net.rst
@@ -26,9 +26,20 @@ NET COMMANDS
 DESCRIPTION
 ===========
 	**bpftool net { show | list } [ dev name ]**
-		  List all networking device driver and tc attachment in the system.
-
-                  Output will start with all xdp program attachment, followed by
+                  List bpf program attachments in the kernel networking subsystem.
+
+                  Currently, only device driver xdp attachments and tc filter
+                  classification/action attachments are implemented, i.e., for
+                  program types **BPF_PROG_TYPE_SCHED_CLS**,
+                  **BPF_PROG_TYPE_SCHED_ACT** and **BPF_PROG_TYPE_XDP**.
+                  For programs attached to a particular cgroup, e.g.,
+                  **BPF_PROG_TYPE_CGROUP_SKB**, **BPF_PROG_TYPE_CGROUP_SOCK**,
+                  **BPF_PROG_TYPE_SOCK_OPS** and **BPF_PROG_TYPE_CGROUP_SOCK_ADDR**,
+                  users can use **bpftool cgroup** to dump cgroup attachments.
+                  For sk_{filter, skb, msg, reuseport} and lwt/seg6
+                  bpf programs, users should consult other tools, e.g., iproute2.
+
+                  The current output will start with all xdp program attachments, followed by
                   all tc class/qdisc bpf program attachments. Both xdp programs and
                   tc programs are ordered based on ifindex number. If multiple bpf
                   programs attached to the same networking device through **tc filter**,
@@ -62,19 +73,14 @@ EXAMPLES
 ::
 
       xdp [
-      ifindex 2 devname eth0 prog_id 198
+       eth0(2) id/drv 198
       ]
       tc_filters [
-      ifindex 2 kind qdisc_htb name prefix_matcher.o:[cls_prefix_matcher_htb]
-                prog_id 111727 tag d08fe3b4319bc2fd act []
-      ifindex 2 kind qdisc_clsact_ingress name fbflow_icmp
-                prog_id 130246 tag 3f265c7f26db62c9 act []
-      ifindex 2 kind qdisc_clsact_egress name prefix_matcher.o:[cls_prefix_matcher_clsact]
-                prog_id 111726 tag 99a197826974c876
-      ifindex 2 kind qdisc_clsact_egress name cls_fg_dscp
-                prog_id 108619 tag dc4630674fd72dcc act []
-      ifindex 2 kind qdisc_clsact_egress name fbflow_egress
-                prog_id 130245 tag 72d2d830d6888d2c
+       eth0(2) qdisc_htb name prefix_matcher.o:[cls_prefix_matcher_htb] id 111727 act []
+       eth0(2) qdisc_clsact_ingress fbflow_icmp id 130246 act []
+       eth0(2) qdisc_clsact_egress prefix_matcher.o:[cls_prefix_matcher_clsact] id 111726
+       eth0(2) qdisc_clsact_egress cls_fg_dscp id 108619 act []
+       eth0(2) qdisc_clsact_egress fbflow_egress id 130245
       ]
 
 |
@@ -84,44 +90,44 @@ EXAMPLES
 
     [{
             "xdp": [{
-                    "ifindex": 2,
                     "devname": "eth0",
-                    "prog_id": 198
+                    "ifindex": 2,
+                    "id/drv": 198
                 }
             ],
             "tc_filters": [{
+                    "devname": "eth0",
                     "ifindex": 2,
                     "kind": "qdisc_htb",
                     "name": "prefix_matcher.o:[cls_prefix_matcher_htb]",
-                    "prog_id": 111727,
-                    "tag": "d08fe3b4319bc2fd",
+                    "id": 111727,
                     "act": []
                 },{
+                    "devname": "eth0",
                     "ifindex": 2,
                     "kind": "qdisc_clsact_ingress",
                     "name": "fbflow_icmp",
-                    "prog_id": 130246,
-                    "tag": "3f265c7f26db62c9",
+                    "id": 130246,
                     "act": []
                 },{
+                    "devname": "eth0",
                     "ifindex": 2,
                     "kind": "qdisc_clsact_egress",
                     "name": "prefix_matcher.o:[cls_prefix_matcher_clsact]",
-                    "prog_id": 111726,
-                    "tag": "99a197826974c876"
+                    "id": 111726,
                 },{
+                    "devname": "eth0",
                     "ifindex": 2,
                     "kind": "qdisc_clsact_egress",
                     "name": "cls_fg_dscp",
-                    "prog_id": 108619,
-                    "tag": "dc4630674fd72dcc",
+                    "id": 108619,
                     "act": []
                 },{
+                    "devname": "eth0",
                     "ifindex": 2,
                     "kind": "qdisc_clsact_egress",
                     "name": "fbflow_egress",
-                    "prog_id": 130245,
-                    "tag": "72d2d830d6888d2c"
+                    "id": 130245,
                 }
             ]
         }
diff --git a/tools/bpf/bpftool/main.h b/tools/bpf/bpftool/main.h
index 02dfbcb92a23..40492cdc4e53 100644
--- a/tools/bpf/bpftool/main.h
+++ b/tools/bpf/bpftool/main.h
@@ -171,5 +171,6 @@ struct nlattr;
 struct ifinfomsg;
 struct tcmsg;
 int do_xdp_dump(struct ifinfomsg *ifinfo, struct nlattr **tb);
-int do_filter_dump(struct tcmsg *ifinfo, struct nlattr **tb, const char *kind);
+int do_filter_dump(struct tcmsg *ifinfo, struct nlattr **tb, const char *kind,
+		   const char *devname, int ifindex);
 #endif
diff --git a/tools/bpf/bpftool/net.c b/tools/bpf/bpftool/net.c
index 77dd73dd9ade..a796c09dae05 100644
--- a/tools/bpf/bpftool/net.c
+++ b/tools/bpf/bpftool/net.c
@@ -2,6 +2,7 @@
 // Copyright (C) 2018 Facebook
 
 #define _GNU_SOURCE
+#include <errno.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
@@ -17,8 +18,13 @@
 #include "main.h"
 #include "netlink_dumper.h"
 
+struct ip_devname_ifindex {
+	char	devname[64];
+	int	ifindex;
+};
+
 struct bpf_netdev_t {
-	int	*ifindex_array;
+	struct ip_devname_ifindex *devices;
 	int	used_len;
 	int	array_len;
 	int	filter_idx;
@@ -36,6 +42,12 @@ struct bpf_tcinfo_t {
 	bool			is_qdisc;
 };
 
+struct bpf_filter_t {
+	const char	*kind;
+	const char	*devname;
+	int		ifindex;
+};
+
 static int dump_link_nlmsg(void *cookie, void *msg, struct nlattr **tb)
 {
 	struct bpf_netdev_t *netinfo = cookie;
@@ -45,11 +57,20 @@ static int dump_link_nlmsg(void *cookie, void *msg, struct nlattr **tb)
 		return 0;
 
 	if (netinfo->used_len == netinfo->array_len) {
-		netinfo->ifindex_array = realloc(netinfo->ifindex_array,
-			(netinfo->array_len + 16) * sizeof(int));
+		netinfo->devices = realloc(netinfo->devices,
+			(netinfo->array_len + 16) *
+			sizeof(struct ip_devname_ifindex));
+		if (!netinfo->devices)
+			return -ENOMEM;
+
 		netinfo->array_len += 16;
 	}
-	netinfo->ifindex_array[netinfo->used_len++] = ifinfo->ifi_index;
+	netinfo->devices[netinfo->used_len].ifindex = ifinfo->ifi_index;
+	snprintf(netinfo->devices[netinfo->used_len].devname,
+		 sizeof(netinfo->devices[netinfo->used_len].devname),
+		 "%s",
+		 tb[IFLA_IFNAME] ? nla_getattr_str(tb[IFLA_IFNAME]) : "");
+	netinfo->used_len++;
 
 	return do_xdp_dump(ifinfo, tb);
 }
@@ -71,6 +92,9 @@ static int dump_class_qdisc_nlmsg(void *cookie, void *msg, struct nlattr **tb)
 	if (tcinfo->used_len == tcinfo->array_len) {
 		tcinfo->handle_array = realloc(tcinfo->handle_array,
 			(tcinfo->array_len + 16) * sizeof(struct tc_kind_handle));
+		if (!tcinfo->handle_array)
+			return -ENOMEM;
+
 		tcinfo->array_len += 16;
 	}
 	tcinfo->handle_array[tcinfo->used_len].handle = info->tcm_handle;
@@ -86,60 +110,71 @@ static int dump_class_qdisc_nlmsg(void *cookie, void *msg, struct nlattr **tb)
 
 static int dump_filter_nlmsg(void *cookie, void *msg, struct nlattr **tb)
 {
-	const char *kind = cookie;
+	const struct bpf_filter_t *filter_info = cookie;
 
-	return do_filter_dump((struct tcmsg *)msg, tb, kind);
+	return do_filter_dump((struct tcmsg *)msg, tb, filter_info->kind,
+			      filter_info->devname, filter_info->ifindex);
 }
 
-static int show_dev_tc_bpf(int sock, unsigned int nl_pid, int ifindex)
+static int show_dev_tc_bpf(int sock, unsigned int nl_pid,
+			   struct ip_devname_ifindex *dev)
 {
+	struct bpf_filter_t filter_info;
 	struct bpf_tcinfo_t tcinfo;
-	int i, handle, ret;
+	int i, handle, ret = 0;
 
 	tcinfo.handle_array = NULL;
 	tcinfo.used_len = 0;
 	tcinfo.array_len = 0;
 
 	tcinfo.is_qdisc = false;
-	ret = nl_get_class(sock, nl_pid, ifindex, dump_class_qdisc_nlmsg,
+	ret = nl_get_class(sock, nl_pid, dev->ifindex, dump_class_qdisc_nlmsg,
 			   &tcinfo);
 	if (ret)
-		return ret;
+		goto out;
 
 	tcinfo.is_qdisc = true;
-	ret = nl_get_qdisc(sock, nl_pid, ifindex, dump_class_qdisc_nlmsg,
+	ret = nl_get_qdisc(sock, nl_pid, dev->ifindex, dump_class_qdisc_nlmsg,
 			   &tcinfo);
 	if (ret)
-		return ret;
+		goto out;
 
+	filter_info.devname = dev->devname;
+	filter_info.ifindex = dev->ifindex;
 	for (i = 0; i < tcinfo.used_len; i++) {
-		ret = nl_get_filter(sock, nl_pid, ifindex,
+		filter_info.kind = tcinfo.handle_array[i].kind;
+		ret = nl_get_filter(sock, nl_pid, dev->ifindex,
 				    tcinfo.handle_array[i].handle,
 				    dump_filter_nlmsg,
-				    tcinfo.handle_array[i].kind);
+				    &filter_info);
 		if (ret)
-			return ret;
+			goto out;
 	}
 
 	/* root, ingress and egress handle */
 	handle = TC_H_ROOT;
-	ret = nl_get_filter(sock, nl_pid, ifindex, handle, dump_filter_nlmsg,
-			    "root");
+	filter_info.kind = "root";
+	ret = nl_get_filter(sock, nl_pid, dev->ifindex, handle,
+			    dump_filter_nlmsg, &filter_info);
 	if (ret)
-		return ret;
+		goto out;
 
 	handle = TC_H_MAKE(TC_H_CLSACT, TC_H_MIN_INGRESS);
-	ret = nl_get_filter(sock, nl_pid, ifindex, handle, dump_filter_nlmsg,
-			    "qdisc_clsact_ingress");
+	filter_info.kind = "qdisc_clsact_ingress";
+	ret = nl_get_filter(sock, nl_pid, dev->ifindex, handle,
+			    dump_filter_nlmsg, &filter_info);
 	if (ret)
-		return ret;
+		goto out;
 
 	handle = TC_H_MAKE(TC_H_CLSACT, TC_H_MIN_EGRESS);
-	ret = nl_get_filter(sock, nl_pid, ifindex, handle, dump_filter_nlmsg,
-			    "qdisc_clsact_egress");
+	filter_info.kind = "qdisc_clsact_egress";
+	ret = nl_get_filter(sock, nl_pid, dev->ifindex, handle,
+			    dump_filter_nlmsg, &filter_info);
 	if (ret)
-		return ret;
+		goto out;
 
+out:
+	free(tcinfo.handle_array);
 	return 0;
 }
 
@@ -168,7 +203,7 @@ static int do_show(int argc, char **argv)
 		return -1;
 	}
 
-	dev_array.ifindex_array = NULL;
+	dev_array.devices = NULL;
 	dev_array.used_len = 0;
 	dev_array.array_len = 0;
 	dev_array.filter_idx = filter_idx;
@@ -176,15 +211,15 @@ static int do_show(int argc, char **argv)
 	if (json_output)
 		jsonw_start_array(json_wtr);
 	NET_START_OBJECT;
-	NET_START_ARRAY("xdp", "\n");
+	NET_START_ARRAY("xdp", "%s [\n");
 	ret = nl_get_link(sock, nl_pid, dump_link_nlmsg, &dev_array);
 	NET_END_ARRAY("\n");
 
 	if (!ret) {
-		NET_START_ARRAY("tc_filters", "\n");
+		NET_START_ARRAY("tc_filters", "%s [\n");
 		for (i = 0; i < dev_array.used_len; i++) {
 			ret = show_dev_tc_bpf(sock, nl_pid,
-					      dev_array.ifindex_array[i]);
+					      &dev_array.devices[i]);
 			if (ret)
 				break;
 		}
@@ -200,7 +235,7 @@ static int do_show(int argc, char **argv)
 		libbpf_strerror(ret, err_buf, sizeof(err_buf));
 		fprintf(stderr, "Error: %s\n", err_buf);
 	}
-	free(dev_array.ifindex_array);
+	free(dev_array.devices);
 	close(sock);
 	return ret;
 }
@@ -214,7 +249,12 @@ static int do_help(int argc, char **argv)
 
 	fprintf(stderr,
 		"Usage: %s %s { show | list } [dev <devname>]\n"
-		"       %s %s help\n",
+		"       %s %s help\n"
+		"Note: Only xdp and tc attachments are supported now.\n"
+		"      For progs attached to cgroups, use \"bpftool cgroup\"\n"
+		"      to dump program attachments. For program types\n"
+		"      sk_{filter,skb,msg,reuseport} and lwt/seg6, please\n"
+		"      consult iproute2.\n",
 		bin_name, argv[-2], bin_name, argv[-2]);
 
 	return 0;
diff --git a/tools/bpf/bpftool/netlink_dumper.c b/tools/bpf/bpftool/netlink_dumper.c
index e12494fd1d2e..30b67dde8f71 100644
--- a/tools/bpf/bpftool/netlink_dumper.c
+++ b/tools/bpf/bpftool/netlink_dumper.c
@@ -12,12 +12,13 @@
 #include "netlink_dumper.h"
 
 static void xdp_dump_prog_id(struct nlattr **tb, int attr,
-			     const char *type)
+			     const char *type,
+			     const char *fmt_str)
 {
 	if (!tb[attr])
 		return;
 
-	NET_DUMP_UINT(type, nla_getattr_u32(tb[attr]))
+	NET_DUMP_UINT(type, fmt_str, nla_getattr_u32(tb[attr]))
 }
 
 static int do_xdp_dump_one(struct nlattr *attr, unsigned int ifindex,
@@ -37,18 +38,26 @@ static int do_xdp_dump_one(struct nlattr *attr, unsigned int ifindex,
 		return 0;
 
 	NET_START_OBJECT;
-	NET_DUMP_UINT("ifindex", ifindex);
-
 	if (name)
-		NET_DUMP_STR("devname", name);
-
-	if (tb[IFLA_XDP_PROG_ID])
-		NET_DUMP_UINT("prog_id", nla_getattr_u32(tb[IFLA_XDP_PROG_ID]));
+		NET_DUMP_STR("devname", " %s", name);
+	NET_DUMP_UINT("ifindex", "(%d)", ifindex);
 
 	if (mode == XDP_ATTACHED_MULTI) {
-		xdp_dump_prog_id(tb, IFLA_XDP_SKB_PROG_ID, "generic_prog_id");
-		xdp_dump_prog_id(tb, IFLA_XDP_DRV_PROG_ID, "drv_prog_id");
-		xdp_dump_prog_id(tb, IFLA_XDP_HW_PROG_ID, "offload_prog_id");
+		xdp_dump_prog_id(tb, IFLA_XDP_SKB_PROG_ID, "id/generic",
+				 " id/generic %u");
+		xdp_dump_prog_id(tb, IFLA_XDP_DRV_PROG_ID, "id/drv",
+				 " id/drv %u");
+		xdp_dump_prog_id(tb, IFLA_XDP_HW_PROG_ID, "id/offload",
+				 " id/offload %u");
+	} else if (mode == XDP_ATTACHED_DRV) {
+		xdp_dump_prog_id(tb, IFLA_XDP_PROG_ID, "id/drv",
+				 " id/drv %u");
+	} else if (mode == XDP_ATTACHED_SKB) {
+		xdp_dump_prog_id(tb, IFLA_XDP_PROG_ID, "id/generic",
+				 " id/generic %u");
+	} else if (mode == XDP_ATTACHED_HW) {
+		xdp_dump_prog_id(tb, IFLA_XDP_PROG_ID, "id/offload",
+				 " id/offload %u");
 	}
 
 	NET_END_OBJECT_FINAL;
@@ -64,26 +73,9 @@ int do_xdp_dump(struct ifinfomsg *ifinfo, struct nlattr **tb)
 			       nla_getattr_str(tb[IFLA_IFNAME]));
 }
 
-static char *hexstring_n2a(const unsigned char *str, int len,
-			   char *buf, int blen)
-{
-	char *ptr = buf;
-	int i;
-
-	for (i = 0; i < len; i++) {
-		if (blen < 3)
-			break;
-		sprintf(ptr, "%02x", str[i]);
-		ptr += 2;
-		blen -= 2;
-	}
-	return buf;
-}
-
 static int do_bpf_dump_one_act(struct nlattr *attr)
 {
 	struct nlattr *tb[TCA_ACT_BPF_MAX + 1];
-	char buf[256];
 
 	if (nla_parse_nested(tb, TCA_ACT_BPF_MAX, attr, NULL) < 0)
 		return -LIBBPF_ERRNO__NLPARSE;
@@ -93,13 +85,11 @@ static int do_bpf_dump_one_act(struct nlattr *attr)
 
 	NET_START_OBJECT_NESTED2;
 	if (tb[TCA_ACT_BPF_NAME])
-		NET_DUMP_STR("name", nla_getattr_str(tb[TCA_ACT_BPF_NAME]));
+		NET_DUMP_STR("name", "%s",
+			     nla_getattr_str(tb[TCA_ACT_BPF_NAME]));
 	if (tb[TCA_ACT_BPF_ID])
-		NET_DUMP_UINT("bpf_id", nla_getattr_u32(tb[TCA_ACT_BPF_ID]));
-	if (tb[TCA_ACT_BPF_TAG])
-		NET_DUMP_STR("tag", hexstring_n2a(nla_data(tb[TCA_ACT_BPF_TAG]),
-						  nla_len(tb[TCA_ACT_BPF_TAG]),
-						  buf, sizeof(buf)));
+		NET_DUMP_UINT("id", " id %u",
+			      nla_getattr_u32(tb[TCA_ACT_BPF_ID]));
 	NET_END_OBJECT_NESTED;
 	return 0;
 }
@@ -128,7 +118,7 @@ static int do_bpf_act_dump(struct nlattr *attr)
 	if (nla_parse_nested(tb, TCA_ACT_MAX_PRIO, attr, NULL) < 0)
 		return -LIBBPF_ERRNO__NLPARSE;
 
-	NET_START_ARRAY("act", "");
+	NET_START_ARRAY("act", " %s [");
 	for (act = 0; act <= TCA_ACT_MAX_PRIO; act++) {
 		ret = do_dump_one_act(tb[act]);
 		if (ret)
@@ -142,20 +132,15 @@ static int do_bpf_act_dump(struct nlattr *attr)
 static int do_bpf_filter_dump(struct nlattr *attr)
 {
 	struct nlattr *tb[TCA_BPF_MAX + 1];
-	char buf[256];
 	int ret;
 
 	if (nla_parse_nested(tb, TCA_BPF_MAX, attr, NULL) < 0)
 		return -LIBBPF_ERRNO__NLPARSE;
 
 	if (tb[TCA_BPF_NAME])
-		NET_DUMP_STR("name", nla_getattr_str(tb[TCA_BPF_NAME]));
+		NET_DUMP_STR("name", " %s", nla_getattr_str(tb[TCA_BPF_NAME]));
 	if (tb[TCA_BPF_ID])
-		NET_DUMP_UINT("prog_id", nla_getattr_u32(tb[TCA_BPF_ID]));
-	if (tb[TCA_BPF_TAG])
-		NET_DUMP_STR("tag", hexstring_n2a(nla_data(tb[TCA_BPF_TAG]),
-						  nla_len(tb[TCA_BPF_TAG]),
-						  buf, sizeof(buf)));
+		NET_DUMP_UINT("id", " id %u", nla_getattr_u32(tb[TCA_BPF_ID]));
 	if (tb[TCA_BPF_ACT]) {
 		ret = do_bpf_act_dump(tb[TCA_BPF_ACT]);
 		if (ret)
@@ -165,14 +150,17 @@ static int do_bpf_filter_dump(struct nlattr *attr)
 	return 0;
 }
 
-int do_filter_dump(struct tcmsg *info, struct nlattr **tb, const char *kind)
+int do_filter_dump(struct tcmsg *info, struct nlattr **tb, const char *kind,
+		   const char *devname, int ifindex)
 {
 	int ret = 0;
 
 	if (tb[TCA_OPTIONS] && strcmp(nla_data(tb[TCA_KIND]), "bpf") == 0) {
 		NET_START_OBJECT;
-		NET_DUMP_UINT("ifindex", info->tcm_ifindex);
-		NET_DUMP_STR("kind", kind);
+		if (devname[0] != '\0')
+			NET_DUMP_STR("devname", " %s", devname);
+		NET_DUMP_UINT("ifindex", "(%u)", ifindex);
+		NET_DUMP_STR("kind", " %s", kind);
 		ret = do_bpf_filter_dump(tb[TCA_OPTIONS]);
 		NET_END_OBJECT_FINAL;
 	}
diff --git a/tools/bpf/bpftool/netlink_dumper.h b/tools/bpf/bpftool/netlink_dumper.h
index 552d8851ac06..6526c46d765b 100644
--- a/tools/bpf/bpftool/netlink_dumper.h
+++ b/tools/bpf/bpftool/netlink_dumper.h
@@ -50,13 +50,13 @@
 		fprintf(stderr, "\n");			\
 }
 
-#define NET_START_ARRAY(name, newline)			\
+#define NET_START_ARRAY(name, fmt_str)			\
 {							\
 	if (json_output) {				\
 		jsonw_name(json_wtr, name);		\
 		jsonw_start_array(json_wtr);		\
 	} else {					\
-		fprintf(stderr, "%s [%s", name, newline);\
+		fprintf(stderr, fmt_str, name);		\
 	}						\
 }
 
@@ -68,28 +68,20 @@
 		fprintf(stderr, "]%s", endstr);		\
 }
 
-#define NET_DUMP_UINT(name, val)			\
+#define NET_DUMP_UINT(name, fmt_str, val)		\
 {							\
 	if (json_output)				\
 		jsonw_uint_field(json_wtr, name, val);	\
 	else						\
-		fprintf(stderr, "%s %d ", name, val);	\
+		fprintf(stderr, fmt_str, val);		\
 }
 
-#define NET_DUMP_LLUINT(name, val)			\
-{							\
-	if (json_output)				\
-		jsonw_lluint_field(json_wtr, name, val);\
-	else						\
-		fprintf(stderr, "%s %lld ", name, val);	\
-}
-
-#define NET_DUMP_STR(name, str)				\
+#define NET_DUMP_STR(name, fmt_str, str)		\
 {							\
 	if (json_output)				\
 		jsonw_string_field(json_wtr, name, str);\
 	else						\
-		fprintf(stderr, "%s %s ", name, str);	\
+		fprintf(stderr, fmt_str, str);		\
 }
 
 #define NET_DUMP_STR_ONLY(str)				\
-- 
2.17.1

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox