* Re: [PATCH][RFC] udp: cache sock to avoid searching it twice
From: Paolo Abeni @ 2018-11-09 13:41 UTC (permalink / raw)
To: Li RongQing, netdev; +Cc: Willem de Bruijn
In-Reply-To: <1541744479-12810-1-git-send-email-lirongqing@baidu.com>
Hi,
Adding Willem, I think he can be interested.
On Fri, 2018-11-09 at 14:21 +0800, Li RongQing wrote:
> GRO for UDP needs to lookup socket twice, first is in gro receive,
> second is gro complete, so if store sock to skb to avoid looking up
> twice, this can give small performance boost
>
> netperf -t UDP_RR -l 10
>
> Before:
> Rate per sec: 28746.01
> After:
> Rate per sec: 29401.67
>
> Signed-off-by: Li RongQing <lirongqing@baidu.com>
> ---
> net/ipv4/udp_offload.c | 18 +++++++++++++++++-
> 1 file changed, 17 insertions(+), 1 deletion(-)
>
> diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c
> index 0646d61f4fa8..429570112a33 100644
> --- a/net/ipv4/udp_offload.c
> +++ b/net/ipv4/udp_offload.c
> @@ -408,6 +408,11 @@ struct sk_buff *udp_gro_receive(struct list_head *head, struct sk_buff *skb,
>
> if (udp_sk(sk)->gro_enabled) {
> pp = call_gro_receive(udp_gro_receive_segment, head, skb);
> +
> + if (!IS_ERR(pp) && NAPI_GRO_CB(pp)->count > 1) {
> + sock_hold(sk);
> + pp->sk = sk;
> + }
> rcu_read_unlock();
> return pp;
> }
What if 'pp' is NULL?
Aside from that, this replace a lookup with 2 atomic ops, and only when
such lookup is amortized on multiple aggregated packets: I'm unsure if
it's worthy and I don't understand how that improves RR tests (where
the socket can't see multiple, consecutive skbs, AFAIK).
Cheers,
Paolo
^ permalink raw reply
* Re: [PATCH v3 04/23] linux/net.h: use unique identifier for each struct _ddebug
From: Rasmus Villemoes @ 2018-11-09 23:31 UTC (permalink / raw)
To: Joe Perches, Rasmus Villemoes, Andrew Morton, Jason Baron
Cc: linux-kernel, netdev
In-Reply-To: <2358250f27022be9eb5c4e6a3d95ee869c3af45f.camel@perches.com>
On 10/11/2018 00.22, Joe Perches wrote:
> On Sat, 2018-11-10 at 00:10 +0100, Rasmus Villemoes wrote:
>> Changes on x86-64 later in this series require that all struct _ddebug
>> descriptors in a translation unit uses distinct identifiers. Realize
>> that for net_dbg_ratelimited by generating such an identifier via
>> __UNIQUE_ID and pass that to an extra level of macros.
>>
>> No functional change.
>
> Why does this require an extra indirection _<macro>?
>
Because the identifier used in the
>> DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt);
line must be the same as the one in the
>> if (DYNAMIC_DEBUG_BRANCH(descriptor) &&
line. That identifier used to be simply "descriptor", with C scope rules
making that ok. But because of the asm games I'm playing later, I need
to generate a fresh identifier for each instance. That identifier must
be referenced in two places in the C source - hence the need to use an
extra level of macros to have the __UNIQUE_ID() expanded before
_net_dbg_ratelimited gets expanded.
More or less every use of __UNIQUE_ID requires such an extra level
(because one very rarely needs to use an identifier exactly once - the
point of giving stuff a name is to refer to it again.)
Rasmus
^ permalink raw reply
* RE: [PATCH net-next 1/2] dpaa2-eth: defer probe on object allocate
From: Ioana Ciornei @ 2018-11-09 14:01 UTC (permalink / raw)
To: Andrew Lunn
Cc: netdev@vger.kernel.org, davem@davemloft.net,
Ioana Ciocoi Radulescu
In-Reply-To: <20181108182507.GC5259@lunn.ch>
> > The fsl_mc_object_allocate function can fail because not all
> > allocatable objects are probed by the fsl_mc_allocator at the call
> > time. Defer the dpaa2-eth probe when this happens.
> >
> > Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
> > ---
> > drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 30
> > +++++++++++++++++-------
> > 1 file changed, 21 insertions(+), 9 deletions(-)
> >
> > diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
> > b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
> > index 88f7acc..71f5cd4 100644
> > --- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
> > +++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
> > @@ -1434,8 +1434,11 @@ static struct fsl_mc_device *setup_dpcon(struct
> dpaa2_eth_priv *priv)
> > err = fsl_mc_object_allocate(to_fsl_mc_device(dev),
> > FSL_MC_POOL_DPCON, &dpcon);
> > if (err) {
> > - dev_info(dev, "Not enough DPCONs, will go on as-is\n");
> > - return NULL;
> > + if (err == -ENXIO)
> > + err = -EPROBE_DEFER;
> > + else
> > + dev_info(dev, "Not enough DPCONs, will go on as-
> is\n");
> > + return ERR_PTR(err);
> > }
> >
> > err = dpcon_open(priv->mc_io, 0, dpcon->obj_desc.id,
> > &dpcon->mc_handle); @@ -1493,8 +1496,10 @@ static void
> free_dpcon(struct dpaa2_eth_priv *priv,
> > return NULL;
> >
> > channel->dpcon = setup_dpcon(priv);
> > - if (!channel->dpcon)
> > + if (IS_ERR_OR_NULL(channel->dpcon)) {
> > + err = PTR_ERR(channel->dpcon);
> > goto err_setup;
> > + }
>
> Hi Ioana
>
> You need to be careful with IS_ERR_OR_NULL(). If it is a NULL,
> PTR_ERR() is going to return 0. You then jump to the error cleanup code, but
> return 0, meaning everything is O.K.
>
Hi Andrew,
I took a closer look at the code path and it seems that if channel->dpcon in the snippet above is NULL,
then indeed PTR_ERR will be 0 but in the error cleanup code, in this case the err_setup label,
a reverse ERR_PTR (NULL in this case) will be returned.
Continuing on the code path, alloc_channel then returns NULL and is handled by the following snippet.
+ if (IS_ERR_OR_NULL(channel)) {
+ err = PTR_ERR(channel);
+ if (err != -EPROBE_DEFER)
+ dev_info(dev,
+ "No affine channel for cpu %d and above\n", i);
goto err_alloc_ch;
}
In case channel is NULL, then the dev_info will be called and the jump to the cleanup is made.
err_alloc_ch:
+ if (err == -EPROBE_DEFER)
+ return err;
+
if (cpumask_empty(&priv->dpio_cpumask)) {
dev_err(dev, "No cpu with an affine DPIO/DPCON\n");
return err;
Here err is 0 so in case the cpumask is empty, 0 will be returned, which is not the intended use.
I will send a v2 changing the return value to -ENODEV in case no cpus with an affine DPIO is found.
Thanks,
Ioana
^ permalink raw reply
* [PATCH v2 0/5] phy: core: rework phy_set_mode to accept phy mode and submode
From: Grygorii Strashko @ 2018-11-09 23:47 UTC (permalink / raw)
To: David S. Miller, Kishon Vijay Abraham I, Russell King - ARM Linux
Cc: netdev, Sekhar Nori, linux-kernel, linux-arm-kernel,
Tony Lindgren, linux-amlogic, linux-mediatek, Alexandre Belloni,
Antoine Tenart, Quentin Schulz, Vivek Gautam, Maxime Ripard,
Chen-Yu Tsai, Carlo Caione, Chunfeng Yun, Matthias Brugger,
Manu Gautam, Grygorii Strashko
Hi Kishon, All,
As was discussed in [1] I'm posting series which introduces rework of
phy_set_mode to accept phy mode and submode. I've dropped TI specific patches as
this change is pretty big by itself.
Patch 1 is cumulative change which refactors PHY framework code to
support dual level PHYs mode configuration - PHY mode and PHY submode. It
extends .set_mode() callback to support additional parameter "int submode"
and converts all corresponding PHY drivers to support new .set_mode()
callback declaration.
The new extended PHY API
int phy_set_mode_ext(struct phy *phy, enum phy_mode mode, int submode)
is introduced to support dual level PHYs mode configuration and existing
phy_set_mode() API is converted to macros, so PHY framework consumers do
not need to be changed (~21 matches).
Patches 2-4: Add new PHY's mode to be used by Ethernet PHY interface drivers or
multipurpose PHYs like serdes and convert ocelot-serdes and mvebu-cp110-comphy
PHY drivers to use recently introduced PHY_MODE_ETHERNET and phy_set_mode_ext().
Patch 5 - removes unused, ethernet specific phy modes from enum phy_mode.
Testing:
- series tested on TI am335x/am437x/am5(dra7) paltforms.
- other driver build tested.
changes in v2:
- marvell PHY and net drivers updated as recommended by Russell King
v1: https://lkml.org/lkml/2018/11/8/260
[1] https://lkml.org/lkml/2018/10/25/366
Grygorii Strashko (5):
phy: core: rework phy_set_mode to accept phy mode and submode
phy: core: add PHY_MODE_ETHERNET
phy: ocelot-serdes: convert to use eth phy mode and submode
phy: mvebu-cp110-comphy: convert to use eth phy mode and submode
phy: core: clean up unused ethernet specific phy modes
drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c | 19 +-----
drivers/net/ethernet/mscc/ocelot.c | 9 +--
drivers/phy/allwinner/phy-sun4i-usb.c | 3 +-
drivers/phy/amlogic/phy-meson-gxl-usb2.c | 5 +-
drivers/phy/amlogic/phy-meson-gxl-usb3.c | 5 +-
drivers/phy/marvell/phy-mvebu-cp110-comphy.c | 86 ++++++++++++++-----------
drivers/phy/mediatek/phy-mtk-tphy.c | 2 +-
drivers/phy/mediatek/phy-mtk-xsphy.c | 2 +-
drivers/phy/mscc/phy-ocelot-serdes.c | 16 +++--
drivers/phy/phy-core.c | 6 +-
drivers/phy/qualcomm/phy-qcom-qmp.c | 3 +-
drivers/phy/qualcomm/phy-qcom-qusb2.c | 3 +-
drivers/phy/qualcomm/phy-qcom-ufs-qmp-14nm.c | 3 +-
drivers/phy/qualcomm/phy-qcom-ufs-qmp-20nm.c | 3 +-
drivers/phy/qualcomm/phy-qcom-usb-hs.c | 3 +-
drivers/phy/ti/phy-da8xx-usb.c | 3 +-
drivers/phy/ti/phy-tusb1210.c | 2 +-
include/linux/phy/phy.h | 18 ++++--
18 files changed, 100 insertions(+), 91 deletions(-)
--
2.10.5
^ permalink raw reply
* [PATCH v2 1/5] phy: core: rework phy_set_mode to accept phy mode and submode
From: Grygorii Strashko @ 2018-11-09 23:47 UTC (permalink / raw)
To: David S. Miller, Kishon Vijay Abraham I, Russell King - ARM Linux
Cc: netdev, Sekhar Nori, linux-kernel, linux-arm-kernel,
Tony Lindgren, linux-amlogic, linux-mediatek, Alexandre Belloni,
Antoine Tenart, Quentin Schulz, Vivek Gautam, Maxime Ripard,
Chen-Yu Tsai, Carlo Caione, Chunfeng Yun, Matthias Brugger,
Manu Gautam, Grygorii Strashko
In-Reply-To: <20181109234755.21687-1-grygorii.strashko@ti.com>
Currently the attempt to add support for Ethernet interface mode PHY
(MII/GMII/RGMII) will lead to the necessity of extending enum phy_mode and
duplicate there values from phy_interface_t enum (or introduce more PHY
callbacks) [1]. Both approaches are ineffective and would lead to fast
bloating of enum phy_mode or struct phy_ops in the process of adding more
PHYs for different subsystems which will make them unmaintainable.
As discussed in [1] the solution could be to introduce dual level PHYs mode
configuration - PHY mode and PHY submode. The PHY mode will define generic
PHY type (subsystem - PCIE/ETHERNET/USB_) while the PHY submode - subsystem
specific interface mode. The last is usually already defined in
corresponding subsystem headers (phy_interface_t for Ethernet, enum
usb_device_speed for USB).
This patch is cumulative change which refactors PHY framework code to
support dual level PHYs mode configuration - PHY mode and PHY submode. It
extends .set_mode() callback to support additional parameter "int submode"
and converts all corresponding PHY drivers to support new .set_mode()
callback declaration.
The new extended PHY API
int phy_set_mode_ext(struct phy *phy, enum phy_mode mode, int submode)
is introduced to support dual level PHYs mode configuration and existing
phy_set_mode() API is converted to macros, so PHY framework consumers do
not need to be changed (~21 matches).
[1] https://lkml.org/lkml/2018/10/25/366
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
---
drivers/phy/allwinner/phy-sun4i-usb.c | 3 ++-
drivers/phy/amlogic/phy-meson-gxl-usb2.c | 5 +++--
drivers/phy/amlogic/phy-meson-gxl-usb3.c | 5 +++--
drivers/phy/marvell/phy-mvebu-cp110-comphy.c | 3 ++-
drivers/phy/mediatek/phy-mtk-tphy.c | 2 +-
drivers/phy/mediatek/phy-mtk-xsphy.c | 2 +-
drivers/phy/mscc/phy-ocelot-serdes.c | 2 +-
drivers/phy/phy-core.c | 6 +++---
drivers/phy/qualcomm/phy-qcom-qmp.c | 3 ++-
drivers/phy/qualcomm/phy-qcom-qusb2.c | 3 ++-
drivers/phy/qualcomm/phy-qcom-ufs-qmp-14nm.c | 3 ++-
drivers/phy/qualcomm/phy-qcom-ufs-qmp-20nm.c | 3 ++-
drivers/phy/qualcomm/phy-qcom-usb-hs.c | 3 ++-
drivers/phy/ti/phy-da8xx-usb.c | 3 ++-
drivers/phy/ti/phy-tusb1210.c | 2 +-
include/linux/phy/phy.h | 13 ++++++++++---
16 files changed, 39 insertions(+), 22 deletions(-)
diff --git a/drivers/phy/allwinner/phy-sun4i-usb.c b/drivers/phy/allwinner/phy-sun4i-usb.c
index d4dcd39..1acdd73 100644
--- a/drivers/phy/allwinner/phy-sun4i-usb.c
+++ b/drivers/phy/allwinner/phy-sun4i-usb.c
@@ -474,7 +474,8 @@ static int sun4i_usb_phy_power_off(struct phy *_phy)
return 0;
}
-static int sun4i_usb_phy_set_mode(struct phy *_phy, enum phy_mode mode)
+static int sun4i_usb_phy_set_mode(struct phy *_phy,
+ enum phy_mode mode, int submode)
{
struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
diff --git a/drivers/phy/amlogic/phy-meson-gxl-usb2.c b/drivers/phy/amlogic/phy-meson-gxl-usb2.c
index 9f9b541..148ef0b 100644
--- a/drivers/phy/amlogic/phy-meson-gxl-usb2.c
+++ b/drivers/phy/amlogic/phy-meson-gxl-usb2.c
@@ -152,7 +152,8 @@ static int phy_meson_gxl_usb2_reset(struct phy *phy)
return 0;
}
-static int phy_meson_gxl_usb2_set_mode(struct phy *phy, enum phy_mode mode)
+static int phy_meson_gxl_usb2_set_mode(struct phy *phy,
+ enum phy_mode mode, int submode)
{
struct phy_meson_gxl_usb2_priv *priv = phy_get_drvdata(phy);
@@ -209,7 +210,7 @@ static int phy_meson_gxl_usb2_power_on(struct phy *phy)
/* power on the PHY by taking it out of reset mode */
regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_POWER_ON_RESET, 0);
- ret = phy_meson_gxl_usb2_set_mode(phy, priv->mode);
+ ret = phy_meson_gxl_usb2_set_mode(phy, priv->mode, 0);
if (ret) {
phy_meson_gxl_usb2_power_off(phy);
diff --git a/drivers/phy/amlogic/phy-meson-gxl-usb3.c b/drivers/phy/amlogic/phy-meson-gxl-usb3.c
index d37d94d..c0e9e4c 100644
--- a/drivers/phy/amlogic/phy-meson-gxl-usb3.c
+++ b/drivers/phy/amlogic/phy-meson-gxl-usb3.c
@@ -119,7 +119,8 @@ static int phy_meson_gxl_usb3_power_off(struct phy *phy)
return 0;
}
-static int phy_meson_gxl_usb3_set_mode(struct phy *phy, enum phy_mode mode)
+static int phy_meson_gxl_usb3_set_mode(struct phy *phy,
+ enum phy_mode mode, int submode)
{
struct phy_meson_gxl_usb3_priv *priv = phy_get_drvdata(phy);
@@ -164,7 +165,7 @@ static int phy_meson_gxl_usb3_init(struct phy *phy)
if (ret)
goto err_disable_clk_phy;
- ret = phy_meson_gxl_usb3_set_mode(phy, priv->mode);
+ ret = phy_meson_gxl_usb3_set_mode(phy, priv->mode, 0);
if (ret)
goto err_disable_clk_peripheral;
diff --git a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c
index 86a5f7b..79b52c3 100644
--- a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c
+++ b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c
@@ -512,7 +512,8 @@ static int mvebu_comphy_power_on(struct phy *phy)
return ret;
}
-static int mvebu_comphy_set_mode(struct phy *phy, enum phy_mode mode)
+static int mvebu_comphy_set_mode(struct phy *phy,
+ enum phy_mode mode, int submode)
{
struct mvebu_comphy_lane *lane = phy_get_drvdata(phy);
diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c
index 3eb8e1b..5b6a470 100644
--- a/drivers/phy/mediatek/phy-mtk-tphy.c
+++ b/drivers/phy/mediatek/phy-mtk-tphy.c
@@ -971,7 +971,7 @@ static int mtk_phy_exit(struct phy *phy)
return 0;
}
-static int mtk_phy_set_mode(struct phy *phy, enum phy_mode mode)
+static int mtk_phy_set_mode(struct phy *phy, enum phy_mode mode, int submode)
{
struct mtk_phy_instance *instance = phy_get_drvdata(phy);
struct mtk_tphy *tphy = dev_get_drvdata(phy->dev.parent);
diff --git a/drivers/phy/mediatek/phy-mtk-xsphy.c b/drivers/phy/mediatek/phy-mtk-xsphy.c
index 020cd02..8c51131 100644
--- a/drivers/phy/mediatek/phy-mtk-xsphy.c
+++ b/drivers/phy/mediatek/phy-mtk-xsphy.c
@@ -426,7 +426,7 @@ static int mtk_phy_exit(struct phy *phy)
return 0;
}
-static int mtk_phy_set_mode(struct phy *phy, enum phy_mode mode)
+static int mtk_phy_set_mode(struct phy *phy, enum phy_mode mode, int submode)
{
struct xsphy_instance *inst = phy_get_drvdata(phy);
struct mtk_xsphy *xsphy = dev_get_drvdata(phy->dev.parent);
diff --git a/drivers/phy/mscc/phy-ocelot-serdes.c b/drivers/phy/mscc/phy-ocelot-serdes.c
index cbb49d9..c61a9890 100644
--- a/drivers/phy/mscc/phy-ocelot-serdes.c
+++ b/drivers/phy/mscc/phy-ocelot-serdes.c
@@ -158,7 +158,7 @@ static const struct serdes_mux ocelot_serdes_muxes[] = {
HSIO_HW_CFG_PCIE_ENA),
};
-static int serdes_set_mode(struct phy *phy, enum phy_mode mode)
+static int serdes_set_mode(struct phy *phy, enum phy_mode mode, int submode)
{
struct serdes_macro *macro = phy_get_drvdata(phy);
unsigned int i;
diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c
index 35fd38c..df3d4ba 100644
--- a/drivers/phy/phy-core.c
+++ b/drivers/phy/phy-core.c
@@ -360,7 +360,7 @@ int phy_power_off(struct phy *phy)
}
EXPORT_SYMBOL_GPL(phy_power_off);
-int phy_set_mode(struct phy *phy, enum phy_mode mode)
+int phy_set_mode_ext(struct phy *phy, enum phy_mode mode, int submode)
{
int ret;
@@ -368,14 +368,14 @@ int phy_set_mode(struct phy *phy, enum phy_mode mode)
return 0;
mutex_lock(&phy->mutex);
- ret = phy->ops->set_mode(phy, mode);
+ ret = phy->ops->set_mode(phy, mode, submode);
if (!ret)
phy->attrs.mode = mode;
mutex_unlock(&phy->mutex);
return ret;
}
-EXPORT_SYMBOL_GPL(phy_set_mode);
+EXPORT_SYMBOL_GPL(phy_set_mode_ext);
int phy_reset(struct phy *phy)
{
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c b/drivers/phy/qualcomm/phy-qcom-qmp.c
index a833324..514db72 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
@@ -1365,7 +1365,8 @@ static int qcom_qmp_phy_poweron(struct phy *phy)
return ret;
}
-static int qcom_qmp_phy_set_mode(struct phy *phy, enum phy_mode mode)
+static int qcom_qmp_phy_set_mode(struct phy *phy,
+ enum phy_mode mode, int submode)
{
struct qmp_phy *qphy = phy_get_drvdata(phy);
struct qcom_qmp *qmp = qphy->qmp;
diff --git a/drivers/phy/qualcomm/phy-qcom-qusb2.c b/drivers/phy/qualcomm/phy-qcom-qusb2.c
index 9ce5311..098d793 100644
--- a/drivers/phy/qualcomm/phy-qcom-qusb2.c
+++ b/drivers/phy/qualcomm/phy-qcom-qusb2.c
@@ -423,7 +423,8 @@ static void qusb2_phy_set_tune2_param(struct qusb2_phy *qphy)
}
-static int qusb2_phy_set_mode(struct phy *phy, enum phy_mode mode)
+static int qusb2_phy_set_mode(struct phy *phy,
+ enum phy_mode mode, int submode)
{
struct qusb2_phy *qphy = phy_get_drvdata(phy);
diff --git a/drivers/phy/qualcomm/phy-qcom-ufs-qmp-14nm.c b/drivers/phy/qualcomm/phy-qcom-ufs-qmp-14nm.c
index ba1895b..1e0d4f2 100644
--- a/drivers/phy/qualcomm/phy-qcom-ufs-qmp-14nm.c
+++ b/drivers/phy/qualcomm/phy-qcom-ufs-qmp-14nm.c
@@ -65,7 +65,8 @@ static int ufs_qcom_phy_qmp_14nm_exit(struct phy *generic_phy)
}
static
-int ufs_qcom_phy_qmp_14nm_set_mode(struct phy *generic_phy, enum phy_mode mode)
+int ufs_qcom_phy_qmp_14nm_set_mode(struct phy *generic_phy,
+ enum phy_mode mode, int submode)
{
struct ufs_qcom_phy *phy_common = get_ufs_qcom_phy(generic_phy);
diff --git a/drivers/phy/qualcomm/phy-qcom-ufs-qmp-20nm.c b/drivers/phy/qualcomm/phy-qcom-ufs-qmp-20nm.c
index 49f435c..aef40f7 100644
--- a/drivers/phy/qualcomm/phy-qcom-ufs-qmp-20nm.c
+++ b/drivers/phy/qualcomm/phy-qcom-ufs-qmp-20nm.c
@@ -84,7 +84,8 @@ static int ufs_qcom_phy_qmp_20nm_exit(struct phy *generic_phy)
}
static
-int ufs_qcom_phy_qmp_20nm_set_mode(struct phy *generic_phy, enum phy_mode mode)
+int ufs_qcom_phy_qmp_20nm_set_mode(struct phy *generic_phy,
+ enum phy_mode mode, int submode)
{
struct ufs_qcom_phy *phy_common = get_ufs_qcom_phy(generic_phy);
diff --git a/drivers/phy/qualcomm/phy-qcom-usb-hs.c b/drivers/phy/qualcomm/phy-qcom-usb-hs.c
index abbbe75..04934f8 100644
--- a/drivers/phy/qualcomm/phy-qcom-usb-hs.c
+++ b/drivers/phy/qualcomm/phy-qcom-usb-hs.c
@@ -42,7 +42,8 @@ struct qcom_usb_hs_phy {
struct notifier_block vbus_notify;
};
-static int qcom_usb_hs_phy_set_mode(struct phy *phy, enum phy_mode mode)
+static int qcom_usb_hs_phy_set_mode(struct phy *phy,
+ enum phy_mode mode, int submode)
{
struct qcom_usb_hs_phy *uphy = phy_get_drvdata(phy);
u8 addr;
diff --git a/drivers/phy/ti/phy-da8xx-usb.c b/drivers/phy/ti/phy-da8xx-usb.c
index befb886..d5f4fbc 100644
--- a/drivers/phy/ti/phy-da8xx-usb.c
+++ b/drivers/phy/ti/phy-da8xx-usb.c
@@ -93,7 +93,8 @@ static int da8xx_usb20_phy_power_off(struct phy *phy)
return 0;
}
-static int da8xx_usb20_phy_set_mode(struct phy *phy, enum phy_mode mode)
+static int da8xx_usb20_phy_set_mode(struct phy *phy,
+ enum phy_mode mode, int submode)
{
struct da8xx_usb_phy *d_phy = phy_get_drvdata(phy);
u32 val;
diff --git a/drivers/phy/ti/phy-tusb1210.c b/drivers/phy/ti/phy-tusb1210.c
index b8ec39a..329fb93 100644
--- a/drivers/phy/ti/phy-tusb1210.c
+++ b/drivers/phy/ti/phy-tusb1210.c
@@ -53,7 +53,7 @@ static int tusb1210_power_off(struct phy *phy)
return 0;
}
-static int tusb1210_set_mode(struct phy *phy, enum phy_mode mode)
+static int tusb1210_set_mode(struct phy *phy, enum phy_mode mode, int submode)
{
struct tusb1210 *tusb = phy_get_drvdata(phy);
int ret;
diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h
index 03b319f..b17e770 100644
--- a/include/linux/phy/phy.h
+++ b/include/linux/phy/phy.h
@@ -60,7 +60,7 @@ struct phy_ops {
int (*exit)(struct phy *phy);
int (*power_on)(struct phy *phy);
int (*power_off)(struct phy *phy);
- int (*set_mode)(struct phy *phy, enum phy_mode mode);
+ int (*set_mode)(struct phy *phy, enum phy_mode mode, int submode);
int (*reset)(struct phy *phy);
int (*calibrate)(struct phy *phy);
struct module *owner;
@@ -164,7 +164,10 @@ int phy_init(struct phy *phy);
int phy_exit(struct phy *phy);
int phy_power_on(struct phy *phy);
int phy_power_off(struct phy *phy);
-int phy_set_mode(struct phy *phy, enum phy_mode mode);
+int phy_set_mode_ext(struct phy *phy, enum phy_mode mode, int submode);
+#define phy_set_mode(phy, mode) \
+ phy_set_mode_ext(phy, mode, 0)
+
static inline enum phy_mode phy_get_mode(struct phy *phy)
{
return phy->attrs.mode;
@@ -278,13 +281,17 @@ static inline int phy_power_off(struct phy *phy)
return -ENOSYS;
}
-static inline int phy_set_mode(struct phy *phy, enum phy_mode mode)
+static inline int phy_set_mode_ext(struct phy *phy, enum phy_mode mode,
+ int submode)
{
if (!phy)
return 0;
return -ENOSYS;
}
+#define phy_set_mode(phy, mode) \
+ phy_set_mode_ext(phy, mode, 0)
+
static inline enum phy_mode phy_get_mode(struct phy *phy)
{
return PHY_MODE_INVALID;
--
2.10.5
^ permalink raw reply related
* [PATCH v2 2/5] phy: core: add PHY_MODE_ETHERNET
From: Grygorii Strashko @ 2018-11-09 23:47 UTC (permalink / raw)
To: David S. Miller, Kishon Vijay Abraham I, Russell King - ARM Linux
Cc: netdev, Sekhar Nori, linux-kernel, linux-arm-kernel,
Tony Lindgren, linux-amlogic, linux-mediatek, Alexandre Belloni,
Antoine Tenart, Quentin Schulz, Vivek Gautam, Maxime Ripard,
Chen-Yu Tsai, Carlo Caione, Chunfeng Yun, Matthias Brugger,
Manu Gautam, Grygorii Strashko
In-Reply-To: <20181109234755.21687-1-grygorii.strashko@ti.com>
Add new PHY's mode to be used by Ethernet PHY interface drivers or
multipurpose PHYs like serdes. It will be reused in further changes.
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
---
include/linux/phy/phy.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h
index b17e770..02c9ef0 100644
--- a/include/linux/phy/phy.h
+++ b/include/linux/phy/phy.h
@@ -42,6 +42,7 @@ enum phy_mode {
PHY_MODE_UFS_HS_A,
PHY_MODE_UFS_HS_B,
PHY_MODE_PCIE,
+ PHY_MODE_ETHERNET,
};
/**
--
2.10.5
^ permalink raw reply related
* [PATCH v2 3/5] phy: ocelot-serdes: convert to use eth phy mode and submode
From: Grygorii Strashko @ 2018-11-09 23:47 UTC (permalink / raw)
To: David S. Miller, Kishon Vijay Abraham I, Russell King - ARM Linux
Cc: Alexandre Belloni, Grygorii Strashko, Quentin Schulz, Manu Gautam,
Tony Lindgren, netdev, Antoine Tenart, Sekhar Nori, linux-kernel,
Maxime Ripard, Chen-Yu Tsai, Chunfeng Yun, linux-mediatek,
Vivek Gautam, Carlo Caione, linux-amlogic, linux-arm-kernel,
Matthias Brugger
In-Reply-To: <20181109234755.21687-1-grygorii.strashko@ti.com>
Convert ocelot-serdes PHY driver to use recently introduced
PHY_MODE_ETHERNET and phy_set_mode_ext().
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
---
drivers/net/ethernet/mscc/ocelot.c | 9 ++-------
drivers/phy/mscc/phy-ocelot-serdes.c | 14 ++++++++++----
2 files changed, 12 insertions(+), 11 deletions(-)
diff --git a/drivers/net/ethernet/mscc/ocelot.c b/drivers/net/ethernet/mscc/ocelot.c
index 3238b9e..3edb608 100644
--- a/drivers/net/ethernet/mscc/ocelot.c
+++ b/drivers/net/ethernet/mscc/ocelot.c
@@ -472,7 +472,6 @@ static int ocelot_port_open(struct net_device *dev)
{
struct ocelot_port *port = netdev_priv(dev);
struct ocelot *ocelot = port->ocelot;
- enum phy_mode phy_mode;
int err;
/* Enable receiving frames on the port, and activate auto-learning of
@@ -484,12 +483,8 @@ static int ocelot_port_open(struct net_device *dev)
ANA_PORT_PORT_CFG, port->chip_port);
if (port->serdes) {
- if (port->phy_mode == PHY_INTERFACE_MODE_SGMII)
- phy_mode = PHY_MODE_SGMII;
- else
- phy_mode = PHY_MODE_QSGMII;
-
- err = phy_set_mode(port->serdes, phy_mode);
+ err = phy_set_mode_ext(port->serdes, PHY_MODE_ETHERNET,
+ port->phy_mode);
if (err) {
netdev_err(dev, "Could not set mode of SerDes\n");
return err;
diff --git a/drivers/phy/mscc/phy-ocelot-serdes.c b/drivers/phy/mscc/phy-ocelot-serdes.c
index c61a9890..f525a21 100644
--- a/drivers/phy/mscc/phy-ocelot-serdes.c
+++ b/drivers/phy/mscc/phy-ocelot-serdes.c
@@ -11,6 +11,7 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_platform.h>
+#include <linux/phy.h>
#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
@@ -116,8 +117,10 @@ struct serdes_mux {
.mux = _mux, \
}
-#define SERDES_MUX_SGMII(i, p, m, c) SERDES_MUX(i, p, PHY_MODE_SGMII, m, c)
-#define SERDES_MUX_QSGMII(i, p, m, c) SERDES_MUX(i, p, PHY_MODE_QSGMII, m, c)
+#define SERDES_MUX_SGMII(i, p, m, c) \
+ SERDES_MUX(i, p, PHY_INTERFACE_MODE_SGMII, m, c)
+#define SERDES_MUX_QSGMII(i, p, m, c) \
+ SERDES_MUX(i, p, PHY_INTERFACE_MODE_QSGMII, m, c)
static const struct serdes_mux ocelot_serdes_muxes[] = {
SERDES_MUX_SGMII(SERDES1G(0), 0, 0, 0),
@@ -164,12 +167,15 @@ static int serdes_set_mode(struct phy *phy, enum phy_mode mode, int submode)
unsigned int i;
int ret;
+ if (mode != PHY_MODE_ETHERNET)
+ return -EINVAL;
+
for (i = 0; i < ARRAY_SIZE(ocelot_serdes_muxes); i++) {
if (macro->idx != ocelot_serdes_muxes[i].idx ||
- mode != ocelot_serdes_muxes[i].mode)
+ submode != ocelot_serdes_muxes[i].mode)
continue;
- if (mode != PHY_MODE_QSGMII &&
+ if (submode != PHY_INTERFACE_MODE_QSGMII &&
macro->port != ocelot_serdes_muxes[i].port)
continue;
--
2.10.5
^ permalink raw reply related
* [PATCH v2 4/5] phy: mvebu-cp110-comphy: convert to use eth phy mode and submode
From: Grygorii Strashko @ 2018-11-09 23:47 UTC (permalink / raw)
To: David S. Miller, Kishon Vijay Abraham I, Russell King - ARM Linux
Cc: netdev, Sekhar Nori, linux-kernel, linux-arm-kernel,
Tony Lindgren, linux-amlogic, linux-mediatek, Alexandre Belloni,
Antoine Tenart, Quentin Schulz, Vivek Gautam, Maxime Ripard,
Chen-Yu Tsai, Carlo Caione, Chunfeng Yun, Matthias Brugger,
Manu Gautam, Grygorii Strashko
In-Reply-To: <20181109234755.21687-1-grygorii.strashko@ti.com>
Convert mvebu-cp110-comphy PHY driver to use recently introduced
PHY_MODE_ETHERNET and phy_set_mode_ext().
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
---
drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c | 19 +-----
drivers/phy/marvell/phy-mvebu-cp110-comphy.c | 83 ++++++++++++++-----------
2 files changed, 48 insertions(+), 54 deletions(-)
diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
index 7a37a37..731793a 100644
--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
@@ -1165,28 +1165,13 @@ static void mvpp22_gop_setup_irq(struct mvpp2_port *port)
*/
static int mvpp22_comphy_init(struct mvpp2_port *port)
{
- enum phy_mode mode;
int ret;
if (!port->comphy)
return 0;
- switch (port->phy_interface) {
- case PHY_INTERFACE_MODE_SGMII:
- case PHY_INTERFACE_MODE_1000BASEX:
- mode = PHY_MODE_SGMII;
- break;
- case PHY_INTERFACE_MODE_2500BASEX:
- mode = PHY_MODE_2500SGMII;
- break;
- case PHY_INTERFACE_MODE_10GKR:
- mode = PHY_MODE_10GKR;
- break;
- default:
- return -EINVAL;
- }
-
- ret = phy_set_mode(port->comphy, mode);
+ ret = phy_set_mode_ext(port->comphy, PHY_MODE_ETHERNET,
+ port->phy_interface);
if (ret)
return ret;
diff --git a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c
index 79b52c3..7dee72b 100644
--- a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c
+++ b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c
@@ -9,6 +9,7 @@
#include <linux/iopoll.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
+#include <linux/phy.h>
#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
@@ -131,26 +132,26 @@ struct mvebu_comhy_conf {
static const struct mvebu_comhy_conf mvebu_comphy_cp110_modes[] = {
/* lane 0 */
- MVEBU_COMPHY_CONF(0, 1, PHY_MODE_SGMII, 0x1),
- MVEBU_COMPHY_CONF(0, 1, PHY_MODE_2500SGMII, 0x1),
+ MVEBU_COMPHY_CONF(0, 1, PHY_INTERFACE_MODE_SGMII, 0x1),
+ MVEBU_COMPHY_CONF(0, 1, PHY_INTERFACE_MODE_2500BASEX, 0x1),
/* lane 1 */
- MVEBU_COMPHY_CONF(1, 2, PHY_MODE_SGMII, 0x1),
- MVEBU_COMPHY_CONF(1, 2, PHY_MODE_2500SGMII, 0x1),
+ MVEBU_COMPHY_CONF(1, 2, PHY_INTERFACE_MODE_SGMII, 0x1),
+ MVEBU_COMPHY_CONF(1, 2, PHY_INTERFACE_MODE_2500BASEX, 0x1),
/* lane 2 */
- MVEBU_COMPHY_CONF(2, 0, PHY_MODE_SGMII, 0x1),
- MVEBU_COMPHY_CONF(2, 0, PHY_MODE_2500SGMII, 0x1),
- MVEBU_COMPHY_CONF(2, 0, PHY_MODE_10GKR, 0x1),
+ MVEBU_COMPHY_CONF(2, 0, PHY_INTERFACE_MODE_SGMII, 0x1),
+ MVEBU_COMPHY_CONF(2, 0, PHY_INTERFACE_MODE_2500BASEX, 0x1),
+ MVEBU_COMPHY_CONF(2, 0, PHY_INTERFACE_MODE_10GKR, 0x1),
/* lane 3 */
- MVEBU_COMPHY_CONF(3, 1, PHY_MODE_SGMII, 0x2),
- MVEBU_COMPHY_CONF(3, 1, PHY_MODE_2500SGMII, 0x2),
+ MVEBU_COMPHY_CONF(3, 1, PHY_INTERFACE_MODE_SGMII, 0x2),
+ MVEBU_COMPHY_CONF(3, 1, PHY_INTERFACE_MODE_2500BASEX, 0x2),
/* lane 4 */
- MVEBU_COMPHY_CONF(4, 0, PHY_MODE_SGMII, 0x2),
- MVEBU_COMPHY_CONF(4, 0, PHY_MODE_2500SGMII, 0x2),
- MVEBU_COMPHY_CONF(4, 0, PHY_MODE_10GKR, 0x2),
- MVEBU_COMPHY_CONF(4, 1, PHY_MODE_SGMII, 0x1),
+ MVEBU_COMPHY_CONF(4, 0, PHY_INTERFACE_MODE_SGMII, 0x2),
+ MVEBU_COMPHY_CONF(4, 0, PHY_INTERFACE_MODE_2500BASEX, 0x2),
+ MVEBU_COMPHY_CONF(4, 0, PHY_INTERFACE_MODE_10GKR, 0x2),
+ MVEBU_COMPHY_CONF(4, 1, PHY_INTERFACE_MODE_SGMII, 0x1),
/* lane 5 */
- MVEBU_COMPHY_CONF(5, 2, PHY_MODE_SGMII, 0x1),
- MVEBU_COMPHY_CONF(5, 2, PHY_MODE_2500SGMII, 0x1),
+ MVEBU_COMPHY_CONF(5, 2, PHY_INTERFACE_MODE_SGMII, 0x1),
+ MVEBU_COMPHY_CONF(5, 2, PHY_INTERFACE_MODE_2500BASEX, 0x1),
};
struct mvebu_comphy_priv {
@@ -163,10 +164,12 @@ struct mvebu_comphy_lane {
struct mvebu_comphy_priv *priv;
unsigned id;
enum phy_mode mode;
+ int submode;
int port;
};
-static int mvebu_comphy_get_mux(int lane, int port, enum phy_mode mode)
+static int mvebu_comphy_get_mux(int lane, int port,
+ enum phy_mode mode, int submode)
{
int i, n = ARRAY_SIZE(mvebu_comphy_cp110_modes);
@@ -177,7 +180,7 @@ static int mvebu_comphy_get_mux(int lane, int port, enum phy_mode mode)
for (i = 0; i < n; i++) {
if (mvebu_comphy_cp110_modes[i].lane == lane &&
mvebu_comphy_cp110_modes[i].port == port &&
- mvebu_comphy_cp110_modes[i].mode == mode)
+ mvebu_comphy_cp110_modes[i].mode == submode)
break;
}
@@ -187,8 +190,7 @@ static int mvebu_comphy_get_mux(int lane, int port, enum phy_mode mode)
return mvebu_comphy_cp110_modes[i].mux;
}
-static void mvebu_comphy_ethernet_init_reset(struct mvebu_comphy_lane *lane,
- enum phy_mode mode)
+static void mvebu_comphy_ethernet_init_reset(struct mvebu_comphy_lane *lane)
{
struct mvebu_comphy_priv *priv = lane->priv;
u32 val;
@@ -206,14 +208,14 @@ static void mvebu_comphy_ethernet_init_reset(struct mvebu_comphy_lane *lane,
MVEBU_COMPHY_SERDES_CFG0_HALF_BUS |
MVEBU_COMPHY_SERDES_CFG0_GEN_RX(0xf) |
MVEBU_COMPHY_SERDES_CFG0_GEN_TX(0xf));
- if (mode == PHY_MODE_10GKR)
+ if (lane->submode == PHY_INTERFACE_MODE_10GKR)
val |= MVEBU_COMPHY_SERDES_CFG0_GEN_RX(0xe) |
MVEBU_COMPHY_SERDES_CFG0_GEN_TX(0xe);
- else if (mode == PHY_MODE_2500SGMII)
+ else if (lane->submode == PHY_INTERFACE_MODE_2500BASEX)
val |= MVEBU_COMPHY_SERDES_CFG0_GEN_RX(0x8) |
MVEBU_COMPHY_SERDES_CFG0_GEN_TX(0x8) |
MVEBU_COMPHY_SERDES_CFG0_HALF_BUS;
- else if (mode == PHY_MODE_SGMII)
+ else if (lane->submode == PHY_INTERFACE_MODE_SGMII)
val |= MVEBU_COMPHY_SERDES_CFG0_GEN_RX(0x6) |
MVEBU_COMPHY_SERDES_CFG0_GEN_TX(0x6) |
MVEBU_COMPHY_SERDES_CFG0_HALF_BUS;
@@ -243,7 +245,7 @@ static void mvebu_comphy_ethernet_init_reset(struct mvebu_comphy_lane *lane,
/* refclk selection */
val = readl(priv->base + MVEBU_COMPHY_MISC_CTRL0(lane->id));
val &= ~MVEBU_COMPHY_MISC_CTRL0_REFCLK_SEL;
- if (mode == PHY_MODE_10GKR)
+ if (lane->submode == PHY_INTERFACE_MODE_10GKR)
val |= MVEBU_COMPHY_MISC_CTRL0_ICP_FORCE;
writel(val, priv->base + MVEBU_COMPHY_MISC_CTRL0(lane->id));
@@ -261,8 +263,7 @@ static void mvebu_comphy_ethernet_init_reset(struct mvebu_comphy_lane *lane,
writel(val, priv->base + MVEBU_COMPHY_LOOPBACK(lane->id));
}
-static int mvebu_comphy_init_plls(struct mvebu_comphy_lane *lane,
- enum phy_mode mode)
+static int mvebu_comphy_init_plls(struct mvebu_comphy_lane *lane)
{
struct mvebu_comphy_priv *priv = lane->priv;
u32 val;
@@ -303,13 +304,13 @@ static int mvebu_comphy_init_plls(struct mvebu_comphy_lane *lane,
return 0;
}
-static int mvebu_comphy_set_mode_sgmii(struct phy *phy, enum phy_mode mode)
+static int mvebu_comphy_set_mode_sgmii(struct phy *phy)
{
struct mvebu_comphy_lane *lane = phy_get_drvdata(phy);
struct mvebu_comphy_priv *priv = lane->priv;
u32 val;
- mvebu_comphy_ethernet_init_reset(lane, mode);
+ mvebu_comphy_ethernet_init_reset(lane);
val = readl(priv->base + MVEBU_COMPHY_RX_CTRL1(lane->id));
val &= ~MVEBU_COMPHY_RX_CTRL1_CLK8T_EN;
@@ -330,7 +331,7 @@ static int mvebu_comphy_set_mode_sgmii(struct phy *phy, enum phy_mode mode)
val |= MVEBU_COMPHY_GEN1_S0_TX_EMPH(0x1);
writel(val, priv->base + MVEBU_COMPHY_GEN1_S0(lane->id));
- return mvebu_comphy_init_plls(lane, PHY_MODE_SGMII);
+ return mvebu_comphy_init_plls(lane);
}
static int mvebu_comphy_set_mode_10gkr(struct phy *phy)
@@ -339,7 +340,7 @@ static int mvebu_comphy_set_mode_10gkr(struct phy *phy)
struct mvebu_comphy_priv *priv = lane->priv;
u32 val;
- mvebu_comphy_ethernet_init_reset(lane, PHY_MODE_10GKR);
+ mvebu_comphy_ethernet_init_reset(lane);
val = readl(priv->base + MVEBU_COMPHY_RX_CTRL1(lane->id));
val |= MVEBU_COMPHY_RX_CTRL1_RXCLK2X_SEL |
@@ -469,7 +470,7 @@ static int mvebu_comphy_set_mode_10gkr(struct phy *phy)
val |= MVEBU_COMPHY_EXT_SELV_RX_SAMPL(0x1a);
writel(val, priv->base + MVEBU_COMPHY_EXT_SELV(lane->id));
- return mvebu_comphy_init_plls(lane, PHY_MODE_10GKR);
+ return mvebu_comphy_init_plls(lane);
}
static int mvebu_comphy_power_on(struct phy *phy)
@@ -479,7 +480,8 @@ static int mvebu_comphy_power_on(struct phy *phy)
int ret, mux;
u32 val;
- mux = mvebu_comphy_get_mux(lane->id, lane->port, lane->mode);
+ mux = mvebu_comphy_get_mux(lane->id, lane->port,
+ lane->mode, lane->submode);
if (mux < 0)
return -ENOTSUPP;
@@ -492,12 +494,12 @@ static int mvebu_comphy_power_on(struct phy *phy)
val |= mux << MVEBU_COMPHY_SELECTOR_PHY(lane->id);
regmap_write(priv->regmap, MVEBU_COMPHY_SELECTOR, val);
- switch (lane->mode) {
- case PHY_MODE_SGMII:
- case PHY_MODE_2500SGMII:
- ret = mvebu_comphy_set_mode_sgmii(phy, lane->mode);
+ switch (lane->submode) {
+ case PHY_INTERFACE_MODE_SGMII:
+ case PHY_INTERFACE_MODE_2500BASEX:
+ ret = mvebu_comphy_set_mode_sgmii(phy);
break;
- case PHY_MODE_10GKR:
+ case PHY_INTERFACE_MODE_10GKR:
ret = mvebu_comphy_set_mode_10gkr(phy);
break;
default:
@@ -517,10 +519,17 @@ static int mvebu_comphy_set_mode(struct phy *phy,
{
struct mvebu_comphy_lane *lane = phy_get_drvdata(phy);
- if (mvebu_comphy_get_mux(lane->id, lane->port, mode) < 0)
+ if (mode != PHY_MODE_ETHERNET)
+ return -EINVAL;
+
+ if (submode == PHY_INTERFACE_MODE_1000BASEX)
+ submode = PHY_INTERFACE_MODE_SGMII;
+
+ if (mvebu_comphy_get_mux(lane->id, lane->port, mode, submode) < 0)
return -EINVAL;
lane->mode = mode;
+ lane->submode = submode;
return 0;
}
--
2.10.5
^ permalink raw reply related
* [PATCH v2 5/5] phy: core: clean up unused ethernet specific phy modes
From: Grygorii Strashko @ 2018-11-09 23:47 UTC (permalink / raw)
To: David S. Miller, Kishon Vijay Abraham I, Russell King - ARM Linux
Cc: netdev, Sekhar Nori, linux-kernel, linux-arm-kernel,
Tony Lindgren, linux-amlogic, linux-mediatek, Alexandre Belloni,
Antoine Tenart, Quentin Schulz, Vivek Gautam, Maxime Ripard,
Chen-Yu Tsai, Carlo Caione, Chunfeng Yun, Matthias Brugger,
Manu Gautam, Grygorii Strashko
In-Reply-To: <20181109234755.21687-1-grygorii.strashko@ti.com>
After recent changes PHY_MODE_SGMII, PHY_MODE_2500SGMII, PHY_MODE_QSGMII,
PHY_MODE_10GKR are not used any more and can be removed. Hence - remove
them.
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
---
include/linux/phy/phy.h | 4 ----
1 file changed, 4 deletions(-)
diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h
index 02c9ef0..79da05a 100644
--- a/include/linux/phy/phy.h
+++ b/include/linux/phy/phy.h
@@ -35,10 +35,6 @@ enum phy_mode {
PHY_MODE_USB_DEVICE_HS,
PHY_MODE_USB_DEVICE_SS,
PHY_MODE_USB_OTG,
- PHY_MODE_SGMII,
- PHY_MODE_2500SGMII,
- PHY_MODE_QSGMII,
- PHY_MODE_10GKR,
PHY_MODE_UFS_HS_A,
PHY_MODE_UFS_HS_B,
PHY_MODE_PCIE,
--
2.10.5
^ permalink raw reply related
* [Patch net-next 03/11] net: hns3: add reset handling for VF when doing PF reset
From: Huazhong Tan @ 2018-11-09 14:07 UTC (permalink / raw)
To: davem; +Cc: netdev, linux-kernel, salil.mehta, yisen.zhuang, linuxarm
In-Reply-To: <1541772476-41478-1-git-send-email-tanhuazhong@huawei.com>
When PF performs a function reset, the hardware will reset both PF
and all the VF belong to this PF. Hence, both PF's driver and VF's
driver need to perform corresponding reset operations.
Before PF driver asserting function reset to hardware, it firstly
set up VF's hardware reset status, and inform the VF driver with
HNAE3_VF_PF_FUNC_RESET, then VF driver sets this reset type to
reset_pending and shechule reset task to stop IO and waits for the
hardware reset status to clear. When PF driver has reinitialized the
hardware and is ready to process mailbox from VF, PF driver clears
VF's hardware reset status for VF to continue its reset process.
Also, this patch uses readl_poll_timeout to simplify the hardware reset
status waitting.
Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
Signed-off-by: Yunsheng Lin <linyunsheng@huawei.com>
---
drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h | 6 ++
drivers/net/ethernet/hisilicon/hns3/hnae3.h | 1 +
drivers/net/ethernet/hisilicon/hns3/hns3_enet.h | 3 +-
.../ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 91 ++++++++++++++++++++++
.../ethernet/hisilicon/hns3/hns3pf/hclge_main.h | 1 +
.../net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c | 11 ++-
.../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | 39 ++++++----
.../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h | 10 ++-
.../ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c | 4 +-
9 files changed, 146 insertions(+), 20 deletions(-)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h b/drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h
index 038326c..3bb313c 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h
@@ -85,6 +85,12 @@ struct hclge_mbx_pf_to_vf_cmd {
u16 msg[8];
};
+struct hclge_vf_rst_cmd {
+ u8 dest_vfid;
+ u8 vf_rst;
+ u8 rsv[22];
+};
+
/* used by VF to store the received Async responses from PF */
struct hclgevf_mbx_arq_ring {
#define HCLGE_MBX_MAX_ARQ_MSG_SIZE 8
diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
index 510dd08..f15f595 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
@@ -125,6 +125,7 @@ enum hnae3_reset_notify_type {
enum hnae3_reset_type {
HNAE3_VF_RESET,
HNAE3_VF_FUNC_RESET,
+ HNAE3_VF_PF_FUNC_RESET,
HNAE3_VF_FULL_RESET,
HNAE3_FUNC_RESET,
HNAE3_CORE_RESET,
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
index 5a38226..bd6ee5c 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
@@ -594,7 +594,8 @@ static inline void hns3_write_reg(void __iomem *base, u32 reg, u32 value)
static inline bool hns3_dev_ongoing_func_reset(struct hnae3_ae_dev *ae_dev)
{
return (ae_dev && (ae_dev->reset_type == HNAE3_FUNC_RESET ||
- ae_dev->reset_type == HNAE3_VF_FUNC_RESET));
+ ae_dev->reset_type == HNAE3_VF_FUNC_RESET ||
+ ae_dev->reset_type == HNAE3_VF_PF_FUNC_RESET));
}
#define hns3_read_dev(a, reg) \
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index 77980e5..ba6ea6b 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -2392,6 +2392,55 @@ static int hclge_reset_wait(struct hclge_dev *hdev)
return 0;
}
+static int hclge_set_vf_rst(struct hclge_dev *hdev, int func_id, bool reset)
+{
+ struct hclge_vf_rst_cmd *req;
+ struct hclge_desc desc;
+
+ req = (struct hclge_vf_rst_cmd *)desc.data;
+ hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_GBL_RST_STATUS, false);
+ req->dest_vfid = func_id;
+
+ if (reset)
+ req->vf_rst = 0x1;
+
+ return hclge_cmd_send(&hdev->hw, &desc, 1);
+}
+
+int hclge_set_all_vf_rst(struct hclge_dev *hdev, bool reset)
+{
+ int i;
+
+ for (i = hdev->num_vmdq_vport + 1; i < hdev->num_alloc_vport; i++) {
+ struct hclge_vport *vport = &hdev->vport[i];
+ int ret;
+
+ /* Send cmd to set/clear VF's FUNC_RST_ING */
+ ret = hclge_set_vf_rst(hdev, vport->vport_id, reset);
+ if (ret) {
+ dev_err(&hdev->pdev->dev,
+ "set vf(%d) rst failded %d!\n",
+ vport->vport_id, ret);
+ return ret;
+ }
+
+ if (!reset)
+ continue;
+
+ /* Inform VF to process the reset.
+ * hclge_inform_reset_assert_to_vf may fail if VF
+ * driver is not loaded.
+ */
+ ret = hclge_inform_reset_assert_to_vf(vport);
+ if (ret)
+ dev_warn(&hdev->pdev->dev,
+ "inform reset to vf(%d) failded %d!\n",
+ vport->vport_id, ret);
+ }
+
+ return 0;
+}
+
int hclge_func_reset_cmd(struct hclge_dev *hdev, int func_id)
{
struct hclge_desc desc;
@@ -2495,12 +2544,31 @@ static void hclge_clear_reset_cause(struct hclge_dev *hdev)
hclge_enable_vector(&hdev->misc_vector, true);
}
+static int hclge_reset_prepare_down(struct hclge_dev *hdev)
+{
+ int ret = 0;
+
+ switch (hdev->reset_type) {
+ case HNAE3_FUNC_RESET:
+ ret = hclge_set_all_vf_rst(hdev, true);
+ break;
+ default:
+ break;
+ }
+
+ return ret;
+}
+
static int hclge_reset_prepare_wait(struct hclge_dev *hdev)
{
int ret = 0;
switch (hdev->reset_type) {
case HNAE3_FUNC_RESET:
+ /* There is no mechanism for PF to know if VF has stopped IO
+ * for now, just wait 100 ms for VF to stop IO
+ */
+ msleep(100);
ret = hclge_func_reset_cmd(hdev, 0);
if (ret) {
dev_err(&hdev->pdev->dev,
@@ -2562,6 +2630,21 @@ static bool hclge_reset_err_handle(struct hclge_dev *hdev, bool is_timeout)
return false;
}
+static int hclge_reset_prepare_up(struct hclge_dev *hdev)
+{
+ int ret = 0;
+
+ switch (hdev->reset_type) {
+ case HNAE3_FUNC_RESET:
+ ret = hclge_set_all_vf_rst(hdev, false);
+ break;
+ default:
+ break;
+ }
+
+ return ret;
+}
+
static void hclge_reset(struct hclge_dev *hdev)
{
struct hnae3_ae_dev *ae_dev = pci_get_drvdata(hdev->pdev);
@@ -2579,6 +2662,10 @@ static void hclge_reset(struct hclge_dev *hdev)
if (ret)
goto err_reset;
+ ret = hclge_reset_prepare_down(hdev);
+ if (ret)
+ goto err_reset;
+
rtnl_lock();
ret = hclge_notify_client(hdev, HNAE3_DOWN_CLIENT);
if (ret)
@@ -2614,6 +2701,10 @@ static void hclge_reset(struct hclge_dev *hdev)
hclge_clear_reset_cause(hdev);
+ ret = hclge_reset_prepare_up(hdev);
+ if (ret)
+ goto err_reset_lock;
+
ret = hclge_notify_client(hdev, HNAE3_UP_CLIENT);
if (ret)
goto err_reset_lock;
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
index 6df4cfe..8ab974c 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
@@ -785,6 +785,7 @@ int hclge_buffer_alloc(struct hclge_dev *hdev);
int hclge_rss_init_hw(struct hclge_dev *hdev);
void hclge_rss_indir_init_cfg(struct hclge_dev *hdev);
+int hclge_inform_reset_assert_to_vf(struct hclge_vport *vport);
void hclge_mbx_handler(struct hclge_dev *hdev);
int hclge_reset_tqp(struct hnae3_handle *handle, u16 queue_id);
void hclge_reset_vf_queue(struct hclge_vport *vport, u16 queue_id);
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c
index 013bc7a..f15b807 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c
@@ -81,13 +81,22 @@ static int hclge_send_mbx_msg(struct hclge_vport *vport, u8 *msg, u16 msg_len,
int hclge_inform_reset_assert_to_vf(struct hclge_vport *vport)
{
+ struct hclge_dev *hdev = vport->back;
+ enum hnae3_reset_type reset_type;
u8 msg_data[2];
u8 dest_vfid;
dest_vfid = (u8)vport->vport_id;
+ if (hdev->reset_type == HNAE3_FUNC_RESET)
+ reset_type = HNAE3_VF_PF_FUNC_RESET;
+ else
+ return -EINVAL;
+
+ memcpy(&msg_data[0], &reset_type, sizeof(u16));
+
/* send this requested info to VF */
- return hclge_send_mbx_msg(vport, msg_data, sizeof(u8),
+ return hclge_send_mbx_msg(vport, msg_data, sizeof(msg_data),
HCLGE_MBX_ASSERTING_RESET, dest_vfid);
}
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
index 7a1462a..9405517 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
@@ -2,6 +2,7 @@
// Copyright (c) 2016-2017 Hisilicon Limited.
#include <linux/etherdevice.h>
+#include <linux/iopoll.h>
#include <net/rtnetlink.h>
#include "hclgevf_cmd.h"
#include "hclgevf_main.h"
@@ -1094,24 +1095,28 @@ static int hclgevf_notify_client(struct hclgevf_dev *hdev,
static int hclgevf_reset_wait(struct hclgevf_dev *hdev)
{
-#define HCLGEVF_RESET_WAIT_MS 500
-#define HCLGEVF_RESET_WAIT_CNT 20
- u32 val, cnt = 0;
+#define HCLGEVF_RESET_WAIT_US 20000
+#define HCLGEVF_RESET_WAIT_CNT 2000
+#define HCLGEVF_RESET_WAIT_TIMEOUT_US \
+ (HCLGEVF_RESET_WAIT_US * HCLGEVF_RESET_WAIT_CNT)
+
+ u32 val;
+ int ret;
/* wait to check the hardware reset completion status */
- val = hclgevf_read_dev(&hdev->hw, HCLGEVF_FUN_RST_ING);
- while (hnae3_get_bit(val, HCLGEVF_FUN_RST_ING_B) &&
- (cnt < HCLGEVF_RESET_WAIT_CNT)) {
- msleep(HCLGEVF_RESET_WAIT_MS);
- val = hclgevf_read_dev(&hdev->hw, HCLGEVF_FUN_RST_ING);
- cnt++;
- }
+ val = hclgevf_read_dev(&hdev->hw, HCLGEVF_RST_ING);
+ dev_info(&hdev->pdev->dev, "checking vf resetting status: %x\n", val);
+
+ ret = readl_poll_timeout(hdev->hw.io_base + HCLGEVF_RST_ING, val,
+ !(val & HCLGEVF_RST_ING_BITS),
+ HCLGEVF_RESET_WAIT_US,
+ HCLGEVF_RESET_WAIT_TIMEOUT_US);
/* hardware completion status should be available by this time */
- if (cnt >= HCLGEVF_RESET_WAIT_CNT) {
- dev_warn(&hdev->pdev->dev,
- "could'nt get reset done status from h/w, timeout!\n");
- return -EBUSY;
+ if (ret) {
+ dev_err(&hdev->pdev->dev,
+ "could'nt get reset done status from h/w, timeout!\n");
+ return ret;
}
/* we will wait a bit more to let reset of the stack to complete. This
@@ -1225,6 +1230,10 @@ static enum hnae3_reset_type hclgevf_get_reset_level(struct hclgevf_dev *hdev,
rst_level = HNAE3_VF_FULL_RESET;
clear_bit(HNAE3_VF_FULL_RESET, addr);
clear_bit(HNAE3_VF_FUNC_RESET, addr);
+ } else if (test_bit(HNAE3_VF_PF_FUNC_RESET, addr)) {
+ rst_level = HNAE3_VF_PF_FUNC_RESET;
+ clear_bit(HNAE3_VF_PF_FUNC_RESET, addr);
+ clear_bit(HNAE3_VF_FUNC_RESET, addr);
} else if (test_bit(HNAE3_VF_FUNC_RESET, addr)) {
rst_level = HNAE3_VF_FUNC_RESET;
clear_bit(HNAE3_VF_FUNC_RESET, addr);
@@ -2178,7 +2187,7 @@ static bool hclgevf_get_hw_reset_stat(struct hnae3_handle *handle)
{
struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
- return !!hclgevf_read_dev(&hdev->hw, HCLGEVF_FUN_RST_ING);
+ return !!hclgevf_read_dev(&hdev->hw, HCLGEVF_RST_ING);
}
static bool hclgevf_ae_dev_resetting(struct hnae3_handle *handle)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h
index e6abc4e..2735414 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h
@@ -34,8 +34,14 @@
#define HCLGEVF_TQP_RESET_TRY_TIMES 10
/* Reset related Registers */
-#define HCLGEVF_FUN_RST_ING 0x20C00
-#define HCLGEVF_FUN_RST_ING_B 0
+#define HCLGEVF_RST_ING 0x20C00
+#define HCLGEVF_FUN_RST_ING_BIT BIT(0)
+#define HCLGEVF_GLOBAL_RST_ING_BIT BIT(5)
+#define HCLGEVF_CORE_RST_ING_BIT BIT(6)
+#define HCLGEVF_IMP_RST_ING_BIT BIT(7)
+#define HCLGEVF_RST_ING_BITS \
+ (HCLGEVF_FUN_RST_ING_BIT | HCLGEVF_GLOBAL_RST_ING_BIT | \
+ HCLGEVF_CORE_RST_ING_BIT | HCLGEVF_IMP_RST_ING_BIT)
#define HCLGEVF_RSS_IND_TBL_SIZE 512
#define HCLGEVF_RSS_SET_BITMAP_MSK 0xffff
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c
index d3519f7..01a028a 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c
@@ -233,6 +233,7 @@ void hclgevf_mbx_handler(struct hclgevf_dev *hdev)
void hclgevf_mbx_async_handler(struct hclgevf_dev *hdev)
{
+ enum hnae3_reset_type reset_type;
u16 link_status;
u16 *msg_q;
u8 duplex;
@@ -267,7 +268,8 @@ void hclgevf_mbx_async_handler(struct hclgevf_dev *hdev)
* has been completely reset. After this stack should
* eventually be re-initialized.
*/
- set_bit(HNAE3_VF_FULL_RESET, &hdev->reset_pending);
+ reset_type = le16_to_cpu(msg_q[1]);
+ set_bit(reset_type, &hdev->reset_pending);
set_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state);
hclgevf_reset_task_schedule(hdev);
--
2.7.4
^ permalink raw reply related
* Re: [PATCH net-next 1/2] dpaa2-eth: defer probe on object allocate
From: Andrew Lunn @ 2018-11-09 14:16 UTC (permalink / raw)
To: Ioana Ciornei
Cc: netdev@vger.kernel.org, davem@davemloft.net,
Ioana Ciocoi Radulescu
In-Reply-To: <VI1PR0402MB28001D2F8046CE09F6EE2433E0C60@VI1PR0402MB2800.eurprd04.prod.outlook.com>
Hi Ioana
> I will send a v2 changing the return value to -ENODEV in case no
> cpus with an affine DPIO is found.
It would be good to review all the cases where IS_ERR_OR_NULL() is
used. It is very easy to get wrong. In fact, it has been suggested
this macro is removed, because it is used wrongly way too often. Try
to avoid it if you can.
Andrew
^ permalink raw reply
* RE: [PATCH net-next 1/2] dpaa2-eth: defer probe on object allocate
From: Ioana Ciornei @ 2018-11-09 14:24 UTC (permalink / raw)
To: Andrew Lunn
Cc: netdev@vger.kernel.org, davem@davemloft.net,
Ioana Ciocoi Radulescu
In-Reply-To: <20181109141634.GC1364@lunn.ch>
> Hi Ioana
>
> > I will send a v2 changing the return value to -ENODEV in case no cpus
> > with an affine DPIO is found.
>
> It would be good to review all the cases where IS_ERR_OR_NULL() is used. It is
> very easy to get wrong. In fact, it has been suggested this macro is removed,
> because it is used wrongly way too often. Try to avoid it if you can.
>
The macro is used just 2 times in the dpaa2-eth and both are part of the error path that I've reviewed and will update with a v2 of this patch.
Ioana
^ permalink raw reply
* Re: [PATCH] net: Add trace events for all receive exit points
From: Steven Rostedt @ 2018-11-09 14:24 UTC (permalink / raw)
To: Geneviève Bastien; +Cc: davem, netdev, Mathieu Desnoyers, Ingo Molnar
In-Reply-To: <20181108195648.31846-1-gbastien@versatic.net>
On Thu, 8 Nov 2018 14:56:48 -0500
Geneviève Bastien <gbastien@versatic.net> wrote:
> Trace events are already present for the receive entry points, to indicate
> how the reception entered the stack.
>
> This patch adds the corresponding exit trace events that will bound the
> reception such that all events occurring between the entry and the exit
> can be considered as part of the reception context. This greatly helps
> for dependency and root cause analyses.
>
> Without this, it is impossible to determine whether a sched_wakeup
> event following a netif_receive_skb event is the result of the packet
> reception or a simple coincidence after further processing by the
> thread.
>
> Signed-off-by: Geneviève Bastien <gbastien@versatic.net>
> CC: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
> CC: Steven Rostedt <rostedt@goodmis.org>
> CC: Ingo Molnar <mingo@redhat.com>
> CC: David S. Miller <davem@davemloft.net>
> ---
> include/trace/events/net.h | 59 ++++++++++++++++++++++++++++++++++++++
> net/core/dev.c | 30 ++++++++++++++++---
> 2 files changed, 85 insertions(+), 4 deletions(-)
>
> diff --git a/include/trace/events/net.h b/include/trace/events/net.h
> index 00aa72ce0e7c..318307511018 100644
> --- a/include/trace/events/net.h
> +++ b/include/trace/events/net.h
> @@ -117,6 +117,23 @@ DECLARE_EVENT_CLASS(net_dev_template,
> __get_str(name), __entry->skbaddr, __entry->len)
> )
>
> +DECLARE_EVENT_CLASS(net_dev_template_simple,
> +
> + TP_PROTO(struct sk_buff *skb),
> +
> + TP_ARGS(skb),
> +
> + TP_STRUCT__entry(
> + __field(void *, skbaddr)
> + ),
> +
> + TP_fast_assign(
> + __entry->skbaddr = skb;
> + ),
> +
> + TP_printk("skbaddr=%p", __entry->skbaddr)
> +)
> +
> DEFINE_EVENT(net_dev_template, net_dev_queue,
>
> TP_PROTO(struct sk_buff *skb),
> @@ -244,6 +261,48 @@ DEFINE_EVENT(net_dev_rx_verbose_template, netif_rx_ni_entry,
> TP_ARGS(skb)
> );
>
> +DEFINE_EVENT(net_dev_template_simple, napi_gro_frags_exit,
> +
> + TP_PROTO(struct sk_buff *skb),
> +
> + TP_ARGS(skb)
> +);
> +
> +DEFINE_EVENT(net_dev_template_simple, napi_gro_receive_exit,
> +
> + TP_PROTO(struct sk_buff *skb),
> +
> + TP_ARGS(skb)
> +);
> +
> +DEFINE_EVENT(net_dev_template_simple, netif_receive_skb_exit,
> +
> + TP_PROTO(struct sk_buff *skb),
> +
> + TP_ARGS(skb)
> +);
> +
> +DEFINE_EVENT(net_dev_template_simple, netif_receive_skb_list_exit,
> +
> + TP_PROTO(struct sk_buff *skb),
> +
> + TP_ARGS(skb)
> +);
> +
> +DEFINE_EVENT(net_dev_template_simple, netif_rx_exit,
> +
> + TP_PROTO(struct sk_buff *skb),
> +
> + TP_ARGS(skb)
> +);
> +
> +DEFINE_EVENT(net_dev_template_simple, netif_rx_ni_exit,
> +
> + TP_PROTO(struct sk_buff *skb),
> +
> + TP_ARGS(skb)
> +);
> +
> #endif /* _TRACE_NET_H */
>
> /* This part must be outside protection */
> diff --git a/net/core/dev.c b/net/core/dev.c
> index 0ffcbdd55fa9..e670ca27e829 100644
> --- a/net/core/dev.c
> +++ b/net/core/dev.c
> @@ -4520,9 +4520,14 @@ static int netif_rx_internal(struct sk_buff *skb)
>
> int netif_rx(struct sk_buff *skb)
> {
> + int ret;
> +
> trace_netif_rx_entry(skb);
>
> - return netif_rx_internal(skb);
> + ret = netif_rx_internal(skb);
> + trace_netif_rx_exit(skb);
> +
> + return ret;
Pretty much all the trace events have a "ret" passed by them, why not
record the ret in the trace event as well?
trace_netif_rx_exit(skb, ret);
> }
> EXPORT_SYMBOL(netif_rx);
>
> @@ -4537,6 +4542,7 @@ int netif_rx_ni(struct sk_buff *skb)
> if (local_softirq_pending())
> do_softirq();
> preempt_enable();
> + trace_netif_rx_ni_exit(skb);
>
> return err;
> }
> @@ -5222,9 +5228,14 @@ static void netif_receive_skb_list_internal(struct list_head *head)
> */
> int netif_receive_skb(struct sk_buff *skb)
> {
> + int ret;
> +
> trace_netif_receive_skb_entry(skb);
>
> - return netif_receive_skb_internal(skb);
> + ret = netif_receive_skb_internal(skb);
> + trace_netif_receive_skb_exit(skb);
> +
> + return ret;
> }
> EXPORT_SYMBOL(netif_receive_skb);
>
> @@ -5247,6 +5258,8 @@ void netif_receive_skb_list(struct list_head *head)
> list_for_each_entry(skb, head, list)
> trace_netif_receive_skb_list_entry(skb);
> netif_receive_skb_list_internal(head);
> + list_for_each_entry(skb, head, list)
> + trace_netif_receive_skb_list_exit(skb);
This needs:
if (trace_netif_receive_skb_list_exit_enabled()) {
list_for_each_entry(skb, head, list)
trace_netif_receive_skb_list_exit(skb);
}
Because we should not be doing the list walk if the trace event is not
enabled. The trace_<event>_enabled() call uses jump labels, so by
default it is a nop that just skips the code completely, and when its
enabled it is a direct jump to the list walk.
-- Steve
> }
> EXPORT_SYMBOL(netif_receive_skb_list);
>
> @@ -5634,12 +5647,17 @@ static gro_result_t napi_skb_finish(gro_result_t ret, struct sk_buff *skb)
>
> gro_result_t napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb)
> {
> + gro_result_t ret;
> +
> skb_mark_napi_id(skb, napi);
> trace_napi_gro_receive_entry(skb);
>
> skb_gro_reset_offset(skb);
>
> - return napi_skb_finish(dev_gro_receive(napi, skb), skb);
> + ret = napi_skb_finish(dev_gro_receive(napi, skb), skb);
> + trace_napi_gro_receive_exit(skb);
> +
> + return ret;
> }
> EXPORT_SYMBOL(napi_gro_receive);
>
> @@ -5753,6 +5771,7 @@ static struct sk_buff *napi_frags_skb(struct napi_struct *napi)
>
> gro_result_t napi_gro_frags(struct napi_struct *napi)
> {
> + gro_result_t ret;
> struct sk_buff *skb = napi_frags_skb(napi);
>
> if (!skb)
> @@ -5760,7 +5779,10 @@ gro_result_t napi_gro_frags(struct napi_struct *napi)
>
> trace_napi_gro_frags_entry(skb);
>
> - return napi_frags_finish(napi, skb, dev_gro_receive(napi, skb));
> + ret = napi_frags_finish(napi, skb, dev_gro_receive(napi, skb));
> + trace_napi_gro_frags_exit(skb);
> +
> + return ret;
> }
> EXPORT_SYMBOL(napi_gro_frags);
>
^ permalink raw reply
* [PATCH net-next] udp6: cleanup stats accounting in recvmsg()
From: Paolo Abeni @ 2018-11-09 14:52 UTC (permalink / raw)
To: netdev; +Cc: David S. Miller
In the udp6 code path, we needed multiple tests to select the correct
mib to be updated. Since we touch at least a counter at each iteration,
it's convenient to use the recently introduced __UDPX_MIB() helper once
and remove some code duplication.
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
net/ipv6/udp.c | 32 +++++++-------------------------
1 file changed, 7 insertions(+), 25 deletions(-)
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 0c0cb1611aef..dde51fc7ac16 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -326,6 +326,7 @@ int udpv6_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
int err;
int is_udplite = IS_UDPLITE(sk);
bool checksum_valid = false;
+ struct udp_mib *mib;
int is_udp4;
if (flags & MSG_ERRQUEUE)
@@ -349,6 +350,7 @@ int udpv6_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
msg->msg_flags |= MSG_TRUNC;
is_udp4 = (skb->protocol == htons(ETH_P_IP));
+ mib = __UDPX_MIB(sk, is_udp4);
/*
* If checksum is needed at all, try to do it while copying the
@@ -377,24 +379,13 @@ int udpv6_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
if (unlikely(err)) {
if (!peeked) {
atomic_inc(&sk->sk_drops);
- if (is_udp4)
- UDP_INC_STATS(sock_net(sk), UDP_MIB_INERRORS,
- is_udplite);
- else
- UDP6_INC_STATS(sock_net(sk), UDP_MIB_INERRORS,
- is_udplite);
+ SNMP_INC_STATS(mib, UDP_MIB_INERRORS);
}
kfree_skb(skb);
return err;
}
- if (!peeked) {
- if (is_udp4)
- UDP_INC_STATS(sock_net(sk), UDP_MIB_INDATAGRAMS,
- is_udplite);
- else
- UDP6_INC_STATS(sock_net(sk), UDP_MIB_INDATAGRAMS,
- is_udplite);
- }
+ if (!peeked)
+ SNMP_INC_STATS(mib, UDP_MIB_INDATAGRAMS);
sock_recv_ts_and_drops(msg, sk, skb);
@@ -443,17 +434,8 @@ int udpv6_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
csum_copy_err:
if (!__sk_queue_drop_skb(sk, &udp_sk(sk)->reader_queue, skb, flags,
udp_skb_destructor)) {
- if (is_udp4) {
- UDP_INC_STATS(sock_net(sk),
- UDP_MIB_CSUMERRORS, is_udplite);
- UDP_INC_STATS(sock_net(sk),
- UDP_MIB_INERRORS, is_udplite);
- } else {
- UDP6_INC_STATS(sock_net(sk),
- UDP_MIB_CSUMERRORS, is_udplite);
- UDP6_INC_STATS(sock_net(sk),
- UDP_MIB_INERRORS, is_udplite);
- }
+ SNMP_INC_STATS(mib, UDP_MIB_CSUMERRORS);
+ SNMP_INC_STATS(mib, UDP_MIB_INERRORS);
}
kfree_skb(skb);
--
2.17.2
^ permalink raw reply related
* Re: [Patch net-next 00/11] add code optimization for VF reset and some new reset feature
From: David Miller @ 2018-11-10 0:47 UTC (permalink / raw)
To: tanhuazhong; +Cc: netdev, linux-kernel, salil.mehta, yisen.zhuang, linuxarm
In-Reply-To: <1541772476-41478-1-git-send-email-tanhuazhong@huawei.com>
From: Huazhong Tan <tanhuazhong@huawei.com>
Date: Fri, 9 Nov 2018 22:07:45 +0800
> Currently hardware supports below reset:
> 1. VF reset: triggered by sending cmd to IMP(Integrated Management
> Processor). Only reset specific VF function and do not affect
> other PF or VF.
> 2. PF reset: triggered by sending cmd to IMP. Only reset specific PF
> and it's VF.
> 3. PF FLR: triggered by PCIe subsystem. Only reset specific PF and
> it's VF.
> 4. VF FLR: triggered by PCIe subsystem. Only reset specific VF function
> and do not affect other PF or VF.
> 5. Core reset: triggered by writing to register. Reset most hardware
> unit, such as SSU, which affects all the PF and VF.
> 6. Global reset: triggered by writing to register. Reset all hardware
> unit, which affects all the PF and VF.
> 7. IMP reset: triggered by IMU(Intelligent Management Unit) when
> IMP is not longer feeding IMU's watchdog. IMU will reload the IMP
> firmware and IMP will perform global reset after firmware reloading,
> which affects all the PF and VF.
>
> Current driver only support PF/VF reset, incomplete core and global
> reset(lacking the vf reset handling). So this patchset adds complete
> reset support in hns3 driver.
>
> Also, this patchset contains some optimization related to reset.
Series applied, thank you.
^ permalink raw reply
* [PATCH net-next v2 0/2] dpaa2-eth: defer probe on object allocate
From: Ioana Ciornei @ 2018-11-09 15:26 UTC (permalink / raw)
To: netdev@vger.kernel.org, davem@davemloft.net, andrew@lunn.ch
Cc: Ioana Ciocoi Radulescu, Ioana Ciornei
Allocatable objects on the fsl-mc bus may be probed by the fsl_mc_allocator
after the first attempts of other drivers to use them. Defer the probe when
this situation happens.
Changes in v2:
- proper handling of IS_ERR_OR_NULL
Ioana Ciornei (2):
dpaa2-eth: defer probe on object allocate
dpaa2-ptp: defer probe when portal allocation failed
drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 32 ++++++++++++++++--------
drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.c | 5 +++-
2 files changed, 26 insertions(+), 11 deletions(-)
--
1.9.1
^ permalink raw reply
* [PATCH net-next v2 1/2] dpaa2-eth: defer probe on object allocate
From: Ioana Ciornei @ 2018-11-09 15:26 UTC (permalink / raw)
To: netdev@vger.kernel.org, davem@davemloft.net, andrew@lunn.ch
Cc: Ioana Ciocoi Radulescu, Ioana Ciornei
In-Reply-To: <1541777182-9135-1-git-send-email-ioana.ciornei@nxp.com>
The fsl_mc_object_allocate function can fail because not all allocatable
objects are probed by the fsl_mc_allocator at the call time. Defer the
dpaa2-eth probe when this happens.
Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
---
Changes in v2:
- proper handling of IS_ERR_OR_NULL
drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 32 ++++++++++++++++--------
1 file changed, 22 insertions(+), 10 deletions(-)
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
index 88f7acc..bdfb13b 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
@@ -1434,8 +1434,11 @@ static struct fsl_mc_device *setup_dpcon(struct dpaa2_eth_priv *priv)
err = fsl_mc_object_allocate(to_fsl_mc_device(dev),
FSL_MC_POOL_DPCON, &dpcon);
if (err) {
- dev_info(dev, "Not enough DPCONs, will go on as-is\n");
- return NULL;
+ if (err == -ENXIO)
+ err = -EPROBE_DEFER;
+ else
+ dev_info(dev, "Not enough DPCONs, will go on as-is\n");
+ return ERR_PTR(err);
}
err = dpcon_open(priv->mc_io, 0, dpcon->obj_desc.id, &dpcon->mc_handle);
@@ -1493,8 +1496,10 @@ static void free_dpcon(struct dpaa2_eth_priv *priv,
return NULL;
channel->dpcon = setup_dpcon(priv);
- if (!channel->dpcon)
+ if (IS_ERR_OR_NULL(channel->dpcon)) {
+ err = PTR_ERR(channel->dpcon);
goto err_setup;
+ }
err = dpcon_get_attributes(priv->mc_io, 0, channel->dpcon->mc_handle,
&attr);
@@ -1513,7 +1518,7 @@ static void free_dpcon(struct dpaa2_eth_priv *priv,
free_dpcon(priv, channel->dpcon);
err_setup:
kfree(channel);
- return NULL;
+ return ERR_PTR(err);
}
static void free_channel(struct dpaa2_eth_priv *priv,
@@ -1547,10 +1552,11 @@ static int setup_dpio(struct dpaa2_eth_priv *priv)
for_each_online_cpu(i) {
/* Try to allocate a channel */
channel = alloc_channel(priv);
- if (!channel) {
- dev_info(dev,
- "No affine channel for cpu %d and above\n", i);
- err = -ENODEV;
+ if (IS_ERR_OR_NULL(channel)) {
+ err = PTR_ERR(channel);
+ if (err != -EPROBE_DEFER)
+ dev_info(dev,
+ "No affine channel for cpu %d and above\n", i);
goto err_alloc_ch;
}
@@ -1608,9 +1614,12 @@ static int setup_dpio(struct dpaa2_eth_priv *priv)
err_service_reg:
free_channel(priv, channel);
err_alloc_ch:
+ if (err == -EPROBE_DEFER)
+ return err;
+
if (cpumask_empty(&priv->dpio_cpumask)) {
dev_err(dev, "No cpu with an affine DPIO/DPCON\n");
- return err;
+ return -ENODEV;
}
dev_info(dev, "Cores %*pbl available for processing ingress traffic\n",
@@ -1732,7 +1741,10 @@ static int setup_dpbp(struct dpaa2_eth_priv *priv)
err = fsl_mc_object_allocate(to_fsl_mc_device(dev), FSL_MC_POOL_DPBP,
&dpbp_dev);
if (err) {
- dev_err(dev, "DPBP device allocation failed\n");
+ if (err == -ENXIO)
+ err = -EPROBE_DEFER;
+ else
+ dev_err(dev, "DPBP device allocation failed\n");
return err;
}
--
1.9.1
^ permalink raw reply related
* [PATCH net-next v2 2/2] dpaa2-ptp: defer probe when portal allocation failed
From: Ioana Ciornei @ 2018-11-09 15:26 UTC (permalink / raw)
To: netdev@vger.kernel.org, davem@davemloft.net, andrew@lunn.ch
Cc: Ioana Ciocoi Radulescu, Ioana Ciornei
In-Reply-To: <1541777182-9135-1-git-send-email-ioana.ciornei@nxp.com>
The fsl_mc_portal_allocate can fail when the requested MC portals are
not yet probed by the fsl_mc_allocator. In this situation, the driver
should defer the probe.
Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
---
Changes in v2:
- none
drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.c
index 84b942b..9b150db 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.c
@@ -140,7 +140,10 @@ static int dpaa2_ptp_probe(struct fsl_mc_device *mc_dev)
err = fsl_mc_portal_allocate(mc_dev, 0, &mc_dev->mc_io);
if (err) {
- dev_err(dev, "fsl_mc_portal_allocate err %d\n", err);
+ if (err == -ENXIO)
+ err = -EPROBE_DEFER;
+ else
+ dev_err(dev, "fsl_mc_portal_allocate err %d\n", err);
goto err_exit;
}
--
1.9.1
^ permalink raw reply related
* Re: [PATCH v4 bpf-next 2/7] libbpf: cleanup after partial failure in bpf_object__pin
From: Stanislav Fomichev @ 2018-11-09 15:41 UTC (permalink / raw)
To: Jakub Kicinski
Cc: netdev, linux-kselftest, ast, daniel, shuah, quentin.monnet, guro,
jiong.wang, sdf, bhole_prashant_q7, john.fastabend, jbenc,
treeze.taeung, yhs, osk, sandipan
In-Reply-To: <20181108193705.2933c2bc@cakuba.netronome.com>
On 11/08, Jakub Kicinski wrote:
> On Thu, 8 Nov 2018 16:22:08 -0800, Stanislav Fomichev wrote:
> > + for (map = bpf_map__prev(map, obj);
> > + map != NULL;
> > + map = bpf_map__prev(map, obj)) {
>
> nit pick: if you need to respin all these for loops on error paths could
> have been more concise while loops
Agreed with everything, will address this one and the other comments in v5.
Thank you for another thorough review!
^ permalink raw reply
* Re: [PATCH v4 bpf-next 5/7] bpftool: add loadall command
From: Stanislav Fomichev @ 2018-11-09 15:42 UTC (permalink / raw)
To: Quentin Monnet
Cc: netdev, linux-kselftest, ast, daniel, shuah, jakub.kicinski, guro,
jiong.wang, sdf, bhole_prashant_q7, john.fastabend, jbenc,
treeze.taeung, yhs, osk, sandipan
In-Reply-To: <30359d0f-40c0-27c9-cd4e-bba60c6cb138@netronome.com>
On 11/09, Quentin Monnet wrote:
> 2018-11-08 16:22 UTC-0800 ~ Stanislav Fomichev <sdf@fomichev.me>
> > From: Stanislav Fomichev <sdf@google.com>
> >
> > This patch adds new *loadall* command which slightly differs from the
> > existing *load*. *load* command loads all programs from the obj file,
> > but pins only the first programs. *loadall* pins all programs from the
> > obj file under specified directory.
> >
> > The intended usecase is flow_dissector, where we want to load a bunch
> > of progs, pin them all and after that construct a jump table.
> >
> > Signed-off-by: Stanislav Fomichev <sdf@google.com>
> > ---
> > .../bpftool/Documentation/bpftool-prog.rst | 14 +++-
> > tools/bpf/bpftool/bash-completion/bpftool | 4 +-
> > tools/bpf/bpftool/common.c | 31 ++++----
> > tools/bpf/bpftool/main.h | 1 +
> > tools/bpf/bpftool/prog.c | 74 ++++++++++++++-----
> > 5 files changed, 82 insertions(+), 42 deletions(-)
> >
> > diff --git a/tools/bpf/bpftool/Documentation/bpftool-prog.rst b/tools/bpf/bpftool/Documentation/bpftool-prog.rst
> > index ac4e904b10fb..d943d9b67a1d 100644
> > --- a/tools/bpf/bpftool/Documentation/bpftool-prog.rst
> > +++ b/tools/bpf/bpftool/Documentation/bpftool-prog.rst
>
> > @@ -24,7 +25,7 @@ MAP COMMANDS
> > | **bpftool** **prog dump xlated** *PROG* [{**file** *FILE* | **opcodes** | **visual**}]
> > | **bpftool** **prog dump jited** *PROG* [{**file** *FILE* | **opcodes**}]
> > | **bpftool** **prog pin** *PROG* *FILE*
> > -| **bpftool** **prog load** *OBJ* *FILE* [**type** *TYPE*] [**map** {**idx** *IDX* | **name** *NAME*} *MAP*] [**dev** *NAME*]
> > +| **bpftool** **prog { load | loadall }** *OBJ* *FILE* [**type** *TYPE*] [**map** {**idx** *IDX* | **name** *NAME*} *MAP*] [**dev** *NAME*]
> > | **bpftool** **prog attach** *PROG* *ATTACH_TYPE* *MAP*
> > | **bpftool** **prog detach** *PROG* *ATTACH_TYPE* *MAP*
> > | **bpftool** **prog help**
> > @@ -79,8 +80,13 @@ DESCRIPTION
> > contain a dot character ('.'), which is reserved for future
> > extensions of *bpffs*.
> >
> > - **bpftool prog load** *OBJ* *FILE* [**type** *TYPE*] [**map** {**idx** *IDX* | **name** *NAME*} *MAP*] [**dev** *NAME*]
> > - Load bpf program from binary *OBJ* and pin as *FILE*.
> > + **bpftool prog { load | loadall }** *OBJ* *FILE* [**type** *TYPE*] [**map** {**idx** *IDX* | **name** *NAME*} *MAP*] [**dev** *NAME*]
> > + Load bpf program(s) from binary *OBJ* and pin as *FILE*.
> > + Both **bpftool prog load** and **bpftool prog loadall** load
> > + all maps and programs from the *OBJ* and differ only in
> > + pinning. **load** pins only the first program from the *OBJ*
> > + as *FILE*. **loadall** pins all programs from the *OBJ*
> > + under *FILE* directory.
> > **type** is optional, if not specified program type will be
> > inferred from section names.
> > By default bpftool will create new maps as declared in the ELF
>
> Thanks a lot for all the changes! The series looks really good to me
> now. The last nit I might have is that we could maybe replace "FILE"
> with "PATH" (as it can now be a directory), in the doc an below. No need
> to respin just for this, though.
Agreed, makes sense, will do another respin to address Jakub's comments
anyway. Thanks for a review!
> > @@ -1035,7 +1067,8 @@ static int do_help(int argc, char **argv)
> > " %s %s dump xlated PROG [{ file FILE | opcodes | visual }]\n"
> > " %s %s dump jited PROG [{ file FILE | opcodes }]\n"
> > " %s %s pin PROG FILE\n"
> > - " %s %s load OBJ FILE [type TYPE] [dev NAME] \\\n"
> > + " %s %s { load | loadall } OBJ FILE \\\n"
> > + " [type TYPE] [dev NAME] \\\n"
> > " [map { idx IDX | name NAME } MAP]\n"
> > " %s %s attach PROG ATTACH_TYPE MAP\n"
> > " %s %s detach PROG ATTACH_TYPE MAP\n"
^ permalink raw reply
* Re: [PATCH iproute2] bridge: fdb: remove redundant dev string in show output
From: Stephen Hemminger @ 2018-11-09 15:54 UTC (permalink / raw)
To: Phil Sutter; +Cc: Roopa Prabhu, netdev, nikolay, dsahern
In-Reply-To: <20181108093505.GK6440@orbyte.nwl.cc>
On Thu, 8 Nov 2018 10:35:05 +0100
Phil Sutter <phil@nwl.cc> wrote:
> Hi Roopa,
>
> On Wed, Nov 07, 2018 at 03:14:09PM -0800, Roopa Prabhu wrote:
> > From: Roopa Prabhu <roopa@cumulusnetworks.com>
> >
> > After commit 4abb8c723a64 ("bridge: fdb: Fix for missing
> > keywords in non-JSON output"), I am seeing a double print for dev
> > in bridge fdb show. eg:
> > "44:38:39:00:6a:82 dev dev bridge vlan 1 master bridge permanent"
> >
> > this patch removes the redundant print.
> >
> > Fixes: 4abb8c723a64 ("bridge: fdb: Fix for missing keywords in non-JSON output")
Applied.
^ permalink raw reply
* Re: Should the bridge learn from frames with link local destination MAC address?
From: Stephen Hemminger @ 2018-11-09 16:00 UTC (permalink / raw)
To: Andrew Lunn; +Cc: Roopa Prabhu, Nikolay Aleksandrov, netdev, Florian Fainelli
In-Reply-To: <20181109032443.GA23331@lunn.ch>
On Fri, 9 Nov 2018 04:24:43 +0100
Andrew Lunn <andrew@lunn.ch> wrote:
> Hi Roopa, Nikolay
>
> br_handle_frame() looks out for frames with a destination MAC
> addresses with is Ethernet link local, those which fit
> 01-80-C2-00-00-XX. It does not normally forward these, but it will
> deliver them locally.
>
> Should the bridge perform learning on such frames?
>
> I've got a setup with two bridges connected together with multiple
> links between them. STP has done its thing, and blocked one of the
> ports to solve the loop.
>
> host0 host1
> +-----------------+ +-----------------+
> | lan0 forwarding |-----| lan0 forwarding |
> | | | |
> | lan1 forwarding |-----| lan1 blocked |
> +-----------------+ +-----------------+
>
> I have LLDP running on both system, and they are sending out periodic
> frames on each port.
>
> Now, lan0 and lan1 on host1 use the same MAC address. So i see the
> MAC address bouncing between ports because of the LLDP packets.
>
> # bridge monitor
> 00:26:55:d2:27:a8 dev lan1 master br0
> 00:26:55:d2:27:a8 dev lan0 master br0
> 00:26:55:d2:27:a8 dev lan1 master br0
> 00:26:55:d2:27:a8 dev lan0 master br0
> 00:26:55:d2:27:a8 dev lan1 master br0
>
> This then results in normal traffic from host0 to host1 being sent to
> the blocked port for some of the time.
>
> LLDP is using 01-80-C2-00-00-0E, a link local MAC address. If the
> bridge did not learn on such frames, i think this setup would
> work. The bridge would learn from ARP, IP etc, coming from the
> forwarding port of host1, and the blocked port would be ignored.
>
> I've tried a similar setup with a hardware switch, Marvell 6352. It
> never seems to learn from such frames.
>
> Thanks
> Andrew
I agree with your analysis. A properly operating 802 compliant bridge
should not learn link local addresses. But changing that in Linux bridge
would probably break some users. There is already a hack to forward link
local frames. There are many usages of Linux vswitch where this behavior
might be a problem:
1. a container or VM hub
2. bump in the wire filter
3. L2 nat etc.
So what ever you decide it has to be optional and unfortunately default
to off.
^ permalink raw reply
* Re: bring back IPX and NCPFS, please!
From: Stephen Hemminger @ 2018-11-09 16:01 UTC (permalink / raw)
To: Johannes C. Schulz; +Cc: netdev
In-Reply-To: <CAFfL_owvKC2rBz6U=aomgbJzKLu-x+RFDSwMQKKj8=DJ5Mdm=Q@mail.gmail.com>
On Fri, 9 Nov 2018 14:23:27 +0100
"Johannes C. Schulz" <enzephalon76@googlemail.com> wrote:
> Hello all!
>
> I like to please you to bring back IPX and NCPFS modules to the kernel.
> Whyever my admins using Novell-shares on our network which I'm not be
> able to use anymore - I'm forced to use cifs instead (and the admins
> will kill the cifs-shares in some time), because my kernel (4.18) does
> not have support for ncpfs anymore.
> Maybe we at my work are not enough people that just for us this
> modules will come back, but maybe out there are other people.
> Thank you.
Are you willing to sign up to maintain it, test it and fix bugs?
^ permalink raw reply
* Re: [PATCH iproute2] bridge: fdb: remove redundant dev string in show output
From: Stephen Hemminger @ 2018-11-09 16:05 UTC (permalink / raw)
To: Roopa Prabhu; +Cc: netdev, phil, nikolay, dsahern
In-Reply-To: <1541632449-9993-1-git-send-email-roopa@cumulusnetworks.com>
On Wed, 7 Nov 2018 15:14:09 -0800
Roopa Prabhu <roopa@cumulusnetworks.com> wrote:
> From: Roopa Prabhu <roopa@cumulusnetworks.com>
>
> After commit 4abb8c723a64 ("bridge: fdb: Fix for missing
> keywords in non-JSON output"), I am seeing a double print for dev
> in bridge fdb show. eg:
> "44:38:39:00:6a:82 dev dev bridge vlan 1 master bridge permanent"
>
> this patch removes the redundant print.
>
> Fixes: 4abb8c723a64 ("bridge: fdb: Fix for missing keywords in non-JSON output")
> CC: Phil Sutter <phil@nwl.cc>
> Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
Applied, thanks.
^ permalink raw reply
* Re: [PATCH iproute2] man: ss.8: break and indent long line
From: Stephen Hemminger @ 2018-11-09 16:06 UTC (permalink / raw)
To: Luca Boccassi; +Cc: netdev, dsahern
In-Reply-To: <20181102132748.22178-1-bluca@debian.org>
On Fri, 2 Nov 2018 13:27:48 +0000
Luca Boccassi <bluca@debian.org> wrote:
> Fixes groff warning:
> ss.8 92: warning [p 2, 2.8i]: can't break line
>
> And makes the line also more readable.
>
> Signed-off-by: Luca Boccassi <bluca@debian.org>
Applied
^ permalink raw reply
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