* [PATCH][net-next][V2] mlxsw: spectrum_ptp: fix duplicated check on orig_egr_types
From: Colin King @ 2019-07-30 11:47 UTC (permalink / raw)
To: Petr Machata, Jiri Pirko, Ido Schimmel, David S . Miller, netdev
Cc: kernel-janitors, linux-kernel
From: Colin Ian King <colin.king@canonical.com>
Currently are duplicated checks on orig_egr_types which are
redundant, I believe this is a typo and should actually be
orig_ing_types || orig_egr_types instead of the expression
orig_egr_types || orig_egr_types. Fix these.
Addresses-Coverity: ("Same on both sides")
Fixes: c6b36bdd04b5 ("mlxsw: spectrum_ptp: Increase parsing depth when PTP is enabled")
Signed-off-by: Colin Ian King <colin.king@canonical.com>
---
drivers/net/ethernet/mellanox/mlxsw/spectrum_ptp.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_ptp.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_ptp.c
index 98c5ba3200bc..63b07edd9d81 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_ptp.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_ptp.c
@@ -999,14 +999,14 @@ static int mlxsw_sp1_ptp_mtpppc_update(struct mlxsw_sp_port *mlxsw_sp_port,
}
}
- if ((ing_types || egr_types) && !(orig_egr_types || orig_egr_types)) {
+ if ((ing_types || egr_types) && !(orig_ing_types || orig_egr_types)) {
err = mlxsw_sp_nve_inc_parsing_depth_get(mlxsw_sp);
if (err) {
netdev_err(mlxsw_sp_port->dev, "Failed to increase parsing depth");
return err;
}
}
- if (!(ing_types || egr_types) && (orig_egr_types || orig_egr_types))
+ if (!(ing_types || egr_types) && (orig_ing_types || orig_egr_types))
mlxsw_sp_nve_inc_parsing_depth_put(mlxsw_sp);
return mlxsw_sp1_ptp_mtpppc_set(mlxsw_sp_port->mlxsw_sp,
--
V2: fix both occurances of this typo. Thanks to Petr Machata for spotting
the 2nd occurrance
--
2.20.1
^ permalink raw reply related
* [PATCH] net: stmmac: Use netif_tx_napi_add() for TX polling function
From: Bartosz Golaszewski @ 2019-07-30 11:38 UTC (permalink / raw)
To: Giuseppe Cavallaro, Alexandre Torgue, Jose Abreu,
David S . Miller, Maxime Coquelin
Cc: netdev, linux-stm32, linux-arm-kernel, linux-kernel,
Frode Isaksen, Bartosz Golaszewski
From: Frode Isaksen <fisaksen@baylibre.com>
This variant of netif_napi_add() should be used from drivers
using NAPI to exclusively poll a TX queue.
Signed-off-by: Frode Isaksen <fisaksen@baylibre.com>
Tested-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 98b1a5c6d537..390dad5b9819 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -4313,8 +4313,9 @@ int stmmac_dvr_probe(struct device *device,
NAPI_POLL_WEIGHT);
}
if (queue < priv->plat->tx_queues_to_use) {
- netif_napi_add(ndev, &ch->tx_napi, stmmac_napi_poll_tx,
- NAPI_POLL_WEIGHT);
+ netif_tx_napi_add(ndev, &ch->tx_napi,
+ stmmac_napi_poll_tx,
+ NAPI_POLL_WEIGHT);
}
}
--
2.21.0
^ permalink raw reply related
* Re: [PATCH][next] mlxsw: spectrum_ptp: fix duplicated check on orig_egr_types
From: Colin Ian King @ 2019-07-30 11:37 UTC (permalink / raw)
To: Petr Machata
Cc: Jiri Pirko, Ido Schimmel, David S . Miller,
netdev@vger.kernel.org, kernel-janitors@vger.kernel.org,
linux-kernel@vger.kernel.org
In-Reply-To: <87imrjzsgu.fsf@mellanox.com>
On 30/07/2019 12:12, Petr Machata wrote:
>
> Petr Machata <petrm@mellanox.com> writes:
>
>> Colin King <colin.king@canonical.com> writes:
>>
>>> From: Colin Ian King <colin.king@canonical.com>
>>>
>>> Currently there is a duplicated check on orig_egr_types which is
>>> redundant, I believe this is a typo and should actually be
>>> orig_ing_types || orig_egr_types instead of the expression
>>> orig_egr_types || orig_egr_types. Fix this.
>>
>> Good catch, yes, there's a typo. Thanks for the fix!
>>
>>> Addresses-Coverity: ("Same on both sides")
>>> Fixes: c6b36bdd04b5 ("mlxsw: spectrum_ptp: Increase parsing depth when PTP is enabled")
>>> Signed-off-by: Colin Ian King <colin.king@canonical.com>
>>
>> Reviewed-by: Petr Machata <petrm@mellanox.com>
>
> I see that there is an identical problem in the code one block further.
> Can you take care of that as well, please? Or should I do it?
>
I'll sort that out too
^ permalink raw reply
* [PATCH net-next] be2net: disable bh with spin_lock in be_process_mcc
From: Denis Kirjanov @ 2019-07-30 11:32 UTC (permalink / raw)
To: sathya.perla, ajit.khaparde, sriharsha.basavapatna; +Cc: netdev, Denis Kirjanov
Signed-off-by: Denis Kirjanov <kdav@linux-powerpc.org>
---
drivers/net/ethernet/emulex/benet/be_cmds.c | 4 ++--
drivers/net/ethernet/emulex/benet/be_main.c | 2 --
2 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
index ef5d61d57597..9365218f4d3b 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
@@ -550,7 +550,7 @@ int be_process_mcc(struct be_adapter *adapter)
int num = 0, status = 0;
struct be_mcc_obj *mcc_obj = &adapter->mcc_obj;
- spin_lock(&adapter->mcc_cq_lock);
+ spin_lock_bh(&adapter->mcc_cq_lock);
while ((compl = be_mcc_compl_get(adapter))) {
if (compl->flags & CQE_FLAGS_ASYNC_MASK) {
@@ -566,7 +566,7 @@ int be_process_mcc(struct be_adapter *adapter)
if (num)
be_cq_notify(adapter, mcc_obj->cq.id, mcc_obj->rearm_cq, num);
- spin_unlock(&adapter->mcc_cq_lock);
+ spin_unlock_bh(&adapter->mcc_cq_lock);
return status;
}
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index 2edb86ec9fe9..4d8e40ac66d2 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -5630,9 +5630,7 @@ static void be_worker(struct work_struct *work)
* mcc completions
*/
if (!netif_running(adapter->netdev)) {
- local_bh_disable();
be_process_mcc(adapter);
- local_bh_enable();
goto reschedule;
}
--
2.12.3
^ permalink raw reply related
* [PATCH net] net: bridge: mcast: don't delete permanent entries when fast leave is enabled
From: Nikolay Aleksandrov @ 2019-07-30 11:21 UTC (permalink / raw)
To: netdev; +Cc: davem, roopa, bridge, Nikolay Aleksandrov
When permanent entries were introduced by the commit below, they were
exempt from timing out and thus igmp leave wouldn't affect them unless
fast leave was enabled on the port which was added before permanent
entries existed. It shouldn't matter if fast leave is enabled or not
if the user added a permanent entry it shouldn't be deleted on igmp
leave.
Before:
$ echo 1 > /sys/class/net/eth4/brport/multicast_fast_leave
$ bridge mdb add dev br0 port eth4 grp 229.1.1.1 permanent
$ bridge mdb show
dev br0 port eth4 grp 229.1.1.1 permanent
< join and leave 229.1.1.1 on eth4 >
$ bridge mdb show
$
After:
$ echo 1 > /sys/class/net/eth4/brport/multicast_fast_leave
$ bridge mdb add dev br0 port eth4 grp 229.1.1.1 permanent
$ bridge mdb show
dev br0 port eth4 grp 229.1.1.1 permanent
< join and leave 229.1.1.1 on eth4 >
$ bridge mdb show
dev br0 port eth4 grp 229.1.1.1 permanent
Fixes: ccb1c31a7a87 ("bridge: add flags to distinguish permanent mdb entires")
Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
---
I'll re-work this code in net-next as there's a lot of duplication.
net/bridge/br_multicast.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
index 3d8deac2353d..f8cac3702712 100644
--- a/net/bridge/br_multicast.c
+++ b/net/bridge/br_multicast.c
@@ -1388,6 +1388,9 @@ br_multicast_leave_group(struct net_bridge *br,
if (!br_port_group_equal(p, port, src))
continue;
+ if (p->flags & MDB_PG_FLAGS_PERMANENT)
+ break;
+
rcu_assign_pointer(*pp, p->next);
hlist_del_init(&p->mglist);
del_timer(&p->timer);
--
2.21.0
^ permalink raw reply related
* Re: [PATCH] net: bridge: Allow bridge to joing multicast groups
From: Allan W. Nielsen @ 2019-07-30 11:23 UTC (permalink / raw)
To: Nikolay Aleksandrov
Cc: Ido Schimmel, Horatiu Vultur, roopa, davem, bridge, netdev,
linux-kernel
In-Reply-To: <5b0c92cd-f78a-a504-4730-c07268366e21@cumulusnetworks.com>
The 07/30/2019 12:55, Nikolay Aleksandrov wrote:
> On 30/07/2019 12:21, Allan W. Nielsen wrote:
> > The 07/30/2019 11:58, Nikolay Aleksandrov wrote:
> >> On 30/07/2019 11:30, Allan W. Nielsen wrote:
> >>> The 07/30/2019 10:06, Ido Schimmel wrote:
> >>>> On Tue, Jul 30, 2019 at 08:27:22AM +0200, Allan W. Nielsen wrote:
> >>>>> The 07/29/2019 20:51, Ido Schimmel wrote:
> >>>>>> Can you please clarify what you're trying to achieve? I just read the
> >>>>>> thread again and my impression is that you're trying to locally receive
> >>>>>> packets with a certain link layer multicast address.
> >>>>> Yes. The thread is also a bit confusing because we half way through realized
> >>>>> that we misunderstood how the multicast packets should be handled (sorry about
> >>>>> that). To begin with we had a driver where multicast packets was only copied to
> >>>>> the CPU if someone needed it. Andrew and Nikolay made us aware that this is not
> >>>>> how other drivers are doing it, so we changed the driver to include the CPU in
> >>>>> the default multicast flood-mask.
> >>>> OK, so what prevents you from removing all other ports from the
> >>>> flood-mask and letting the CPU handle the flooding? Then you can install
> >>>> software tc filters to limit the flooding.
> >>> I do not have the bandwidth to forward the multicast traffic in the CPU.
> >>>
> >>> It will also cause enormous latency on the forwarding of L2 multicast packets.
> >>>
> >>>>> This changes the objective a bit. To begin with we needed to get more packets to
> >>>>> the CPU (which could have been done using tc ingress rules and a trap action).
> >>>>>
> >>>>> Now after we changed the driver, we realized that we need something to limit the
> >>>>> flooding of certain L2 multicast packets. This is the new problem we are trying
> >>>>> to solve!
> >>>>>
> >>>>> Example: Say we have a bridge with 4 slave interfaces, then we want to install a
> >>>>> forwarding rule saying that packets to a given L2-multicast MAC address, should
> >>>>> only be flooded to 2 of the 4 ports.
> >>>>>
> >>>>> (instead of adding rules to get certain packets to the CPU, we are now adding
> >>>>> other rules to prevent other packets from going to the CPU and other ports where
> >>>>> they are not needed/wanted).
> >>>>>
> >>>>> This is exactly the same thing as IGMP snooping does dynamically, but only for
> >>>>> IP multicast.
> >>>>>
> >>>>> The "bridge mdb" allow users to manually/static add/del a port to a multicast
> >>>>> group, but still it operates on IP multicast address (not L2 multicast
> >>>>> addresses).
> >>>>>
> >>>>>> Nik suggested SIOCADDMULTI.
> >>>>> It is not clear to me how this should be used to limit the flooding, maybe we
> >>>>> can make some hacks, but as far as I understand the intend of this is maintain
> >>>>> the list of addresses an interface should receive. I'm not sure this should
> >>>>> influence how for forwarding decisions are being made.
> >>>>>
> >>>>>> and I suggested a tc filter to get the packet to the CPU.
> >>>>> The TC solution is a good solution to the original problem where wanted to copy
> >>>>> more frames to the CPU. But we were convinced that this is not the right
> >>>>> approach, and that the CPU by default should receive all multicast packets, and
> >>>>> we should instead try to find a way to limit the flooding of certain frames as
> >>>>> an optimization.
> >>>>
> >>>> This can still work. In Linux, ingress tc filters are executed before the
> >>>> bridge's Rx handler. The same happens in every sane HW. Ingress ACL is
> >>>> performed before L2 forwarding. Assuming you have eth0-eth3 bridged and
> >>>> you want to prevent packets with DMAC 01:21:6C:00:00:01 from egressing
> >>>> eth2:
> >>>>
> >>>> # tc filter add dev eth0 ingress pref 1 flower skip_sw \
> >>>> dst_mac 01:21:6C:00:00:01 action trap
> >>>> # tc filter add dev eth2 egress pref 1 flower skip_hw \
> >>>> dst_mac 01:21:6C:00:00:01 action drop
> >>>>
> >>>> The first filter is only present in HW ('skip_sw') and should result in
> >>>> your HW passing you the sole copy of the packet.
> >>> Agree.
> >>>
> >>>> The second filter is only present in SW ('skip_hw', not using HW egress
> >>>> ACL that you don't have) and drops the packet after it was flooded by
> >>>> the SW bridge.
> >>> Agree.
> >>>
> >>>> As I mentioned earlier, you can install the filter once in your HW and
> >>>> share it between different ports using a shared block. This means you
> >>>> only consume one TCAM entry.
> >>>>
> >>>> Note that this allows you to keep flooding all other multicast packets
> >>>> in HW.
> >>> Yes, but the frames we want to limit the flood-mask on are the exact frames
> >>> which occurs at a very high rate, and where latency is important.
> >>>
> >>> I really do not consider it as an option to forward this in SW, when it is
> >>> something that can easily be offloaded in HW.
> >>>
> >>>>>> If you now want to limit the ports to which this packet is flooded, then
> >>>>>> you can use tc filters in *software*:
> >>>>>>
> >>>>>> # tc qdisc add dev eth2 clsact
> >>>>>> # tc filter add dev eth2 egress pref 1 flower skip_hw \
> >>>>>> dst_mac 01:21:6C:00:00:01 action drop
> >>>>> Yes. This can work in the SW bridge.
> >>>>>
> >>>>>> If you want to forward the packet in hardware and locally receive it,
> >>>>>> you can chain several mirred action and then a trap action.
> >>>>> I'm not I fully understand how this should be done, but it does sound like it
> >>>>> becomes quite complicated. Also, as far as I understand it will mean that we
> >>>>> will be using TCAM/ACL resources to do something that could have been done with
> >>>>> a simple MAC entry.
> >>>>>
> >>>>>> Both options avoid HW egress ACLs which your design does not support.
> >>>>> True, but what is wrong with expanding the functionality of the normal
> >>>>> forwarding/MAC operations to allow multiple destinations?
> >>>>>
> >>>>> It is not an uncommon feature (I just browsed the manual of some common L2
> >>>>> switches and they all has this feature).
> >>>>>
> >>>>> It seems to fit nicely into the existing user-interface:
> >>>>>
> >>>>> bridge fdb add 01:21:6C:00:00:01 port eth0
> >>>>> bridge fdb append 01:21:6C:00:00:01 port eth1
> >>>>
> >>>> Wouldn't it be better to instead extend the MDB entries so that they are
> >>>> either keyed by IP or MAC? I believe FDB should remain as unicast-only.
> >>>
> >>> You might be right, it was not clear to me which of the two would fit the
> >>> purpose best.
> >>>
> >>> From a user-space iproute2 perspective I prefer using the "bridge fdb" command
> >>> as it already supports the needed syntax, and I do not think it will be too
> >>> pretty if we squeeze this into the "bridge mdb" command syntax.
> >>>
> >>
> >> MDB is a much better fit as Ido already suggested. FDB should remain unicast
> >> and mixing them is not a good idea, we already have a good ucast/mcast separation
> >> and we'd like to keep it that way.
> > Okay. We will explore that option.
> >
> >
> Great, thanks.
>
> >>> But that does not mean that it need to go into the FDB database in the
> >>> implementation.
> >>>
> >>> Last evening when I looked at it again, I was considering keeping the
> >>> net_bridge_fdb_entry structure as is, and add a new hashtable with the
> >>> following:
> >>>
> >>> struct net_bridge_fdbmc_entry {
> >>> struct rhash_head rhnode;
> >>> struct net_bridge_fdbmc_ports *dst;
> >>>
> >>> struct net_bridge_fdb_key key;
> >>> struct hlist_node fdb_node;
> >>> unsigned char offloaded:1;
> >>>
> >>> struct rcu_head rcu;
> >>> };
> >>>
> >>
> >> What would the notification for this look like ?
> > Not sure. But we will change the direction and use the MDB structures instead.
> >
>
> Ack
>
> >>> If we go with this approach then we can look at the MAC address and see if it is
> >>> a unicast which will cause a lookup in the fdb, l3-multicast (33:33:* or
> >>> 01:00:5e:*) which will cause a lookup in the mdb, or finally a fdbmc which will
> >>> need to do a lookup in this new hashtable.
> >>
> >> That sounds wrong, you will change the current default behaviour of flooding these
> >> packets. This will have to be well hidden behind a new option and enabled only on user
> >> request.
> > It will only affect users who install a static L2-multicast entry. If no entry
> > is found, it will default to flooding, which will be the same as before.
> >
>
> Ack
>
> >>> Alternative it would be like this:
> >>>
> >>> struct net_bridge_fdb_entry {
> >>> struct rhash_head rhnode;
> >>> union net_bridge_port_or_list *dst;
> >>>
> >>> struct net_bridge_fdb_key key;
> >>> struct hlist_node fdb_node;
> >>> unsigned char is_local:1,
> >>> is_static:1,
> >>> is_sticky:1,
> >>> added_by_user:1,
> >>> added_by_external_learn:1,
> >>> offloaded:1;
> >>> multi_dst:1;
> >>>
> >>> /* write-heavy members should not affect lookups */
> >>> unsigned long updated ____cacheline_aligned_in_smp;
> >>> unsigned long used;
> >>>
> >>> struct rcu_head rcu;
> >>> };
> >>>
> >>> Both solutions should require fairly few changes, and should not cause any
> >>> measurable performance hit.
> >>>
> >>
> >> You'll have to convert these bits to use the proper atomic bitops if you go with
> >> the second solution. That has to be done even today, but the second case would
> >> make it a must.
> > Good to know.
> >
> > Just for my understanding, is this because this is the "current" guide lines on
> > how things should be done, or is this because the multi_dst as a special need.
> >
> > The multi_dst flag will never be changed in the life-cycle of the structure, and
> > the structure is protected by rcu. If this is causeing a raise, then I do not
> > see it.
> >
>
> These flags are changed from different contexts without any locking and you can end
> up with wrong values since these are not atomic ops. We need to move to atomic ops
> to guarantee consistent results. It is not only multi_dst issue, it's a problem
> for all of them, it's just not critical today since you'll end up with wrong
> flag values in such cases, but with multi_dst it will be important because the union
> pointer will have to be treated different based on the multi_dst value.
Okay, thanks for explaining.
> >>> Making it fit into the net_bridge_mdb_entry seems to be harder.
> >>>
> >>
> >> But it is the correct abstraction from bridge POV, so please stop trying to change
> >> the FDB code and try to keep to the multicast code.
> > We are planning on letting the net_bridge_port_or_list union use the
> > net_bridge_port_group structure, which will mean that we can re-use the
> > br_multicast_flood function (if we change the signatire to accept the ports
> > instead of the entry).
> >
>
> That sounds great, definitely a step in the right direction.
>
> >>>> As a bonus, existing drivers could benefit from it, as MDB entries are already
> >>>> notified by MAC.
> >>> Not sure I follow. When FDB entries are added, it also generates notification
> >>> events.
> >>>
> >>
> >> Could you please show fdb event with multiple ports ?
> > We will get to that. Maybe this is an argument for converting to mdb. We have
> > not looked into the details of this yet.
> I can see a few potential problems, the important thing here would be to keep
> backwards compatibility.
Okay, good to be aware of
> >>>>> It seems that it can be added to the existing implementation with out adding
> >>>>> significant complexity.
> >>>>>
> >>>>> It will be easy to offload in HW.
> >>>>>
> >>>>> I do not believe that it will be a performance issue, if this is a concern then
> >>>>> we may have to do a bit of benchmarking, or we can make it a configuration
> >>>>> option.
> >>>>>
> >>>>> Long story short, we (Horatiu and I) learned a lot from the discussion here, and
> >>>>> I think we should try do a new patch with the learning we got. Then it is easier
> >>>>> to see what it actually means to the exiting code, complexity, exiting drivers,
> >>>>> performance, default behavioral, backwards compatibly, and other valid concerns.
> >>>>>
> >>>>> If the patch is no good, and cannot be fixed, then we will go back and look
> >>>>> further into alternative solutions.
> >>>> Overall, I tend to agree with Nik. I think your use case is too specific
> >>>> to justify the amount of changes you want to make in the bridge driver.
> >>>> We also provided other alternatives. That being said, you're more than
> >>>> welcome to send the patches and we can continue the discussion then.
> >>> Okay, good to know. I'm not sure I agree that the alternative solutions really
> >>> solves the issue this is trying to solve, nor do I agree that this is specific
> >>> to our needs.
> >>>
> >>> But lets take a look at a new patch, and see what is the amount of changes we
> >>> are talking about. Without having the patch it is really hard to know for sure.
> >> Please keep in mind that this case is the exception, not the norm, thus it should
> >> not under any circumstance affect the standard deployments.
> > Understood - no surprises.
> >
>
> Great, thanks again. Will continue discussing when the new patch arrives.
Sure, looking forward to that.
/Allan
^ permalink raw reply
* Re: [PATCH nf] netfilter: nf_tables: map basechain priority to hardware priority
From: Pablo Neira Ayuso @ 2019-07-30 11:19 UTC (permalink / raw)
To: netfilter-devel
Cc: wenxu, jiri, marcelo.leitner, saeedm, gerlitz.or, paulb, netdev
In-Reply-To: <20190730111800.yhtd5pgd32wyfilt@salvia>
On Tue, Jul 30, 2019 at 01:18:00PM +0200, Pablo Neira Ayuso wrote:
> On Tue, Jul 30, 2019 at 12:54:17PM +0200, Pablo Neira Ayuso wrote:
> [...]
> > @@ -180,6 +181,29 @@ static int nft_setup_cb_call(struct nft_base_chain *basechain,
> > return 0;
> > }
> >
> > +/* Available priorities for hardware offload range: -8192..8191 */
> > +#define NFT_BASECHAIN_OFFLOAD_PRIO_MAX (SHRT_MAX / 4)
> > +#define NFT_BASECHAIN_OFFLOAD_PRIO_MIN (SHRT_MIN / 4)
> > +#define NFT_BASECHAIN_OFFLOAD_PRIO_RANGE (USHRT_MAX / 4)
> > +/* tcf_auto_prio() uses 0xC000 as base, then subtract one for each new chain. */
> > +#define NFT_BASECHAIN_OFFLOAD_HW_PRIO_BASE (0xC000 + 1)
> > +
> > +u16 nft_chain_offload_priority(struct nft_base_chain *basechain)
> > +{
> > + u16 prio;
> > +
> > + if (basechain->ops.priority < NFT_BASECHAIN_OFFLOAD_PRIO_MIN ||
> > + basechain->ops.priority > NFT_BASECHAIN_OFFLOAD_PRIO_MAX)
> > + return 0;
> > +
> > + /* map netfilter chain priority to hardware priority. */
> > + prio = basechain->ops.priority +
> > + NFT_BASECHAIN_OFFLOAD_PRIO_MAX +
> > + NFT_BASECHAIN_OFFLOAD_HW_PRIO_BASE;
> > +
> > + return prio;
>
> This function should actually return:
>
> return prio << 16;
Better shift it from here:
static void nft_flow_offload_common_init(struct flow_cls_common_offload *common,
__be16 proto, int priority,
struct netlink_ext_ack *extack)
{
common->protocol = proto;
common->prio = priority << 16;
common->extack = extack;
}
Drivers assume tc handle format.
^ permalink raw reply
* Re: [PATCH nf] netfilter: nf_tables: map basechain priority to hardware priority
From: Pablo Neira Ayuso @ 2019-07-30 11:18 UTC (permalink / raw)
To: netfilter-devel
Cc: wenxu, jiri, marcelo.leitner, saeedm, gerlitz.or, paulb, netdev
In-Reply-To: <20190730105417.14538-1-pablo@netfilter.org>
On Tue, Jul 30, 2019 at 12:54:17PM +0200, Pablo Neira Ayuso wrote:
[...]
> @@ -180,6 +181,29 @@ static int nft_setup_cb_call(struct nft_base_chain *basechain,
> return 0;
> }
>
> +/* Available priorities for hardware offload range: -8192..8191 */
> +#define NFT_BASECHAIN_OFFLOAD_PRIO_MAX (SHRT_MAX / 4)
> +#define NFT_BASECHAIN_OFFLOAD_PRIO_MIN (SHRT_MIN / 4)
> +#define NFT_BASECHAIN_OFFLOAD_PRIO_RANGE (USHRT_MAX / 4)
> +/* tcf_auto_prio() uses 0xC000 as base, then subtract one for each new chain. */
> +#define NFT_BASECHAIN_OFFLOAD_HW_PRIO_BASE (0xC000 + 1)
> +
> +u16 nft_chain_offload_priority(struct nft_base_chain *basechain)
> +{
> + u16 prio;
> +
> + if (basechain->ops.priority < NFT_BASECHAIN_OFFLOAD_PRIO_MIN ||
> + basechain->ops.priority > NFT_BASECHAIN_OFFLOAD_PRIO_MAX)
> + return 0;
> +
> + /* map netfilter chain priority to hardware priority. */
> + prio = basechain->ops.priority +
> + NFT_BASECHAIN_OFFLOAD_PRIO_MAX +
> + NFT_BASECHAIN_OFFLOAD_HW_PRIO_BASE;
> +
> + return prio;
This function should actually return:
return prio << 16;
> +}
> +
> static int nft_flow_offload_rule(struct nft_trans *trans,
> enum flow_cls_command command)
> {
^ permalink raw reply
* Re: [PATCH][next] mlxsw: spectrum_ptp: fix duplicated check on orig_egr_types
From: Petr Machata @ 2019-07-30 11:12 UTC (permalink / raw)
To: Colin King
Cc: Jiri Pirko, Ido Schimmel, David S . Miller,
netdev@vger.kernel.org, kernel-janitors@vger.kernel.org,
linux-kernel@vger.kernel.org
In-Reply-To: <87mugvzt1m.fsf@mellanox.com>
Petr Machata <petrm@mellanox.com> writes:
> Colin King <colin.king@canonical.com> writes:
>
>> From: Colin Ian King <colin.king@canonical.com>
>>
>> Currently there is a duplicated check on orig_egr_types which is
>> redundant, I believe this is a typo and should actually be
>> orig_ing_types || orig_egr_types instead of the expression
>> orig_egr_types || orig_egr_types. Fix this.
>
> Good catch, yes, there's a typo. Thanks for the fix!
>
>> Addresses-Coverity: ("Same on both sides")
>> Fixes: c6b36bdd04b5 ("mlxsw: spectrum_ptp: Increase parsing depth when PTP is enabled")
>> Signed-off-by: Colin Ian King <colin.king@canonical.com>
>
> Reviewed-by: Petr Machata <petrm@mellanox.com>
I see that there is an identical problem in the code one block further.
Can you take care of that as well, please? Or should I do it?
^ permalink raw reply
* Re: [PATCH][next] mlxsw: spectrum_ptp: fix duplicated check on orig_egr_types
From: Petr Machata @ 2019-07-30 11:05 UTC (permalink / raw)
To: Colin King
Cc: Jiri Pirko, Ido Schimmel, David S . Miller,
netdev@vger.kernel.org, kernel-janitors@vger.kernel.org,
linux-kernel@vger.kernel.org
In-Reply-To: <87mugvzt1m.fsf@mellanox.com>
Petr Machata <petrm@mellanox.com> writes:
> Colin King <colin.king@canonical.com> writes:
>
>> From: Colin Ian King <colin.king@canonical.com>
>>
>> Currently there is a duplicated check on orig_egr_types which is
>> redundant, I believe this is a typo and should actually be
>> orig_ing_types || orig_egr_types instead of the expression
>> orig_egr_types || orig_egr_types. Fix this.
>
> Good catch, yes, there's a typo. Thanks for the fix!
>
>> Addresses-Coverity: ("Same on both sides")
>> Fixes: c6b36bdd04b5 ("mlxsw: spectrum_ptp: Increase parsing depth when PTP is enabled")
>> Signed-off-by: Colin Ian King <colin.king@canonical.com>
>
> Reviewed-by: Petr Machata <petrm@mellanox.com>
However the patch should address "net", not "next". Can you please respin?
^ permalink raw reply
* Re: [PATCH][next] mlxsw: spectrum_ptp: fix duplicated check on orig_egr_types
From: Petr Machata @ 2019-07-30 11:00 UTC (permalink / raw)
To: Colin King
Cc: Jiri Pirko, Ido Schimmel, David S . Miller,
netdev@vger.kernel.org, kernel-janitors@vger.kernel.org,
linux-kernel@vger.kernel.org
In-Reply-To: <20190730102114.1506-1-colin.king@canonical.com>
Colin King <colin.king@canonical.com> writes:
> From: Colin Ian King <colin.king@canonical.com>
>
> Currently there is a duplicated check on orig_egr_types which is
> redundant, I believe this is a typo and should actually be
> orig_ing_types || orig_egr_types instead of the expression
> orig_egr_types || orig_egr_types. Fix this.
Good catch, yes, there's a typo. Thanks for the fix!
> Addresses-Coverity: ("Same on both sides")
> Fixes: c6b36bdd04b5 ("mlxsw: spectrum_ptp: Increase parsing depth when PTP is enabled")
> Signed-off-by: Colin Ian King <colin.king@canonical.com>
Reviewed-by: Petr Machata <petrm@mellanox.com>
> ---
> drivers/net/ethernet/mellanox/mlxsw/spectrum_ptp.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_ptp.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_ptp.c
> index 98c5ba3200bc..f02d74e55d95 100644
> --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_ptp.c
> +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_ptp.c
> @@ -999,7 +999,7 @@ static int mlxsw_sp1_ptp_mtpppc_update(struct mlxsw_sp_port *mlxsw_sp_port,
> }
> }
>
> - if ((ing_types || egr_types) && !(orig_egr_types || orig_egr_types)) {
> + if ((ing_types || egr_types) && !(orig_ing_types || orig_egr_types)) {
> err = mlxsw_sp_nve_inc_parsing_depth_get(mlxsw_sp);
> if (err) {
> netdev_err(mlxsw_sp_port->dev, "Failed to increase parsing depth");
^ permalink raw reply
* [PATCH nf] netfilter: nf_tables: map basechain priority to hardware priority
From: Pablo Neira Ayuso @ 2019-07-30 10:54 UTC (permalink / raw)
To: netfilter-devel
Cc: wenxu, jiri, marcelo.leitner, saeedm, gerlitz.or, paulb, netdev
This patch maps basechain netfilter priorities from -8192 to 8191 to
hardware priority 0xC000 + 1. tcf_auto_prio() uses 0xC000 if the user
specifies no priority, then it subtract 1 for each new tcf_proto object.
This patch uses the hardware priority range from 0xC000 to 0xFFFF for
netfilter.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
This follows a rather conservative approach, I could just expose the
2^16 hardware priority range, but we may need to split this priority
range among the ethtool_rx, tc and netfilter subsystems to start with
and it should be possible to extend the priority range later on.
By netfilter priority, I'm refering to the basechain priority:
add chain x y { type filter hook ingress device eth0 priority 0; }
^^^^^^^^^^^
This is no transparently mapped to hardware, this patch shifts it to
make it fit into the 0xC000 + 1 .. 0xFFFF hardware priority range.
include/net/netfilter/nf_tables_offload.h | 2 ++
net/netfilter/nf_tables_api.c | 4 ++++
net/netfilter/nf_tables_offload.c | 32 ++++++++++++++++++++++++++++---
3 files changed, 35 insertions(+), 3 deletions(-)
diff --git a/include/net/netfilter/nf_tables_offload.h b/include/net/netfilter/nf_tables_offload.h
index 3196663a10e3..2d497394021e 100644
--- a/include/net/netfilter/nf_tables_offload.h
+++ b/include/net/netfilter/nf_tables_offload.h
@@ -73,4 +73,6 @@ int nft_flow_rule_offload_commit(struct net *net);
(__reg)->key = __key; \
memset(&(__reg)->mask, 0xff, (__reg)->len);
+u16 nft_chain_offload_priority(struct nft_base_chain *basechain);
+
#endif
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 93647fdf435c..9ee6db9a668d 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -1669,6 +1669,10 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask,
chain->flags |= NFT_BASE_CHAIN | flags;
basechain->policy = NF_ACCEPT;
+ if (chain->flags & NFT_CHAIN_HW_OFFLOAD &&
+ !nft_chain_offload_priority(basechain))
+ return -EOPNOTSUPP;
+
flow_block_init(&basechain->flow_block);
} else {
chain = kzalloc(sizeof(*chain), GFP_KERNEL);
diff --git a/net/netfilter/nf_tables_offload.c b/net/netfilter/nf_tables_offload.c
index ec70978eba5a..df8427ba857c 100644
--- a/net/netfilter/nf_tables_offload.c
+++ b/net/netfilter/nf_tables_offload.c
@@ -156,10 +156,11 @@ void nft_offload_update_dependency(struct nft_offload_ctx *ctx,
}
static void nft_flow_offload_common_init(struct flow_cls_common_offload *common,
- __be16 proto,
- struct netlink_ext_ack *extack)
+ __be16 proto, int priority,
+ struct netlink_ext_ack *extack)
{
common->protocol = proto;
+ common->prio = priority;
common->extack = extack;
}
@@ -180,6 +181,29 @@ static int nft_setup_cb_call(struct nft_base_chain *basechain,
return 0;
}
+/* Available priorities for hardware offload range: -8192..8191 */
+#define NFT_BASECHAIN_OFFLOAD_PRIO_MAX (SHRT_MAX / 4)
+#define NFT_BASECHAIN_OFFLOAD_PRIO_MIN (SHRT_MIN / 4)
+#define NFT_BASECHAIN_OFFLOAD_PRIO_RANGE (USHRT_MAX / 4)
+/* tcf_auto_prio() uses 0xC000 as base, then subtract one for each new chain. */
+#define NFT_BASECHAIN_OFFLOAD_HW_PRIO_BASE (0xC000 + 1)
+
+u16 nft_chain_offload_priority(struct nft_base_chain *basechain)
+{
+ u16 prio;
+
+ if (basechain->ops.priority < NFT_BASECHAIN_OFFLOAD_PRIO_MIN ||
+ basechain->ops.priority > NFT_BASECHAIN_OFFLOAD_PRIO_MAX)
+ return 0;
+
+ /* map netfilter chain priority to hardware priority. */
+ prio = basechain->ops.priority +
+ NFT_BASECHAIN_OFFLOAD_PRIO_MAX +
+ NFT_BASECHAIN_OFFLOAD_HW_PRIO_BASE;
+
+ return prio;
+}
+
static int nft_flow_offload_rule(struct nft_trans *trans,
enum flow_cls_command command)
{
@@ -200,7 +224,9 @@ static int nft_flow_offload_rule(struct nft_trans *trans,
if (flow)
proto = flow->proto;
- nft_flow_offload_common_init(&cls_flow.common, proto, &extack);
+ nft_flow_offload_common_init(&cls_flow.common, proto,
+ nft_chain_offload_priority(basechain),
+ &extack);
cls_flow.command = command;
cls_flow.cookie = (unsigned long) rule;
if (flow)
--
2.11.0
^ permalink raw reply related
* Re: net: ipv6: Fix a bug in ndisc_send_ns when netdev only has a global address
From: Mark Smith @ 2019-07-30 10:28 UTC (permalink / raw)
To: Su Yanjun; +Cc: netdev
In-Reply-To: <93c401b9-bf8b-4d49-9c3b-72d09073444e@cn.fujitsu.com>
Hi Su,
On Tue, 30 Jul 2019 at 19:41, Su Yanjun <suyj.fnst@cn.fujitsu.com> wrote:
>
>
> 在 2019/7/30 16:15, Mark Smith 写道:
> > Hi,
> >
> > I'm not subscribed to the Linux netdev mailing list, so I can't
> > directly reply to the patch email.
> >
> > This patch is not the correct solution to this issue.
> >
<snip>
> In linux implementation, one interface may have no link local address if
> kernel config
>
> *addr_gen_mode* is set to IN6_ADDR_GEN_MODE_NONE. My patch is to fix
> this problem.
>
So this "IN6_ADDR_GEN_MODE_NONE" behaviour doesn't comply with RFC 4291.
As RFC 4291 says,
"All interfaces are *required* to have *at least one* Link-Local
unicast address."
That's not an ambiguous requirement.
This specific, explicit requirement goes as back as far as RFC 2373
from 1998, the ancestor of RFC 4291. It is also heavily implied in RFC
1884s, 2.7 A Node's Required Addresses.
> And what you say is related to the lo interface. I'm not sure whether
> the lo interface needs a ll adreess.
>
It is an IPv6 enabled interface, so it requires a link-local address,
per RFC 4291. RFC 4291 doesn't exclude any interfaces types from the
LL address requirement.
Even special NBMA links/interfaces are not excluded from this
requirement, as Link-Local addresses are formed and used in the NBMA
operation, per RFC 2491.
> IMO the ll address is used to get l2 address by sending ND ns. The lo is
> very special.
>
From an IPv6 perspective, the virtual loopback interface isn't all that special.
A general theme of IPv6 is to try to treat things as similarly as
possible, compared to the IPv4 where a lot of things were treated as
special cases (e.g. ND runs over ICMPv4, in comparison to ARP running
directly and only over Ethernet/802.3. RFC 4861 treats point-to-point
links as multicast capable links, emulating multicast if necessary.
RAs and DHCPv6 are used over PPP links to carry parameters, rather
than using IPv6CP, compared to using IPv4 IPCP to carry e.g. DNS
addresses)
The main place the loopback behaviour causes issues is with IPv6 ND
Duplicate Address Detection. Appendix A of RFC 4861, and RFC 7527,
"Enhanced Duplicate Address Detection" discuss how to deal with that.
Some physical interfaces can be in loopback mode too, so IPv6 DAD has
to deal with that temporary situation.
LL addresses are and can be used for lots of things, including by
end-user applications as a preference when there is a choice between a
set of LL addr(s), GUA and ULA addresses.
Here is an Internet Draft that describes the general characteristics
of Link-Local addresses with references, as well as the benefits of
and how to use them in applications.
"How to use IPv6 Link-Local Addresses in Applications"
https://tools.ietf.org/html/draft-smith-ipv6-link-locals-apps-00
Regards,
Mark.
> Thanks
>
> Su
>
> >
> > "2.1. Addressing Model"
> >
> > ...
> >
> > "All interfaces are required to have at least one Link-Local unicast
> > address (see Section 2.8 for additional required addresses)."
> >
> > I have submitted a more specific bug regarding no Link-Local
> > address/prefix on the Linux kernel loopback interface through RedHat
> > bugzilla as I use Fedora 30, however it doesn't seem to have been
> > looked at yet.
> >
> > "Loopback network interface does not have a Link Local address,
> > contrary to RFC 4291"
> > https://bugzilla.redhat.com/show_bug.cgi?id=1706709
> >
> >
> > Thanks very much,
> > Mark.
> >
> >
>
>
^ permalink raw reply
* Re: [PATCH 03/12] block: bio_release_pages: use flags arg instead of bool
From: Christoph Hellwig @ 2019-07-30 10:25 UTC (permalink / raw)
To: Jerome Glisse
Cc: Christoph Hellwig, john.hubbard, Andrew Morton, Alexander Viro,
Anna Schumaker, David S . Miller, Dominique Martinet,
Eric Van Hensbergen, Jason Gunthorpe, Jason Wang, Jens Axboe,
Latchesar Ionkov, Michael S . Tsirkin, Miklos Szeredi,
Trond Myklebust, Christoph Hellwig, Matthew Wilcox, linux-mm,
LKML, ceph-devel, kvm, linux-block, linux-cifs, linux-fsdevel,
linux-nfs, linux-rdma, netdev, samba-technical, v9fs-developer,
virtualization, John Hubbard, Minwoo Im
In-Reply-To: <20190729205721.GB3760@redhat.com>
On Mon, Jul 29, 2019 at 04:57:21PM -0400, Jerome Glisse wrote:
> > All pages releases by bio_release_pages should come from
> > get_get_user_pages, so I don't really see the point here.
>
> No they do not all comes from GUP for see various callers
> of bio_check_pages_dirty() for instance iomap_dio_zero()
>
> I have carefully tracked down all this and i did not do
> anyconvertion just for the fun of it :)
Well, the point is _should_ not necessarily do. iomap_dio_zero adds the
ZERO_PAGE, which we by definition don't need to refcount. So we can
mark this bio BIO_NO_PAGE_REF safely after removing the get_page there.
Note that the equivalent in the old direct I/O code, dio_refill_pages,
will be a little more complicated as it can match user pages and the
ZERO_PAGE in a single bio, so a per-bio flag won't handle it easily.
Maybe we just need to use a separate bio there as well.
In general with series like this we should not encode the status quo an
pile new hacks upon the old one, but thing where we should be and fix
up the old warts while having to wade through all that code.
^ permalink raw reply
* Re: [RFC PATCH 1/2] gianfar: convert to phylink
From: Russell King - ARM Linux admin @ 2019-07-30 10:23 UTC (permalink / raw)
To: Vladimir Oltean
Cc: Arseny Solokha, Claudiu Manoil, Ioana Ciornei, Andrew Lunn,
netdev, Florian Fainelli
In-Reply-To: <CA+h21hpacLmKzoeKrdE-frZSTsiYCi4rKCObJ4LfAmfrCJ6H9g@mail.gmail.com>
On Tue, Jul 30, 2019 at 02:39:58AM +0300, Vladimir Oltean wrote:
> To be honest I don't have a complete answer to that question. The
> literature recommends writing 0x01a0 to the MII_ADVERTISE (0x4)
> register of the MAC PCS for 1000Base-X, and 0x4001 for SGMII.
That looks entirely sane for both modes.
0x01a0 for 802.3z (1000BASE-X) is defined in 802.3 37.2.5.1.3 as:
bit 5 - full duplex = 1
bit 6 - half duplex = 0
bit 7 - pause = 1
bit 8 - asym_pause = 1
The description of the bits match the config word that is sent in the
link with the exception of bit 14, which is the acknowledgement bit.
Normally, in 802.3z, bit 14 will not be set in the transmitted config
word until we have received the config word from the other end of the
link.
For SGMII, 0x4001 is the acknowledgement code word, which is defined
in the SGMII spec as "tx_config_Reg[15:0] sent from the MAC to the
PHY" which requires:
bit 0 - must be 1
bit 1 .. 13, 15 - must be 0, reserved for future use
bit 14 - must be 1 (auto-negotiation acknowledgement in 802.3z)
> The FMan driver which uses the TSEC MAC does exactly that:
> https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git/tree/drivers/net/ethernet/freescale/fman/fman_dtsec.c#n58
> However I can't seem to be able to trace down the definition of bit 14
> from 0x4001 - it's reserved in all the manuals I see. I have a hunch
> that it selects the format of the Config_Reg base page between
> 1000Base-X and SGMII.
It could be that is what bit 14 is being used for, or it could just be
that they've taken the values from the appropriate specs, and the
hardware behaves the same way irrespective of whether it is in SGMII
or 1000BASE-X mode.
> > +static int gfar_mac_link_state(struct phylink_config *config,
> > + struct phylink_link_state *state)
> > +{
> > + if (state->interface == PHY_INTERFACE_MODE_SGMII ||
> > + state->interface == PHY_INTERFACE_MODE_1000BASEX) {
>
> What if you reduce the indentation level by 1 here, by just exiting if
> the interface mode is not SGMII?
It's only called for in-band negotiation modes anyway, so the above
protection probably doesn't gain much.
> > + struct gfar_private *priv =
> > + netdev_priv(to_net_dev(config->dev));
> > + u16 tbi_cr;
> > +
> > + if (!priv->tbi_phy)
> > + return -ENODEV;
> > +
> > + tbi_cr = phy_read(priv->tbi_phy, MII_TBI_CR);
> > +
> > + state->duplex = !!(tbi_cr & TBI_CR_FULL_DUPLEX);
>
> Woah there. Aren't you supposed to first ensure state->an_complete is
> ok, based on TBI_MII_Register_Set_SR[AN_Done]? There's also a
> Link_Status bit in that register that you could retrieve.
Indeed.
> > + if ((tbi_cr & TBI_CR_SPEED_1000_MASK) == TBI_CR_SPEED_1000_MASK)
> > + state->speed = SPEED_1000;
> > + }
>
> See the Speed_Bit table from TBI_MII_Register_Set_ANLPBPA_SGMII for
> the link partner (aka SGMII PHY) advertisement. You have to do a
> logical-and between that and your own. Also please make sure you
> really are in SGMII AN and not 1000 Base-X when interpreting registers
> 4 & 5 as one way or another.
From what you've said above, yes, this needs to do exactly that.
> > -static noinline void gfar_update_link_state(struct gfar_private *priv)
> > +static void gfar_mac_config(struct phylink_config *config, unsigned int mode,
> > + const struct phylink_link_state *state)
> > {
> > + struct gfar_private *priv = netdev_priv(to_net_dev(config->dev));
> > struct gfar __iomem *regs = priv->gfargrp[0].regs;
> > - struct net_device *ndev = priv->ndev;
> > - struct phy_device *phydev = ndev->phydev;
> > - struct gfar_priv_rx_q *rx_queue = NULL;
> > - int i;
> > + u32 maccfg1, new_maccfg1;
> > + u32 maccfg2, new_maccfg2;
> > + u32 ecntrl, new_ecntrl;
> > + u32 tx_flow, new_tx_flow;
>
> Don't introduce new_ variables. Is there any issue if you
> unconditionally write to the MAC registers?
We do this in every driver, as mac_config() can be called with only a
small number of changes in the settings, and it is important not to
upset the MAC for minor updates.
An example of this is when we are in SGMII mode with an attached PHY.
SGMII will communicate the speed and duplex, but not the results of
the pause negotiation. We read that from the attached PHY and report
it back by calling mac_config() - but at that point, we don't want to
cause the established link to bounce.
So, mac_config() should be implemented to avoid upsetting an already
established link where possible (unless the configuration items that
affect the link have changed.)
> > +static void gfar_mac_an_restart(struct phylink_config *config)
> > +{
> > + /* Not supported */
> > +}
>
> What about running gfar_configure_serdes again?
The intention here is to cause the 802.3z link to renegotiate...
>
> > +
> > +static void gfar_mac_link_down(struct phylink_config *config, unsigned int mode,
> > + phy_interface_t interface)
> > +{
> > + /* Not supported */
> > +}
> > +
>
> What about disabling RX_EN and TX_EN from MACCFG1?
>
> > +static void gfar_mac_link_up(struct phylink_config *config, unsigned int mode,
> > + phy_interface_t interface, struct phy_device *phy)
> > +{
> > + /* Not supported */
> > }
> >
>
> What about enabling RX_EN and TX_EN from MACCFG1?
Note that both of these functions must still allow the link to be
established if we are using in-band negotiation - but they are
expected to start/stop the transmission of packets.
> > @@ -149,8 +148,13 @@ extern const char gfar_driver_version[];
> > #define GFAR_SUPPORTED_GBIT SUPPORTED_1000baseT_Full
> >
> > /* TBI register addresses */
> > +#define MII_TBI_CR 0x00
> > #define MII_TBICON 0x11
> >
> > +/* TBI_CR register bit fields */
> > +#define TBI_CR_FULL_DUPLEX 0x0100
> > +#define TBI_CR_SPEED_1000_MASK 0x0040
> > +
>
> I think BIT() definitions are preferred, even if that means you have
> to convert existing code first.
If MII_TBI_CR is the BMCR of the PCS, how about using the definitions
that we already have in the kernel:
BMCR_SPEED1000 is TBI_CR_SPEED_1000_MASK
BMCR_FULLDPLX is TBI_CR_FULL_DUPLEX
?
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 12.1Mbps down 622kbps up
According to speedtest.net: 11.9Mbps down 500kbps up
^ permalink raw reply
* [PATCH][next] mlxsw: spectrum_ptp: fix duplicated check on orig_egr_types
From: Colin King @ 2019-07-30 10:21 UTC (permalink / raw)
To: Petr Machata, Jiri Pirko, Ido Schimmel, David S . Miller, netdev
Cc: kernel-janitors, linux-kernel
From: Colin Ian King <colin.king@canonical.com>
Currently there is a duplicated check on orig_egr_types which is
redundant, I believe this is a typo and should actually be
orig_ing_types || orig_egr_types instead of the expression
orig_egr_types || orig_egr_types. Fix this.
Addresses-Coverity: ("Same on both sides")
Fixes: c6b36bdd04b5 ("mlxsw: spectrum_ptp: Increase parsing depth when PTP is enabled")
Signed-off-by: Colin Ian King <colin.king@canonical.com>
---
drivers/net/ethernet/mellanox/mlxsw/spectrum_ptp.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_ptp.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_ptp.c
index 98c5ba3200bc..f02d74e55d95 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_ptp.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_ptp.c
@@ -999,7 +999,7 @@ static int mlxsw_sp1_ptp_mtpppc_update(struct mlxsw_sp_port *mlxsw_sp_port,
}
}
- if ((ing_types || egr_types) && !(orig_egr_types || orig_egr_types)) {
+ if ((ing_types || egr_types) && !(orig_ing_types || orig_egr_types)) {
err = mlxsw_sp_nve_inc_parsing_depth_get(mlxsw_sp);
if (err) {
netdev_err(mlxsw_sp_port->dev, "Failed to increase parsing depth");
--
2.20.1
^ permalink raw reply related
* Re: [PATCH net-next 2/2] net: phy: broadcom: add 1000Base-X support for BCM54616S
From: Vladimir Oltean @ 2019-07-30 10:15 UTC (permalink / raw)
To: Tao Ren
Cc: Andrew Lunn, Florian Fainelli, Heiner Kallweit, David S . Miller,
Arun Parameswaran, Justin Chen, netdev, lkml, Andrew Jeffery,
openbmc@lists.ozlabs.org
In-Reply-To: <3987251b-9679-dfbe-6e15-f991c2893bac@fb.com>
On Tue, 30 Jul 2019 at 07:52, Tao Ren <taoren@fb.com> wrote:
>
> On 7/29/19 6:32 PM, Vladimir Oltean wrote:
> > Hi Tao,
> >
> > On Tue, 30 Jul 2019 at 03:31, Tao Ren <taoren@fb.com> wrote:
> >>
> >> Configure the BCM54616S for 1000Base-X mode when "brcm-phy-mode-1000bx"
> >> is set in device tree. This is needed when the PHY is used for fiber and
> >> backplane connections.
> >>
> >> The patch is inspired by commit cd9af3dac6d1 ("PHYLIB: Add 1000Base-X
> >> support for Broadcom bcm5482").
> >
> > As far as I can see, for the commit you referenced,
> > PHY_BCM_FLAGS_MODE_1000BX is referenced from nowhere in the entire
> > mainline kernel:
> > https://urldefense.proofpoint.com/v2/url?u=https-3A__elixir.bootlin.com_linux_latest_ident_PHY-5FBCM-5FFLAGS-5FMODE-5F1000BX&d=DwIBaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=iYElT7HC77pRZ3byVvW8ng&m=gy6Y-3Ylme-_GQcGF4fvOX10irgAT4xh253Weo0np38&s=KL__E2bvsmvUL-hBL9hUmOS5vyPQ92EMj6fEfByn8t8&e=
> > (it is supposed to be put by the MAC driver in phydev->dev_flags prior
> > to calling phy_connect). But I don't see the point to this - can't you
> > check for phydev->interface == PHY_INTERFACE_MODE_1000BASEX?
> > This has the advantage that no MAC driver will need to know that it's
> > talking to a Broadcom PHY. Additionally, no custom DT bindings are
> > needed.
> > Also, for backplane connections you probably want 1000Base-KX which
> > has its own AN/LT, not plain 1000Base-X.
>
> Thank you Vladimir for the quick review!
> Perhaps I misunderstood the purpose of phydev->interface, and I thought it was usually used to defined the interface between MAC and PHY. For example, if I need to pass both "rgmii-id" and "1000base-x" from MAC to PHY driver, what would be the preferred way?
>
Ohhhhhh, now I understand what you're trying to do, sorry, somehow I
was too tired and I thought of something totally unrelated.
Let me see if I can explain: you've got the INTF_SEL pin strapping
configured for something else (like RGMII to copper mode) and then
you're changing the operating mode at runtime through MDIO? Is this
intended to be for production code, or is it just some quick hack to
fix a bad board design?
I think what's supposed to happen (Heiner can comment) is that
genphy_config_init will automatically read the out-of-reset PHY
registers and figure out which link modes are supported. This includes
the 1000Base-X media type, *if* the PHY is strapped correctly.
But you are changing the strapping configuration too late (again, in
.config_init), so phylib doesn't pick up the new Base-X modes. What
happens if you do the switchover from the .probe callback of the
driver, instead of .config_init?
I think what got me confused was your "add support for 1000Base-X"
commit message. If I understand correctly, you're not adding support,
you're just forcing it.
Again, I don't think Linux has generic support for overwriting (or
even describing) the operating mode of a PHY, although maybe that's a
direction we would want to push the discussion towards. RGMII to
copper, RGMII to fiber, SGMII to copper, copper to fiber (media
converter), even RGMII to SGMII (RTL8211FS supports this) - lots of
modes, and this is only for gigabit PHYs...
> >> Signed-off-by: Tao Ren <taoren@fb.com>
> >> ---
> >> drivers/net/phy/broadcom.c | 58 +++++++++++++++++++++++++++++++++++---
> >> include/linux/brcmphy.h | 4 +--
> >> 2 files changed, 56 insertions(+), 6 deletions(-)
> >>
> >> diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c
> >> index 2b4e41a9d35a..6c22ac3a844b 100644
> >> --- a/drivers/net/phy/broadcom.c
> >> +++ b/drivers/net/phy/broadcom.c
> >> @@ -383,9 +383,9 @@ static int bcm5482_config_init(struct phy_device *phydev)
> >> /*
> >> * Select 1000BASE-X register set (primary SerDes)
> >> */
> >> - reg = bcm_phy_read_shadow(phydev, BCM5482_SHD_MODE);
> >> - bcm_phy_write_shadow(phydev, BCM5482_SHD_MODE,
> >> - reg | BCM5482_SHD_MODE_1000BX);
> >> + reg = bcm_phy_read_shadow(phydev, BCM54XX_SHD_MODE);
> >> + bcm_phy_write_shadow(phydev, BCM54XX_SHD_MODE,
> >> + reg | BCM54XX_SHD_MODE_1000BX);
> >>
> >> /*
> >> * LED1=ACTIVITYLED, LED3=LINKSPD[2]
> >> @@ -451,6 +451,34 @@ static int bcm5481_config_aneg(struct phy_device *phydev)
> >> return ret;
> >> }
> >>
> >> +static int bcm54616s_config_init(struct phy_device *phydev)
> >> +{
> >> + int err, reg;
> >> + struct device_node *np = phydev->mdio.dev.of_node;
> >> +
> >> + err = bcm54xx_config_init(phydev);
> >> +
> >> + if (of_property_read_bool(np, "brcm-phy-mode-1000bx")) {
> >> + /* Select 1000BASE-X register set. */
> >> + reg = bcm_phy_read_shadow(phydev, BCM54XX_SHD_MODE);
> >> + bcm_phy_write_shadow(phydev, BCM54XX_SHD_MODE,
> >> + reg | BCM54XX_SHD_MODE_1000BX);
> >> +
> >> + /* Auto-negotiation doesn't seem to work quite right
> >> + * in this mode, so we disable it and force it to the
> >> + * right speed/duplex setting. Only 'link status'
> >> + * is important.
> >> + */
> >> + phydev->autoneg = AUTONEG_DISABLE;
> >> + phydev->speed = SPEED_1000;
> >> + phydev->duplex = DUPLEX_FULL;
> >> +
> >
> > 1000Base-X AN does not include speed negotiation, so hardcoding
> > SPEED_1000 is probably correct.
> > What is wrong with the AN of duplex settings?
>
> FULL_DUPLEX bit is set on my platform by default. Let me enable AN and test it out; will share you results tomorrow.
>
> >> + phydev->dev_flags |= PHY_BCM_FLAGS_MODE_1000BX;
> >> + }
> >> +
> >> + return err;
> >> +}
> >> +
> >> static int bcm54616s_config_aneg(struct phy_device *phydev)
> >> {
> >> int ret;
> >> @@ -464,6 +492,27 @@ static int bcm54616s_config_aneg(struct phy_device *phydev)
> >> return ret;
> >> }
> >>
> >> +static int bcm54616s_read_status(struct phy_device *phydev)
> >> +{
> >> + int ret;
> >> +
> >> + ret = genphy_read_status(phydev);
> >> + if (ret < 0)
> >> + return ret;
> >> +
> >> + if (phydev->dev_flags & PHY_BCM_FLAGS_MODE_1000BX) {
> >> + /* Only link status matters for 1000Base-X mode, so force
> >> + * 1000 Mbit/s full-duplex status.
> >> + */
> >> + if (phydev->link) {
> >> + phydev->speed = SPEED_1000;
> >> + phydev->duplex = DUPLEX_FULL;
> >> + }
> >> + }
> >> +
> >> + return 0;
> >> +}
> >> +
> >> static int brcm_phy_setbits(struct phy_device *phydev, int reg, int set)
> >> {
> >> int val;
> >> @@ -651,8 +700,9 @@ static struct phy_driver broadcom_drivers[] = {
> >> .phy_id_mask = 0xfffffff0,
> >> .name = "Broadcom BCM54616S",
> >> .features = PHY_GBIT_FEATURES,
> >> - .config_init = bcm54xx_config_init,
> >> + .config_init = bcm54616s_config_init,
> >> .config_aneg = bcm54616s_config_aneg,
> >> + .read_status = bcm54616s_read_status,
> >> .ack_interrupt = bcm_phy_ack_intr,
> >> .config_intr = bcm_phy_config_intr,
> >> }, {
> >> diff --git a/include/linux/brcmphy.h b/include/linux/brcmphy.h
> >> index 6db2d9a6e503..82030155558c 100644
> >> --- a/include/linux/brcmphy.h
> >> +++ b/include/linux/brcmphy.h
> >> @@ -200,8 +200,8 @@
> >> #define BCM5482_SHD_SSD 0x14 /* 10100: Secondary SerDes control */
> >> #define BCM5482_SHD_SSD_LEDM 0x0008 /* SSD LED Mode enable */
> >> #define BCM5482_SHD_SSD_EN 0x0001 /* SSD enable */
> >> -#define BCM5482_SHD_MODE 0x1f /* 11111: Mode Control Register */
> >> -#define BCM5482_SHD_MODE_1000BX 0x0001 /* Enable 1000BASE-X registers */
> >> +#define BCM54XX_SHD_MODE 0x1f /* 11111: Mode Control Register */
> >> +#define BCM54XX_SHD_MODE_1000BX 0x0001 /* Enable 1000BASE-X registers */
> >
> > These registers are also present on my BCM5464, probably safe to
> > assume they're generic for the entire family.
> > So if you make the registers definitions common, you can probably make
> > the 1000Base-X configuration common as well.
>
> If I understand correctly, your recommendation is to add a common function (such as "bcm54xx_config_1000bx") so it can be used by other BCM chips? Sure, I will take care of it.
>
>
> Thanks,
>
> Tao
Regards,
-Vladimir
^ permalink raw reply
* [PATCH 1/2] net: dsa: mv88e6xxx: add support to setup led-control register through device-tree
From: Hubert Feurstein @ 2019-07-30 10:14 UTC (permalink / raw)
To: netdev, linux-kernel
Cc: Hubert Feurstein, Andrew Lunn, Vivien Didelot, Florian Fainelli,
David S. Miller
So it is possible to change the default behaviour of the switch LEDs.
Signed-off-by: Hubert Feurstein <h.feurstein@gmail.com>
---
drivers/net/dsa/mv88e6xxx/chip.c | 52 ++++++++++++++++++++++++++++++++
drivers/net/dsa/mv88e6xxx/chip.h | 2 ++
drivers/net/dsa/mv88e6xxx/port.c | 13 ++++++++
drivers/net/dsa/mv88e6xxx/port.h | 10 ++++++
4 files changed, 77 insertions(+)
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 85638b868d8e..e5a11454e1e0 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -1985,6 +1985,52 @@ static int mv88e6xxx_switch_reset(struct mv88e6xxx_chip *chip)
return mv88e6xxx_software_reset(chip);
}
+static void mv88e6xxx_led_control_init(struct mv88e6xxx_chip *chip,
+ const struct device_node *np)
+{
+ struct device_node *ports, *port;
+ struct mv88e6xxx_port *chip_port;
+ u32 led_control, reg;
+ int err;
+
+ if (!np)
+ return;
+
+ /* Read LED Control register value from device-tree */
+ ports = of_get_child_by_name(np, "ports");
+ if (!ports)
+ return;
+
+ for_each_available_child_of_node(ports, port) {
+ err = of_property_read_u32(port, "reg", ®);
+ if (err || reg >= ARRAY_SIZE(chip->ports))
+ break;
+
+ err = of_property_read_u32(port, "marvell,led-control",
+ &led_control);
+ if (!err) {
+ chip_port = &chip->ports[reg];
+ chip_port->led_control = led_control |
+ MV88E6XXX_LED_CONTROL_VALID;
+ dev_dbg(chip->dev, "LED control value for port%d = 0x%02x\n",
+ reg, led_control);
+ }
+ }
+
+ of_node_put(ports);
+}
+
+static int mv88e6xxx_led_control_setup(struct mv88e6xxx_chip *chip, int port)
+{
+ u16 led_control = chip->ports[port].led_control;
+
+ if ((led_control & MV88E6XXX_LED_CONTROL_VALID) == 0)
+ return 0;
+
+ led_control &= ~MV88E6XXX_LED_CONTROL_VALID;
+ return mv88e6xxx_port_set_led_control(chip, port, led_control);
+}
+
static int mv88e6xxx_set_port_mode(struct mv88e6xxx_chip *chip, int port,
enum mv88e6xxx_frame_mode frame,
enum mv88e6xxx_egress_mode egress, u16 etype)
@@ -2120,6 +2166,11 @@ static int mv88e6xxx_setup_port(struct mv88e6xxx_chip *chip, int port)
chip->ports[port].chip = chip;
chip->ports[port].port = port;
+ /* Setup LED Control before link-up or link-unforce */
+ err = mv88e6xxx_led_control_setup(chip, port);
+ if (err)
+ return err;
+
/* MAC Forcing register: don't force link, speed, duplex or flow control
* state to any particular values on physical ports, but force the CPU
* port and all DSA ports to their maximum bandwidth and full duplex.
@@ -4851,6 +4902,7 @@ static int mv88e6xxx_probe(struct mdio_device *mdiodev)
goto out;
mv88e6xxx_phy_init(chip);
+ mv88e6xxx_led_control_init(chip, np);
if (chip->info->ops->get_eeprom) {
if (np)
diff --git a/drivers/net/dsa/mv88e6xxx/chip.h b/drivers/net/dsa/mv88e6xxx/chip.h
index 64872251e479..1bb775855d62 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.h
+++ b/drivers/net/dsa/mv88e6xxx/chip.h
@@ -24,6 +24,7 @@
#define MV88E6XXX_MAX_PVT_PORTS 16
#define MV88E6XXX_MAX_GPIO 16
+#define MV88E6XXX_LED_CONTROL_VALID 0x8000
enum mv88e6xxx_egress_mode {
MV88E6XXX_EGRESS_MODE_UNMODIFIED,
@@ -194,6 +195,7 @@ struct mv88e6xxx_port {
u64 vtu_member_violation;
u64 vtu_miss_violation;
u8 cmode;
+ u16 led_control;
int serdes_irq;
};
diff --git a/drivers/net/dsa/mv88e6xxx/port.c b/drivers/net/dsa/mv88e6xxx/port.c
index 04309ef0a1cc..111bb686b764 100644
--- a/drivers/net/dsa/mv88e6xxx/port.c
+++ b/drivers/net/dsa/mv88e6xxx/port.c
@@ -1183,6 +1183,19 @@ int mv88e6351_port_set_ether_type(struct mv88e6xxx_chip *chip, int port,
return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_ETH_TYPE, etype);
}
+/* Offset 0x16: LED Control Register */
+
+int mv88e6xxx_port_set_led_control(struct mv88e6xxx_chip *chip, int port,
+ u16 led_control)
+{
+ led_control &= MV88E6XXX_PORT_LED_CONTROL_DATA_MASK;
+ led_control |= MV88E6XXX_PORT_LED_CONTROL_POINTER_CONTROL_LED01
+ | MV88E6XXX_PORT_LED_CONTROL_UPDATE;
+
+ return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_LED_CONTROL,
+ led_control);
+}
+
/* Offset 0x18: Port IEEE Priority Remapping Registers [0-3]
* Offset 0x19: Port IEEE Priority Remapping Registers [4-7]
*/
diff --git a/drivers/net/dsa/mv88e6xxx/port.h b/drivers/net/dsa/mv88e6xxx/port.h
index 141df2988cd1..5aacbccf81e3 100644
--- a/drivers/net/dsa/mv88e6xxx/port.h
+++ b/drivers/net/dsa/mv88e6xxx/port.h
@@ -239,6 +239,14 @@
/* Offset 0x13: OutFiltered Counter */
#define MV88E6XXX_PORT_OUT_FILTERED 0x13
+/* Offset 0x16: LED Control Register */
+#define MV88E6XXX_PORT_LED_CONTROL 0x16
+#define MV88E6XXX_PORT_LED_CONTROL_DATA_MASK 0x07ff
+#define MV88E6XXX_PORT_LED_CONTROL_UPDATE 0x8000
+#define MV88E6XXX_PORT_LED_CONTROL_POINTER_CONTROL_LED01 0x0000
+#define MV88E6XXX_PORT_LED_CONTROL_POINTER_STRECH_BLINK_RATE 0x6000
+#define MV88E6XXX_PORT_LED_CONTROL_POINTER_CONTROL_SPECIAL 0x7000
+
/* Offset 0x18: IEEE Priority Mapping Table */
#define MV88E6390_PORT_IEEE_PRIO_MAP_TABLE 0x18
#define MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_UPDATE 0x8000
@@ -323,6 +331,8 @@ int mv88e6352_port_set_egress_floods(struct mv88e6xxx_chip *chip, int port,
bool unicast, bool multicast);
int mv88e6351_port_set_ether_type(struct mv88e6xxx_chip *chip, int port,
u16 etype);
+int mv88e6xxx_port_set_led_control(struct mv88e6xxx_chip *chip, int port,
+ u16 led_control);
int mv88e6xxx_port_set_message_port(struct mv88e6xxx_chip *chip, int port,
bool message_port);
int mv88e6165_port_set_jumbo_size(struct mv88e6xxx_chip *chip, int port,
--
2.22.0
^ permalink raw reply related
* [PATCH 2/2] dt-bindings: net: dsa: marvell: add property "marvell,led-control"
From: Hubert Feurstein @ 2019-07-30 10:14 UTC (permalink / raw)
To: netdev, linux-kernel
Cc: Hubert Feurstein, Andrew Lunn, Vivien Didelot, Florian Fainelli,
David S. Miller
In-Reply-To: <20190730101451.845-1-h.feurstein@gmail.com>
With this property it is possible to change the default behaviour of
the switch LEDs.
Signed-off-by: Hubert Feurstein <h.feurstein@gmail.com>
---
Documentation/devicetree/bindings/net/dsa/marvell.txt | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/Documentation/devicetree/bindings/net/dsa/marvell.txt b/Documentation/devicetree/bindings/net/dsa/marvell.txt
index 30c11fea491b..5e094e37c76d 100644
--- a/Documentation/devicetree/bindings/net/dsa/marvell.txt
+++ b/Documentation/devicetree/bindings/net/dsa/marvell.txt
@@ -46,6 +46,16 @@ Optional properties:
- mdio? : Container of PHYs and devices on the external MDIO
bus. The node must contains a compatible string of
"marvell,mv88e6xxx-mdio-external"
+- marvell,led-control : The register value for the LED control register (
+ Control for LED 0 & 1). This property can be defined
+ per port. Example:
+ ports {
+ port@0 {
+ [...]
+ marvell,led-control = <0x11>
+ };
+ [...]
+ }
Example:
--
2.22.0
^ permalink raw reply related
* [PATCH] net: dsa: mv88e6xxx: use link-down-define instead of plain value
From: Hubert Feurstein @ 2019-07-30 10:11 UTC (permalink / raw)
To: netdev, linux-kernel
Cc: Hubert Feurstein, Andrew Lunn, Vivien Didelot, Florian Fainelli,
David S. Miller
Using the define here makes the code more expressive.
Signed-off-by: Hubert Feurstein <h.feurstein@gmail.com>
---
drivers/net/dsa/mv88e6xxx/chip.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 58e298cc90e0..85638b868d8e 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -430,7 +430,7 @@ int mv88e6xxx_port_setup_mac(struct mv88e6xxx_chip *chip, int port, int link,
return 0;
/* Port's MAC control must not be changed unless the link is down */
- err = chip->info->ops->port_set_link(chip, port, 0);
+ err = chip->info->ops->port_set_link(chip, port, LINK_FORCED_DOWN);
if (err)
return err;
--
2.22.0
^ permalink raw reply related
* [PATCH] net: dsa: mv88e6xxx: extend PTP gettime function to read system clock
From: Hubert Feurstein @ 2019-07-30 10:10 UTC (permalink / raw)
To: netdev, linux-kernel
Cc: Hubert Feurstein, Andrew Lunn, Vivien Didelot, Florian Fainelli,
David S. Miller
This adds support for the PTP_SYS_OFFSET_EXTENDED ioctl.
Signed-off-by: Hubert Feurstein <h.feurstein@gmail.com>
---
drivers/net/dsa/mv88e6xxx/ptp.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/drivers/net/dsa/mv88e6xxx/ptp.c b/drivers/net/dsa/mv88e6xxx/ptp.c
index 51cdf4712517..1ff983376f95 100644
--- a/drivers/net/dsa/mv88e6xxx/ptp.c
+++ b/drivers/net/dsa/mv88e6xxx/ptp.c
@@ -230,14 +230,17 @@ static int mv88e6xxx_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
return 0;
}
-static int mv88e6xxx_ptp_gettime(struct ptp_clock_info *ptp,
- struct timespec64 *ts)
+static int mv88e6xxx_ptp_gettimex(struct ptp_clock_info *ptp,
+ struct timespec64 *ts,
+ struct ptp_system_timestamp *sts)
{
struct mv88e6xxx_chip *chip = ptp_to_chip(ptp);
u64 ns;
mv88e6xxx_reg_lock(chip);
+ ptp_read_system_prets(sts);
ns = timecounter_read(&chip->tstamp_tc);
+ ptp_read_system_postts(sts);
mv88e6xxx_reg_unlock(chip);
*ts = ns_to_timespec64(ns);
@@ -386,7 +389,7 @@ static void mv88e6xxx_ptp_overflow_check(struct work_struct *work)
struct mv88e6xxx_chip *chip = dw_overflow_to_chip(dw);
struct timespec64 ts;
- mv88e6xxx_ptp_gettime(&chip->ptp_clock_info, &ts);
+ mv88e6xxx_ptp_gettimex(&chip->ptp_clock_info, &ts, NULL);
schedule_delayed_work(&chip->overflow_work,
MV88E6XXX_TAI_OVERFLOW_PERIOD);
@@ -444,7 +447,7 @@ int mv88e6xxx_ptp_setup(struct mv88e6xxx_chip *chip)
chip->ptp_clock_info.max_adj = MV88E6XXX_MAX_ADJ_PPB;
chip->ptp_clock_info.adjfine = mv88e6xxx_ptp_adjfine;
chip->ptp_clock_info.adjtime = mv88e6xxx_ptp_adjtime;
- chip->ptp_clock_info.gettime64 = mv88e6xxx_ptp_gettime;
+ chip->ptp_clock_info.gettimex64 = mv88e6xxx_ptp_gettimex;
chip->ptp_clock_info.settime64 = mv88e6xxx_ptp_settime;
chip->ptp_clock_info.enable = ptp_ops->ptp_enable;
chip->ptp_clock_info.verify = ptp_ops->ptp_verify;
--
2.22.0
^ permalink raw reply related
* [PATCH 1/4] net: dsa: mv88e6xxx: add support for MV88E6220
From: Hubert Feurstein @ 2019-07-30 10:04 UTC (permalink / raw)
To: netdev, linux-kernel
Cc: Hubert Feurstein, Andrew Lunn, Vivien Didelot, Florian Fainelli,
David S. Miller, Rasmus Villemoes
In-Reply-To: <20190730100429.32479-1-h.feurstein@gmail.com>
The MV88E6220 is almost the same as MV88E6250 except that the ports 2-4 are
not routed to pins. So the usable ports are 0, 1, 5 and 6.
Signed-off-by: Hubert Feurstein <h.feurstein@gmail.com>
---
drivers/net/dsa/mv88e6xxx/chip.c | 25 +++++++++++++++++++++++++
drivers/net/dsa/mv88e6xxx/chip.h | 3 ++-
drivers/net/dsa/mv88e6xxx/port.h | 1 +
3 files changed, 28 insertions(+), 1 deletion(-)
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 6b17cd961d06..c4982ced908e 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -4283,6 +4283,31 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.ops = &mv88e6240_ops,
},
+ [MV88E6220] = {
+ .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6220,
+ .family = MV88E6XXX_FAMILY_6250,
+ .name = "Marvell 88E6220",
+ .num_databases = 64,
+
+ /* Ports 2-4 are not routed to pins
+ * => usable ports 0, 1, 5, 6
+ */
+ .num_ports = 7,
+ .num_internal_phys = 2,
+ .max_vid = 4095,
+ .port_base_addr = 0x08,
+ .phy_base_addr = 0x00,
+ .global1_addr = 0x0f,
+ .global2_addr = 0x07,
+ .age_time_coeff = 15000,
+ .g1_irqs = 9,
+ .g2_irqs = 10,
+ .atu_move_port_mask = 0xf,
+ .dual_chip = true,
+ .tag_protocol = DSA_TAG_PROTO_DSA,
+ .ops = &mv88e6250_ops,
+ },
+
[MV88E6250] = {
.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6250,
.family = MV88E6XXX_FAMILY_6250,
diff --git a/drivers/net/dsa/mv88e6xxx/chip.h b/drivers/net/dsa/mv88e6xxx/chip.h
index 4646e46d47f2..6eb13f269366 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.h
+++ b/drivers/net/dsa/mv88e6xxx/chip.h
@@ -58,6 +58,7 @@ enum mv88e6xxx_model {
MV88E6190X,
MV88E6191,
MV88E6240,
+ MV88E6220,
MV88E6250,
MV88E6290,
MV88E6320,
@@ -77,7 +78,7 @@ enum mv88e6xxx_family {
MV88E6XXX_FAMILY_6097, /* 6046 6085 6096 6097 */
MV88E6XXX_FAMILY_6165, /* 6123 6161 6165 */
MV88E6XXX_FAMILY_6185, /* 6108 6121 6122 6131 6152 6155 6182 6185 */
- MV88E6XXX_FAMILY_6250, /* 6250 */
+ MV88E6XXX_FAMILY_6250, /* 6220, 6250 */
MV88E6XXX_FAMILY_6320, /* 6320 6321 */
MV88E6XXX_FAMILY_6341, /* 6141 6341 */
MV88E6XXX_FAMILY_6351, /* 6171 6175 6350 6351 */
diff --git a/drivers/net/dsa/mv88e6xxx/port.h b/drivers/net/dsa/mv88e6xxx/port.h
index 8d5a6cd6fb19..141df2988cd1 100644
--- a/drivers/net/dsa/mv88e6xxx/port.h
+++ b/drivers/net/dsa/mv88e6xxx/port.h
@@ -118,6 +118,7 @@
#define MV88E6XXX_PORT_SWITCH_ID_PROD_6191 0x1910
#define MV88E6XXX_PORT_SWITCH_ID_PROD_6185 0x1a70
#define MV88E6XXX_PORT_SWITCH_ID_PROD_6240 0x2400
+#define MV88E6XXX_PORT_SWITCH_ID_PROD_6220 0x2200
#define MV88E6XXX_PORT_SWITCH_ID_PROD_6250 0x2500
#define MV88E6XXX_PORT_SWITCH_ID_PROD_6290 0x2900
#define MV88E6XXX_PORT_SWITCH_ID_PROD_6321 0x3100
--
2.22.0
^ permalink raw reply related
* [PATCH 2/4] dt-bindings: net: dsa: marvell: add 6220 model to the 6250 family
From: Hubert Feurstein @ 2019-07-30 10:04 UTC (permalink / raw)
To: netdev, linux-kernel
Cc: Hubert Feurstein, Andrew Lunn, Vivien Didelot, Florian Fainelli,
David S. Miller, Rasmus Villemoes
In-Reply-To: <20190730100429.32479-1-h.feurstein@gmail.com>
The MV88E6220 is part of the MV88E6250 family.
Signed-off-by: Hubert Feurstein <h.feurstein@gmail.com>
---
Documentation/devicetree/bindings/net/dsa/marvell.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/net/dsa/marvell.txt b/Documentation/devicetree/bindings/net/dsa/marvell.txt
index 6f9538974bb9..30c11fea491b 100644
--- a/Documentation/devicetree/bindings/net/dsa/marvell.txt
+++ b/Documentation/devicetree/bindings/net/dsa/marvell.txt
@@ -22,7 +22,7 @@ which is at a different MDIO base address in different switch families.
- "marvell,mv88e6190" : Switch has base address 0x00. Use with models:
6190, 6190X, 6191, 6290, 6390, 6390X
- "marvell,mv88e6250" : Switch has base address 0x08 or 0x18. Use with model:
- 6250
+ 6220, 6250
Required properties:
- compatible : Should be one of "marvell,mv88e6085",
--
2.22.0
^ permalink raw reply related
* [PATCH 3/4] net: dsa: mv88e6xxx: setup message port is not supported in the 6250 family
From: Hubert Feurstein @ 2019-07-30 10:04 UTC (permalink / raw)
To: netdev, linux-kernel
Cc: Hubert Feurstein, Andrew Lunn, Vivien Didelot, Florian Fainelli,
David S. Miller, Rasmus Villemoes
In-Reply-To: <20190730100429.32479-1-h.feurstein@gmail.com>
The MV88E6250 family doesn't support the MV88E6XXX_PORT_CTL1_MESSAGE_PORT
bit.
Signed-off-by: Hubert Feurstein <h.feurstein@gmail.com>
---
drivers/net/dsa/mv88e6xxx/chip.c | 34 +++++++++++++++++++++++++++++---
drivers/net/dsa/mv88e6xxx/chip.h | 1 +
2 files changed, 32 insertions(+), 3 deletions(-)
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index c4982ced908e..c2fb4ea66434 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -2252,9 +2252,11 @@ static int mv88e6xxx_setup_port(struct mv88e6xxx_chip *chip, int port)
return err;
}
- err = mv88e6xxx_setup_message_port(chip, port);
- if (err)
- return err;
+ if (chip->info->ops->port_setup_message_port) {
+ err = chip->info->ops->port_setup_message_port(chip, port);
+ if (err)
+ return err;
+ }
/* Port based VLAN map: give each port the same default address
* database, and allow bidirectional communication between the
@@ -2797,6 +2799,7 @@ static const struct mv88e6xxx_ops mv88e6085_ops = {
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
.port_link_state = mv88e6352_port_link_state,
.port_get_cmode = mv88e6185_port_get_cmode,
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
.stats_snapshot = mv88e6xxx_g1_stats_snapshot,
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
@@ -2831,6 +2834,7 @@ static const struct mv88e6xxx_ops mv88e6095_ops = {
.port_set_upstream_port = mv88e6095_port_set_upstream_port,
.port_link_state = mv88e6185_port_link_state,
.port_get_cmode = mv88e6185_port_get_cmode,
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
.stats_snapshot = mv88e6xxx_g1_stats_snapshot,
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
@@ -2867,6 +2871,7 @@ static const struct mv88e6xxx_ops mv88e6097_ops = {
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
.port_link_state = mv88e6352_port_link_state,
.port_get_cmode = mv88e6185_port_get_cmode,
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
.stats_snapshot = mv88e6xxx_g1_stats_snapshot,
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
@@ -2901,6 +2906,7 @@ static const struct mv88e6xxx_ops mv88e6123_ops = {
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
.port_link_state = mv88e6352_port_link_state,
.port_get_cmode = mv88e6185_port_get_cmode,
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
.stats_snapshot = mv88e6320_g1_stats_snapshot,
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
@@ -2938,6 +2944,7 @@ static const struct mv88e6xxx_ops mv88e6131_ops = {
.port_set_pause = mv88e6185_port_set_pause,
.port_link_state = mv88e6352_port_link_state,
.port_get_cmode = mv88e6185_port_get_cmode,
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
.stats_snapshot = mv88e6xxx_g1_stats_snapshot,
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
@@ -2982,6 +2989,7 @@ static const struct mv88e6xxx_ops mv88e6141_ops = {
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
.port_link_state = mv88e6352_port_link_state,
.port_get_cmode = mv88e6352_port_get_cmode,
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
.stats_snapshot = mv88e6390_g1_stats_snapshot,
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
@@ -3022,6 +3030,7 @@ static const struct mv88e6xxx_ops mv88e6161_ops = {
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
.port_link_state = mv88e6352_port_link_state,
.port_get_cmode = mv88e6185_port_get_cmode,
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
.stats_snapshot = mv88e6xxx_g1_stats_snapshot,
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
@@ -3055,6 +3064,7 @@ static const struct mv88e6xxx_ops mv88e6165_ops = {
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
.port_link_state = mv88e6352_port_link_state,
.port_get_cmode = mv88e6185_port_get_cmode,
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
.stats_snapshot = mv88e6xxx_g1_stats_snapshot,
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
@@ -3096,6 +3106,7 @@ static const struct mv88e6xxx_ops mv88e6171_ops = {
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
.port_link_state = mv88e6352_port_link_state,
.port_get_cmode = mv88e6352_port_get_cmode,
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
.stats_snapshot = mv88e6320_g1_stats_snapshot,
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
@@ -3137,6 +3148,7 @@ static const struct mv88e6xxx_ops mv88e6172_ops = {
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
.port_link_state = mv88e6352_port_link_state,
.port_get_cmode = mv88e6352_port_get_cmode,
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
.stats_snapshot = mv88e6320_g1_stats_snapshot,
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
@@ -3179,6 +3191,7 @@ static const struct mv88e6xxx_ops mv88e6175_ops = {
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
.port_link_state = mv88e6352_port_link_state,
.port_get_cmode = mv88e6352_port_get_cmode,
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
.stats_snapshot = mv88e6320_g1_stats_snapshot,
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
@@ -3220,6 +3233,7 @@ static const struct mv88e6xxx_ops mv88e6176_ops = {
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
.port_link_state = mv88e6352_port_link_state,
.port_get_cmode = mv88e6352_port_get_cmode,
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
.stats_snapshot = mv88e6320_g1_stats_snapshot,
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
@@ -3258,6 +3272,7 @@ static const struct mv88e6xxx_ops mv88e6185_ops = {
.port_set_pause = mv88e6185_port_set_pause,
.port_link_state = mv88e6185_port_link_state,
.port_get_cmode = mv88e6185_port_get_cmode,
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
.stats_snapshot = mv88e6xxx_g1_stats_snapshot,
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
@@ -3300,6 +3315,7 @@ static const struct mv88e6xxx_ops mv88e6190_ops = {
.port_link_state = mv88e6352_port_link_state,
.port_get_cmode = mv88e6352_port_get_cmode,
.port_set_cmode = mv88e6390_port_set_cmode,
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
.stats_snapshot = mv88e6390_g1_stats_snapshot,
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
@@ -3345,6 +3361,7 @@ static const struct mv88e6xxx_ops mv88e6190x_ops = {
.port_link_state = mv88e6352_port_link_state,
.port_get_cmode = mv88e6352_port_get_cmode,
.port_set_cmode = mv88e6390x_port_set_cmode,
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
.stats_snapshot = mv88e6390_g1_stats_snapshot,
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
@@ -3390,6 +3407,7 @@ static const struct mv88e6xxx_ops mv88e6191_ops = {
.port_link_state = mv88e6352_port_link_state,
.port_get_cmode = mv88e6352_port_get_cmode,
.port_set_cmode = mv88e6390_port_set_cmode,
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
.stats_snapshot = mv88e6390_g1_stats_snapshot,
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
@@ -3437,6 +3455,7 @@ static const struct mv88e6xxx_ops mv88e6240_ops = {
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
.port_link_state = mv88e6352_port_link_state,
.port_get_cmode = mv88e6352_port_get_cmode,
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
.stats_snapshot = mv88e6320_g1_stats_snapshot,
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
@@ -3522,6 +3541,7 @@ static const struct mv88e6xxx_ops mv88e6290_ops = {
.port_link_state = mv88e6352_port_link_state,
.port_get_cmode = mv88e6352_port_get_cmode,
.port_set_cmode = mv88e6390_port_set_cmode,
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
.stats_snapshot = mv88e6390_g1_stats_snapshot,
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
@@ -3569,6 +3589,7 @@ static const struct mv88e6xxx_ops mv88e6320_ops = {
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
.port_link_state = mv88e6352_port_link_state,
.port_get_cmode = mv88e6352_port_get_cmode,
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
.stats_snapshot = mv88e6320_g1_stats_snapshot,
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
@@ -3612,6 +3633,7 @@ static const struct mv88e6xxx_ops mv88e6321_ops = {
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
.port_link_state = mv88e6352_port_link_state,
.port_get_cmode = mv88e6352_port_get_cmode,
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
.stats_snapshot = mv88e6320_g1_stats_snapshot,
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
@@ -3655,6 +3677,7 @@ static const struct mv88e6xxx_ops mv88e6341_ops = {
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
.port_link_state = mv88e6352_port_link_state,
.port_get_cmode = mv88e6352_port_get_cmode,
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
.stats_snapshot = mv88e6390_g1_stats_snapshot,
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
@@ -3698,6 +3721,7 @@ static const struct mv88e6xxx_ops mv88e6350_ops = {
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
.port_link_state = mv88e6352_port_link_state,
.port_get_cmode = mv88e6352_port_get_cmode,
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
.stats_snapshot = mv88e6320_g1_stats_snapshot,
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
@@ -3737,6 +3761,7 @@ static const struct mv88e6xxx_ops mv88e6351_ops = {
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
.port_link_state = mv88e6352_port_link_state,
.port_get_cmode = mv88e6352_port_get_cmode,
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
.stats_snapshot = mv88e6320_g1_stats_snapshot,
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
@@ -3780,6 +3805,7 @@ static const struct mv88e6xxx_ops mv88e6352_ops = {
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
.port_link_state = mv88e6352_port_link_state,
.port_get_cmode = mv88e6352_port_get_cmode,
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
.stats_snapshot = mv88e6320_g1_stats_snapshot,
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
@@ -3832,6 +3858,7 @@ static const struct mv88e6xxx_ops mv88e6390_ops = {
.port_link_state = mv88e6352_port_link_state,
.port_get_cmode = mv88e6352_port_get_cmode,
.port_set_cmode = mv88e6390_port_set_cmode,
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
.stats_snapshot = mv88e6390_g1_stats_snapshot,
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
@@ -3881,6 +3908,7 @@ static const struct mv88e6xxx_ops mv88e6390x_ops = {
.port_link_state = mv88e6352_port_link_state,
.port_get_cmode = mv88e6352_port_get_cmode,
.port_set_cmode = mv88e6390x_port_set_cmode,
+ .port_setup_message_port = mv88e6xxx_setup_message_port,
.stats_snapshot = mv88e6390_g1_stats_snapshot,
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
diff --git a/drivers/net/dsa/mv88e6xxx/chip.h b/drivers/net/dsa/mv88e6xxx/chip.h
index 6eb13f269366..720cace3db4e 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.h
+++ b/drivers/net/dsa/mv88e6xxx/chip.h
@@ -390,6 +390,7 @@ struct mv88e6xxx_ops {
u8 out);
int (*port_disable_learn_limit)(struct mv88e6xxx_chip *chip, int port);
int (*port_disable_pri_override)(struct mv88e6xxx_chip *chip, int port);
+ int (*port_setup_message_port)(struct mv88e6xxx_chip *chip, int port);
/* CMODE control what PHY mode the MAC will use, eg. SGMII, RGMII, etc.
* Some chips allow this to be configured on specific ports.
--
2.22.0
^ permalink raw reply related
* [PATCH 4/4] net: dsa: mv88e6xxx: add PTP support for MV88E6250 family
From: Hubert Feurstein @ 2019-07-30 10:04 UTC (permalink / raw)
To: netdev, linux-kernel
Cc: Hubert Feurstein, Andrew Lunn, Vivien Didelot, Florian Fainelli,
David S. Miller, Rasmus Villemoes
In-Reply-To: <20190730100429.32479-1-h.feurstein@gmail.com>
This adds PTP support for the MV88E6250 family.
Signed-off-by: Hubert Feurstein <h.feurstein@gmail.com>
---
drivers/net/dsa/mv88e6xxx/chip.c | 4 ++
drivers/net/dsa/mv88e6xxx/chip.h | 4 ++
drivers/net/dsa/mv88e6xxx/ptp.c | 73 ++++++++++++++++++++++----------
3 files changed, 59 insertions(+), 22 deletions(-)
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index c2fb4ea66434..58e298cc90e0 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -3514,6 +3514,8 @@ static const struct mv88e6xxx_ops mv88e6250_ops = {
.reset = mv88e6250_g1_reset,
.vtu_getnext = mv88e6250_g1_vtu_getnext,
.vtu_loadpurge = mv88e6250_g1_vtu_loadpurge,
+ .avb_ops = &mv88e6352_avb_ops,
+ .ptp_ops = &mv88e6352_ptp_ops,
.phylink_validate = mv88e6065_phylink_validate,
};
@@ -4333,6 +4335,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.atu_move_port_mask = 0xf,
.dual_chip = true,
.tag_protocol = DSA_TAG_PROTO_DSA,
+ .ptp_support = true,
.ops = &mv88e6250_ops,
},
@@ -4354,6 +4357,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.atu_move_port_mask = 0xf,
.dual_chip = true,
.tag_protocol = DSA_TAG_PROTO_DSA,
+ .ptp_support = true,
.ops = &mv88e6250_ops,
},
diff --git a/drivers/net/dsa/mv88e6xxx/chip.h b/drivers/net/dsa/mv88e6xxx/chip.h
index 720cace3db4e..64872251e479 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.h
+++ b/drivers/net/dsa/mv88e6xxx/chip.h
@@ -273,6 +273,10 @@ struct mv88e6xxx_chip {
u16 trig_config;
u16 evcap_config;
u16 enable_count;
+ u32 ptp_cc_shift;
+ u32 ptp_cc_mult;
+ u32 ptp_cc_mult_num;
+ u32 ptp_cc_mult_dem;
/* Per-port timestamping resources. */
struct mv88e6xxx_port_hwtstamp port_hwtstamp[DSA_MAX_PORTS];
diff --git a/drivers/net/dsa/mv88e6xxx/ptp.c b/drivers/net/dsa/mv88e6xxx/ptp.c
index 768d256f7c9f..51cdf4712517 100644
--- a/drivers/net/dsa/mv88e6xxx/ptp.c
+++ b/drivers/net/dsa/mv88e6xxx/ptp.c
@@ -15,11 +15,38 @@
#include "hwtstamp.h"
#include "ptp.h"
-/* Raw timestamps are in units of 8-ns clock periods. */
-#define CC_SHIFT 28
-#define CC_MULT (8 << CC_SHIFT)
-#define CC_MULT_NUM (1 << 9)
-#define CC_MULT_DEM 15625ULL
+/* The adjfine API clamps ppb between [-32,768,000, 32,768,000], and
+ * therefore scaled_ppm between [-2,147,483,648, 2,147,483,647].
+ * Set the maximum supported ppb to a round value smaller than the maximum.
+ *
+ * Percentually speaking, this is a +/- 0.032x adjustment of the
+ * free-running counter (0.968x to 1.032x).
+ */
+#define MV88E6XXX_MAX_ADJ_PPB 32000000
+
+/* Family MV88E6250:
+ * Raw timestamps are in units of 10-ns clock periods.
+ *
+ * clkadj = scaled_ppm * 10*2^28 / (10^6 * 2^16)
+ * simplifies to
+ * clkadj = scaled_ppm * 2^7 / 5^5
+ */
+#define MV88E6250_CC_SHIFT 28
+#define MV88E6250_CC_MULT (10 << MV88E6250_CC_SHIFT)
+#define MV88E6250_CC_MULT_NUM (1 << 7)
+#define MV88E6250_CC_MULT_DEM 3125ULL
+
+/* Other families:
+ * Raw timestamps are in units of 8-ns clock periods.
+ *
+ * clkadj = scaled_ppm * 8*2^28 / (10^6 * 2^16)
+ * simplifies to
+ * clkadj = scaled_ppm * 2^9 / 5^6
+ */
+#define MV88E6XXX_CC_SHIFT 28
+#define MV88E6XXX_CC_MULT (8 << MV88E6XXX_CC_SHIFT)
+#define MV88E6XXX_CC_MULT_NUM (1 << 9)
+#define MV88E6XXX_CC_MULT_DEM 15625ULL
#define TAI_EVENT_WORK_INTERVAL msecs_to_jiffies(100)
@@ -179,24 +206,14 @@ static void mv88e6352_tai_event_work(struct work_struct *ugly)
static int mv88e6xxx_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
{
struct mv88e6xxx_chip *chip = ptp_to_chip(ptp);
- int neg_adj = 0;
- u32 diff, mult;
- u64 adj;
+ s64 adj;
- if (scaled_ppm < 0) {
- neg_adj = 1;
- scaled_ppm = -scaled_ppm;
- }
- mult = CC_MULT;
- adj = CC_MULT_NUM;
- adj *= scaled_ppm;
- diff = div_u64(adj, CC_MULT_DEM);
+ adj = (s64)scaled_ppm * chip->ptp_cc_mult_num;
+ adj = div_s64(adj, chip->ptp_cc_mult_dem);
mv88e6xxx_reg_lock(chip);
-
timecounter_read(&chip->tstamp_tc);
- chip->tstamp_cc.mult = neg_adj ? mult - diff : mult + diff;
-
+ chip->tstamp_cc.mult = chip->ptp_cc_mult + adj;
mv88e6xxx_reg_unlock(chip);
return 0;
@@ -380,12 +397,24 @@ int mv88e6xxx_ptp_setup(struct mv88e6xxx_chip *chip)
const struct mv88e6xxx_ptp_ops *ptp_ops = chip->info->ops->ptp_ops;
int i;
+ if (chip->info->family == MV88E6XXX_FAMILY_6250) {
+ chip->ptp_cc_shift = MV88E6250_CC_SHIFT;
+ chip->ptp_cc_mult = MV88E6250_CC_MULT;
+ chip->ptp_cc_mult_num = MV88E6250_CC_MULT_NUM;
+ chip->ptp_cc_mult_dem = MV88E6250_CC_MULT_DEM;
+ } else {
+ chip->ptp_cc_shift = MV88E6XXX_CC_SHIFT;
+ chip->ptp_cc_mult = MV88E6XXX_CC_MULT;
+ chip->ptp_cc_mult_num = MV88E6XXX_CC_MULT_NUM;
+ chip->ptp_cc_mult_dem = MV88E6XXX_CC_MULT_DEM;
+ }
+
/* Set up the cycle counter */
memset(&chip->tstamp_cc, 0, sizeof(chip->tstamp_cc));
chip->tstamp_cc.read = mv88e6xxx_ptp_clock_read;
chip->tstamp_cc.mask = CYCLECOUNTER_MASK(32);
- chip->tstamp_cc.mult = CC_MULT;
- chip->tstamp_cc.shift = CC_SHIFT;
+ chip->tstamp_cc.mult = chip->ptp_cc_mult;
+ chip->tstamp_cc.shift = chip->ptp_cc_shift;
timecounter_init(&chip->tstamp_tc, &chip->tstamp_cc,
ktime_to_ns(ktime_get_real()));
@@ -397,7 +426,6 @@ int mv88e6xxx_ptp_setup(struct mv88e6xxx_chip *chip)
chip->ptp_clock_info.owner = THIS_MODULE;
snprintf(chip->ptp_clock_info.name, sizeof(chip->ptp_clock_info.name),
"%s", dev_name(chip->dev));
- chip->ptp_clock_info.max_adj = 1000000;
chip->ptp_clock_info.n_ext_ts = ptp_ops->n_ext_ts;
chip->ptp_clock_info.n_per_out = 0;
@@ -413,6 +441,7 @@ int mv88e6xxx_ptp_setup(struct mv88e6xxx_chip *chip)
}
chip->ptp_clock_info.pin_config = chip->pin_config;
+ chip->ptp_clock_info.max_adj = MV88E6XXX_MAX_ADJ_PPB;
chip->ptp_clock_info.adjfine = mv88e6xxx_ptp_adjfine;
chip->ptp_clock_info.adjtime = mv88e6xxx_ptp_adjtime;
chip->ptp_clock_info.gettime64 = mv88e6xxx_ptp_gettime;
--
2.22.0
^ 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