From c953e23936f902c7719166327e3113639105c981 Mon Sep 17 00:00:00 2001 From: Ken-ichirou MATSUZAWA Date: Thu, 20 Aug 2015 12:43:53 +0900 Subject: [PATCH 01/18] netlink: mmap: fix tx type check I can't send netlink message via mmaped netlink socket since commit: a8866ff6a5bce7d0ec465a63bc482a85c09b0d39 netlink: make the check for "send from tx_ring" deterministic msg->msg_iter.type is set to WRITE (1) at SYSCALL_DEFINE6(sendto, ... import_single_range(WRITE, ... iov_iter_init(1, WRITE, ... call path, so that we need to check the type by iter_is_iovec() to accept the WRITE. Signed-off-by: Ken-ichirou MATSUZAWA Signed-off-by: David S. Miller --- net/netlink/af_netlink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 67d210477863..a774985489e2 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -2401,7 +2401,7 @@ static int netlink_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) * sendmsg(), but that's what we've got... */ if (netlink_tx_is_mmaped(sk) && - msg->msg_iter.type == ITER_IOVEC && + iter_is_iovec(&msg->msg_iter) && msg->msg_iter.nr_segs == 1 && msg->msg_iter.iov->iov_base == NULL) { err = netlink_mmap_sendmsg(sk, msg, dst_portid, dst_group, From eed635699abaacebc9b19a2f9de9ddc688c390c2 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Thu, 20 Aug 2015 18:04:22 -0700 Subject: [PATCH 02/18] net: bcmgenet: Avoid sleeping in bcmgenet_timeout bcmgenet_timeout() executes in atomic context, yet we will invoke napi_disable() which does sleep. Looking back at the changes, disabling TX napi and re-enabling it is completely useless, since we reclaim all TX buffers and re-enable interrupts, and wake up the TX queues. Fixes: 13ea657806cf ("net: bcmgenet: improve TX timeout") Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index 64c1e9db6b0b..12a020c105bb 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -2820,8 +2820,6 @@ static void bcmgenet_timeout(struct net_device *dev) netif_dbg(priv, tx_err, dev, "bcmgenet_timeout\n"); - bcmgenet_disable_tx_napi(priv); - for (q = 0; q < priv->hw_params->tx_queues; q++) bcmgenet_dump_tx_queue(&priv->tx_rings[q]); bcmgenet_dump_tx_queue(&priv->tx_rings[DESC_INDEX]); @@ -2837,8 +2835,6 @@ static void bcmgenet_timeout(struct net_device *dev) bcmgenet_intrl2_0_writel(priv, int0_enable, INTRL2_CPU_MASK_CLEAR); bcmgenet_intrl2_1_writel(priv, int1_enable, INTRL2_CPU_MASK_CLEAR); - bcmgenet_enable_tx_napi(priv); - dev->trans_start = jiffies; dev->stats.tx_errors++; From b6df7d61c8776a882dd47ba4714d1445dd7ef2d9 Mon Sep 17 00:00:00 2001 From: Jaedon Shin Date: Fri, 21 Aug 2015 10:08:26 +0900 Subject: [PATCH 03/18] net: bcmgenet: fix uncleaned dma flags Clean the dma flags of multiq ring buffer int the interface stop process. This patch fixes that the genet is not running while the interface is re-enabled. $ ifup eth0 - running after booting $ ifdown eth0 $ ifup eth0 - not running and occur tx_timeout The bcmgenet_dma_disable() in bcmgenet_open() do clean ring16 dma flag only. If the genet has multiq, the dma register is not cleaned. and bcmgenet_init_dma() is not done correctly. in case GENET_V2(tx_queues=4), tdma_ctrl has 0x1e after running bcmgenet_dma_disable(). Signed-off-by: Jaedon Shin Reviewed-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index 12a020c105bb..09ff09f828d0 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -2126,6 +2126,8 @@ static int bcmgenet_dma_teardown(struct bcmgenet_priv *priv) int ret = 0; int timeout = 0; u32 reg; + u32 dma_ctrl; + int i; /* Disable TDMA to stop add more frames in TX DMA */ reg = bcmgenet_tdma_readl(priv, DMA_CTRL); @@ -2169,6 +2171,20 @@ static int bcmgenet_dma_teardown(struct bcmgenet_priv *priv) ret = -ETIMEDOUT; } + dma_ctrl = 0; + for (i = 0; i < priv->hw_params->rx_queues; i++) + dma_ctrl |= (1 << (i + DMA_RING_BUF_EN_SHIFT)); + reg = bcmgenet_rdma_readl(priv, DMA_CTRL); + reg &= ~dma_ctrl; + bcmgenet_rdma_writel(priv, reg, DMA_CTRL); + + dma_ctrl = 0; + for (i = 0; i < priv->hw_params->tx_queues; i++) + dma_ctrl |= (1 << (i + DMA_RING_BUF_EN_SHIFT)); + reg = bcmgenet_tdma_readl(priv, DMA_CTRL); + reg &= ~dma_ctrl; + bcmgenet_tdma_writel(priv, reg, DMA_CTRL); + return ret; } From ba51b6be38c122f7dab40965b4397aaf6188a464 Mon Sep 17 00:00:00 2001 From: David Ahern Date: Mon, 24 Aug 2015 15:17:17 -0600 Subject: [PATCH 04/18] net: Fix RCU splat in af_key Hit the following splat testing VRF change for ipsec: [ 113.475692] =============================== [ 113.476194] [ INFO: suspicious RCU usage. ] [ 113.476667] 4.2.0-rc6-1+deb7u2+clUNRELEASED #3.2.65-1+deb7u2+clUNRELEASED Not tainted [ 113.477545] ------------------------------- [ 113.478013] /work/monster-14/dsa/kernel.git/include/linux/rcupdate.h:568 Illegal context switch in RCU read-side critical section! [ 113.479288] [ 113.479288] other info that might help us debug this: [ 113.479288] [ 113.480207] [ 113.480207] rcu_scheduler_active = 1, debug_locks = 1 [ 113.480931] 2 locks held by setkey/6829: [ 113.481371] #0: (&net->xfrm.xfrm_cfg_mutex){+.+.+.}, at: [] pfkey_sendmsg+0xfb/0x213 [ 113.482509] #1: (rcu_read_lock){......}, at: [] rcu_read_lock+0x0/0x6e [ 113.483509] [ 113.483509] stack backtrace: [ 113.484041] CPU: 0 PID: 6829 Comm: setkey Not tainted 4.2.0-rc6-1+deb7u2+clUNRELEASED #3.2.65-1+deb7u2+clUNRELEASED [ 113.485422] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.7.5.1-0-g8936dbb-20141113_115728-nilsson.home.kraxel.org 04/01/2014 [ 113.486845] 0000000000000001 ffff88001d4c7a98 ffffffff81518af2 ffffffff81086962 [ 113.487732] ffff88001d538480 ffff88001d4c7ac8 ffffffff8107ae75 ffffffff8180a154 [ 113.488628] 0000000000000b30 0000000000000000 00000000000000d0 ffff88001d4c7ad8 [ 113.489525] Call Trace: [ 113.489813] [] dump_stack+0x4c/0x65 [ 113.490389] [] ? console_unlock+0x3d6/0x405 [ 113.491039] [] lockdep_rcu_suspicious+0xfa/0x103 [ 113.491735] [] rcu_preempt_sleep_check+0x45/0x47 [ 113.492442] [] ___might_sleep+0x19/0x1c8 [ 113.493077] [] __might_sleep+0x6c/0x82 [ 113.493681] [] cache_alloc_debugcheck_before.isra.50+0x1d/0x24 [ 113.494508] [] kmem_cache_alloc+0x31/0x18f [ 113.495149] [] skb_clone+0x64/0x80 [ 113.495712] [] pfkey_broadcast_one+0x3d/0xff [ 113.496380] [] pfkey_broadcast+0xb5/0x11e [ 113.497024] [] pfkey_register+0x191/0x1b1 [ 113.497653] [] pfkey_process+0x162/0x17e [ 113.498274] [] pfkey_sendmsg+0x109/0x213 In pfkey_sendmsg the net mutex is taken and then pfkey_broadcast takes the RCU lock. Since pfkey_broadcast takes the RCU lock the allocation argument is pointless since GFP_ATOMIC must be used between the rcu_read_{,un}lock. The one call outside of rcu can be done with GFP_KERNEL. Fixes: 7f6b9dbd5afbd ("af_key: locking change") Signed-off-by: David Ahern Acked-by: Eric Dumazet Signed-off-by: David S. Miller --- net/key/af_key.c | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/net/key/af_key.c b/net/key/af_key.c index b397f0aa9005..83a70688784b 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c @@ -219,7 +219,7 @@ static int pfkey_broadcast_one(struct sk_buff *skb, struct sk_buff **skb2, #define BROADCAST_ONE 1 #define BROADCAST_REGISTERED 2 #define BROADCAST_PROMISC_ONLY 4 -static int pfkey_broadcast(struct sk_buff *skb, gfp_t allocation, +static int pfkey_broadcast(struct sk_buff *skb, int broadcast_flags, struct sock *one_sk, struct net *net) { @@ -244,7 +244,7 @@ static int pfkey_broadcast(struct sk_buff *skb, gfp_t allocation, * socket. */ if (pfk->promisc) - pfkey_broadcast_one(skb, &skb2, allocation, sk); + pfkey_broadcast_one(skb, &skb2, GFP_ATOMIC, sk); /* the exact target will be processed later */ if (sk == one_sk) @@ -259,7 +259,7 @@ static int pfkey_broadcast(struct sk_buff *skb, gfp_t allocation, continue; } - err2 = pfkey_broadcast_one(skb, &skb2, allocation, sk); + err2 = pfkey_broadcast_one(skb, &skb2, GFP_ATOMIC, sk); /* Error is cleare after succecful sending to at least one * registered KM */ @@ -269,7 +269,7 @@ static int pfkey_broadcast(struct sk_buff *skb, gfp_t allocation, rcu_read_unlock(); if (one_sk != NULL) - err = pfkey_broadcast_one(skb, &skb2, allocation, one_sk); + err = pfkey_broadcast_one(skb, &skb2, GFP_KERNEL, one_sk); kfree_skb(skb2); kfree_skb(skb); @@ -292,7 +292,7 @@ static int pfkey_do_dump(struct pfkey_sock *pfk) hdr = (struct sadb_msg *) pfk->dump.skb->data; hdr->sadb_msg_seq = 0; hdr->sadb_msg_errno = rc; - pfkey_broadcast(pfk->dump.skb, GFP_ATOMIC, BROADCAST_ONE, + pfkey_broadcast(pfk->dump.skb, BROADCAST_ONE, &pfk->sk, sock_net(&pfk->sk)); pfk->dump.skb = NULL; } @@ -333,7 +333,7 @@ static int pfkey_error(const struct sadb_msg *orig, int err, struct sock *sk) hdr->sadb_msg_len = (sizeof(struct sadb_msg) / sizeof(uint64_t)); - pfkey_broadcast(skb, GFP_KERNEL, BROADCAST_ONE, sk, sock_net(sk)); + pfkey_broadcast(skb, BROADCAST_ONE, sk, sock_net(sk)); return 0; } @@ -1365,7 +1365,7 @@ static int pfkey_getspi(struct sock *sk, struct sk_buff *skb, const struct sadb_ xfrm_state_put(x); - pfkey_broadcast(resp_skb, GFP_KERNEL, BROADCAST_ONE, sk, net); + pfkey_broadcast(resp_skb, BROADCAST_ONE, sk, net); return 0; } @@ -1452,7 +1452,7 @@ static int key_notify_sa(struct xfrm_state *x, const struct km_event *c) hdr->sadb_msg_seq = c->seq; hdr->sadb_msg_pid = c->portid; - pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ALL, NULL, xs_net(x)); + pfkey_broadcast(skb, BROADCAST_ALL, NULL, xs_net(x)); return 0; } @@ -1565,7 +1565,7 @@ static int pfkey_get(struct sock *sk, struct sk_buff *skb, const struct sadb_msg out_hdr->sadb_msg_reserved = 0; out_hdr->sadb_msg_seq = hdr->sadb_msg_seq; out_hdr->sadb_msg_pid = hdr->sadb_msg_pid; - pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ONE, sk, sock_net(sk)); + pfkey_broadcast(out_skb, BROADCAST_ONE, sk, sock_net(sk)); return 0; } @@ -1670,7 +1670,7 @@ static int pfkey_register(struct sock *sk, struct sk_buff *skb, const struct sad return -ENOBUFS; } - pfkey_broadcast(supp_skb, GFP_KERNEL, BROADCAST_REGISTERED, sk, sock_net(sk)); + pfkey_broadcast(supp_skb, BROADCAST_REGISTERED, sk, sock_net(sk)); return 0; } @@ -1689,7 +1689,7 @@ static int unicast_flush_resp(struct sock *sk, const struct sadb_msg *ihdr) hdr->sadb_msg_errno = (uint8_t) 0; hdr->sadb_msg_len = (sizeof(struct sadb_msg) / sizeof(uint64_t)); - return pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ONE, sk, sock_net(sk)); + return pfkey_broadcast(skb, BROADCAST_ONE, sk, sock_net(sk)); } static int key_notify_sa_flush(const struct km_event *c) @@ -1710,7 +1710,7 @@ static int key_notify_sa_flush(const struct km_event *c) hdr->sadb_msg_len = (sizeof(struct sadb_msg) / sizeof(uint64_t)); hdr->sadb_msg_reserved = 0; - pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ALL, NULL, c->net); + pfkey_broadcast(skb, BROADCAST_ALL, NULL, c->net); return 0; } @@ -1767,7 +1767,7 @@ static int dump_sa(struct xfrm_state *x, int count, void *ptr) out_hdr->sadb_msg_pid = pfk->dump.msg_portid; if (pfk->dump.skb) - pfkey_broadcast(pfk->dump.skb, GFP_ATOMIC, BROADCAST_ONE, + pfkey_broadcast(pfk->dump.skb, BROADCAST_ONE, &pfk->sk, sock_net(&pfk->sk)); pfk->dump.skb = out_skb; @@ -1847,7 +1847,7 @@ static int pfkey_promisc(struct sock *sk, struct sk_buff *skb, const struct sadb new_hdr->sadb_msg_errno = 0; } - pfkey_broadcast(skb, GFP_KERNEL, BROADCAST_ALL, NULL, sock_net(sk)); + pfkey_broadcast(skb, BROADCAST_ALL, NULL, sock_net(sk)); return 0; } @@ -2181,7 +2181,7 @@ static int key_notify_policy(struct xfrm_policy *xp, int dir, const struct km_ev out_hdr->sadb_msg_errno = 0; out_hdr->sadb_msg_seq = c->seq; out_hdr->sadb_msg_pid = c->portid; - pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ALL, NULL, xp_net(xp)); + pfkey_broadcast(out_skb, BROADCAST_ALL, NULL, xp_net(xp)); return 0; } @@ -2401,7 +2401,7 @@ static int key_pol_get_resp(struct sock *sk, struct xfrm_policy *xp, const struc out_hdr->sadb_msg_errno = 0; out_hdr->sadb_msg_seq = hdr->sadb_msg_seq; out_hdr->sadb_msg_pid = hdr->sadb_msg_pid; - pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ONE, sk, xp_net(xp)); + pfkey_broadcast(out_skb, BROADCAST_ONE, sk, xp_net(xp)); err = 0; out: @@ -2655,7 +2655,7 @@ static int dump_sp(struct xfrm_policy *xp, int dir, int count, void *ptr) out_hdr->sadb_msg_pid = pfk->dump.msg_portid; if (pfk->dump.skb) - pfkey_broadcast(pfk->dump.skb, GFP_ATOMIC, BROADCAST_ONE, + pfkey_broadcast(pfk->dump.skb, BROADCAST_ONE, &pfk->sk, sock_net(&pfk->sk)); pfk->dump.skb = out_skb; @@ -2708,7 +2708,7 @@ static int key_notify_policy_flush(const struct km_event *c) hdr->sadb_msg_satype = SADB_SATYPE_UNSPEC; hdr->sadb_msg_len = (sizeof(struct sadb_msg) / sizeof(uint64_t)); hdr->sadb_msg_reserved = 0; - pfkey_broadcast(skb_out, GFP_ATOMIC, BROADCAST_ALL, NULL, c->net); + pfkey_broadcast(skb_out, BROADCAST_ALL, NULL, c->net); return 0; } @@ -2770,7 +2770,7 @@ static int pfkey_process(struct sock *sk, struct sk_buff *skb, const struct sadb void *ext_hdrs[SADB_EXT_MAX]; int err; - pfkey_broadcast(skb_clone(skb, GFP_KERNEL), GFP_KERNEL, + pfkey_broadcast(skb_clone(skb, GFP_KERNEL), BROADCAST_PROMISC_ONLY, NULL, sock_net(sk)); memset(ext_hdrs, 0, sizeof(ext_hdrs)); @@ -2992,7 +2992,7 @@ static int key_notify_sa_expire(struct xfrm_state *x, const struct km_event *c) out_hdr->sadb_msg_seq = 0; out_hdr->sadb_msg_pid = 0; - pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_REGISTERED, NULL, xs_net(x)); + pfkey_broadcast(out_skb, BROADCAST_REGISTERED, NULL, xs_net(x)); return 0; } @@ -3182,7 +3182,7 @@ static int pfkey_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *t, struct xfrm_ctx->ctx_len); } - return pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_REGISTERED, NULL, xs_net(x)); + return pfkey_broadcast(skb, BROADCAST_REGISTERED, NULL, xs_net(x)); } static struct xfrm_policy *pfkey_compile_policy(struct sock *sk, int opt, @@ -3380,7 +3380,7 @@ static int pfkey_send_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, n_port->sadb_x_nat_t_port_port = sport; n_port->sadb_x_nat_t_port_reserved = 0; - return pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_REGISTERED, NULL, xs_net(x)); + return pfkey_broadcast(skb, BROADCAST_REGISTERED, NULL, xs_net(x)); } #ifdef CONFIG_NET_KEY_MIGRATE @@ -3572,7 +3572,7 @@ static int pfkey_send_migrate(const struct xfrm_selector *sel, u8 dir, u8 type, } /* broadcast migrate message to sockets */ - pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ALL, NULL, &init_net); + pfkey_broadcast(skb, BROADCAST_ALL, NULL, &init_net); return 0; From 06b23f7fbbf26a025fd68395c7586949db586b47 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Thu, 6 Aug 2015 09:48:34 +0200 Subject: [PATCH 05/18] can: pcan_usb: don't provide CAN FD bittimings by non-FD adapters The CAN FD data bittiming constants are provided via netlink only when there are valid CAN FD constants available in priv->data_bittiming_const. Due to the indirection of pointer assignments in the peak_usb driver the priv->data_bittiming_const never becomes NULL - not even for non-FD adapters. The data_bittiming_const points to zero'ed data which leads to this result when running 'ip -details link show can0': 35: can0: mtu 16 qdisc noop state DOWN mode DEFAULT group default qlen 10 link/can promiscuity 0 can state STOPPED restart-ms 0 pcan_usb: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..64 brp-inc 1 : dtseg1 0..0 dtseg2 0..0 dsjw 1..0 dbrp 0..0 dbrp-inc 0 <== BROKEN! clock 8000000 This patch changes the struct peak_usb_adapter::bittiming_const and struct peak_usb_adapter::data_bittiming_const to pointers to fix the assignemnt problems. Cc: linux-stable # >= 4.0 Reported-by: Oliver Hartkopp Tested-by: Oliver Hartkopp Signed-off-by: Marc Kleine-Budde --- drivers/net/can/usb/peak_usb/pcan_usb.c | 24 ++--- drivers/net/can/usb/peak_usb/pcan_usb_core.c | 4 +- drivers/net/can/usb/peak_usb/pcan_usb_core.h | 4 +- drivers/net/can/usb/peak_usb/pcan_usb_fd.c | 96 +++++++++++--------- drivers/net/can/usb/peak_usb/pcan_usb_pro.c | 24 ++--- 5 files changed, 82 insertions(+), 70 deletions(-) diff --git a/drivers/net/can/usb/peak_usb/pcan_usb.c b/drivers/net/can/usb/peak_usb/pcan_usb.c index 6b94007ae052..838545ce468d 100644 --- a/drivers/net/can/usb/peak_usb/pcan_usb.c +++ b/drivers/net/can/usb/peak_usb/pcan_usb.c @@ -854,6 +854,18 @@ static int pcan_usb_probe(struct usb_interface *intf) /* * describe the PCAN-USB adapter */ +static const struct can_bittiming_const pcan_usb_const = { + .name = "pcan_usb", + .tseg1_min = 1, + .tseg1_max = 16, + .tseg2_min = 1, + .tseg2_max = 8, + .sjw_max = 4, + .brp_min = 1, + .brp_max = 64, + .brp_inc = 1, +}; + const struct peak_usb_adapter pcan_usb = { .name = "PCAN-USB", .device_id = PCAN_USB_PRODUCT_ID, @@ -862,17 +874,7 @@ const struct peak_usb_adapter pcan_usb = { .clock = { .freq = PCAN_USB_CRYSTAL_HZ / 2 , }, - .bittiming_const = { - .name = "pcan_usb", - .tseg1_min = 1, - .tseg1_max = 16, - .tseg2_min = 1, - .tseg2_max = 8, - .sjw_max = 4, - .brp_min = 1, - .brp_max = 64, - .brp_inc = 1, - }, + .bittiming_const = &pcan_usb_const, /* size of device private data */ .sizeof_dev_private = sizeof(struct pcan_usb), diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c index 7921cff93a63..5a2e341a6d1e 100644 --- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c +++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c @@ -792,9 +792,9 @@ static int peak_usb_create_dev(const struct peak_usb_adapter *peak_usb_adapter, dev->ep_msg_out = peak_usb_adapter->ep_msg_out[ctrl_idx]; dev->can.clock = peak_usb_adapter->clock; - dev->can.bittiming_const = &peak_usb_adapter->bittiming_const; + dev->can.bittiming_const = peak_usb_adapter->bittiming_const; dev->can.do_set_bittiming = peak_usb_set_bittiming; - dev->can.data_bittiming_const = &peak_usb_adapter->data_bittiming_const; + dev->can.data_bittiming_const = peak_usb_adapter->data_bittiming_const; dev->can.do_set_data_bittiming = peak_usb_set_data_bittiming; dev->can.do_set_mode = peak_usb_set_mode; dev->can.do_get_berr_counter = peak_usb_adapter->do_get_berr_counter; diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.h b/drivers/net/can/usb/peak_usb/pcan_usb_core.h index 9e624f05ad4d..506fe506c9d3 100644 --- a/drivers/net/can/usb/peak_usb/pcan_usb_core.h +++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.h @@ -48,8 +48,8 @@ struct peak_usb_adapter { u32 device_id; u32 ctrlmode_supported; struct can_clock clock; - const struct can_bittiming_const bittiming_const; - const struct can_bittiming_const data_bittiming_const; + const struct can_bittiming_const * const bittiming_const; + const struct can_bittiming_const * const data_bittiming_const; unsigned int ctrl_count; int (*intf_probe)(struct usb_interface *intf); diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c index 09d14e70abd7..ce44a033f63b 100644 --- a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c +++ b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c @@ -990,6 +990,30 @@ static void pcan_usb_fd_free(struct peak_usb_device *dev) } /* describes the PCAN-USB FD adapter */ +static const struct can_bittiming_const pcan_usb_fd_const = { + .name = "pcan_usb_fd", + .tseg1_min = 1, + .tseg1_max = 64, + .tseg2_min = 1, + .tseg2_max = 16, + .sjw_max = 16, + .brp_min = 1, + .brp_max = 1024, + .brp_inc = 1, +}; + +static const struct can_bittiming_const pcan_usb_fd_data_const = { + .name = "pcan_usb_fd", + .tseg1_min = 1, + .tseg1_max = 16, + .tseg2_min = 1, + .tseg2_max = 8, + .sjw_max = 4, + .brp_min = 1, + .brp_max = 1024, + .brp_inc = 1, +}; + const struct peak_usb_adapter pcan_usb_fd = { .name = "PCAN-USB FD", .device_id = PCAN_USBFD_PRODUCT_ID, @@ -999,28 +1023,8 @@ const struct peak_usb_adapter pcan_usb_fd = { .clock = { .freq = PCAN_UFD_CRYSTAL_HZ, }, - .bittiming_const = { - .name = "pcan_usb_fd", - .tseg1_min = 1, - .tseg1_max = 64, - .tseg2_min = 1, - .tseg2_max = 16, - .sjw_max = 16, - .brp_min = 1, - .brp_max = 1024, - .brp_inc = 1, - }, - .data_bittiming_const = { - .name = "pcan_usb_fd", - .tseg1_min = 1, - .tseg1_max = 16, - .tseg2_min = 1, - .tseg2_max = 8, - .sjw_max = 4, - .brp_min = 1, - .brp_max = 1024, - .brp_inc = 1, - }, + .bittiming_const = &pcan_usb_fd_const, + .data_bittiming_const = &pcan_usb_fd_data_const, /* size of device private data */ .sizeof_dev_private = sizeof(struct pcan_usb_fd_device), @@ -1058,6 +1062,30 @@ const struct peak_usb_adapter pcan_usb_fd = { }; /* describes the PCAN-USB Pro FD adapter */ +static const struct can_bittiming_const pcan_usb_pro_fd_const = { + .name = "pcan_usb_pro_fd", + .tseg1_min = 1, + .tseg1_max = 64, + .tseg2_min = 1, + .tseg2_max = 16, + .sjw_max = 16, + .brp_min = 1, + .brp_max = 1024, + .brp_inc = 1, +}; + +static const struct can_bittiming_const pcan_usb_pro_fd_data_const = { + .name = "pcan_usb_pro_fd", + .tseg1_min = 1, + .tseg1_max = 16, + .tseg2_min = 1, + .tseg2_max = 8, + .sjw_max = 4, + .brp_min = 1, + .brp_max = 1024, + .brp_inc = 1, +}; + const struct peak_usb_adapter pcan_usb_pro_fd = { .name = "PCAN-USB Pro FD", .device_id = PCAN_USBPROFD_PRODUCT_ID, @@ -1067,28 +1095,8 @@ const struct peak_usb_adapter pcan_usb_pro_fd = { .clock = { .freq = PCAN_UFD_CRYSTAL_HZ, }, - .bittiming_const = { - .name = "pcan_usb_pro_fd", - .tseg1_min = 1, - .tseg1_max = 64, - .tseg2_min = 1, - .tseg2_max = 16, - .sjw_max = 16, - .brp_min = 1, - .brp_max = 1024, - .brp_inc = 1, - }, - .data_bittiming_const = { - .name = "pcan_usb_pro_fd", - .tseg1_min = 1, - .tseg1_max = 16, - .tseg2_min = 1, - .tseg2_max = 8, - .sjw_max = 4, - .brp_min = 1, - .brp_max = 1024, - .brp_inc = 1, - }, + .bittiming_const = &pcan_usb_pro_fd_const, + .data_bittiming_const = &pcan_usb_pro_fd_data_const, /* size of device private data */ .sizeof_dev_private = sizeof(struct pcan_usb_fd_device), diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c index 7d61b3279798..bbdd6058cd2f 100644 --- a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c +++ b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c @@ -1004,6 +1004,18 @@ int pcan_usb_pro_probe(struct usb_interface *intf) /* * describe the PCAN-USB Pro adapter */ +static const struct can_bittiming_const pcan_usb_pro_const = { + .name = "pcan_usb_pro", + .tseg1_min = 1, + .tseg1_max = 16, + .tseg2_min = 1, + .tseg2_max = 8, + .sjw_max = 4, + .brp_min = 1, + .brp_max = 1024, + .brp_inc = 1, +}; + const struct peak_usb_adapter pcan_usb_pro = { .name = "PCAN-USB Pro", .device_id = PCAN_USBPRO_PRODUCT_ID, @@ -1012,17 +1024,7 @@ const struct peak_usb_adapter pcan_usb_pro = { .clock = { .freq = PCAN_USBPRO_CRYSTAL_HZ, }, - .bittiming_const = { - .name = "pcan_usb_pro", - .tseg1_min = 1, - .tseg1_max = 16, - .tseg2_min = 1, - .tseg2_max = 8, - .sjw_max = 4, - .brp_min = 1, - .brp_max = 1024, - .brp_inc = 1, - }, + .bittiming_const = &pcan_usb_pro_const, /* size of device private data */ .sizeof_dev_private = sizeof(struct pcan_usb_pro_device), From 8b63ec1837fa4c1ea604b278d201454eb3b85066 Mon Sep 17 00:00:00 2001 From: David Daney Date: Fri, 21 Aug 2015 16:16:03 -0700 Subject: [PATCH 06/18] phylib: Make PHYs children of their MDIO bus, not the bus' parent. commit 18ee49ddb0d2 ("phylib: rename mii_bus::dev to mii_bus::parent") changed the parent of PHY devices from the bus to the bus parent. Then, commit 4dea547fef1b ("phylib: rework to prepare for OF registration of PHYs") moved the code into phy_device.c At this point, it is somewhat unclear why the change was seen as necessary. But, when we look at the device model tree in /sys/devices, it is clearly incorrect. The PHYs should be children of their MDIO bus. Change the PHY's parent device to be the MDIO bus device. Cc: Lennert Buytenhek Cc: Grant Likely Signed-off-by: David Daney Acked-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/phy/phy_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index 0302483de240..55f01788df5e 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -176,7 +176,7 @@ struct phy_device *phy_device_create(struct mii_bus *bus, int addr, int phy_id, if (c45_ids) dev->c45_ids = *c45_ids; dev->bus = bus; - dev->dev.parent = bus->parent; + dev->dev.parent = &bus->dev; dev->dev.bus = &mdio_bus_type; dev->irq = bus->irq != NULL ? bus->irq[addr] : PHY_POLL; dev_set_name(&dev->dev, PHY_ID_FMT, bus->id, addr); From d4257295ba1b389c693b79de857a96e4b7cd8ac0 Mon Sep 17 00:00:00 2001 From: huaibin Wang Date: Tue, 25 Aug 2015 16:20:34 +0200 Subject: [PATCH 07/18] ip6_gre: release cached dst on tunnel removal When a tunnel is deleted, the cached dst entry should be released. This problem may prevent the removal of a netns (seen with a x-netns IPv6 gre tunnel): unregister_netdevice: waiting for lo to become free. Usage count = 3 CC: Dmitry Kozlov Fixes: c12b395a4664 ("gre: Support GRE over IPv6") Signed-off-by: huaibin Wang Signed-off-by: Nicolas Dichtel Signed-off-by: David S. Miller --- net/ipv6/ip6_gre.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c index a38d3ac0f18f..69f4f689f06a 100644 --- a/net/ipv6/ip6_gre.c +++ b/net/ipv6/ip6_gre.c @@ -361,6 +361,7 @@ static void ip6gre_tunnel_uninit(struct net_device *dev) struct ip6gre_net *ign = net_generic(t->net, ip6gre_net_id); ip6gre_tunnel_unlink(ign, t); + ip6_tnl_dst_reset(t); dev_put(dev); } From 83bc805bff89854e4c81c67633a52ce1015b1502 Mon Sep 17 00:00:00 2001 From: Kazuya Mizuguchi Date: Tue, 25 Aug 2015 18:03:20 +1000 Subject: [PATCH 08/18] net: compile renesas directory if NET_VENDOR_RENESAS is configured Currently the renesas ethernet driver directory is compiled if SH_ETH is configured rather than NET_VENDOR_RENESAS. Although incorrect that was quite harmless as until recently as SH_ETH configured the only driver in the renesas directory. However, as of c156633f1353 ("Renesas Ethernet AVB driver proper") the renesas directory includes another driver, configured by RAVB, and it makes little sense for it to have a hidden dependency on SH_ETH. Signed-off-by: Kazuya Mizuguchi [horms: rewrote changelog] Signed-off-by: Simon Horman Signed-off-by: David S. Miller --- drivers/net/ethernet/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/Makefile b/drivers/net/ethernet/Makefile index c51014b0464f..b52e0f63f9a3 100644 --- a/drivers/net/ethernet/Makefile +++ b/drivers/net/ethernet/Makefile @@ -65,7 +65,7 @@ obj-$(CONFIG_NET_VENDOR_PASEMI) += pasemi/ obj-$(CONFIG_NET_VENDOR_QLOGIC) += qlogic/ obj-$(CONFIG_NET_VENDOR_QUALCOMM) += qualcomm/ obj-$(CONFIG_NET_VENDOR_REALTEK) += realtek/ -obj-$(CONFIG_SH_ETH) += renesas/ +obj-$(CONFIG_NET_VENDOR_RENESAS) += renesas/ obj-$(CONFIG_NET_VENDOR_RDC) += rdc/ obj-$(CONFIG_NET_VENDOR_ROCKER) += rocker/ obj-$(CONFIG_NET_VENDOR_SAMSUNG) += samsung/ From bef0057b7ba881d5ae67eec876df7a26fe672a59 Mon Sep 17 00:00:00 2001 From: Marcelo Ricardo Leitner Date: Tue, 25 Aug 2015 20:22:35 -0300 Subject: [PATCH 09/18] vxlan: re-ignore EADDRINUSE from igmp_join Before 56ef9c909b40[1] it used to ignore all errors from igmp_join(). That commit enhanced that and made it error out whatever error happened with igmp_join(), but that's not good because when using multicast groups vxlan will try to join it multiple times if the socket is reused and then the 2nd and further attempts will fail with EADDRINUSE. As we don't track to which groups the socket is already subscribed, it's okay to just ignore that error. Fixes: 56ef9c909b40 ("vxlan: Move socket initialization to within rtnl scope") Reported-by: John Nielsen Signed-off-by: Marcelo Ricardo Leitner Signed-off-by: David S. Miller --- drivers/net/vxlan.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index 34c519eb1db5..5bc4b1ed67b3 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c @@ -2216,6 +2216,8 @@ static int vxlan_open(struct net_device *dev) if (vxlan_addr_multicast(&vxlan->default_dst.remote_ip)) { ret = vxlan_igmp_join(vxlan); + if (ret == -EADDRINUSE) + ret = 0; if (ret) { vxlan_sock_release(vs); return ret; From 05a7f582be961824d62a7f4a817f3783148b5f8a Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 25 Aug 2015 09:49:47 +0100 Subject: [PATCH 10/18] net: phy: add locking to phy_read_mmd_indirect()/phy_write_mmd_indirect() The phy layer is missing locking for the above two functions - it has been observed that two threads (userspace and the phy worker thread) can race, entering the bus ->write or ->read functions simultaneously. This causes the FEC driver to initialise a completion while another thread is waiting on it or while the interrupt is calling complete() on it, which causes spinlock unlock-without-lock, spinlock lockups, and completion timeouts. Fixes: a59a4d192 ("phy: add the EEE support and the way to access to the MMD registers.") Fixes: 0c1d77dfb ("net: libphy: Add phy specific function to access mmd phy registers") Signed-off-by: Russell King Acked-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/phy/phy.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 1e1fbb049ec6..34fe339f4e80 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -1038,10 +1038,14 @@ int phy_read_mmd_indirect(struct phy_device *phydev, int prtad, int value = -1; if (phydrv->read_mmd_indirect == NULL) { - mmd_phy_indirect(phydev->bus, prtad, devad, addr); + struct mii_bus *bus = phydev->bus; + + mutex_lock(&bus->mdio_lock); + mmd_phy_indirect(bus, prtad, devad, addr); /* Read the content of the MMD's selected register */ - value = phydev->bus->read(phydev->bus, addr, MII_MMD_DATA); + value = bus->read(bus, addr, MII_MMD_DATA); + mutex_unlock(&bus->mdio_lock); } else { value = phydrv->read_mmd_indirect(phydev, prtad, devad, addr); } @@ -1071,10 +1075,14 @@ void phy_write_mmd_indirect(struct phy_device *phydev, int prtad, struct phy_driver *phydrv = phydev->drv; if (phydrv->write_mmd_indirect == NULL) { - mmd_phy_indirect(phydev->bus, prtad, devad, addr); + struct mii_bus *bus = phydev->bus; + + mutex_lock(&bus->mdio_lock); + mmd_phy_indirect(bus, prtad, devad, addr); /* Write the data into MMD's selected register */ - phydev->bus->write(phydev->bus, addr, MII_MMD_DATA, data); + bus->write(bus, addr, MII_MMD_DATA, data); + mutex_unlock(&bus->mdio_lock); } else { phydrv->write_mmd_indirect(phydev, prtad, devad, addr, data); } From aac27c7a0d76683f7f4bdf41cec174db2819f635 Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 25 Aug 2015 09:49:53 +0100 Subject: [PATCH 11/18] net: fec: use reinit_completion() in mdio accessor functions Rather than re-initialising the entire completion on every mdio access, use reinit_completion() which only resets the completion count. This avoids possible reinitialisation of the contained spinlock and waitqueue while they may be in use (eg, mid-completion.) Such an event could occur if there's a long delay in interrupt handling causing the mdio accessor to time out, then a second access comes in while the interrupt handler on a different CPU has called complete(). Another scenario where this has been observed is while locking has been missing at the phy layer, allowing concurrent attempts to access the MDIO bus. Signed-off-by: Russell King Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/fec_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index 271bb5862346..b349e6f36ea7 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c @@ -1778,7 +1778,7 @@ static int fec_enet_mdio_read(struct mii_bus *bus, int mii_id, int regnum) return ret; fep->mii_timeout = 0; - init_completion(&fep->mdio_done); + reinit_completion(&fep->mdio_done); /* start a read op */ writel(FEC_MMFR_ST | FEC_MMFR_OP_READ | @@ -1817,7 +1817,7 @@ static int fec_enet_mdio_write(struct mii_bus *bus, int mii_id, int regnum, return ret; fep->mii_timeout = 0; - init_completion(&fep->mdio_done); + reinit_completion(&fep->mdio_done); /* start a write op */ writel(FEC_MMFR_ST | FEC_MMFR_OP_WRITE | From a6c1aea044e490da3e59124ec55991fe316818d5 Mon Sep 17 00:00:00 2001 From: WANG Cong Date: Tue, 25 Aug 2015 16:38:12 -0700 Subject: [PATCH 12/18] cls_u32: complete the check for non-forced case in u32_destroy() In commit 1e052be69d04 ("net_sched: destroy proto tp when all filters are gone") I added a check in u32_destroy() to see if all real filters are gone for each tp, however, that is only done for root_ht, same is needed for others. This can be reproduced by the following tc commands: tc filter add dev eth0 parent 1:0 prio 5 handle 15: protocol ip u32 divisor 256 tc filter add dev eth0 protocol ip parent 1: prio 5 handle 15:2:2 u32 ht 15:2: match ip src 10.0.0.2 flowid 1:10 tc filter add dev eth0 protocol ip parent 1: prio 5 handle 15:2:3 u32 ht 15:2: match ip src 10.0.0.3 flowid 1:10 Fixes: 1e052be69d04 ("net_sched: destroy proto tp when all filters are gone") Reported-by: Akshat Kakkar Cc: Jamal Hadi Salim Signed-off-by: Cong Wang Signed-off-by: Cong Wang Signed-off-by: David S. Miller --- net/sched/cls_u32.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c index cab9e9b43967..4fbb67430ce4 100644 --- a/net/sched/cls_u32.c +++ b/net/sched/cls_u32.c @@ -490,6 +490,19 @@ static bool u32_destroy(struct tcf_proto *tp, bool force) return false; } } + + if (tp_c->refcnt > 1) + return false; + + if (tp_c->refcnt == 1) { + struct tc_u_hnode *ht; + + for (ht = rtnl_dereference(tp_c->hlist); + ht; + ht = rtnl_dereference(ht->next)) + if (!ht_empty(ht)) + return false; + } } if (root_ht && --root_ht->refcnt == 0) From ccc02ddb1bb7c0c1cac695db18f7533296b51ecc Mon Sep 17 00:00:00 2001 From: Iyappan Subramanian Date: Tue, 25 Aug 2015 15:03:03 -0700 Subject: [PATCH 13/18] drivers: net: xgene: fix: Oops in linkwatch_fire_event [ 1065.801569] Internal error: Oops: 96000006 [#1] SMP ... [ 1065.866655] Hardware name: AppliedMicro Mustang/Mustang, BIOS 1.1.0 Apr 22 2015 [ 1065.873937] Workqueue: events_power_efficient phy_state_machine [ 1065.879837] task: fffffe01de105e80 ti: fffffe00bcf18000 task.ti: fffffe00bcf18000 [ 1065.887288] PC is at linkwatch_fire_event+0xac/0xc0 [ 1065.892141] LR is at linkwatch_fire_event+0xa0/0xc0 [ 1065.896995] pc : [] lr : [] pstate: 200001c5 [ 1065.904356] sp : fffffe00bcf1bd00 ... [ 1066.196813] Call Trace: [ 1066.199248] [] linkwatch_fire_event+0xac/0xc0 [ 1066.205140] [] netif_carrier_off+0x54/0x64 [ 1066.210773] [] phy_state_machine+0x120/0x3bc [ 1066.216578] [] process_one_work+0x15c/0x3a8 [ 1066.222296] [] worker_thread+0x134/0x470 [ 1066.227757] [] kthread+0xe0/0xf8 [ 1066.232525] Code: 97f65ee9 f9420660 d538d082 8b000042 (885f7c40) The fix is to call phy_disconnect() from xgene_enet_mdio_remove, which in turn call cancel_delayed_work_sync(). Signed-off-by: Iyappan Subramanian Signed-off-by: David S. Miller --- drivers/net/ethernet/apm/xgene/xgene_enet_hw.c | 3 +++ drivers/net/ethernet/apm/xgene/xgene_enet_main.c | 5 +++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c index a626c4315a89..cfa37041ab71 100644 --- a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c +++ b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c @@ -801,6 +801,9 @@ int xgene_enet_mdio_config(struct xgene_enet_pdata *pdata) void xgene_enet_mdio_remove(struct xgene_enet_pdata *pdata) { + if (pdata->phy_dev) + phy_disconnect(pdata->phy_dev); + mdiobus_unregister(pdata->mdio_bus); mdiobus_free(pdata->mdio_bus); pdata->mdio_bus = NULL; diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c index 299eb4315fe6..a02ea7f8fdae 100644 --- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c +++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c @@ -1277,9 +1277,10 @@ static int xgene_enet_remove(struct platform_device *pdev) mac_ops->tx_disable(pdata); xgene_enet_napi_del(pdata); - xgene_enet_mdio_remove(pdata); - xgene_enet_delete_desc_rings(pdata); + if (pdata->phy_mode == PHY_INTERFACE_MODE_RGMII) + xgene_enet_mdio_remove(pdata); unregister_netdev(ndev); + xgene_enet_delete_desc_rings(pdata); pdata->port_ops->shutdown(pdata); free_netdev(ndev); From f50791ac1aca1ac1b0370d62397b43e9f831421a Mon Sep 17 00:00:00 2001 From: Eugene Shatokhin Date: Mon, 24 Aug 2015 23:13:42 +0300 Subject: [PATCH 14/18] usbnet: Get EVENT_NO_RUNTIME_PM bit before it is cleared It is needed to check EVENT_NO_RUNTIME_PM bit of dev->flags in usbnet_stop(), but its value should be read before it is cleared when dev->flags is set to 0. The problem was spotted and the fix was provided by Oliver Neukum . Signed-off-by: Eugene Shatokhin Acked-by: Oliver Neukum Signed-off-by: David S. Miller --- drivers/net/usb/usbnet.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 3c86b107275a..e0498571ae26 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -778,7 +778,7 @@ int usbnet_stop (struct net_device *net) { struct usbnet *dev = netdev_priv(net); struct driver_info *info = dev->driver_info; - int retval, pm; + int retval, pm, mpn; clear_bit(EVENT_DEV_OPEN, &dev->flags); netif_stop_queue (net); @@ -809,6 +809,8 @@ int usbnet_stop (struct net_device *net) usbnet_purge_paused_rxq(dev); + mpn = !test_and_clear_bit(EVENT_NO_RUNTIME_PM, &dev->flags); + /* deferred work (task, timer, softirq) must also stop. * can't flush_scheduled_work() until we drop rtnl (later), * else workers could deadlock; so make workers a NOP. @@ -819,8 +821,7 @@ int usbnet_stop (struct net_device *net) if (!pm) usb_autopm_put_interface(dev->intf); - if (info->manage_power && - !test_and_clear_bit(EVENT_NO_RUNTIME_PM, &dev->flags)) + if (info->manage_power && mpn) info->manage_power(dev, 0); else usb_autopm_put_interface(dev->intf); From 4b195360914583899070835a08ceb06ac7b848d6 Mon Sep 17 00:00:00 2001 From: Madalin Bucur Date: Wed, 26 Aug 2015 17:58:47 +0300 Subject: [PATCH 15/18] net: phy: fixed: propagate fixed link values to struct The fixed link values parsed from the device tree are stored in the struct fixed_phy member status. The struct phy_device members speed, duplex were not updated. Signed-off-by: Madalin Bucur Reviewed-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/phy/fixed_phy.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/net/phy/fixed_phy.c b/drivers/net/phy/fixed_phy.c index 1960b46add65..d7a65247f952 100644 --- a/drivers/net/phy/fixed_phy.c +++ b/drivers/net/phy/fixed_phy.c @@ -290,6 +290,15 @@ struct phy_device *fixed_phy_register(unsigned int irq, return ERR_PTR(-EINVAL); } + /* propagate the fixed link values to struct phy_device */ + phy->link = status->link; + if (status->link) { + phy->speed = status->speed; + phy->duplex = status->duplex; + phy->pause = status->pause; + phy->asym_pause = status->asym_pause; + } + of_node_get(np); phy->dev.of_node = np; From fbe4307e9ffd9b9c9d4631a37c8f16080da8df85 Mon Sep 17 00:00:00 2001 From: Bert Kenward Date: Wed, 26 Aug 2015 16:39:03 +0100 Subject: [PATCH 16/18] sfc: only use vadaptor stats if firmware is capable Some of the stats handling code differs based on SR-IOV support, and SRIOV support is only available if full-featured firmware is used. Do not use vadaptor stats if firmware mode is not set to full-featured. Signed-off-by: Shradha Shah Signed-off-by: David S. Miller --- drivers/net/ethernet/sfc/ef10.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c index 605cc8948594..b1a4ea21c91c 100644 --- a/drivers/net/ethernet/sfc/ef10.c +++ b/drivers/net/ethernet/sfc/ef10.c @@ -1282,7 +1282,12 @@ static size_t efx_ef10_update_stats_common(struct efx_nic *efx, u64 *full_stats, } } - if (core_stats) { + if (!core_stats) + return stats_count; + + if (nic_data->datapath_caps & + 1 << MC_CMD_GET_CAPABILITIES_OUT_EVB_LBN) { + /* Use vadaptor stats. */ core_stats->rx_packets = stats[EF10_STAT_rx_unicast] + stats[EF10_STAT_rx_multicast] + stats[EF10_STAT_rx_broadcast]; @@ -1302,6 +1307,26 @@ static size_t efx_ef10_update_stats_common(struct efx_nic *efx, u64 *full_stats, core_stats->rx_fifo_errors = stats[EF10_STAT_rx_overflow]; core_stats->rx_errors = core_stats->rx_crc_errors; core_stats->tx_errors = stats[EF10_STAT_tx_bad]; + } else { + /* Use port stats. */ + core_stats->rx_packets = stats[EF10_STAT_port_rx_packets]; + core_stats->tx_packets = stats[EF10_STAT_port_tx_packets]; + core_stats->rx_bytes = stats[EF10_STAT_port_rx_bytes]; + core_stats->tx_bytes = stats[EF10_STAT_port_tx_bytes]; + core_stats->rx_dropped = stats[EF10_STAT_port_rx_nodesc_drops] + + stats[GENERIC_STAT_rx_nodesc_trunc] + + stats[GENERIC_STAT_rx_noskb_drops]; + core_stats->multicast = stats[EF10_STAT_port_rx_multicast]; + core_stats->rx_length_errors = + stats[EF10_STAT_port_rx_gtjumbo] + + stats[EF10_STAT_port_rx_length_error]; + core_stats->rx_crc_errors = stats[EF10_STAT_port_rx_bad]; + core_stats->rx_frame_errors = + stats[EF10_STAT_port_rx_align_error]; + core_stats->rx_fifo_errors = stats[EF10_STAT_port_rx_overflow]; + core_stats->rx_errors = (core_stats->rx_length_errors + + core_stats->rx_crc_errors + + core_stats->rx_frame_errors); } return stats_count; From ce7b4ccc4f62775f4167495a06fbee0025f87175 Mon Sep 17 00:00:00 2001 From: lucien Date: Thu, 27 Aug 2015 16:26:34 +0800 Subject: [PATCH 17/18] sctp: asconf's process should verify address parameter is in the beginning in sctp_process_asconf(), we get address parameter from the beginning of the addip params. but we never check if it's really there. if the addr param is not there, it still can pass sctp_verify_asconf(), then to be handled by sctp_process_asconf(), it will not be safe. so add a code in sctp_verify_asconf() to check the address parameter is in the beginning, or return false to send abort. note that this can also detect multiple address parameters, and reject it. Signed-off-by: Xin Long Signed-off-by: Marcelo Ricardo Leitner Acked-by: Vlad Yasevich Signed-off-by: David S. Miller --- net/sctp/sm_make_chunk.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index 06320c8c1c86..a655ddc3f353 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c @@ -3132,11 +3132,18 @@ bool sctp_verify_asconf(const struct sctp_association *asoc, case SCTP_PARAM_IPV4_ADDRESS: if (length != sizeof(sctp_ipv4addr_param_t)) return false; + /* ensure there is only one addr param and it's in the + * beginning of addip_hdr params, or we reject it. + */ + if (param.v != addip->addip_hdr.params) + return false; addr_param_seen = true; break; case SCTP_PARAM_IPV6_ADDRESS: if (length != sizeof(sctp_ipv6addr_param_t)) return false; + if (param.v != addip->addip_hdr.params) + return false; addr_param_seen = true; break; case SCTP_PARAM_ADD_IP: From f648f807f61e64d247d26611e34cc97e4ed03401 Mon Sep 17 00:00:00 2001 From: lucien Date: Thu, 27 Aug 2015 04:52:20 +0800 Subject: [PATCH 18/18] sctp: donot reset the overall_error_count in SHUTDOWN_RECEIVE state Commit f8d960524328 ("sctp: Enforce retransmission limit during shutdown") fixed a problem with excessive retransmissions in the SHUTDOWN_PENDING by not resetting the association overall_error_count. This allowed the association to better enforce assoc.max_retrans limit. However, the same issue still exists when the association is in SHUTDOWN_RECEIVED state. In this state, HB-ACKs will continue to reset the overall_error_count for the association would extend the lifetime of association unnecessarily. This patch solves this by resetting the overall_error_count whenever the current state is small then SCTP_STATE_SHUTDOWN_PENDING. As a small side-effect, we end up also handling SCTP_STATE_SHUTDOWN_ACK_SENT and SCTP_STATE_SHUTDOWN_SENT states, but they are not really impacted because we disable Heartbeats in those states. Fixes: Commit f8d960524328 ("sctp: Enforce retransmission limit during shutdown") Signed-off-by: Xin Long Acked-by: Marcelo Ricardo Leitner Acked-by: Vlad Yasevich Signed-off-by: David S. Miller --- net/sctp/sm_sideeffect.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index fef2acdf4a2e..85e6f03aeb70 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c @@ -702,7 +702,7 @@ static void sctp_cmd_transport_on(sctp_cmd_seq_t *cmds, * outstanding data and rely on the retransmission limit be reached * to shutdown the association. */ - if (t->asoc->state != SCTP_STATE_SHUTDOWN_PENDING) + if (t->asoc->state < SCTP_STATE_SHUTDOWN_PENDING) t->asoc->overall_error_count = 0; /* Clear the hb_sent flag to signal that we had a good