* Re: [PATCH net-next 1/2] net: dsa: store CPU switch structure in the tree
From: Andrew Lunn @ 2017-01-18 12:49 UTC (permalink / raw)
To: Vivien Didelot
Cc: netdev, linux-kernel, kernel, David S. Miller, Florian Fainelli
In-Reply-To: <20170118014139.31417-1-vivien.didelot@savoirfairelinux.com>
On Tue, Jan 17, 2017 at 08:41:38PM -0500, Vivien Didelot wrote:
> Store a dsa_switch pointer to the CPU switch in the tree instead of only
> its index. This avoids the need to initialize it to -1.
Hi Vivien
A cover note would be nice.
I expect these patches are going to clash with Florians platform
device patches, but they are on hold for a while. Also John's rework
of the multi-cpu ports, but that has gone quite.
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Andrew
>
> Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
> ---
> include/net/dsa.h | 8 ++++----
> net/dsa/dsa.c | 7 +++----
> net/dsa/dsa2.c | 5 ++---
> 3 files changed, 9 insertions(+), 11 deletions(-)
>
> diff --git a/include/net/dsa.h b/include/net/dsa.h
> index 454667952d6d..82f7019f27f2 100644
> --- a/include/net/dsa.h
> +++ b/include/net/dsa.h
> @@ -124,7 +124,7 @@ struct dsa_switch_tree {
> /*
> * The switch and port to which the CPU is attached.
> */
> - s8 cpu_switch;
> + struct dsa_switch *cpu_switch;
> s8 cpu_port;
>
> /*
> @@ -211,7 +211,7 @@ struct dsa_switch {
>
> static inline bool dsa_is_cpu_port(struct dsa_switch *ds, int p)
> {
> - return !!(ds->index == ds->dst->cpu_switch && p == ds->dst->cpu_port);
> + return !!(ds == ds->dst->cpu_switch && p == ds->dst->cpu_port);
> }
>
> static inline bool dsa_is_dsa_port(struct dsa_switch *ds, int p)
> @@ -234,10 +234,10 @@ static inline u8 dsa_upstream_port(struct dsa_switch *ds)
> * Else return the (DSA) port number that connects to the
> * switch that is one hop closer to the cpu.
> */
> - if (dst->cpu_switch == ds->index)
> + if (dst->cpu_switch == ds)
> return dst->cpu_port;
> else
> - return ds->rtable[dst->cpu_switch];
> + return ds->rtable[dst->cpu_switch->index];
> }
>
> struct switchdev_trans;
> diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c
> index 96d1544df518..cb42655ba7da 100644
> --- a/net/dsa/dsa.c
> +++ b/net/dsa/dsa.c
> @@ -225,12 +225,12 @@ static int dsa_switch_setup_one(struct dsa_switch *ds, struct device *parent)
> continue;
>
> if (!strcmp(name, "cpu")) {
> - if (dst->cpu_switch != -1) {
> + if (!dst->cpu_switch) {
> netdev_err(dst->master_netdev,
> "multiple cpu ports?!\n");
> return -EINVAL;
> }
> - dst->cpu_switch = index;
> + dst->cpu_switch = ds;
> dst->cpu_port = i;
> ds->cpu_port_mask |= 1 << i;
> } else if (!strcmp(name, "dsa")) {
> @@ -254,7 +254,7 @@ static int dsa_switch_setup_one(struct dsa_switch *ds, struct device *parent)
> * tagging protocol to the preferred tagging format of this
> * switch.
> */
> - if (dst->cpu_switch == index) {
> + if (dst->cpu_switch == ds) {
> enum dsa_tag_protocol tag_protocol;
>
> tag_protocol = ops->get_tag_protocol(ds);
> @@ -757,7 +757,6 @@ static int dsa_setup_dst(struct dsa_switch_tree *dst, struct net_device *dev,
>
> dst->pd = pd;
> dst->master_netdev = dev;
> - dst->cpu_switch = -1;
> dst->cpu_port = -1;
>
> for (i = 0; i < pd->nr_chips; i++) {
> diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c
> index a1f26fc0f585..a9bf28d9f41f 100644
> --- a/net/dsa/dsa2.c
> +++ b/net/dsa/dsa2.c
> @@ -57,7 +57,6 @@ static struct dsa_switch_tree *dsa_add_dst(u32 tree)
> if (!dst)
> return NULL;
> dst->tree = tree;
> - dst->cpu_switch = -1;
> INIT_LIST_HEAD(&dst->list);
> list_add_tail(&dsa_switch_trees, &dst->list);
> kref_init(&dst->refcount);
> @@ -456,8 +455,8 @@ static int dsa_cpu_parse(struct device_node *port, u32 index,
> if (!dst->master_netdev)
> dst->master_netdev = ethernet_dev;
>
> - if (dst->cpu_switch == -1) {
> - dst->cpu_switch = ds->index;
> + if (!dst->cpu_switch) {
> + dst->cpu_switch = ds;
> dst->cpu_port = index;
> }
>
> --
> 2.11.0
>
^ permalink raw reply
* [PATCH iproute2] Revert "man pages: add man page for skbmod action"
From: Jiri Benc @ 2017-01-18 12:37 UTC (permalink / raw)
To: netdev; +Cc: Lucas Bates, Jamal Hadi Salim, Stephen Hemminger
This reverts commit a40995d1c79e5a1b8711f6cd26eca9807fc4dd50.
The patch is missing the actual tc-skbmod.8 file which causes 'make
install' to fail:
install -m 0755 -d /tmp/ip/usr/share/man/man8
install -m 0644 ip-address.8 ip-link.8 ip-route.8 ip.8 arpd.8 lnstat.8
routel.8 rtacct.8 rtmon.8 rtpr.8 ss.8 tc.8 tc-bfifo.8 tc-bpf.8 tc-cbq.8
tc-cbq-details.8 tc-choke.8 tc-codel.8 tc-fq.8 tc-drr.8 tc-ematch.8
tc-fq_codel.8 tc-hfsc.8 tc-htb.8 tc-pie.8 tc-mqprio.8 tc-netem.8 tc-pfifo.8
tc-pfifo_fast.8 tc-prio.8 tc-red.8 tc-sfb.8 tc-sfq.8 tc-stab.8 tc-tbf.8
bridge.8 rtstat.8 ctstat.8 nstat.8 routef.8 ip-addrlabel.8 ip-fou.8 ip-gue.8
ip-l2tp.8 ip-macsec.8 ip-maddress.8 ip-monitor.8 ip-mroute.8 ip-neighbour.8
ip-netns.8 ip-ntable.8 ip-rule.8 ip-tunnel.8 ip-xfrm.8 ip-tcp_metrics.8
ip-netconf.8 ip-token.8 tipc.8 tipc-bearer.8 tipc-link.8 tipc-media.8
tipc-nametable.8 tipc-node.8 tipc-socket.8 tc-basic.8 tc-cgroup.8 tc-flow.8
tc-flower.8 tc-fw.8 tc-route.8 tc-tcindex.8 tc-u32.8 tc-matchall.8
tc-connmark.8 tc-csum.8 tc-mirred.8 tc-nat.8 tc-pedit.8 tc-police.8
tc-simple.8 tc-skbedit.8 tc-vlan.8 tc-xt.8 tc-ife.8 tc-skbmod.8
tc-tunnel_key.8 devlink.8 devlink-dev.8 devlink-monitor.8 devlink-port.8
devlink-sb.8 /tmp/ip/usr/share/man/man8
install: cannot stat ‘tc-skbmod.8’: No such file or directory
make[2]: *** [install] Error 1
make[1]: *** [install] Error 2
Signed-off-by: Jiri Benc <jbenc@redhat.com>
---
man/man8/Makefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/man/man8/Makefile b/man/man8/Makefile
index d4cb01ac3f13..77d347ca98fc 100644
--- a/man/man8/Makefile
+++ b/man/man8/Makefile
@@ -16,7 +16,7 @@ MAN8PAGES = $(TARGETS) ip.8 arpd.8 lnstat.8 routel.8 rtacct.8 rtmon.8 rtpr.8 ss.
tc-basic.8 tc-cgroup.8 tc-flow.8 tc-flower.8 tc-fw.8 tc-route.8 \
tc-tcindex.8 tc-u32.8 tc-matchall.8 \
tc-connmark.8 tc-csum.8 tc-mirred.8 tc-nat.8 tc-pedit.8 tc-police.8 \
- tc-simple.8 tc-skbedit.8 tc-vlan.8 tc-xt.8 tc-ife.8 tc-skbmod.8 \
+ tc-simple.8 tc-skbedit.8 tc-vlan.8 tc-xt.8 tc-ife.8 \
tc-tunnel_key.8 \
devlink.8 devlink-dev.8 devlink-monitor.8 devlink-port.8 devlink-sb.8
--
1.8.3.1
^ permalink raw reply related
* Re: [PATCH] net: add regs attribute to phy device for user diagnose
From: Zefir Kurtisi @ 2017-01-18 12:37 UTC (permalink / raw)
To: YUAN Linyu, David Miller, f.fainelli@gmail.com
Cc: cugyly@163.com, andrew@lunn.ch, netdev@vger.kernel.org
In-Reply-To: <8729016553E3654398EA69218DA29EEF15A58E63@cnshjmbx04>
[-- Attachment #1: Type: text/plain, Size: 1058 bytes --]
On 01/17/2017 01:11 AM, YUAN Linyu wrote:
>
>
>> -----Original Message-----
>> From: David Miller [mailto:davem@davemloft.net]
>> Sent: Tuesday, January 17, 2017 5:54 AM
>> To: f.fainelli@gmail.com
>> Cc: cugyly@163.com; andrew@lunn.ch; netdev@vger.kernel.org; YUAN Linyu
>> Subject: Re: [PATCH] net: add regs attribute to phy device for user diagnose
>>
>> From: Florian Fainelli <f.fainelli@gmail.com>
>> Date: Mon, 16 Jan 2017 12:22:16 -0800
>>
>>>
>>> So why not add support in ethtool for reading PHY registers if you need
>>> it? There are handful of PHY "things" in ethtool, such as reading
>>> counters, configuring downshift etc., adding support for dumping
>>> registers does not sound out of space.
> Thanks, I will try this direction.
>>
>> Agreed.
... on the other hand, having direct RW access to MDIO regs can ease your life
greatly during bring-up / debugging of PHYs.
Attached is a patch we are using to track down PHY problems at register level, not
for integrating into the kernel but as a handy tool for developers.
Cheers,
Zefir
[-- Attachment #2: 0001-phy_device-add-sysfs-access-to-mdio-registers.patch --]
[-- Type: text/x-patch, Size: 3606 bytes --]
>From f90fced08ca6094919483b0d9a4bde50053bbbd7 Mon Sep 17 00:00:00 2001
From: Zefir Kurtisi <zefir.kurtisi@neratec.com>
Date: Wed, 18 Jan 2017 13:17:42 +0100
Subject: [PATCH] phy_device: add sysfs access to mdio registers
This commit adds a direct RW access to MDIO registers
over sysfs.
It is meant only for debugging and testing of PHYs
at register level.
WARNING: Writing to registers directly in most cases
will interfere with the phylib and/or upper layer
components or even crash your system.
Signed-off-by: Zefir Kurtisi <zefir.kurtisi@neratec.com>
---
drivers/net/phy/phy_device.c | 111 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 111 insertions(+)
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 92b0838..16646763 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -617,10 +617,121 @@ phy_has_fixups_show(struct device *dev, struct device_attribute *attr,
}
static DEVICE_ATTR_RO(phy_has_fixups);
+static ssize_t
+mdio_reg_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct phy_device *phydev = to_phy_device(dev);
+ struct mii_bus *bus = to_mii_bus(dev);
+ int regnum;
+ int val;
+
+ if (sscanf(attr->attr.name, "%d", ®num) != 1)
+ return -EINVAL;
+
+ val = mdiobus_read(bus, phydev->mdio.addr, regnum);
+ if (val < 0)
+ return -EIO;
+
+ return sprintf(buf, "0x%.4x\n", val);
+}
+
+static ssize_t mdio_reg_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ struct phy_device *phydev = to_phy_device(dev);
+ struct mii_bus *bus = to_mii_bus(dev);
+ int regnum;
+ int val;
+ int err;
+
+ if (sscanf(attr->attr.name, "%d", ®num) != 1)
+ return -EINVAL;
+
+ if (sscanf(buf, "%x", &val) != 1)
+ return -EINVAL;
+
+ if (val < 0 || val > 0xffff)
+ return -EINVAL;
+
+ err = mdiobus_write(bus, phydev->mdio.addr, regnum, val);
+ if (err < 0)
+ return -EIO;
+
+ return size;
+}
+
+#define MDIO_REG(_name) \
+ DEVICE_ATTR(_name, (S_IWUSR | S_IRUGO), mdio_reg_show, mdio_reg_store)
+
+static MDIO_REG(0);
+static MDIO_REG(1);
+static MDIO_REG(2);
+static MDIO_REG(3);
+static MDIO_REG(4);
+static MDIO_REG(5);
+static MDIO_REG(6);
+static MDIO_REG(7);
+static MDIO_REG(8);
+static MDIO_REG(9);
+static MDIO_REG(10);
+static MDIO_REG(11);
+static MDIO_REG(12);
+static MDIO_REG(13);
+static MDIO_REG(14);
+static MDIO_REG(15);
+static MDIO_REG(16);
+static MDIO_REG(17);
+static MDIO_REG(18);
+static MDIO_REG(19);
+static MDIO_REG(20);
+static MDIO_REG(21);
+static MDIO_REG(22);
+static MDIO_REG(23);
+static MDIO_REG(24);
+static MDIO_REG(25);
+static MDIO_REG(26);
+static MDIO_REG(27);
+static MDIO_REG(28);
+static MDIO_REG(29);
+static MDIO_REG(30);
+static MDIO_REG(31);
+
static struct attribute *phy_dev_attrs[] = {
&dev_attr_phy_id.attr,
&dev_attr_phy_interface.attr,
&dev_attr_phy_has_fixups.attr,
+ &dev_attr_0.attr,
+ &dev_attr_1.attr,
+ &dev_attr_2.attr,
+ &dev_attr_3.attr,
+ &dev_attr_4.attr,
+ &dev_attr_5.attr,
+ &dev_attr_6.attr,
+ &dev_attr_7.attr,
+ &dev_attr_8.attr,
+ &dev_attr_9.attr,
+ &dev_attr_10.attr,
+ &dev_attr_11.attr,
+ &dev_attr_12.attr,
+ &dev_attr_13.attr,
+ &dev_attr_14.attr,
+ &dev_attr_15.attr,
+ &dev_attr_16.attr,
+ &dev_attr_17.attr,
+ &dev_attr_18.attr,
+ &dev_attr_19.attr,
+ &dev_attr_20.attr,
+ &dev_attr_21.attr,
+ &dev_attr_22.attr,
+ &dev_attr_23.attr,
+ &dev_attr_24.attr,
+ &dev_attr_25.attr,
+ &dev_attr_26.attr,
+ &dev_attr_27.attr,
+ &dev_attr_28.attr,
+ &dev_attr_29.attr,
+ &dev_attr_30.attr,
+ &dev_attr_31.attr,
NULL,
};
ATTRIBUTE_GROUPS(phy_dev);
--
2.7.4
^ permalink raw reply related
* Re: [PATCH] virtio: don't set VIRTIO_NET_HDR_F_DATA_VALID on xmit
From: Sergei Shtylyov @ 2017-01-18 12:07 UTC (permalink / raw)
To: Rolf Neugebauer, netdev; +Cc: mst, davem, jasowang, rppt
In-Reply-To: <20170117181351.98291-1-rolf.neugebauer@docker.com>
Hello!
On 1/17/2017 9:13 PM, Rolf Neugebauer wrote:
> This patch part reverts fd2a0437dc33 and e858fae2b0b8 which introduced a
You also need to specify the patch summary lines enclosed in ("").
> subtle change in how the virtio_net flags are derived from the SKBs
> ip_summed field.
>
> With the above commits, the flags are set to VIRTIO_NET_HDR_F_DATA_VALID
> when ip_summed == CHECKSUM_UNNECESSARY, thus treating it differently to
> ip_summed == CHECKSUM_NONE, which should be the same.
>
> Further, the virtio spec 1.0 / CS04 explicitly says that
> VIRTIO_NET_HDR_F_DATA_VALID must not be set by the driver.
>
> Signed-off-by: Rolf Neugebauer <rolf.neugebauer@docker.com>
[...]
MBR, Sergei
^ permalink raw reply
* Re: [PATCH net-next v4 1/2] net sched actions: Add support for user cookies
From: Jamal Hadi Salim @ 2017-01-18 12:13 UTC (permalink / raw)
To: Paul Blakey, davem
Cc: netdev, jiri, john.fastabend, simon.horman, mrv, hadarh, ogerlitz,
roid, xiyou.wangcong, daniel
In-Reply-To: <7f598705-4cef-e2d4-0da2-1068baabf4fe@mellanox.com>
On 17-01-18 06:47 AM, Paul Blakey wrote:
>
>
> On 17/01/2017 13:11, Jamal Hadi Salim wrote:
>> From: Jamal Hadi Salim <jhs@mojatatu.com>
>>
>> Introduce optional 128-bit action cookie.
>> Like all other cookie schemes in the networking world (eg in protocols
>> like http or existing kernel fib protocol field, etc) the idea is to save
>> user state that when retrieved serves as a correlator. The kernel
>> _should not_ intepret it. The user can store whatever they wish in the
>> 128 bits.
>>
>> Sample exercise(showing variable length use of cookie)
>>
>> .. create an accept action with cookie a1b2c3d4
>> sudo $TC actions add action ok index 1 cookie a1b2c3d4
>>
>> .. dump all gact actions..
>> sudo $TC -s actions ls action gact
>>
>> action order 0: gact action pass
>> random type none pass val 0
>> index 1 ref 1 bind 0 installed 5 sec used 5 sec
>> Action statistics:
>> Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
>> backlog 0b 0p requeues 0
>> cookie a1b2c3d4
>>
>> .. bind the accept action to a filter..
>> sudo $TC filter add dev lo parent ffff: protocol ip prio 1 \
>> u32 match ip dst 127.0.0.1/32 flowid 1:1 action gact index 1
>>
>> ... send some traffic..
>> $ ping 127.0.0.1 -c 3
>> PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
>> 64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.020 ms
>> 64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.027 ms
>> 64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.038 ms
>>
>> --- 127.0.0.1 ping statistics ---
>> 3 packets transmitted, 3 received, 0% packet loss, time 2109ms
>> rtt min/avg/max/mdev = 0.020/0.028/0.038/0.008 ms 1
>>
>> ... show some stats
>> $ sudo $TC -s actions get action gact index 1
>>
>> action order 1: gact action pass
>> random type none pass val 0
>> index 1 ref 2 bind 1 installed 204 sec used 5 sec
>> Action statistics:
>> Sent 12168 bytes 164 pkt (dropped 0, overlimits 0 requeues 0)
>> backlog 0b 0p requeues 0
>> cookie a1b2c3d4
>>
>> .. try longer cookie...
>> $ sudo $TC actions replace action ok index 1 cookie 1234567890abcdef
>> .. dump..
>> $ sudo $TC -s actions ls action gact
>>
>> action order 1: gact action pass
>> random type none pass val 0
>> index 1 ref 2 bind 1 installed 204 sec used 5 sec
>> Action statistics:
>> Sent 12168 bytes 164 pkt (dropped 0, overlimits 0 requeues 0)
>> backlog 0b 0p requeues 0
>> cookie 1234567890abcdef
>>
>> Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
>> ---
>> include/net/act_api.h | 1 +
>> include/net/pkt_cls.h | 8 ++++++++
>> include/uapi/linux/pkt_cls.h | 3 +++
>> net/sched/act_api.c | 25 +++++++++++++++++++++++++
>> 4 files changed, 37 insertions(+)
>>
>> diff --git a/include/net/act_api.h b/include/net/act_api.h
>> index 1d71644..0692458 100644
>> --- a/include/net/act_api.h
>> +++ b/include/net/act_api.h
>> @@ -41,6 +41,7 @@ struct tc_action {
>> struct rcu_head tcfa_rcu;
>> struct gnet_stats_basic_cpu __percpu *cpu_bstats;
>> struct gnet_stats_queue __percpu *cpu_qstats;
>> + struct tc_cookie *act_ck;
>> };
>> #define tcf_head common.tcfa_head
>> #define tcf_index common.tcfa_index
>> diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h
>> index f0a0514..e0bc7e8 100644
>> --- a/include/net/pkt_cls.h
>> +++ b/include/net/pkt_cls.h
>> @@ -515,4 +515,12 @@ struct tc_cls_bpf_offload {
>> u32 gen_flags;
>> };
>>
>> +
>> +/* This structure holds cookie structure that is passed from user
>> + * to the kernel for actions and classifiers
>> + */
>> +struct tc_cookie {
>> + unsigned char ck[TC_COOKIE_MAX_SIZE];
>> + unsigned char ck_len;
>> +};
>> #endif
>> diff --git a/include/uapi/linux/pkt_cls.h b/include/uapi/linux/pkt_cls.h
>> index 1e5e1dd..2d2414e 100644
>> --- a/include/uapi/linux/pkt_cls.h
>> +++ b/include/uapi/linux/pkt_cls.h
>> @@ -4,6 +4,8 @@
>> #include <linux/types.h>
>> #include <linux/pkt_sched.h>
>>
>> +#define TC_COOKIE_MAX_SIZE 16
>> +
>> /* Action attributes */
>> enum {
>> TCA_ACT_UNSPEC,
>> @@ -12,6 +14,7 @@ enum {
>> TCA_ACT_INDEX,
>> TCA_ACT_STATS,
>> TCA_ACT_PAD,
>> + TCA_ACT_COOKIE,
>> __TCA_ACT_MAX
>> };
>>
>> diff --git a/net/sched/act_api.c b/net/sched/act_api.c
>> index f04715a..43f1f42 100644
>> --- a/net/sched/act_api.c
>> +++ b/net/sched/act_api.c
>> @@ -24,6 +24,7 @@
>> #include <net/net_namespace.h>
>> #include <net/sock.h>
>> #include <net/sch_generic.h>
>> +#include <net/pkt_cls.h>
>> #include <net/act_api.h>
>> #include <net/netlink.h>
>>
>> @@ -33,6 +34,7 @@ static void free_tcf(struct rcu_head *head)
>>
>> free_percpu(p->cpu_bstats);
>> free_percpu(p->cpu_qstats);
>> + kfree(p->act_ck);
>> kfree(p);
>> }
>>
>> @@ -475,6 +477,12 @@ int tcf_action_destroy(struct list_head *actions,
>> int bind)
>> goto nla_put_failure;
>> if (tcf_action_copy_stats(skb, a, 0))
>> goto nla_put_failure;
>> + if (a->act_ck) {
>> + if (nla_put(skb, TCA_ACT_COOKIE, a->act_ck->ck_len,
>> + a->act_ck))
>> + goto nla_put_failure;
>> + }
>> +
>> nest = nla_nest_start(skb, TCA_OPTIONS);
>> if (nest == NULL)
>> goto nla_put_failure;
>> @@ -575,6 +583,23 @@ struct tc_action *tcf_action_init_1(struct net
>> *net, struct nlattr *nla,
>> if (err < 0)
>> goto err_mod;
>>
>> + if (tb[TCA_ACT_COOKIE]) {
>> + if (nla_len(tb[TCA_ACT_COOKIE]) > TC_COOKIE_MAX_SIZE) {
>> + err = -EINVAL;
>> + goto err_mod;
>> + }
>> +
>> + a->act_ck = kzalloc(sizeof(*a->act_ck), GFP_KERNEL);
>
> Hi Jamal, How about
> struct tc_cookie {
> unsigned int len;
> unsigned long ck[0];
> };
>
> and then:
>
> a->act_ck = kzalloc(sizeof(*a->act_ck) + nla_len(tb[TCA_ACT_COOKIE]),
> GFP_KERNEL);
>
> to save some space?
>
Doesnt make much of a difference in the larger scope. Look at Daniel's
email;
I started incorporating his change...
(Unfortunately my time has run out so i will post the patch later or
tommorow).
>
>
>> + if (unlikely(!a->act_ck)) {
>> + err = -ENOMEM;
>> + goto err_mod;
>> + }
>> +
>> + memcpy(a->act_ck->ck, nla_data(tb[TCA_ACT_COOKIE]),
>> + nla_len(tb[TCA_ACT_COOKIE]));
>> + a->act_ck->ck_len = nla_len(tb[TCA_ACT_COOKIE]);
>> + }
>> +
>> /* module count goes up only when brand new policy is created
>> * if it exists and is only bound to in a_o->init() then
>> * ACT_P_CREATED is not returned (a zero is).
>>
>
>
> Besides if I'll reuse tc_cookie for classifiers, I'll need 20 bytes :)
>
You should be able to change the define when you submit your patch.
cheers,
jamal
^ permalink raw reply
* [PATCH 1/2] can: c_can_pci: fix null-pointer-deref in c_can_start() - set device pointer
From: Marc Kleine-Budde @ 2017-01-18 12:08 UTC (permalink / raw)
To: netdev
Cc: davem, linux-can, kernel, Einar Jón, linux-stable,
Marc Kleine-Budde
In-Reply-To: <20170118120852.6095-1-mkl@pengutronix.de>
From: Einar Jón <tolvupostur@gmail.com>
The priv->device pointer for c_can_pci is never set, but it is used
without a NULL check in c_can_start(). Setting it in c_can_pci_probe()
like c_can_plat_probe() prevents c_can_pci.ko from crashing, with and
without CONFIG_PM.
This might also cause the pm_runtime_*() functions in c_can.c to
actually be executed for c_can_pci devices - they are the only other
place where priv->device is used, but they all contain a null check.
Signed-off-by: Einar Jón <tolvupostur@gmail.com>
Cc: linux-stable <stable@vger.kernel.org>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
drivers/net/can/c_can/c_can_pci.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/can/c_can/c_can_pci.c b/drivers/net/can/c_can/c_can_pci.c
index 7be393c96b1a..cf7c18947189 100644
--- a/drivers/net/can/c_can/c_can_pci.c
+++ b/drivers/net/can/c_can/c_can_pci.c
@@ -161,6 +161,7 @@ static int c_can_pci_probe(struct pci_dev *pdev,
dev->irq = pdev->irq;
priv->base = addr;
+ priv->device = &pdev->dev;
if (!c_can_pci_data->freq) {
dev_err(&pdev->dev, "no clock frequency defined\n");
--
2.11.0
^ permalink raw reply related
* pull-request: can 2017-01-18
From: Marc Kleine-Budde @ 2017-01-18 12:08 UTC (permalink / raw)
To: netdev; +Cc: davem, linux-can, kernel
Hello David,
this is a pull request for net/master consisting of two patches.
In the first patch Einar Jón fixes a NULL-pointer-deref in the c_can_pci
driver. In the second patch Yegor Yefremov fixes the clock handling in the
ti_hecc driver.
regards,
Marc
---
The following changes since commit 93b43fd137cd8865adf9978ab9870a344365d3af:
net: phy: dp83848: add DP83620 PHY support (2017-01-17 15:47:25 -0500)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can.git tags/linux-can-fixes-for-4.10-20170118
for you to fetch changes up to befa60113ce7ea270cb51eada28443ca2756f480:
can: ti_hecc: add missing prepare and unprepare of the clock (2017-01-18 13:03:15 +0100)
----------------------------------------------------------------
linux-can-fixes-for-4.10-20170118
----------------------------------------------------------------
Einar Jón (1):
can: c_can_pci: fix null-pointer-deref in c_can_start() - set device pointer
Yegor Yefremov (1):
can: ti_hecc: add missing prepare and unprepare of the clock
drivers/net/can/c_can/c_can_pci.c | 1 +
drivers/net/can/ti_hecc.c | 16 ++++++++++++----
2 files changed, 13 insertions(+), 4 deletions(-)
^ permalink raw reply
* [PATCH 2/2] can: ti_hecc: add missing prepare and unprepare of the clock
From: Marc Kleine-Budde @ 2017-01-18 12:08 UTC (permalink / raw)
To: netdev
Cc: davem, linux-can, kernel, Yegor Yefremov, linux-stable,
Marc Kleine-Budde
In-Reply-To: <20170118120852.6095-1-mkl@pengutronix.de>
From: Yegor Yefremov <yegorslists@googlemail.com>
In order to make the driver work with the common clock framework, this
patch converts the clk_enable()/clk_disable() to
clk_prepare_enable()/clk_disable_unprepare().
Also add error checking for clk_prepare_enable().
Signed-off-by: Yegor Yefremov <yegorslists@googlemail.com>
Cc: linux-stable <stable@vger.kernel.org>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
drivers/net/can/ti_hecc.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/drivers/net/can/ti_hecc.c b/drivers/net/can/ti_hecc.c
index 680d1ff07a55..6749b1829469 100644
--- a/drivers/net/can/ti_hecc.c
+++ b/drivers/net/can/ti_hecc.c
@@ -948,7 +948,12 @@ static int ti_hecc_probe(struct platform_device *pdev)
netif_napi_add(ndev, &priv->napi, ti_hecc_rx_poll,
HECC_DEF_NAPI_WEIGHT);
- clk_enable(priv->clk);
+ err = clk_prepare_enable(priv->clk);
+ if (err) {
+ dev_err(&pdev->dev, "clk_prepare_enable() failed\n");
+ goto probe_exit_clk;
+ }
+
err = register_candev(ndev);
if (err) {
dev_err(&pdev->dev, "register_candev() failed\n");
@@ -981,7 +986,7 @@ static int ti_hecc_remove(struct platform_device *pdev)
struct ti_hecc_priv *priv = netdev_priv(ndev);
unregister_candev(ndev);
- clk_disable(priv->clk);
+ clk_disable_unprepare(priv->clk);
clk_put(priv->clk);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
iounmap(priv->base);
@@ -1006,7 +1011,7 @@ static int ti_hecc_suspend(struct platform_device *pdev, pm_message_t state)
hecc_set_bit(priv, HECC_CANMC, HECC_CANMC_PDR);
priv->can.state = CAN_STATE_SLEEPING;
- clk_disable(priv->clk);
+ clk_disable_unprepare(priv->clk);
return 0;
}
@@ -1015,8 +1020,11 @@ static int ti_hecc_resume(struct platform_device *pdev)
{
struct net_device *dev = platform_get_drvdata(pdev);
struct ti_hecc_priv *priv = netdev_priv(dev);
+ int err;
- clk_enable(priv->clk);
+ err = clk_prepare_enable(priv->clk);
+ if (err)
+ return err;
hecc_clear_bit(priv, HECC_CANMC, HECC_CANMC_PDR);
priv->can.state = CAN_STATE_ERROR_ACTIVE;
--
2.11.0
^ permalink raw reply related
* Re: [PATCH v2] can: ti_hecc: add missing prepare and unprepare of the clock
From: Marc Kleine-Budde @ 2017-01-18 12:03 UTC (permalink / raw)
To: yegorslists, linux-can; +Cc: netdev, wg
In-Reply-To: <1484735757-21172-1-git-send-email-yegorslists@googlemail.com>
[-- Attachment #1.1: Type: text/plain, Size: 2614 bytes --]
On 01/18/2017 11:35 AM, yegorslists@googlemail.com wrote:
> From: Yegor Yefremov <yegorslists@googlemail.com>
>
> In order to make the driver work with the common clock framework, this
> patch converts the clk_enable()/clk_disable() to
> clk_prepare_enable()/clk_disable_unprepare().
>
> Also add error checking for clk_prepare_enable().
>
> Signed-off-by: Yegor Yefremov <yegorslists@googlemail.com>
> ---
> Changes v1 -> v2:
> - add error checking for clk_prepare_enable (Marc Kleine-Budde)
>
> drivers/net/can/ti_hecc.c | 13 +++++++++----
> 1 file changed, 9 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/net/can/ti_hecc.c b/drivers/net/can/ti_hecc.c
> index 680d1ff..8771531 100644
> --- a/drivers/net/can/ti_hecc.c
> +++ b/drivers/net/can/ti_hecc.c
> @@ -948,7 +948,12 @@ static int ti_hecc_probe(struct platform_device *pdev)
> netif_napi_add(ndev, &priv->napi, ti_hecc_rx_poll,
> HECC_DEF_NAPI_WEIGHT);
>
> - clk_enable(priv->clk);
> + err = clk_prepare_enable(priv->clk);
> + if (err) {
> + dev_err(&pdev->dev, "clk_prepare_enable() failed\n");
> + goto probe_exit_clk;
> + }
> +
> err = register_candev(ndev);
> if (err) {
> dev_err(&pdev->dev, "register_candev() failed\n");
> @@ -981,7 +986,7 @@ static int ti_hecc_remove(struct platform_device *pdev)
> struct ti_hecc_priv *priv = netdev_priv(ndev);
>
> unregister_candev(ndev);
> - clk_disable(priv->clk);
> + clk_disable_unprepare(priv->clk);
> clk_put(priv->clk);
> res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> iounmap(priv->base);
> @@ -1006,7 +1011,7 @@ static int ti_hecc_suspend(struct platform_device *pdev, pm_message_t state)
> hecc_set_bit(priv, HECC_CANMC, HECC_CANMC_PDR);
> priv->can.state = CAN_STATE_SLEEPING;
>
> - clk_disable(priv->clk);
> + clk_disable_unprepare(priv->clk);
>
> return 0;
> }
> @@ -1016,7 +1021,7 @@ static int ti_hecc_resume(struct platform_device *pdev)
> struct net_device *dev = platform_get_drvdata(pdev);
> struct ti_hecc_priv *priv = netdev_priv(dev);
>
> - clk_enable(priv->clk);
> + clk_prepare_enable(priv->clk);
I've added error checking here, too.
>
> hecc_clear_bit(priv, HECC_CANMC, HECC_CANMC_PDR);
> priv->can.state = CAN_STATE_ERROR_ACTIVE;
>
Applied to can.
Tnx,
Marc
--
Pengutronix e.K. | Marc Kleine-Budde |
Industrial Linux Solutions | Phone: +49-231-2826-924 |
Vertretung West/Dortmund | Fax: +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de |
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply
* Re: [PATCH net-next v4 1/2] net sched actions: Add support for user cookies
From: Paul Blakey @ 2017-01-18 11:47 UTC (permalink / raw)
To: Jamal Hadi Salim, davem
Cc: paulb, netdev, jiri, john.fastabend, simon.horman, mrv, hadarh,
ogerlitz, roid, xiyou.wangcong, daniel
In-Reply-To: <1484651509-27500-2-git-send-email-jhs@emojatatu.com>
On 17/01/2017 13:11, Jamal Hadi Salim wrote:
> From: Jamal Hadi Salim <jhs@mojatatu.com>
>
> Introduce optional 128-bit action cookie.
> Like all other cookie schemes in the networking world (eg in protocols
> like http or existing kernel fib protocol field, etc) the idea is to save
> user state that when retrieved serves as a correlator. The kernel
> _should not_ intepret it. The user can store whatever they wish in the
> 128 bits.
>
> Sample exercise(showing variable length use of cookie)
>
> .. create an accept action with cookie a1b2c3d4
> sudo $TC actions add action ok index 1 cookie a1b2c3d4
>
> .. dump all gact actions..
> sudo $TC -s actions ls action gact
>
> action order 0: gact action pass
> random type none pass val 0
> index 1 ref 1 bind 0 installed 5 sec used 5 sec
> Action statistics:
> Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
> backlog 0b 0p requeues 0
> cookie a1b2c3d4
>
> .. bind the accept action to a filter..
> sudo $TC filter add dev lo parent ffff: protocol ip prio 1 \
> u32 match ip dst 127.0.0.1/32 flowid 1:1 action gact index 1
>
> ... send some traffic..
> $ ping 127.0.0.1 -c 3
> PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
> 64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.020 ms
> 64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.027 ms
> 64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.038 ms
>
> --- 127.0.0.1 ping statistics ---
> 3 packets transmitted, 3 received, 0% packet loss, time 2109ms
> rtt min/avg/max/mdev = 0.020/0.028/0.038/0.008 ms 1
>
> ... show some stats
> $ sudo $TC -s actions get action gact index 1
>
> action order 1: gact action pass
> random type none pass val 0
> index 1 ref 2 bind 1 installed 204 sec used 5 sec
> Action statistics:
> Sent 12168 bytes 164 pkt (dropped 0, overlimits 0 requeues 0)
> backlog 0b 0p requeues 0
> cookie a1b2c3d4
>
> .. try longer cookie...
> $ sudo $TC actions replace action ok index 1 cookie 1234567890abcdef
> .. dump..
> $ sudo $TC -s actions ls action gact
>
> action order 1: gact action pass
> random type none pass val 0
> index 1 ref 2 bind 1 installed 204 sec used 5 sec
> Action statistics:
> Sent 12168 bytes 164 pkt (dropped 0, overlimits 0 requeues 0)
> backlog 0b 0p requeues 0
> cookie 1234567890abcdef
>
> Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
> ---
> include/net/act_api.h | 1 +
> include/net/pkt_cls.h | 8 ++++++++
> include/uapi/linux/pkt_cls.h | 3 +++
> net/sched/act_api.c | 25 +++++++++++++++++++++++++
> 4 files changed, 37 insertions(+)
>
> diff --git a/include/net/act_api.h b/include/net/act_api.h
> index 1d71644..0692458 100644
> --- a/include/net/act_api.h
> +++ b/include/net/act_api.h
> @@ -41,6 +41,7 @@ struct tc_action {
> struct rcu_head tcfa_rcu;
> struct gnet_stats_basic_cpu __percpu *cpu_bstats;
> struct gnet_stats_queue __percpu *cpu_qstats;
> + struct tc_cookie *act_ck;
> };
> #define tcf_head common.tcfa_head
> #define tcf_index common.tcfa_index
> diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h
> index f0a0514..e0bc7e8 100644
> --- a/include/net/pkt_cls.h
> +++ b/include/net/pkt_cls.h
> @@ -515,4 +515,12 @@ struct tc_cls_bpf_offload {
> u32 gen_flags;
> };
>
> +
> +/* This structure holds cookie structure that is passed from user
> + * to the kernel for actions and classifiers
> + */
> +struct tc_cookie {
> + unsigned char ck[TC_COOKIE_MAX_SIZE];
> + unsigned char ck_len;
> +};
> #endif
> diff --git a/include/uapi/linux/pkt_cls.h b/include/uapi/linux/pkt_cls.h
> index 1e5e1dd..2d2414e 100644
> --- a/include/uapi/linux/pkt_cls.h
> +++ b/include/uapi/linux/pkt_cls.h
> @@ -4,6 +4,8 @@
> #include <linux/types.h>
> #include <linux/pkt_sched.h>
>
> +#define TC_COOKIE_MAX_SIZE 16
> +
> /* Action attributes */
> enum {
> TCA_ACT_UNSPEC,
> @@ -12,6 +14,7 @@ enum {
> TCA_ACT_INDEX,
> TCA_ACT_STATS,
> TCA_ACT_PAD,
> + TCA_ACT_COOKIE,
> __TCA_ACT_MAX
> };
>
> diff --git a/net/sched/act_api.c b/net/sched/act_api.c
> index f04715a..43f1f42 100644
> --- a/net/sched/act_api.c
> +++ b/net/sched/act_api.c
> @@ -24,6 +24,7 @@
> #include <net/net_namespace.h>
> #include <net/sock.h>
> #include <net/sch_generic.h>
> +#include <net/pkt_cls.h>
> #include <net/act_api.h>
> #include <net/netlink.h>
>
> @@ -33,6 +34,7 @@ static void free_tcf(struct rcu_head *head)
>
> free_percpu(p->cpu_bstats);
> free_percpu(p->cpu_qstats);
> + kfree(p->act_ck);
> kfree(p);
> }
>
> @@ -475,6 +477,12 @@ int tcf_action_destroy(struct list_head *actions, int bind)
> goto nla_put_failure;
> if (tcf_action_copy_stats(skb, a, 0))
> goto nla_put_failure;
> + if (a->act_ck) {
> + if (nla_put(skb, TCA_ACT_COOKIE, a->act_ck->ck_len,
> + a->act_ck))
> + goto nla_put_failure;
> + }
> +
> nest = nla_nest_start(skb, TCA_OPTIONS);
> if (nest == NULL)
> goto nla_put_failure;
> @@ -575,6 +583,23 @@ struct tc_action *tcf_action_init_1(struct net *net, struct nlattr *nla,
> if (err < 0)
> goto err_mod;
>
> + if (tb[TCA_ACT_COOKIE]) {
> + if (nla_len(tb[TCA_ACT_COOKIE]) > TC_COOKIE_MAX_SIZE) {
> + err = -EINVAL;
> + goto err_mod;
> + }
> +
> + a->act_ck = kzalloc(sizeof(*a->act_ck), GFP_KERNEL);
Hi Jamal, How about
struct tc_cookie {
unsigned int len;
unsigned long ck[0];
};
and then:
a->act_ck = kzalloc(sizeof(*a->act_ck) + nla_len(tb[TCA_ACT_COOKIE]),
GFP_KERNEL);
to save some space?
> + if (unlikely(!a->act_ck)) {
> + err = -ENOMEM;
> + goto err_mod;
> + }
> +
> + memcpy(a->act_ck->ck, nla_data(tb[TCA_ACT_COOKIE]),
> + nla_len(tb[TCA_ACT_COOKIE]));
> + a->act_ck->ck_len = nla_len(tb[TCA_ACT_COOKIE]);
> + }
> +
> /* module count goes up only when brand new policy is created
> * if it exists and is only bound to in a_o->init() then
> * ACT_P_CREATED is not returned (a zero is).
>
Besides if I'll reuse tc_cookie for classifiers, I'll need 20 bytes :)
^ permalink raw reply
* Re: [PATCH net-next v2] net/mlx5e: Support bpf_xdp_adjust_head()
From: Saeed Mahameed @ 2017-01-18 11:45 UTC (permalink / raw)
To: Martin KaFai Lau
Cc: Linux Netdev List, Saeed Mahameed, Tariq Toukan, Kernel Team
In-Reply-To: <1484719567-2774431-1-git-send-email-kafai@fb.com>
On Wed, Jan 18, 2017 at 8:06 AM, Martin KaFai Lau <kafai@fb.com> wrote:
> This patch adds bpf_xdp_adjust_head() support to mlx5e.
>
> 1. rx_headroom is added to struct mlx5e_rq. It uses
> an existing 4 byte hole in the struct.
> 2. The adjusted data length is checked against
> MLX5E_XDP_MIN_INLINE and MLX5E_SW2HW_MTU(rq->netdev->mtu).
> 3. The macro MLX5E_SW2HW_MTU is moved from en_main.c to en.h.
> MLX5E_HW2SW_MTU is also moved to en.h for symmetric reason
> but it is not a must.
>
> v2:
> - Keep the xdp specific logic in mlx5e_xdp_handle()
> - Update dma_len after the sanity checks in mlx5e_xmit_xdp_frame()
>
> Signed-off-by: Martin KaFai Lau <kafai@fb.com>
Acked-by: Saeed Mahameed <saeedm@mellanox.com>
Thank you Martin.
^ permalink raw reply
* Re: [PATCH net-next v4 1/2] net sched actions: Add support for user cookies
From: Jamal Hadi Salim @ 2017-01-18 11:35 UTC (permalink / raw)
To: Cong Wang
Cc: David Miller, Linux Kernel Network Developers, Jiri Pirko, paulb,
John Fastabend, Simon Horman, Roman Mashak, Hadar Har-Zion,
Or Gerlitz, Roi Dayan, Daniel Borkmann
In-Reply-To: <CAM_iQpUfvSCJ6j+GsefShWK++tfuBr=buWauBY81gaOpqvN=gA@mail.gmail.com>
On 17-01-17 01:40 PM, Cong Wang wrote:
> On Tue, Jan 17, 2017 at 3:11 AM, Jamal Hadi Salim <jhs@mojatatu.com> wrote:
>> @@ -575,6 +583,23 @@ struct tc_action *tcf_action_init_1(struct net *net, struct nlattr *nla,
>> if (err < 0)
>> goto err_mod;
>>
>> + if (tb[TCA_ACT_COOKIE]) {
>> + if (nla_len(tb[TCA_ACT_COOKIE]) > TC_COOKIE_MAX_SIZE) {
>> + err = -EINVAL;
>> + goto err_mod;
>> + }
>> +
>> + a->act_ck = kzalloc(sizeof(*a->act_ck), GFP_KERNEL);
>> + if (unlikely(!a->act_ck)) {
>> + err = -ENOMEM;
>> + goto err_mod;
>> + }
>> +
>
> I am afraid you can't just goto err_mod for error case here, b/c ->init()
> is already called before this, you probably either have to call ->destroy()
> for error path, or move this before ->init().
>
Thanks for catching this. Deserves a respin.
Easier to move it earlier.
cheers,
jamal
^ permalink raw reply
* Re: [PATCH net 1/1] net sched actions: fix refcnt when GETing of action after bind
From: Jamal Hadi Salim @ 2017-01-18 11:33 UTC (permalink / raw)
To: Cong Wang; +Cc: David Miller, Linux Kernel Network Developers
In-Reply-To: <CAM_iQpURppLMupbxCSqmZe866APGrcYficzaOTFNyzheQrrePg@mail.gmail.com>
On 17-01-17 01:17 PM, Cong Wang wrote:
> On Sun, Jan 15, 2017 at 7:14 AM, Jamal Hadi Salim <jhs@mojatatu.com> wrote:
>> diff --git a/net/sched/act_api.c b/net/sched/act_api.c
>> index 2095c83..e10456ef6f 100644
>> --- a/net/sched/act_api.c
>> +++ b/net/sched/act_api.c
>> @@ -900,8 +900,6 @@ static int tca_action_flush(struct net *net, struct nlattr *nla,
>> goto err;
>> }
>> act->order = i;
>> - if (event == RTM_GETACTION)
>> - act->tcfa_refcnt++;
>> list_add_tail(&act->list, &actions);
>> }
>>
>> @@ -914,7 +912,8 @@ static int tca_action_flush(struct net *net, struct nlattr *nla,
>> return ret;
>> }
>> err:
>> - tcf_action_destroy(&actions, 0);
>> + if (event != RTM_GETACTION)
>> + tcf_action_destroy(&actions, 0);
>
> Why this check for RTM_GETACTION? It does not make sense
> at least for the error case, that is, when tcf_action_get_1() fails
> in the middle of the loop, all the previous ones should be destroyed
> no matter it's GETACTION or DELACTION...
>
> Also, for the non-error case of GETACTION, they should be
> destroyed too after dumping to user-space, otherwise there is no
> way to use them since 'actions' is local to that function.
>
> I thought in commit aecc5cefc389 you grab that refcnt on purpose.
>
I did.
The issue there (after your original patch) was destroy() would
decrement the refcount to zero and a GET was essentially translated
to a DEL. Incrementing the refcount earlier protected against that
assuming destroy was going to decrement it.
However, when an action is bound the destroy() doesnt decrement
the refcnt. So the refcnt keeps going up forever (and therefore
deleting fails in the future). So we cant use destroy() as is.
We need another function to cover the scenario you are
describing. I had thought of using cleanup_a() for GET and leave
the refcount alone. But that is insufficient incase the module
refcounts went up. Maybe it is better to refactor get/del
to have different code paths (instead of the clever code reuse).
cheers,
jamal
^ permalink raw reply
* Re: [PATCH iproute2 net-next] iplink: bridge_slave: add support for IFLA_BRPORT_FLUSH
From: Nikolay Aleksandrov @ 2017-01-18 11:13 UTC (permalink / raw)
To: Hangbin Liu, netdev
In-Reply-To: <1484721405-22519-1-git-send-email-liuhangbin@gmail.com>
On 18/01/17 07:36, Hangbin Liu wrote:
> This patch implements support for the IFLA_BRPORT_FLUSH attribute
> in iproute2 so it can flush bridge slave's fdb dynamic entries.
>
> Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
> ---
> ip/iplink_bridge_slave.c | 9 +++++++--
> 1 file changed, 7 insertions(+), 2 deletions(-)
>
Reviewed-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
^ permalink raw reply
* Re: [PATCHv2 iproute2 net-next 2/5] iplink: bridge: add support for IFLA_BR_VLAN_STATS_ENABLED
From: Nikolay Aleksandrov @ 2017-01-18 11:11 UTC (permalink / raw)
To: Hangbin Liu, netdev
In-Reply-To: <1484719971-21693-3-git-send-email-liuhangbin@gmail.com>
On 18/01/17 07:12, Hangbin Liu wrote:
> This patch implements support for the IFLA_BR_VLAN_STATS_ENABLED
> attribute in iproute2 so it can enable/disable vlan stats accounting.
>
> Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
> ---
> ip/iplink_bridge.c | 13 +++++++++++++
> 1 file changed, 13 insertions(+)
>
Thanks,
Reviewed-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
^ permalink raw reply
* Re: [PATCHv2 iproute2 net-next 3/5] iplink: bridge: add support for IFLA_BR_MCAST_STATS_ENABLED
From: Nikolay Aleksandrov @ 2017-01-18 11:11 UTC (permalink / raw)
To: Hangbin Liu, netdev
In-Reply-To: <1484719971-21693-4-git-send-email-liuhangbin@gmail.com>
On 18/01/17 07:12, Hangbin Liu wrote:
> This patch implements support for the IFLA_BR_MCAST_STATS_ENABLED
> attribute in iproute2 so it can enable/disable mcast stats accounting.
>
> Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
> ---
> ip/iplink_bridge.c | 13 +++++++++++++
> 1 file changed, 13 insertions(+)
>
Thanks,
Reviewed-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
^ permalink raw reply
* Re: [PATCH 2/2] at803x: double check SGMII side autoneg
From: Zefir Kurtisi @ 2017-01-18 11:00 UTC (permalink / raw)
To: Timur Tabi, netdev; +Cc: andrew, f.fainelli
In-Reply-To: <e063a5fd-a1c5-e9ec-1700-21c6974a7cbe@codeaurora.org>
On 01/18/2017 12:32 AM, Timur Tabi wrote:
> On 10/24/2016 05:40 AM, Zefir Kurtisi wrote:
>> As a result, if you ever see a warning
>> '803x_aneg_done: SGMII link is not ok' you will
>> end up having an Ethernet link up but won't get
>> any data through. This should not happen, if it
>> does, please contact the module maintainer.
>
> I am now seeing this:
>
> ubuntu@ubuntu:~$ ifup eth1
> ubuntu@ubuntu:~$ [ 588.687689] 803x_aneg_done: SGMII link is not ok
> [ 588.694909] qcom-emac QCOM8070:00 eth1: Link is Up - 1Gbps/Full - flow control
> rx/tx
> [ 588.703985] qcom-emac QCOM8070:00 eth1: Link is Up - 1Gbps/Full - flow control
> rx/tx
>
> ubuntu@ubuntu:~$ ping 192.168.3.1
> PING 192.168.3.1 (192.168.3.1) 56(84) bytes of data.
> 64 bytes from 192.168.3.1: icmp_seq=1 ttl=64 time=0.502 ms
> 64 bytes from 192.168.3.1: icmp_seq=2 ttl=64 time=0.244 ms
> 64 bytes from 192.168.3.1: icmp_seq=3 ttl=64 time=0.220 ms
> ^C
> --- 192.168.3.1 ping statistics ---
> 3 packets transmitted, 3 received, 0% packet loss, time 2107ms
> rtt min/avg/max/mdev = 0.220/0.322/0.502/0.127 ms
>
> So I do get the "SGMII link is not ok" message, but my connection is fine. I
> don't know why the link-up message is displayed twice. It's only displayed once
> if I use the genphy driver instead of the at803x driver.
>
> I'm going to debug the at803x to see what it does that causes the double link-up
> message.
>
The fact that you see the warning means external autoneg completes before the
SGMII side in best case or SGMII link remains down in worst case. To prevent this,
I am using a private variant of the at8031 driver that ensures that the SGMII
autoneg is never restarted. If you ever end up with a dead link, feel free to test
with the related functions below.
Cheers,
Zefir
---
static int nt_at8031_no_soft_reset(struct phy_device *phydev)
{
return 0;
}
/*
* Powering the chip down occasionally causes SGMII link loss, which in turn
* causes the connection to gianfar to remain down.
*
* To prevent permanent link loss, instead of power down just isolate pins.
*/
static int nt_at8031_suspend(struct phy_device *phydev)
{
mutex_lock(&phydev->lock);
phy_write(phydev, MII_BMCR, phy_read(phydev, MII_BMCR) | BMCR_ISOLATE);
mutex_unlock(&phydev->lock);
return 0;
}
static int nt_at8031_resume(struct phy_device *phydev)
{
mutex_lock(&phydev->lock);
phy_write(phydev, MII_BMCR, phy_read(phydev, MII_BMCR) & ~BMCR_ISOLATE);
mutex_unlock(&phydev->lock);
return 0;
}
^ permalink raw reply
* Re: [PATCH net-next v4 1/2] net sched actions: Add support for user cookies
From: Jamal Hadi Salim @ 2017-01-18 11:00 UTC (permalink / raw)
To: Jiri Pirko, Daniel Borkmann
Cc: davem, netdev, jiri, paulb, john.fastabend, simon.horman, mrv,
hadarh, ogerlitz, roid, xiyou.wangcong
In-Reply-To: <20170117170501.GE1807@nanopsycho.orion>
On 17-01-17 12:05 PM, Jiri Pirko wrote:
> Tue, Jan 17, 2017 at 05:57:58PM CET, daniel@iogearbox.net wrote:
>> Given this cookie is just used for correlation in user space anyway
>> and not processed any further by the kernel, I think we can well
>> handle these very few spots, so would be better if the code is more
>> maintainable instead.
>
> I agree with Daniel. His naming change suggestions make sense.
>
> In fact, Jamal, now I know why there are names like this all over TC :)
>
Jiri, how about Hungarian Notation with that? ;->
I will change the name but it is getting towards proving
Parkinson's law of Triviality.
cheers,
jamal
^ permalink raw reply
* Re: [PATCH net-next] net/sched: cls_flower: Add user specified data
From: Jamal Hadi Salim @ 2017-01-18 11:06 UTC (permalink / raw)
To: Paul Blakey, Jiri Pirko
Cc: John Fastabend, David S. Miller, netdev, Jiri Pirko,
Hadar Hen Zion, Or Gerlitz, Roi Dayan, Roman Mashak
In-Reply-To: <6be8f641-16ad-88a4-d7c3-474dc3b10e71@mellanox.com>
On 17-01-17 06:53 AM, Paul Blakey wrote:
>
>
>>
>> Should be "trivial" like my patch.
>> Add a new TLV type in TCA_XXX enum in rtnetlink.h
>> in tc_ctl_tfilter look for it and memcpy it
>> in tcf_fill_node set it on the new TCA_XXX if the cls struct
>> has it present.
>>
>
> That's exactly what I did before I realized it won't work per internal
> element (per handle), which is what I want. see my example.
>
> So I'll probably implement it like actions dumping/init works -
> tcf_exts_init, tcf_exts_dump (calling a generic functions on all
> classifiers who want this).
> I'll add something like get_cookie, dump_cookie. which get/set the
> TCA_COOKIE.
>
Yes, that makes more sense.
cheers,
jamal
^ permalink raw reply
* [PATCH v2] can: ti_hecc: add missing prepare and unprepare of the clock
From: yegorslists @ 2017-01-18 10:35 UTC (permalink / raw)
To: linux-can; +Cc: netdev, mkl, wg, Yegor Yefremov
From: Yegor Yefremov <yegorslists@googlemail.com>
In order to make the driver work with the common clock framework, this
patch converts the clk_enable()/clk_disable() to
clk_prepare_enable()/clk_disable_unprepare().
Also add error checking for clk_prepare_enable().
Signed-off-by: Yegor Yefremov <yegorslists@googlemail.com>
---
Changes v1 -> v2:
- add error checking for clk_prepare_enable (Marc Kleine-Budde)
drivers/net/can/ti_hecc.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/drivers/net/can/ti_hecc.c b/drivers/net/can/ti_hecc.c
index 680d1ff..8771531 100644
--- a/drivers/net/can/ti_hecc.c
+++ b/drivers/net/can/ti_hecc.c
@@ -948,7 +948,12 @@ static int ti_hecc_probe(struct platform_device *pdev)
netif_napi_add(ndev, &priv->napi, ti_hecc_rx_poll,
HECC_DEF_NAPI_WEIGHT);
- clk_enable(priv->clk);
+ err = clk_prepare_enable(priv->clk);
+ if (err) {
+ dev_err(&pdev->dev, "clk_prepare_enable() failed\n");
+ goto probe_exit_clk;
+ }
+
err = register_candev(ndev);
if (err) {
dev_err(&pdev->dev, "register_candev() failed\n");
@@ -981,7 +986,7 @@ static int ti_hecc_remove(struct platform_device *pdev)
struct ti_hecc_priv *priv = netdev_priv(ndev);
unregister_candev(ndev);
- clk_disable(priv->clk);
+ clk_disable_unprepare(priv->clk);
clk_put(priv->clk);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
iounmap(priv->base);
@@ -1006,7 +1011,7 @@ static int ti_hecc_suspend(struct platform_device *pdev, pm_message_t state)
hecc_set_bit(priv, HECC_CANMC, HECC_CANMC_PDR);
priv->can.state = CAN_STATE_SLEEPING;
- clk_disable(priv->clk);
+ clk_disable_unprepare(priv->clk);
return 0;
}
@@ -1016,7 +1021,7 @@ static int ti_hecc_resume(struct platform_device *pdev)
struct net_device *dev = platform_get_drvdata(pdev);
struct ti_hecc_priv *priv = netdev_priv(dev);
- clk_enable(priv->clk);
+ clk_prepare_enable(priv->clk);
hecc_clear_bit(priv, HECC_CANMC, HECC_CANMC_PDR);
priv->can.state = CAN_STATE_ERROR_ACTIVE;
--
2.1.4
^ permalink raw reply related
* Re: Setting link down or up in software
From: Zefir Kurtisi @ 2017-01-18 10:29 UTC (permalink / raw)
To: Mason, netdev
Cc: Mans Rullgard, Florian Fainelli, Andrew Lunn, Thibaud Cornic
In-Reply-To: <660b7b17-0136-bf69-fd12-1c125069829b@free.fr>
On 01/13/2017 06:35 PM, Mason wrote:
> On 13/01/2017 17:28, Zefir Kurtisi wrote:
>
>> As for your specific problem: since I fought myself with the PHY/ETH subsystems
>> over the past months, I might remember something relevant to your issue. Could you
>> give some more info on your setup (PHY driver, opmode (SGMII, RGMII, etc.), ETH).
>
> Hello Zefir,
>
> My boards are using these drivers:
>
> http://lxr.free-electrons.com/source/drivers/net/ethernet/aurora/nb8800.c
> http://lxr.free-electrons.com/source/drivers/net/phy/at803x.c
>
> The relevant device tree nodes are:
>
> eth0: ethernet@26000 {
> compatible = "sigma,smp8734-ethernet";
> reg = <0x26000 0x800>;
> interrupts = <38 IRQ_TYPE_LEVEL_HIGH>;
> clocks = <&clkgen SYS_CLK>;
> };
>
> ð0 {
> phy-connection-type = "rgmii";
> phy-handle = <ð0_phy>;
> #address-cells = <1>;
> #size-cells = <0>;
>
> /* Atheros AR8035 */
> eth0_phy: ethernet-phy@4 {
> compatible = "ethernet-phy-id004d.d072",
> "ethernet-phy-ieee802.3-c22";
> interrupts = <37 IRQ_TYPE_EDGE_RISING>;
> reg = <4>;
> };
> };
>
> If I comment the PHY "interrupts" property, then the PHY framework
> falls back to polling.
>
> Am I forgetting important information?
>
> Regards.
>
Hi,
in our system we attach the at8031 over SGMII to the gianfar (Freescale eTSEC) and
to fibre optics transceivers, which operate in fixed speeds. Getting this setup to
work reliably was challenging for various reasons, maybe worth to note
1) fixed SGMII speed not working: link is up on both ends, but no data is passed
2) known issue with SGMII link not completing autonegotiation correctly, see [1]
3) once autoneg is started or chip is reset, MII_CTRL1000 can not be written to
until autoneg is completed => breaks phy state machine when the driver loads with
unplugged cable and tries to set fixed speed
Unless you are using fixed speed links in your setup, none of those should affect
it. My experience with at8031 attached to RGMII is that it is genphy compliant,
therefore I would a) disable interrupts, and b) prevent loading at803x.ko and try
the genphy instead. Yours is an at8035, results may vary.
Cheers,
Zefir
[1] https://www.spinics.net/lists/netdev/msg400804.html
^ permalink raw reply
* Re: [PATCH] net: ethernet: stmmac: add ARP management
From: Rayagond Kokatanur @ 2017-01-18 10:19 UTC (permalink / raw)
To: Christophe Roullier
Cc: Alexandre Torgue, Giuseppe Cavallaro, netdev, linux-kernel
In-Reply-To: <1484672200-7755-1-git-send-email-christophe.roullier@st.com>
On Tue, Jan 17, 2017 at 10:26 PM, Christophe Roullier
<christophe.roullier@st.com> wrote:
>
> DWC_ether_qos supports the Address Recognition
> Protocol (ARP) Offload for IPv4 packets. This feature
> allows the processing of the IPv4 ARP request packet
> in the receive path and generating corresponding ARP
> response packet in the transmit path. DWC_ether_qos
> generates the ARP reply packets for appropriate ARP
> request packets.
>
> Signed-off-by: Christophe Roullier <christophe.roullier@st.com>
> ---
> drivers/net/ethernet/stmicro/stmmac/common.h | 4 ++++
> drivers/net/ethernet/stmicro/stmmac/dwmac4.h | 3 +++
> drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c | 15 ++++++++++++++
> drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c | 23 ++++++++++++++++++++++
> drivers/net/ethernet/stmicro/stmmac/stmmac.h | 1 +
> drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 13 ++++++++++++
> .../net/ethernet/stmicro/stmmac/stmmac_platform.c | 1 +
> include/linux/stmmac.h | 1 +
> 8 files changed, 61 insertions(+)
>
> diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
> index 75e2666..1d1c815 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/common.h
> +++ b/drivers/net/ethernet/stmicro/stmmac/common.h
> @@ -306,6 +306,7 @@ struct dma_features {
> unsigned int pmt_remote_wake_up;
> unsigned int pmt_magic_frame;
> unsigned int rmon;
> + unsigned int arpoffsel;
> /* IEEE 1588-2002 */
> unsigned int time_stamp;
> /* IEEE 1588-2008 */
> @@ -447,6 +448,7 @@ struct stmmac_dma_ops {
> void (*set_rx_tail_ptr)(void __iomem *ioaddr, u32 tail_ptr, u32 chan);
> void (*set_tx_tail_ptr)(void __iomem *ioaddr, u32 tail_ptr, u32 chan);
> void (*enable_tso)(void __iomem *ioaddr, bool en, u32 chan);
> + void (*set_arp_addr)(void __iomem *ioaddr, bool en, u32 addr);
> };
>
> struct mac_device_info;
> @@ -459,6 +461,8 @@ struct stmmac_ops {
> int (*rx_ipc)(struct mac_device_info *hw);
> /* Enable RX Queues */
> void (*rx_queue_enable)(struct mac_device_info *hw, u32 queue);
> + /* Enable and verify that the ARP feature is supported */
> + int (*arp_en)(struct mac_device_info *hw);
> /* Dump MAC registers */
> void (*dump_regs)(struct mac_device_info *hw);
> /* Handle extra events on specific interrupts hw dependent */
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h
> index db45134..d1e2e37 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h
> @@ -35,6 +35,7 @@
> #define GMAC_HW_FEATURE2 0x00000124
> #define GMAC_MDIO_ADDR 0x00000200
> #define GMAC_MDIO_DATA 0x00000204
> +#define GMAC_ARP_ADDR 0x00000210
> #define GMAC_ADDR_HIGH(reg) (0x300 + reg * 8)
> #define GMAC_ADDR_LOW(reg) (0x304 + reg * 8)
>
> @@ -116,6 +117,7 @@ enum power_event {
> #define GMAC_DEBUG_RPESTS BIT(0)
>
> /* MAC config */
> +#define GMAC_CONFIG_ARPEN BIT(31)
> #define GMAC_CONFIG_IPC BIT(27)
> #define GMAC_CONFIG_2K BIT(22)
> #define GMAC_CONFIG_ACS BIT(20)
> @@ -135,6 +137,7 @@ enum power_event {
> #define GMAC_HW_FEAT_TXCOSEL BIT(14)
> #define GMAC_HW_FEAT_EEESEL BIT(13)
> #define GMAC_HW_FEAT_TSSEL BIT(12)
> +#define GMAC_HW_FEAT_ARPOFFSEL BIT(9)
> #define GMAC_HW_FEAT_MMCSEL BIT(8)
> #define GMAC_HW_FEAT_MGKSEL BIT(7)
> #define GMAC_HW_FEAT_RWKSEL BIT(6)
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
> index 834f40f..33d0fb3 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
> @@ -102,6 +102,20 @@ static int dwmac4_rx_ipc_enable(struct mac_device_info *hw)
> return !!(value & GMAC_CONFIG_IPC);
> }
>
> +static int dwmac4_arp_enable(struct mac_device_info *hw)
> +{
> + void __iomem *ioaddr = hw->pcsr;
> + u32 value = readl(ioaddr + GMAC_CONFIG);
> +
> + value |= GMAC_CONFIG_ARPEN;
> +
> + writel(value, ioaddr + GMAC_CONFIG);
> +
> + value = readl(ioaddr + GMAC_CONFIG);
> +
> + return !!(value & GMAC_CONFIG_ARPEN);
> +}
> +
> static void dwmac4_pmt(struct mac_device_info *hw, unsigned long mode)
> {
> void __iomem *ioaddr = hw->pcsr;
> @@ -463,6 +477,7 @@ static void dwmac4_debug(void __iomem *ioaddr, struct stmmac_extra_stats *x)
> .core_init = dwmac4_core_init,
> .rx_ipc = dwmac4_rx_ipc_enable,
> .rx_queue_enable = dwmac4_rx_queue_enable,
> + .arp_en = dwmac4_arp_enable,
> .dump_regs = dwmac4_dump_regs,
> .host_irq_status = dwmac4_irq_status,
> .flow_ctrl = dwmac4_flow_ctrl,
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
> index 377d1b4..fbbd303 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
> @@ -284,6 +284,8 @@ static void dwmac4_get_hw_feature(void __iomem *ioaddr,
> dma_cap->pmt_magic_frame = (hw_cap & GMAC_HW_FEAT_MGKSEL) >> 7;
> /* MMC */
> dma_cap->rmon = (hw_cap & GMAC_HW_FEAT_MMCSEL) >> 8;
> + /* ARP */
> + dma_cap->arpoffsel = (hw_cap & GMAC_HW_FEAT_ARPOFFSEL) >> 9;
> /* IEEE 1588-2008 */
> dma_cap->atime_stamp = (hw_cap & GMAC_HW_FEAT_TSSEL) >> 12;
> /* 802.3az - Energy-Efficient Ethernet (EEE) */
> @@ -331,6 +333,25 @@ static void dwmac4_enable_tso(void __iomem *ioaddr, bool en, u32 chan)
> }
> }
>
> +/* Set ARP Address */
> +static void dwmac4_set_arp_addr(void __iomem *ioaddr, bool set, u32 addr)
> +{
> + u32 value;
> +
> + value = readl(ioaddr + GMAC_ARP_ADDR);
> +
> + if (set) {
> + /* set arp address */
> + value = addr;
> + } else {
> + /* unset arp address */
> + value = 0;
> + }
> +
> + writel(value, ioaddr + GMAC_ARP_ADDR);
> + value = readl(ioaddr + GMAC_ARP_ADDR);
> +}
> +
> const struct stmmac_dma_ops dwmac4_dma_ops = {
> .reset = dwmac4_dma_reset,
> .init = dwmac4_dma_init,
> @@ -351,6 +372,7 @@ static void dwmac4_enable_tso(void __iomem *ioaddr, bool en, u32 chan)
> .set_rx_tail_ptr = dwmac4_set_rx_tail_ptr,
> .set_tx_tail_ptr = dwmac4_set_tx_tail_ptr,
> .enable_tso = dwmac4_enable_tso,
> + .set_arp_addr = dwmac4_set_arp_addr,
> };
>
> const struct stmmac_dma_ops dwmac410_dma_ops = {
> @@ -373,4 +395,5 @@ static void dwmac4_enable_tso(void __iomem *ioaddr, bool en, u32 chan)
> .set_rx_tail_ptr = dwmac4_set_rx_tail_ptr,
> .set_tx_tail_ptr = dwmac4_set_tx_tail_ptr,
> .enable_tso = dwmac4_enable_tso,
> + .set_arp_addr = dwmac4_set_arp_addr,
> };
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
> index bf8a83e..51666fa 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
> @@ -67,6 +67,7 @@ struct stmmac_priv {
> bool tx_path_in_lpi_mode;
> struct timer_list txtimer;
> bool tso;
> + int arp;
>
> struct dma_desc *dma_rx ____cacheline_aligned_in_smp;
> struct dma_extended_desc *dma_erx;
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> index d481c5f..2217dc3 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> @@ -3284,6 +3284,19 @@ int stmmac_dvr_probe(struct device *device,
> priv->tso = true;
> dev_info(priv->device, "TSO feature enabled\n");
> }
> +
> + if ((priv->plat->arp_en) && (priv->dma_cap.arpoffsel)) {
> + ret = priv->hw->mac->arp_en(priv->hw);
> + if (!ret) {
> + pr_warn(" ARP feature disabled\n");
> + } else {
> + pr_info(" ARP feature enabled\n");
> + /* Copy MAC addr into MAC_ARP_ADDRESS register*/
> + priv->hw->dma->set_arp_addr(priv->ioaddr, 1,
> + priv->dev->dev_addr);
GMAC_ARP_ADDR register suppose to contains IPv4 address not MAC address.
Also priv->dev->dev_addr will be 6 bytes long but GMAC_ARP_ADDR is 4 bytes long.
What about arp request packet received by device, driver rx poll
should check the arp reply generate by device or not and decide
whehther received arp request packet should be passed to stack or not.
Else stack also ends up trasmiting ARP reply always.
>
> + }
> + }
> +
> ndev->features |= ndev->hw_features | NETIF_F_HIGHDMA;
> ndev->watchdog_timeo = msecs_to_jiffies(watchdog);
> #ifdef STMMAC_VLAN_TAG_USED
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
> index 4daa8a3..92a0db9 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
> @@ -306,6 +306,7 @@ struct plat_stmmacenet_data *
> plat->has_gmac = 0;
> plat->pmt = 1;
> plat->tso_en = of_property_read_bool(np, "snps,tso");
> + plat->arp_en = of_property_read_bool(np, "snps,arp");
> }
>
> if (of_device_is_compatible(np, "snps,dwmac-3.610") ||
> diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h
> index d76033d6..2491285 100644
> --- a/include/linux/stmmac.h
> +++ b/include/linux/stmmac.h
> @@ -148,5 +148,6 @@ struct plat_stmmacenet_data {
> bool tso_en;
> int mac_port_sel_speed;
> bool en_tx_lpi_clockgating;
> + bool arp_en;
> };
> #endif
> --
> 1.9.1
>
--
wwr
Rayagond
^ permalink raw reply
* Geschäftsvorschlag
From: tester @ 2017-01-14 23:24 UTC (permalink / raw)
To: Recipients
Lieber Freund.
Erlauben Sie mir, auf diese Weise auf Sie zuzugehen. Ich bin Dr. Arnold Kristofferson, ein US-Auftragnehmer, der mit Nichtkämpfer US Marine in Ba'qubah, Irak arbeitet. Ich habe die Summe von 10,6 Millionen Dollar, die ich aus einem Rohöl-Deal gemacht habe, und ich möchte, dass Sie mir helfen, es zu erhalten. Da ich hier auf offizieller Kapazität arbeite, kann ich diesen Fonds nicht bei mir behalten und dies ist mein einziger Grund für die Kontaktaufnahme mit Ihnen. Wenn Sie interessiert sind und Sie diesen Fonds in Ihrer Kapazität erhalten können, melden Sie sich bitte bei mir, damit ich Ihnen weitere Details geben kann, wie Sie dieses Geld für mich erhalten können. Bitte erreichen Sie mich per E-Mail: arnoldkristoferson101@gmail.com
Mit freundlichen Grüßen.
^ permalink raw reply
* Re: [PATCH] can: ti_hecc: add missing prepare and unprepare of the clock
From: Yegor Yefremov @ 2017-01-18 10:05 UTC (permalink / raw)
To: Marc Kleine-Budde; +Cc: linux-can@vger.kernel.org, netdev, Wolfgang Grandegger
In-Reply-To: <5ccf750a-e468-5c4b-eb26-1e248b712a93@pengutronix.de>
On Wed, Jan 18, 2017 at 11:01 AM, Marc Kleine-Budde <mkl@pengutronix.de> wrote:
> On 01/18/2017 10:43 AM, yegorslists@googlemail.com wrote:
>> From: Yegor Yefremov <yegorslists@googlemail.com>
>>
>> In order to make the driver work with the common clock framework, this
>> patch converts the clk_enable()/clk_disable() to
>> clk_prepare_enable()/clk_disable_unprepare().
>>
>
> Can you add the missing error checking for the prepare_enable call?
Will do.
Yegor
>> Signed-off-by: Yegor Yefremov <yegorslists@googlemail.com>
>> ---
>> drivers/net/can/ti_hecc.c | 9 +++++----
>> 1 file changed, 5 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/net/can/ti_hecc.c b/drivers/net/can/ti_hecc.c
>> index 680d1ff..0448cb5 100644
>> --- a/drivers/net/can/ti_hecc.c
>> +++ b/drivers/net/can/ti_hecc.c
>> @@ -948,7 +948,8 @@ static int ti_hecc_probe(struct platform_device *pdev)
>> netif_napi_add(ndev, &priv->napi, ti_hecc_rx_poll,
>> HECC_DEF_NAPI_WEIGHT);
>>
>> - clk_enable(priv->clk);
>> + clk_prepare_enable(priv->clk);
>> +
>> err = register_candev(ndev);
>> if (err) {
>> dev_err(&pdev->dev, "register_candev() failed\n");
>> @@ -981,7 +982,7 @@ static int ti_hecc_remove(struct platform_device *pdev)
>> struct ti_hecc_priv *priv = netdev_priv(ndev);
>>
>> unregister_candev(ndev);
>> - clk_disable(priv->clk);
>> + clk_disable_unprepare(priv->clk);
>> clk_put(priv->clk);
>> res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>> iounmap(priv->base);
>> @@ -1006,7 +1007,7 @@ static int ti_hecc_suspend(struct platform_device *pdev, pm_message_t state)
>> hecc_set_bit(priv, HECC_CANMC, HECC_CANMC_PDR);
>> priv->can.state = CAN_STATE_SLEEPING;
>>
>> - clk_disable(priv->clk);
>> + clk_disable_unprepare(priv->clk);
>>
>> return 0;
>> }
>> @@ -1016,7 +1017,7 @@ static int ti_hecc_resume(struct platform_device *pdev)
>> struct net_device *dev = platform_get_drvdata(pdev);
>> struct ti_hecc_priv *priv = netdev_priv(dev);
>>
>> - clk_enable(priv->clk);
>> + clk_prepare_enable(priv->clk);
>>
>> hecc_clear_bit(priv, HECC_CANMC, HECC_CANMC_PDR);
>> priv->can.state = CAN_STATE_ERROR_ACTIVE;
>>
>
>
> --
> Pengutronix e.K. | Marc Kleine-Budde |
> Industrial Linux Solutions | Phone: +49-231-2826-924 |
> Vertretung West/Dortmund | Fax: +49-5121-206917-5555 |
> Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de |
>
^ permalink raw reply
* Re: [PATCH for bnxt_re V4 03/21] RDMA/bnxt_re: register with the NIC driver
From: Leon Romanovsky @ 2017-01-18 10:11 UTC (permalink / raw)
To: Selvin Xavier
Cc: dledford, linux-rdma, netdev, michael.chan, Eddie Wai,
Devesh Sharma, Somnath Kotur, Sriharsha Basavapatna
In-Reply-To: <1482320530-5344-4-git-send-email-selvin.xavier@broadcom.com>
[-- Attachment #1: Type: text/plain, Size: 15667 bytes --]
On Wed, Dec 21, 2016 at 03:41:52AM -0800, Selvin Xavier wrote:
> This patch handles the registration with the bnxt_en driver.
> The bnxt_re driver first registers with netdev notifier chain and upon
> receiving the NETDEV_REGISTER event, it registers with bnxt_en driver.
>
> 1. bnxt_en's ulp_probe function returns a structure that contains
> information about the device and additional entry points.
> 2. bnxt_en driver returns 'struct bnxt_eth_dev' that contains set
> of operation vectors that bnxt_re driver invokes later.
> 3. bnxt_request_msix() allows the bnxt_re driver to specify the
> number of MSI-X vectors that are needed.
> 4. bnxt_send_fw_msg () is used to send messages to the FW
> 5. bnxt_register_async_events() is used to register for async
> event callbacks.
>
> v2: Remove some sparse warning. Also, remove some unused code from unreg
> path.
> v3: Removed condition checks for rdev reported during static code analysis.
> Check the return value of try_module_get while getting bnxt_en
> reference.
>
> Signed-off-by: Eddie Wai <eddie.wai@broadcom.com>
> Signed-off-by: Devesh Sharma <devesh.sharma@broadcom.com>
> Signed-off-by: Somnath Kotur <somnath.kotur@broadcom.com>
> Signed-off-by: Sriharsha Basavapatna <sriharsha.basavapatna@broadcom.com>
> Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
> ---
> drivers/infiniband/hw/bnxt_re/bnxt_re.h | 51 ++++
> drivers/infiniband/hw/bnxt_re/main.c | 448 ++++++++++++++++++++++++++++++++
> 2 files changed, 499 insertions(+)
>
> diff --git a/drivers/infiniband/hw/bnxt_re/bnxt_re.h b/drivers/infiniband/hw/bnxt_re/bnxt_re.h
> index f9b8542..8b73e3d 100644
> --- a/drivers/infiniband/hw/bnxt_re/bnxt_re.h
> +++ b/drivers/infiniband/hw/bnxt_re/bnxt_re.h
> @@ -42,5 +42,56 @@
> #define ROCE_DRV_MODULE_NAME "bnxt_re"
> #define ROCE_DRV_MODULE_VERSION "1.0.0"
>
> +#define BNXT_RE_REF_WAIT_COUNT 10
> #define BNXT_RE_DESC "Broadcom NetXtreme-C/E RoCE Driver"
> +
> +struct bnxt_re_work {
> + struct work_struct work;
> + unsigned long event;
> + struct bnxt_re_dev *rdev;
> + struct net_device *vlan_dev;
> +};
> +
> +#define BNXT_RE_MIN_MSIX 2
> +#define BNXT_RE_MAX_MSIX 16
> +struct bnxt_re_dev {
> + struct ib_device ibdev;
> + struct list_head list;
> + atomic_t ref_count;
> + unsigned long flags;
> +#define BNXT_RE_FLAG_NETDEV_REGISTERED 0
> +#define BNXT_RE_FLAG_IBDEV_REGISTERED 1
> +#define BNXT_RE_FLAG_GOT_MSIX 2
> +#define BNXT_RE_FLAG_RCFW_CHANNEL_EN 8
> +#define BNXT_RE_FLAG_QOS_WORK_REG 16
> + struct net_device *netdev;
> + unsigned int version, major, minor;
> + struct bnxt_en_dev *en_dev;
> + struct bnxt_msix_entry msix_entries[BNXT_RE_MAX_MSIX];
> + int num_msix;
> +
> + int id;
> +
> + atomic_t qp_count;
> + struct mutex qp_lock; /* protect qp list */
> + struct list_head qp_list;
> +
> + atomic_t cq_count;
> + atomic_t srq_count;
> + atomic_t mr_count;
> + atomic_t mw_count;
> + /* Max of 2 lossless traffic class supported per port */
> + u16 cosq[2];
> +};
> +
> +#define to_bnxt_re_dev(ptr, member) \
> + container_of((ptr), struct bnxt_re_dev, member)
> +
> +static inline struct device *rdev_to_dev(struct bnxt_re_dev *rdev)
> +{
> + if (rdev)
> + return &rdev->ibdev.dev;
> + return NULL;
> +}
> +
> #endif
> diff --git a/drivers/infiniband/hw/bnxt_re/main.c b/drivers/infiniband/hw/bnxt_re/main.c
> index 6c22d51..71d7501 100644
> --- a/drivers/infiniband/hw/bnxt_re/main.c
> +++ b/drivers/infiniband/hw/bnxt_re/main.c
> @@ -38,10 +38,24 @@
>
> #include <linux/module.h>
> #include <linux/netdevice.h>
> +#include <linux/ethtool.h>
> #include <linux/mutex.h>
> #include <linux/list.h>
> #include <linux/rculist.h>
> +#include <linux/spinlock.h>
> +#include <linux/pci.h>
> +#include <net/ipv6.h>
> +#include <net/addrconf.h>
> +
> +#include <rdma/ib_verbs.h>
> +#include <rdma/ib_user_verbs.h>
> +#include <rdma/ib_umem.h>
> +#include <rdma/ib_addr.h>
> +
> +#include "bnxt_ulp.h"
> +#include "roce_hsi.h"
> #include "bnxt_re.h"
> +#include "bnxt.h"
> static char version[] =
> BNXT_RE_DESC " v" ROCE_DRV_MODULE_VERSION "\n";
>
> @@ -55,6 +69,384 @@ static struct list_head bnxt_re_dev_list = LIST_HEAD_INIT(bnxt_re_dev_list);
> /* Mutex to protect the list of bnxt_re devices added */
> static DEFINE_MUTEX(bnxt_re_dev_lock);
> static struct workqueue_struct *bnxt_re_wq;
> +
> +/* for handling bnxt_en callbacks later */
> +static void bnxt_re_stop(void *p)
> +{
> +}
> +
> +static void bnxt_re_start(void *p)
> +{
> +}
> +
> +static void bnxt_re_sriov_config(void *p, int num_vfs)
> +{
> +}
> +
> +static struct bnxt_ulp_ops bnxt_re_ulp_ops = {
> + .ulp_async_notifier = NULL,
> + .ulp_stop = bnxt_re_stop,
> + .ulp_start = bnxt_re_start,
> + .ulp_sriov_config = bnxt_re_sriov_config
> +};
> +
> +/* The rdev ref_count is to protect immature removal of the device */
> +static inline void bnxt_re_hold(struct bnxt_re_dev *rdev)
> +{
> + atomic_inc(&rdev->ref_count);
> +}
> +
> +static inline void bnxt_re_put(struct bnxt_re_dev *rdev)
> +{
> + atomic_dec(&rdev->ref_count);
> +}
> +
> +/* RoCE -> Net driver */
> +
> +/* Driver registration routines used to let the networking driver (bnxt_en)
> + * to know that the RoCE driver is now installed
> + */
> +static int bnxt_re_unregister_netdev(struct bnxt_re_dev *rdev, bool lock_wait)
> +{
> + struct bnxt_en_dev *en_dev;
> + int rc;
> +
> + if (!rdev)
> + return -EINVAL;
> +
> + en_dev = rdev->en_dev;
> + /* Acquire rtnl lock if it is not invokded from netdev event */
> + if (lock_wait)
> + rtnl_lock();
> +
> + rc = en_dev->en_ops->bnxt_unregister_device(rdev->en_dev,
> + BNXT_ROCE_ULP);
> + if (lock_wait)
> + rtnl_unlock();
> + return rc;
> +}
> +
> +static int bnxt_re_register_netdev(struct bnxt_re_dev *rdev)
> +{
> + struct bnxt_en_dev *en_dev;
> + int rc = 0;
> +
> + if (!rdev)
> + return -EINVAL;
> +
> + en_dev = rdev->en_dev;
> +
> + rtnl_lock();
> + rc = en_dev->en_ops->bnxt_register_device(en_dev, BNXT_ROCE_ULP,
> + &bnxt_re_ulp_ops, rdev);
> + rtnl_unlock();
> + return rc;
> +}
> +
> +static int bnxt_re_free_msix(struct bnxt_re_dev *rdev, bool lock_wait)
> +{
> + struct bnxt_en_dev *en_dev;
> + int rc;
> +
> + if (!rdev)
> + return -EINVAL;
> +
> + en_dev = rdev->en_dev;
> +
> + if (lock_wait)
> + rtnl_lock();
> +
> + rc = en_dev->en_ops->bnxt_free_msix(rdev->en_dev, BNXT_ROCE_ULP);
> +
> + if (lock_wait)
> + rtnl_unlock();
> + return rc;
> +}
> +
> +static int bnxt_re_request_msix(struct bnxt_re_dev *rdev)
> +{
> + int rc = 0, num_msix_want = BNXT_RE_MIN_MSIX, num_msix_got;
> + struct bnxt_en_dev *en_dev;
> +
> + if (!rdev)
> + return -EINVAL;
> +
> + en_dev = rdev->en_dev;
> +
> + rtnl_lock();
> + num_msix_got = en_dev->en_ops->bnxt_request_msix(en_dev, BNXT_ROCE_ULP,
> + rdev->msix_entries,
> + num_msix_want);
> + if (num_msix_got < BNXT_RE_MIN_MSIX) {
> + rc = -EINVAL;
> + goto done;
> + }
> + if (num_msix_got != num_msix_want) {
> + dev_warn(rdev_to_dev(rdev),
> + "Requested %d MSI-X vectors, got %d\n",
> + num_msix_want, num_msix_got);
> + }
> + rdev->num_msix = num_msix_got;
> +done:
> + rtnl_unlock();
> + return rc;
> +}
> +
> +/* Device */
> +
> +static bool is_bnxt_re_dev(struct net_device *netdev)
> +{
> + struct ethtool_drvinfo drvinfo;
> +
> + if (netdev->ethtool_ops && netdev->ethtool_ops->get_drvinfo) {
> + memset(&drvinfo, 0, sizeof(drvinfo));
> + netdev->ethtool_ops->get_drvinfo(netdev, &drvinfo);
> +
> + if (strcmp(drvinfo.driver, "bnxt_en"))
> + return false;
> + return true;
> + }
> + return false;
> +}
> +
> +static struct bnxt_re_dev *bnxt_re_from_netdev(struct net_device *netdev)
> +{
> + struct bnxt_re_dev *rdev;
> +
> + rcu_read_lock();
> + list_for_each_entry_rcu(rdev, &bnxt_re_dev_list, list) {
> + if (rdev->netdev == netdev) {
> + rcu_read_unlock();
> + return rdev;
> + }
> + }
> + rcu_read_unlock();
> + return NULL;
> +}
> +
> +static void bnxt_re_dev_unprobe(struct net_device *netdev,
> + struct bnxt_en_dev *en_dev)
> +{
> + dev_put(netdev);
> + module_put(en_dev->pdev->driver->driver.owner);
> +}
> +
> +static struct bnxt_en_dev *bnxt_re_dev_probe(struct net_device *netdev)
> +{
> + struct bnxt *bp = netdev_priv(netdev);
> + struct bnxt_en_dev *en_dev;
> + struct pci_dev *pdev;
> +
> + /* Call bnxt_en's RoCE probe via indirect API */
> + if (!bp->ulp_probe)
> + return ERR_PTR(-EINVAL);
> +
> + en_dev = bp->ulp_probe(netdev);
> + if (IS_ERR(en_dev))
> + return en_dev;
> +
> + pdev = en_dev->pdev;
> + if (!pdev)
> + return ERR_PTR(-EINVAL);
> +
> + /* Bump net device reference count */
> + if (!try_module_get(pdev->driver->driver.owner))
> + return ERR_PTR(-ENODEV);
> +
> + dev_hold(netdev);
> +
> + return en_dev;
> +}
> +
> +static void bnxt_re_dev_remove(struct bnxt_re_dev *rdev)
> +{
> + int i = BNXT_RE_REF_WAIT_COUNT;
> +
> + /* Wait for rdev refcount to come down */
> + while ((atomic_read(&rdev->ref_count) > 1) && i--)
> + msleep(100);
> +
> + if (atomic_read(&rdev->ref_count) > 1)
> + dev_err(rdev_to_dev(rdev),
> + "Failed waiting for ref count to deplete %d",
> + atomic_read(&rdev->ref_count));
> +
> + atomic_set(&rdev->ref_count, 0);
> + dev_put(rdev->netdev);
> + rdev->netdev = NULL;
> +
> + mutex_lock(&bnxt_re_dev_lock);
> + list_del_rcu(&rdev->list);
> + mutex_unlock(&bnxt_re_dev_lock);
> +
> + synchronize_rcu();
> + flush_workqueue(bnxt_re_wq);
> +
> + ib_dealloc_device(&rdev->ibdev);
> + /* rdev is gone */
> +}
> +
> +static struct bnxt_re_dev *bnxt_re_dev_add(struct net_device *netdev,
> + struct bnxt_en_dev *en_dev)
> +{
> + struct bnxt_re_dev *rdev;
> +
> + /* Allocate bnxt_re_dev instance here */
> + rdev = (struct bnxt_re_dev *)ib_alloc_device(sizeof(*rdev));
> + if (!rdev) {
> + dev_err(NULL, "%s: bnxt_re_dev allocation failure!",
> + ROCE_DRV_MODULE_NAME);
> + return NULL;
> + }
> + /* Default values */
> + atomic_set(&rdev->ref_count, 0);
> + rdev->netdev = netdev;
> + dev_hold(rdev->netdev);
> + rdev->en_dev = en_dev;
> + rdev->id = rdev->en_dev->pdev->devfn;
> + INIT_LIST_HEAD(&rdev->qp_list);
> + mutex_init(&rdev->qp_lock);
> + atomic_set(&rdev->qp_count, 0);
> + atomic_set(&rdev->cq_count, 0);
> + atomic_set(&rdev->srq_count, 0);
> + atomic_set(&rdev->mr_count, 0);
> + atomic_set(&rdev->mw_count, 0);
> + rdev->cosq[0] = 0xFFFF;
> + rdev->cosq[1] = 0xFFFF;
> +
> + mutex_lock(&bnxt_re_dev_lock);
> + list_add_tail_rcu(&rdev->list, &bnxt_re_dev_list);
> + mutex_unlock(&bnxt_re_dev_lock);
> + return rdev;
> +}
> +
> +static void bnxt_re_ib_unreg(struct bnxt_re_dev *rdev, bool lock_wait)
> +{
> + int rc;
> +
> + if (test_and_clear_bit(BNXT_RE_FLAG_GOT_MSIX, &rdev->flags)) {
> + rc = bnxt_re_free_msix(rdev, lock_wait);
> + if (rc)
> + dev_warn(rdev_to_dev(rdev),
> + "Failed to free MSI-X vectors: %#x", rc);
> + }
> + if (test_and_clear_bit(BNXT_RE_FLAG_NETDEV_REGISTERED, &rdev->flags)) {
> + rc = bnxt_re_unregister_netdev(rdev, lock_wait);
> + if (rc)
> + dev_warn(rdev_to_dev(rdev),
> + "Failed to unregister with netdev: %#x", rc);
> + }
> +}
> +
> +static int bnxt_re_ib_reg(struct bnxt_re_dev *rdev)
> +{
> + int i, j, rc;
> +
> + /* Registered a new RoCE device instance to netdev */
> + rc = bnxt_re_register_netdev(rdev);
> + if (rc) {
> + pr_err("Failed to register with netedev: %#x\n", rc);
> + return -EINVAL;
> + }
> + set_bit(BNXT_RE_FLAG_NETDEV_REGISTERED, &rdev->flags);
> +
> + rc = bnxt_re_request_msix(rdev);
> + if (rc) {
> + pr_err("Failed to get MSI-X vectors: %#x\n", rc);
> + rc = -EINVAL;
> + goto fail;
> + }
> + set_bit(BNXT_RE_FLAG_GOT_MSIX, &rdev->flags);
> +
> + return 0;
> +fail:
> + bnxt_re_ib_unreg(rdev, true);
> + return rc;
> +}
> +
> +static void bnxt_re_dev_unreg(struct bnxt_re_dev *rdev)
> +{
> + struct bnxt_en_dev *en_dev = rdev->en_dev;
> + struct net_device *netdev = rdev->netdev;
> +
> + bnxt_re_dev_remove(rdev);
> +
> + if (netdev)
> + bnxt_re_dev_unprobe(netdev, en_dev);
> +}
> +
> +static int bnxt_re_dev_reg(struct bnxt_re_dev **rdev, struct net_device *netdev)
> +{
> + struct bnxt_en_dev *en_dev;
> + int rc = 0;
> +
> + if (!is_bnxt_re_dev(netdev))
> + return -ENODEV;
> +
> + en_dev = bnxt_re_dev_probe(netdev);
> + if (IS_ERR(en_dev)) {
> + pr_err("%s: Failed to probe\n", ROCE_DRV_MODULE_NAME);
> + rc = PTR_ERR(en_dev);
> + goto exit;
> + }
> + *rdev = bnxt_re_dev_add(netdev, en_dev);
> + if (!*rdev) {
> + rc = -ENOMEM;
> + bnxt_re_dev_unprobe(netdev, en_dev);
> + goto exit;
> + }
> + bnxt_re_hold(*rdev);
> +exit:
> + return rc;
> +}
> +
> +static void bnxt_re_remove_one(struct bnxt_re_dev *rdev)
> +{
> + pci_dev_put(rdev->en_dev->pdev);
> +}
> +
> +/* Handle all deferred netevents tasks */
> +static void bnxt_re_task(struct work_struct *work)
> +{
> + struct bnxt_re_work *re_work;
> + struct bnxt_re_dev *rdev;
> + int rc = 0;
> +
> + re_work = container_of(work, struct bnxt_re_work, work);
> + rdev = re_work->rdev;
> +
> + if (re_work->event != NETDEV_REGISTER &&
> + !test_bit(BNXT_RE_FLAG_IBDEV_REGISTERED, &rdev->flags))
> + return;
> +
> + switch (re_work->event) {
> + case NETDEV_REGISTER:
> + rc = bnxt_re_ib_reg(rdev);
> + if (rc)
> + dev_err(rdev_to_dev(rdev),
> + "Failed to register with IB: %#x", rc);
> + break;
> + case NETDEV_UP:
> +
> + break;
> + case NETDEV_DOWN:
> +
> + break;
> +
> + case NETDEV_CHANGE:
> +
> + break;
> + default:
> + break;
> + }
Why do you need empty lines and "break"s between cases?
It can be written as a fallback
case ..:
case ..:
break;
> + kfree(re_work);
> +}
> +
> +static void bnxt_re_init_one(struct bnxt_re_dev *rdev)
> +{
> + pci_dev_get(rdev->en_dev->pdev);
> +}
> +
> /*
> * "Notifier chain callback can be invoked for the same chain from
> * different CPUs at the same time".
> @@ -72,6 +464,62 @@ static struct workqueue_struct *bnxt_re_wq;
> static int bnxt_re_netdev_event(struct notifier_block *notifier,
> unsigned long event, void *ptr)
> {
> + struct net_device *real_dev, *netdev = netdev_notifier_info_to_dev(ptr);
> + struct bnxt_re_work *re_work;
> + struct bnxt_re_dev *rdev;
> + int rc = 0;
> +
> + real_dev = rdma_vlan_dev_real_dev(netdev);
> + if (!real_dev)
> + real_dev = netdev;
> +
> + rdev = bnxt_re_from_netdev(real_dev);
> + if (!rdev && event != NETDEV_REGISTER)
> + goto exit;
> + if (real_dev != netdev)
> + goto exit;
> +
> + if (rdev)
> + bnxt_re_hold(rdev);
> +
> + switch (event) {
> + case NETDEV_REGISTER:
> + if (rdev)
> + break;
> + rc = bnxt_re_dev_reg(&rdev, real_dev);
> + if (rc == -ENODEV)
> + break;
> + if (rc) {
> + pr_err("Failed to register with the device %s: %#x\n",
> + real_dev->name, rc);
> + break;
> + }
> + bnxt_re_init_one(rdev);
> + goto sch_work;
> +
> + case NETDEV_UNREGISTER:
> + bnxt_re_ib_unreg(rdev, false);
> + bnxt_re_remove_one(rdev);
> + bnxt_re_dev_unreg(rdev);
> + break;
> +
> + default:
> +sch_work:
It is very awkward goto label at the middle of switch construction.
Please consider to rewrite it.
> + /* Allocate for the deferred task */
> + re_work = kzalloc(sizeof(*re_work), GFP_ATOMIC);
> + if (!re_work)
> + break;
> +
> + re_work->rdev = rdev;
> + re_work->event = event;
> + re_work->vlan_dev = (real_dev == netdev ? NULL : netdev);
> + INIT_WORK(&re_work->work, bnxt_re_task);
> + queue_work(bnxt_re_wq, &re_work->work);
> + break;
> + }
> + if (rdev)
> + bnxt_re_put(rdev);
> +exit:
> return NOTIFY_DONE;
> }
>
> --
> 2.5.5
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ 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