* [PATCH net-next v2 00/14] rename and shrink i40evf
From: Jesse Brandeburg @ 2018-09-15 0:37 UTC (permalink / raw)
To: netdev, intel-wired-lan; +Cc: jeffrey.t.kirsher
This series contains changes to i40evf so that it becomes a more
generic virtual function driver for current and future silicon.
While doing the rename of i40evf to a more generic name of iavf,
we also put the driver on a severe diet due to how much of the
code was unneeded or was unused. The outcome is a lean and mean
virtual function driver that continues to work on existing 40GbE
(i40e) virtual devices and prepped for future supported devices,
like the 100GbE (ice) virtual devices.
This solves 2 issues we saw coming or were already present, the
first was constant code duplication happening with i40e/i40evf,
when much of the duplicate code in the i40evf was not used or was
not needed. The second was to remove the future confusion of why
future VF devices that were not considered "40GbE" only devices
were supported by i40evf.
The thought is that iavf will be the virtual function driver for
all future devices, so it should have a "generic" name to properly
represent that it is the VF driver for multiple generations of
devices.
The last patch in this series is unreleated to the iavf conversion
and just has to do with a MODULE_LICENSE correction.
Known Caveats:
Existing user space configurations may have to change, but the module
alias in patch 1 helps a bit here.
---
NOTE: This series is compile tested, but needs more testing before
commit. I expect it will go through Jeff's regular
intel-wired-lan process.
v2: first non-RFC version, updated Kconfig migration in patch 1
v1: initial RFC
Jesse Brandeburg (14):
intel-ethernet: rename i40evf to iavf
iavf: diet and reformat
iavf: rename functions and structs to new name
iavf: rename i40e_status to iavf_status
iavf: move i40evf files to new name
iavf: remove references to old names
iavf: rename device ID defines
iavf: rename I40E_ADMINQ_DESC
iavf: rename i40e_hw to iavf_hw
iavf: replace i40e_debug with iavf version
iavf: tracing infrastructure rename
iavf: rename most of i40e strings
iavf: finish renaming files to iavf
intel-ethernet: use correct module license
Documentation/networking/00-INDEX | 4 +-
Documentation/networking/{i40evf.txt => iavf.txt} | 16 +-
MAINTAINERS | 2 +-
drivers/net/ethernet/intel/Kconfig | 15 +-
drivers/net/ethernet/intel/Makefile | 2 +-
drivers/net/ethernet/intel/e100.c | 2 +-
drivers/net/ethernet/intel/e1000/e1000_main.c | 2 +-
drivers/net/ethernet/intel/e1000e/netdev.c | 2 +-
drivers/net/ethernet/intel/fm10k/fm10k_main.c | 2 +-
drivers/net/ethernet/intel/i40e/i40e_main.c | 2 +-
drivers/net/ethernet/intel/i40evf/i40e_devids.h | 34 -
drivers/net/ethernet/intel/i40evf/i40e_hmc.h | 215 --
drivers/net/ethernet/intel/i40evf/i40e_lan_hmc.h | 158 --
drivers/net/ethernet/intel/i40evf/i40e_register.h | 313 ---
.../net/ethernet/intel/{i40evf => iavf}/Makefile | 11 +-
.../ethernet/intel/{i40evf => iavf}/i40e_adminq.c | 309 ++-
.../ethernet/intel/{i40evf => iavf}/i40e_adminq.h | 35 +-
.../intel/{i40evf => iavf}/i40e_adminq_cmd.h | 2281 +-------------------
.../intel/{i40evf/i40evf.h => iavf/iavf.h} | 407 ++--
.../{i40evf/i40e_alloc.h => iavf/iavf_alloc.h} | 47 +-
.../{i40evf/i40evf_client.c => iavf/iavf_client.c} | 200 +-
.../{i40evf/i40evf_client.h => iavf/iavf_client.h} | 30 +-
.../{i40evf/i40e_common.c => iavf/iavf_common.c} | 1105 ++++------
drivers/net/ethernet/intel/iavf/iavf_devids.h | 12 +
.../i40evf_ethtool.c => iavf/iavf_ethtool.c} | 510 +++--
.../{i40evf/i40evf_main.c => iavf/iavf_main.c} | 1688 ++++++++-------
.../{i40evf/i40e_osdep.h => iavf/iavf_osdep.h} | 28 +-
.../i40e_prototype.h => iavf/iavf_prototype.h} | 147 +-
drivers/net/ethernet/intel/iavf/iavf_register.h | 68 +
.../{i40evf/i40e_status.h => iavf/iavf_status.h} | 8 +-
.../{i40evf/i40e_trace.h => iavf/iavf_trace.h} | 86 +-
.../intel/{i40evf/i40e_txrx.c => iavf/iavf_txrx.c} | 804 +++----
.../intel/{i40evf/i40e_txrx.h => iavf/iavf_txrx.h} | 359 ++-
.../intel/{i40evf/i40e_type.h => iavf/iavf_type.h} | 1604 ++++----------
.../i40evf_virtchnl.c => iavf/iavf_virtchnl.c} | 501 +++--
drivers/net/ethernet/intel/ice/ice_main.c | 2 +-
drivers/net/ethernet/intel/igb/igb_main.c | 2 +-
drivers/net/ethernet/intel/igbvf/netdev.c | 2 +-
drivers/net/ethernet/intel/ixgb/ixgb_main.c | 2 +-
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 2 +-
drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 2 +-
41 files changed, 3440 insertions(+), 7581 deletions(-)
rename Documentation/networking/{i40evf.txt => iavf.txt} (72%)
delete mode 100644 drivers/net/ethernet/intel/i40evf/i40e_devids.h
delete mode 100644 drivers/net/ethernet/intel/i40evf/i40e_hmc.h
delete mode 100644 drivers/net/ethernet/intel/i40evf/i40e_lan_hmc.h
delete mode 100644 drivers/net/ethernet/intel/i40evf/i40e_register.h
rename drivers/net/ethernet/intel/{i40evf => iavf}/Makefile (38%)
rename drivers/net/ethernet/intel/{i40evf => iavf}/i40e_adminq.c (74%)
rename drivers/net/ethernet/intel/{i40evf => iavf}/i40e_adminq.h (82%)
rename drivers/net/ethernet/intel/{i40evf => iavf}/i40e_adminq_cmd.h (22%)
rename drivers/net/ethernet/intel/{i40evf/i40evf.h => iavf/iavf.h} (37%)
rename drivers/net/ethernet/intel/{i40evf/i40e_alloc.h => iavf/iavf_alloc.h} (16%)
rename drivers/net/ethernet/intel/{i40evf/i40evf_client.c => iavf/iavf_client.c} (66%)
rename drivers/net/ethernet/intel/{i40evf/i40evf_client.h => iavf/iavf_client.h} (87%)
rename drivers/net/ethernet/intel/{i40evf/i40e_common.c => iavf/iavf_common.c} (37%)
create mode 100644 drivers/net/ethernet/intel/iavf/iavf_devids.h
rename drivers/net/ethernet/intel/{i40evf/i40evf_ethtool.c => iavf/iavf_ethtool.c} (59%)
rename drivers/net/ethernet/intel/{i40evf/i40evf_main.c => iavf/iavf_main.c} (63%)
rename drivers/net/ethernet/intel/{i40evf/i40e_osdep.h => iavf/iavf_osdep.h} (56%)
rename drivers/net/ethernet/intel/{i40evf/i40e_prototype.h => iavf/iavf_prototype.h} (10%)
create mode 100644 drivers/net/ethernet/intel/iavf/iavf_register.h
rename drivers/net/ethernet/intel/{i40evf/i40e_status.h => iavf/iavf_status.h} (95%)
rename drivers/net/ethernet/intel/{i40evf/i40e_trace.h => iavf/iavf_trace.h} (66%)
rename drivers/net/ethernet/intel/{i40evf/i40e_txrx.c => iavf/iavf_txrx.c} (72%)
rename drivers/net/ethernet/intel/{i40evf/i40e_txrx.h => iavf/iavf_txrx.h} (52%)
rename drivers/net/ethernet/intel/{i40evf/i40e_type.h => iavf/iavf_type.h} (12%)
rename drivers/net/ethernet/intel/{i40evf/i40evf_virtchnl.c => iavf/iavf_virtchnl.c} (73%)
--
2.14.4
^ permalink raw reply
* Re: [PATH RFC net-next 5/8] net: phy: Add limkmode equivalents to some of the MII ethtool helpers
From: Florian Fainelli @ 2018-09-15 0:28 UTC (permalink / raw)
To: Andrew Lunn, netdev
In-Reply-To: <1536961136-30453-6-git-send-email-andrew@lunn.ch>
On 09/14/2018 02:38 PM, Andrew Lunn wrote:
> Add helpers which take a linkmode rather than a u32 ethtool for
> advertising settings.
>
> Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
--
Florian
^ permalink raw reply
* Re: [PATH RFC net-next 4/8] net: phy: Add helper for advertise to lcl value
From: Florian Fainelli @ 2018-09-15 0:27 UTC (permalink / raw)
To: Andrew Lunn, netdev
In-Reply-To: <1536961136-30453-5-git-send-email-andrew@lunn.ch>
On 09/14/2018 02:38 PM, Andrew Lunn wrote:
> 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>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
--
Florian
^ permalink raw reply
* Re: [PATH RFC net-next 2/8] net: phy: Add phydev_warn()
From: Andrew Lunn @ 2018-09-14 23:26 UTC (permalink / raw)
To: Florian Fainelli; +Cc: netdev
In-Reply-To: <3da34be9-2960-9867-a421-976df5e09f7c@gmail.com>
On Fri, Sep 14, 2018 at 03:10:36PM -0700, Florian Fainelli wrote:
> On 09/14/2018 02:38 PM, Andrew Lunn wrote:
> > 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>
>
> Acked-by: Florian Fainelli <f.fainelli@gmail.com>
>
> Do you mind converting drivers/net/phy/marvell10g.c to use it? I would
> also suggest adding phydev_info() while we are at it and do the two
> conversions to it that exist in drivers/net/phy/phy_device.c?
Yes, we might as well have the full set.
Andrew
^ permalink raw reply
* Re: [PATH RFC net-next 3/8] net: phy: Add helper to convert MII ADV register to a linkmode
From: Andrew Lunn @ 2018-09-14 23:23 UTC (permalink / raw)
To: Florian Fainelli; +Cc: netdev
In-Reply-To: <8c8fd712-d7bd-59b3-6ef9-187f45ba62b8@gmail.com>
On Fri, Sep 14, 2018 at 03:23:14PM -0700, Florian Fainelli wrote:
> On 09/14/2018 02:38 PM, Andrew Lunn wrote:
> > 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.
>
> It would have been nice if we could eliminate the duplication between
> mii_adv_to_ethtool_adv_t() and mii_adv_to_linkmode_adv_t() but I don't
> really see how without changing the former function's signature.
Some of these functions are also used by non-phylib MAC drivers. So
the ethtool version cannot be eliminated.
And the UAPI for EEE still uses a u32 for which modes EEE is
advertised :-(
Andrew
^ permalink raw reply
* Re: [PATCH net-next RFC 6/8] net: make gro configurable
From: Willem de Bruijn @ 2018-09-14 23:14 UTC (permalink / raw)
To: Network Development
Cc: Paolo Abeni, steffen.klassert, David Miller, Willem de Bruijn
In-Reply-To: <20180914175941.213950-7-willemdebruijn.kernel@gmail.com>
On Fri, Sep 14, 2018 at 1:59 PM Willem de Bruijn
<willemdebruijn.kernel@gmail.com> wrote:
>
> From: Willem de Bruijn <willemb@google.com>
>
> Add net_offload flag NET_OFF_FLAG_GRO_OFF. If set, a net_offload will
> not be used for gro receive processing.
>
> Also add sysctl helper proc_do_net_offload that toggles this flag and
> register sysctls net.{core,ipv4,ipv6}.gro
>
> Signed-off-by: Willem de Bruijn <willemb@google.com>
> ---
> diff --git a/net/core/dev.c b/net/core/dev.c
> index 20d9552afd38..0fd5273bc931 100644
> --- a/net/core/dev.c
> +++ b/net/core/dev.c
> @@ -154,6 +154,7 @@
> #define GRO_MAX_HEAD (MAX_HEADER + 128)
>
> static DEFINE_SPINLOCK(ptype_lock);
> +DEFINE_SPINLOCK(offload_lock);
> struct list_head ptype_base[PTYPE_HASH_SIZE] __read_mostly;
> struct list_head ptype_all __read_mostly; /* Taps */
> static struct list_head offload_base __read_mostly;
> diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c
> index b1a2c5e38530..d2d72afdd9eb 100644
> --- a/net/core/sysctl_net_core.c
> +++ b/net/core/sysctl_net_core.c
> @@ -15,6 +15,7 @@
> #include <linux/vmalloc.h>
> #include <linux/init.h>
> #include <linux/slab.h>
> +#include <linux/bitmap.h>
>
> #include <net/ip.h>
> #include <net/sock.h>
> @@ -34,6 +35,58 @@ static int net_msg_warn; /* Unused, but still a sysctl */
> int sysctl_fb_tunnels_only_for_init_net __read_mostly = 0;
> EXPORT_SYMBOL(sysctl_fb_tunnels_only_for_init_net);
>
> +extern spinlock_t offload_lock;
> +
> +#define NET_OFF_TBL_LEN 256
> +
> +int proc_do_net_offload(struct ctl_table *ctl, int write, void __user *buffer,
> + size_t *lenp, loff_t *ppos)
> +{
> + unsigned long bitmap[NET_OFF_TBL_LEN / (sizeof(unsigned long) << 3)];
> + struct ctl_table tbl = { .maxlen = NET_OFF_TBL_LEN, .data = bitmap };
> + unsigned long flag = (unsigned long) ctl->extra2;
> + struct net_offload __rcu **offs = ctl->extra1;
> + struct net_offload *off;
> + int i, ret;
> +
> + memset(bitmap, 0, sizeof(bitmap));
> +
> + spin_lock(&offload_lock);
> +
> + for (i = 0; i < tbl.maxlen; i++) {
> + off = rcu_dereference_protected(offs[i], lockdep_is_held(&offload_lock));
> + if (off && off->flags & flag) {
This does not actually work as is. No protocol will have this flag set
out of the box.
I was in the middle of rewriting some of this when it became topical,
so I sent it out for discussion. It's bound not to be the only bug of
the patchset as is. I'll work through them to get it back in shape.
^ permalink raw reply
* Re: [PATCH net-next RFC 6/8] net: make gro configurable
From: Willem de Bruijn @ 2018-09-14 23:09 UTC (permalink / raw)
To: Stephen Hemminger
Cc: Network Development, Paolo Abeni, steffen.klassert, David Miller,
Willem de Bruijn
In-Reply-To: <CAF=yD-Km0PGZxU+zE1eo2dcg42x8pj1V4XCNXdej8OtwKxkaQA@mail.gmail.com>
On Fri, Sep 14, 2018 at 6:50 PM Willem de Bruijn
<willemdebruijn.kernel@gmail.com> wrote:
>
> On Fri, Sep 14, 2018 at 2:39 PM Stephen Hemminger
> <stephen@networkplumber.org> wrote:
> >
> > On Fri, 14 Sep 2018 13:59:39 -0400
> > Willem de Bruijn <willemdebruijn.kernel@gmail.com> wrote:
> >
> > > diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
> > > index e5d236595206..8cb8e02c8ab6 100644
> > > --- a/drivers/net/vxlan.c
> > > +++ b/drivers/net/vxlan.c
> > > @@ -572,6 +572,7 @@ static struct sk_buff *vxlan_gro_receive(struct sock *sk,
> > > struct list_head *head,
> > > struct sk_buff *skb)
> > > {
> > > + const struct net_offload *ops;
> > > struct sk_buff *pp = NULL;
> > > struct sk_buff *p;
> > > struct vxlanhdr *vh, *vh2;
> > > @@ -606,6 +607,12 @@ static struct sk_buff *vxlan_gro_receive(struct sock *sk,
> > > goto out;
> > > }
> > >
> > > + rcu_read_lock();
> > > + ops = net_gro_receive(dev_offloads, ETH_P_TEB);
> > > + rcu_read_unlock();
> > > + if (!ops)
> > > + goto out;
> >
> > Isn't rcu_read_lock already held here?
> > RCU read lock is always held in the receive handler path
>
> There is a critical section on receive, taken in
> netif_receive_skb_core, but gro code runs before that. All the
> existing gro handlers call rcu_read_lock.
Though if dev_gro_receive is the entry point for all of gro, then
all other handlers are ensured to be executed within its rcu
readside section.
^ permalink raw reply
* [PATCH net] net: phy: sfp: Prevent NULL deference of socket_ops
From: Florian Fainelli @ 2018-09-14 23:01 UTC (permalink / raw)
To: netdev
Cc: rmk+kernel, Florian Fainelli, Andrew Lunn, David S. Miller,
open list
In case we have specified a SFP and an I2C phandle in the Device Tree,
but we somehow failed to look up the I2C adapter (e.g: the driver is not
enabled), we will leave dangling socket_ops, and the sfp_bus will still
have been registered. We can then observe NULL pointer dereferences
while doing ethtool -m:
[ 20.218613] Unable to handle kernel NULL pointer dereference at virtual address 00000008
[ 20.226977] pgd = (ptrval)
[ 20.229785] [00000008] *pgd=7c400831, *pte=00000000, *ppte=00000000
[ 20.236274] Internal error: Oops: 17 [#1] SMP ARM
[ 20.241122] Modules linked in:
[ 20.244278] CPU: 0 PID: 1480 Comm: ethtool Not tainted 4.19.0-rc3 #138
[ 20.251013] Hardware name: Broadcom Northstar Plus SoC
[ 20.256316] PC is at sfp_get_module_info+0x8/0x10
[ 20.261172] LR is at dev_ethtool+0x218c/0x2afc
Specifically guard against that.
Fixes: ce0aa27ff3f6 ("sfp: add sfp-bus to bridge between network devices and sfp cages")
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
drivers/net/phy/sfp-bus.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/net/phy/sfp-bus.c b/drivers/net/phy/sfp-bus.c
index 740655261e5b..9465be501372 100644
--- a/drivers/net/phy/sfp-bus.c
+++ b/drivers/net/phy/sfp-bus.c
@@ -378,6 +378,9 @@ static void sfp_unregister_bus(struct sfp_bus *bus)
*/
int sfp_get_module_info(struct sfp_bus *bus, struct ethtool_modinfo *modinfo)
{
+ if (!bus->socket_ops)
+ return -EOPNOTSUPP;
+
return bus->socket_ops->module_info(bus->sfp, modinfo);
}
EXPORT_SYMBOL_GPL(sfp_get_module_info);
@@ -396,6 +399,9 @@ EXPORT_SYMBOL_GPL(sfp_get_module_info);
int sfp_get_module_eeprom(struct sfp_bus *bus, struct ethtool_eeprom *ee,
u8 *data)
{
+ if (!bus->socket_ops)
+ return -EOPNOTSUPP;
+
return bus->socket_ops->module_eeprom(bus->sfp, ee, data);
}
EXPORT_SYMBOL_GPL(sfp_get_module_eeprom);
--
2.17.1
^ permalink raw reply related
* Re: [PATCH net-next RFC 6/8] net: make gro configurable
From: Willem de Bruijn @ 2018-09-14 22:50 UTC (permalink / raw)
To: Stephen Hemminger
Cc: Network Development, Paolo Abeni, steffen.klassert, David Miller,
Willem de Bruijn
In-Reply-To: <20180914113848.14b931df@xeon-e3>
On Fri, Sep 14, 2018 at 2:39 PM Stephen Hemminger
<stephen@networkplumber.org> wrote:
>
> On Fri, 14 Sep 2018 13:59:39 -0400
> Willem de Bruijn <willemdebruijn.kernel@gmail.com> wrote:
>
> > diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
> > index e5d236595206..8cb8e02c8ab6 100644
> > --- a/drivers/net/vxlan.c
> > +++ b/drivers/net/vxlan.c
> > @@ -572,6 +572,7 @@ static struct sk_buff *vxlan_gro_receive(struct sock *sk,
> > struct list_head *head,
> > struct sk_buff *skb)
> > {
> > + const struct net_offload *ops;
> > struct sk_buff *pp = NULL;
> > struct sk_buff *p;
> > struct vxlanhdr *vh, *vh2;
> > @@ -606,6 +607,12 @@ static struct sk_buff *vxlan_gro_receive(struct sock *sk,
> > goto out;
> > }
> >
> > + rcu_read_lock();
> > + ops = net_gro_receive(dev_offloads, ETH_P_TEB);
> > + rcu_read_unlock();
> > + if (!ops)
> > + goto out;
>
> Isn't rcu_read_lock already held here?
> RCU read lock is always held in the receive handler path
There is a critical section on receive, taken in
netif_receive_skb_core, but gro code runs before that. All the
existing gro handlers call rcu_read_lock.
> > +
> > skb_gro_pull(skb, sizeof(struct vxlanhdr)); /* pull vxlan header */
> >
> > list_for_each_entry(p, head, list) {
> > @@ -621,6 +628,7 @@ static struct sk_buff *vxlan_gro_receive(struct sock *sk,
> > }
> >
> > pp = call_gro_receive(eth_gro_receive, head, skb);
> > +
> > flush = 0;
>
> whitespace change crept into this patch.
Oops, thanks.
^ permalink raw reply
* Re: [PATH RFC net-next 3/8] net: phy: Add helper to convert MII ADV register to a linkmode
From: Florian Fainelli @ 2018-09-14 22:23 UTC (permalink / raw)
To: Andrew Lunn, netdev
In-Reply-To: <1536961136-30453-4-git-send-email-andrew@lunn.ch>
On 09/14/2018 02:38 PM, Andrew Lunn wrote:
> 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.
It would have been nice if we could eliminate the duplication between
mii_adv_to_ethtool_adv_t() and mii_adv_to_linkmode_adv_t() but I don't
really see how without changing the former function's signature.
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
>
> 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)
>
--
Florian
^ permalink raw reply
* Re: [PATH RFC net-next 2/8] net: phy: Add phydev_warn()
From: Florian Fainelli @ 2018-09-14 22:10 UTC (permalink / raw)
To: Andrew Lunn, netdev
In-Reply-To: <1536961136-30453-3-git-send-email-andrew@lunn.ch>
On 09/14/2018 02:38 PM, Andrew Lunn wrote:
> 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>
Acked-by: Florian Fainelli <f.fainelli@gmail.com>
Do you mind converting drivers/net/phy/marvell10g.c to use it? I would
also suggest adding phydev_info() while we are at it and do the two
conversions to it that exist in drivers/net/phy/phy_device.c?
Thanks!
--
Florian
^ permalink raw reply
* Re: [PATH RFC net-next 1/8] net: phy: Move linkmode helpers to somewhere public
From: Florian Fainelli @ 2018-09-14 22:08 UTC (permalink / raw)
To: Andrew Lunn, netdev
In-Reply-To: <1536961136-30453-2-git-send-email-andrew@lunn.ch>
On 09/14/2018 02:38 PM, Andrew Lunn wrote:
> phylink has some useful helpers to working with linkmode bitmaps.
> Move them to there own header so other code can use them.
Good idea, I wonder if we should create a more specific directory within
include/linux/ that can host a variety of PHYLIB, PHYLINK and what not
header files, but this could be solved later on.
>
> Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Acked-by: Florian Fainelli <f.fainelli@gmail.com>
--
Florian
^ 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
* 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
* 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
* [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
* [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
* [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 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 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 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 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 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 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 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
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox