* Re: [net-next PATCH V2 3/5] samples/bpf: add a README file to get users started
From: Jesper Dangaard Brouer @ 2016-04-27 6:30 UTC (permalink / raw)
To: Alexei Starovoitov
Cc: brouer, netdev, linux-kbuild, bblanco, naveen.n.rao, borkmann
In-Reply-To: <20160426173105.GD42777@ast-mbp.thefacebook.com>
On Tue, 26 Apr 2016 10:31:06 -0700
Alexei Starovoitov <alexei.starovoitov@gmail.com> wrote:
> On Tue, Apr 26, 2016 at 06:27:22PM +0200, Jesper Dangaard Brouer wrote:
> > +
> > +Manually compiling LLVM with 'bpf' support
> > +------------------------------------------
> > +
> > +In some LLVM versions the BPF target were marked experimental. They
> > +needed the 'cmake .. -DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=BPF'. Since
> > +version 3.7.1, LLVM adds a proper LLVM backend target for the BPF
> > +bytecode architecture.
>
> it's actually non-experimental since 3.7.0.
> It was experimental after 3.6 was released during development of 3.7.
> I doubt you can find this anywhere, so I suggest to just drop this paragraph.
Okay lets drop this paragraph, given the LLVM period was so short, it
does not make sense to mention here.
I will send a V3 patch series, as DaveM usually likes a full resubmit
(I'll add your acks to the other patches, but you need to ack this one).
--
Best regards,
Jesper Dangaard Brouer
MSc.CS, Principal Kernel Engineer at Red Hat
Author of http://www.iptv-analyzer.org
LinkedIn: http://www.linkedin.com/in/brouer
^ permalink raw reply
* Re: [RFC PATCH 4/5] bnxt: Add support for segmentation of tunnels with outer checksums
From: Michael Chan @ 2016-04-27 5:55 UTC (permalink / raw)
To: Alexander Duyck
Cc: eugenia, bruce.w.allan, saeedm, netdev, intel-wired-lan,
ariel.elior, Michael Chan
In-Reply-To: <20160419190615.11723.53966.stgit@ahduyck-xeon-server>
On Tue, Apr 19, 2016 at 12:06 PM, Alexander Duyck <aduyck@mirantis.com> wrote:
> This patch assumes that the bnxt hardware will ignore existing IPv4/v6
> header fields for length and checksum as well as the length and checksum
> fields for outer UDP and GRE headers.
>
> I have no means of testing this as I do not have any bnx2x hardware but
> thought I would submit it as an RFC to see if anyone out there wants to
> test this and see if this does in fact enable this functionality allowing
> us to to segment tunneled frames that have an outer checksum.
>
> Signed-off-by: Alexander Duyck <aduyck@mirantis.com>
Hi Alex, I just did a very quick test of this patch on our bnxt
hardware and it seemed to work.
I created a vxlan endpoint with udpcsum enabled and I saw TSO packets
getting through. I've verified that our hardware can be programmed to
either ignore outer UDP checksum or to calculate it. Current default
is to ignore ipv4 UDP checksum and calculate ipv6 UDP checksum.
Thanks.
> ---
> drivers/net/ethernet/broadcom/bnxt/bnxt.c | 9 +++++++--
> 1 file changed, 7 insertions(+), 2 deletions(-)
>
^ permalink raw reply
* [PATCH v2] net: Add Qualcomm IPC router
From: Bjorn Andersson @ 2016-04-27 5:48 UTC (permalink / raw)
To: David S. Miller
Cc: linux-kernel, netdev, linux-arm-msm, Courtney Cavin,
Bjorn Andersson
From: Courtney Cavin <courtney.cavin@sonymobile.com>
Add an implementation of Qualcomm's IPC router protocol, used to
communicate with service providing remote processors.
Signed-off-by: Courtney Cavin <courtney.cavin@sonymobile.com>
Signed-off-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
[bjorn: Cope with 0 being a valid node id and implement RTM_NEWADDR]
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
---
Changes since v1:
- Made node 0 (normally the Qualcomm modem) a valid node
- Implemented RTM_NEWADDR for specifying the local node id
include/linux/socket.h | 4 +-
include/uapi/linux/qrtr.h | 12 +
net/Kconfig | 1 +
net/Makefile | 1 +
net/qrtr/Kconfig | 24 ++
net/qrtr/Makefile | 2 +
net/qrtr/qrtr.c | 1007 +++++++++++++++++++++++++++++++++++++++++++++
net/qrtr/qrtr.h | 31 ++
net/qrtr/smd.c | 117 ++++++
9 files changed, 1198 insertions(+), 1 deletion(-)
create mode 100644 include/uapi/linux/qrtr.h
create mode 100644 net/qrtr/Kconfig
create mode 100644 net/qrtr/Makefile
create mode 100644 net/qrtr/qrtr.c
create mode 100644 net/qrtr/qrtr.h
create mode 100644 net/qrtr/smd.c
diff --git a/include/linux/socket.h b/include/linux/socket.h
index 73bf6c6a833b..b5cc5a6d7011 100644
--- a/include/linux/socket.h
+++ b/include/linux/socket.h
@@ -201,8 +201,9 @@ struct ucred {
#define AF_NFC 39 /* NFC sockets */
#define AF_VSOCK 40 /* vSockets */
#define AF_KCM 41 /* Kernel Connection Multiplexor*/
+#define AF_QIPCRTR 42 /* Qualcomm IPC Router */
-#define AF_MAX 42 /* For now.. */
+#define AF_MAX 43 /* For now.. */
/* Protocol families, same as address families. */
#define PF_UNSPEC AF_UNSPEC
@@ -249,6 +250,7 @@ struct ucred {
#define PF_NFC AF_NFC
#define PF_VSOCK AF_VSOCK
#define PF_KCM AF_KCM
+#define PF_QIPCRTR AF_QIPCRTR
#define PF_MAX AF_MAX
/* Maximum queue length specifiable by listen. */
diff --git a/include/uapi/linux/qrtr.h b/include/uapi/linux/qrtr.h
new file mode 100644
index 000000000000..66c0748d26e2
--- /dev/null
+++ b/include/uapi/linux/qrtr.h
@@ -0,0 +1,12 @@
+#ifndef _LINUX_QRTR_H
+#define _LINUX_QRTR_H
+
+#include <linux/socket.h>
+
+struct sockaddr_qrtr {
+ __kernel_sa_family_t sq_family;
+ __u32 sq_node;
+ __u32 sq_port;
+};
+
+#endif /* _LINUX_QRTR_H */
diff --git a/net/Kconfig b/net/Kconfig
index a8934d8c8fda..b841c42e5c9b 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -236,6 +236,7 @@ source "net/mpls/Kconfig"
source "net/hsr/Kconfig"
source "net/switchdev/Kconfig"
source "net/l3mdev/Kconfig"
+source "net/qrtr/Kconfig"
config RPS
bool
diff --git a/net/Makefile b/net/Makefile
index 81d14119eab5..bdd14553a774 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -78,3 +78,4 @@ endif
ifneq ($(CONFIG_NET_L3_MASTER_DEV),)
obj-y += l3mdev/
endif
+obj-$(CONFIG_QRTR) += qrtr/
diff --git a/net/qrtr/Kconfig b/net/qrtr/Kconfig
new file mode 100644
index 000000000000..f053cc25f621
--- /dev/null
+++ b/net/qrtr/Kconfig
@@ -0,0 +1,24 @@
+# Qualcomm IPC Router configuration
+#
+
+config QRTR
+ bool "Qualcomm IPC Router support"
+ depends on ARCH_QCOM || COMPILE_TEST
+ ---help---
+ Say Y if you intend to use Qualcomm IPC router protocol. The
+ protocol is used to communicate with services provided by other
+ hardware blocks in the system.
+
+ In order to do service lookups, a userspace daemon is required to
+ maintain a service listing.
+
+if QRTR
+
+config QRTR_SMD
+ tristate "SMD IPC Router channels"
+ depends on QRTR && QCOM_SMD && OF
+ ---help---
+ Say Y here to support SMD based ipcrouter channels. SMD is the
+ most common transport for IPC Router.
+
+endif # QRTR
diff --git a/net/qrtr/Makefile b/net/qrtr/Makefile
new file mode 100644
index 000000000000..e282a84ffc5c
--- /dev/null
+++ b/net/qrtr/Makefile
@@ -0,0 +1,2 @@
+obj-y := qrtr.o
+obj-$(CONFIG_QRTR_SMD) += smd.o
diff --git a/net/qrtr/qrtr.c b/net/qrtr/qrtr.c
new file mode 100644
index 000000000000..c985ecbe9bd6
--- /dev/null
+++ b/net/qrtr/qrtr.c
@@ -0,0 +1,1007 @@
+/*
+ * Copyright (c) 2015, Sony Mobile Communications Inc.
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include <linux/module.h>
+#include <linux/netlink.h>
+#include <linux/qrtr.h>
+#include <linux/termios.h> /* For TIOCINQ/OUTQ */
+
+#include <net/sock.h>
+
+#include "qrtr.h"
+
+#define QRTR_PROTO_VER 1
+
+/* auto-bind range */
+#define QRTR_MIN_EPH_SOCKET 0x4000
+#define QRTR_MAX_EPH_SOCKET 0x7fff
+
+enum qrtr_pkt_type {
+ QRTR_TYPE_DATA = 1,
+ QRTR_TYPE_HELLO = 2,
+ QRTR_TYPE_BYE = 3,
+ QRTR_TYPE_NEW_SERVER = 4,
+ QRTR_TYPE_DEL_SERVER = 5,
+ QRTR_TYPE_DEL_CLIENT = 6,
+ QRTR_TYPE_RESUME_TX = 7,
+ QRTR_TYPE_EXIT = 8,
+ QRTR_TYPE_PING = 9,
+};
+
+/**
+ * struct qrtr_hdr - (I|R)PCrouter packet header
+ * @version: protocol version
+ * @type: packet type; one of QRTR_TYPE_*
+ * @src_node_id: source node
+ * @src_port_id: source port
+ * @confirm_rx: boolean; whether a resume-tx packet should be send in reply
+ * @size: length of packet, excluding this header
+ * @dst_node_id: destination node
+ * @dst_port_id: destination port
+ */
+struct qrtr_hdr {
+ __le32 version;
+ __le32 type;
+ __le32 src_node_id;
+ __le32 src_port_id;
+ __le32 confirm_rx;
+ __le32 size;
+ __le32 dst_node_id;
+ __le32 dst_port_id;
+} __packed;
+
+#define QRTR_HDR_SIZE sizeof(struct qrtr_hdr)
+#define QRTR_NODE_BCAST ((unsigned int)-1)
+#define QRTR_PORT_CTRL ((unsigned int)-2)
+
+struct qrtr_sock {
+ /* WARNING: sk must be the first member */
+ struct sock sk;
+ struct sockaddr_qrtr us;
+ struct sockaddr_qrtr peer;
+};
+
+static inline struct qrtr_sock *qrtr_sk(struct sock *sk)
+{
+ BUILD_BUG_ON(offsetof(struct qrtr_sock, sk) != 0);
+ return container_of(sk, struct qrtr_sock, sk);
+}
+
+static unsigned int qrtr_local_nid = -1;
+
+/* for node ids */
+static RADIX_TREE(qrtr_nodes, GFP_KERNEL);
+/* broadcast list */
+static LIST_HEAD(qrtr_all_nodes);
+/* lock for qrtr_nodes, qrtr_all_nodes and node reference */
+static DEFINE_MUTEX(qrtr_node_lock);
+
+/* local port allocation management */
+static DEFINE_IDR(qrtr_ports);
+static DEFINE_MUTEX(qrtr_port_lock);
+
+/**
+ * struct qrtr_node - endpoint node
+ * @ep_lock: lock for endpoint management and callbacks
+ * @ep: endpoint
+ * @ref: reference count for node
+ * @nid: node id
+ * @rx_queue: receive queue
+ * @work: scheduled work struct for recv work
+ * @item: list item for broadcast list
+ */
+struct qrtr_node {
+ struct mutex ep_lock;
+ struct qrtr_endpoint *ep;
+ struct kref ref;
+ unsigned int nid;
+
+ struct sk_buff_head rx_queue;
+ struct work_struct work;
+ struct list_head item;
+};
+
+/* Release node resources and free the node.
+ *
+ * Do not call directly, use qrtr_node_release. To be used with
+ * kref_put_mutex. As such, the node mutex is expected to be locked on call.
+ */
+static void __qrtr_node_release(struct kref *kref)
+{
+ struct qrtr_node *node = container_of(kref, struct qrtr_node, ref);
+
+ if (node->nid != QRTR_EP_NID_AUTO)
+ radix_tree_delete(&qrtr_nodes, node->nid);
+
+ list_del(&node->item);
+ mutex_unlock(&qrtr_node_lock);
+
+ skb_queue_purge(&node->rx_queue);
+ kfree(node);
+}
+
+/* Increment reference to node. */
+static struct qrtr_node *qrtr_node_acquire(struct qrtr_node *node)
+{
+ if (node)
+ kref_get(&node->ref);
+ return node;
+}
+
+/* Decrement reference to node and release as necessary. */
+static void qrtr_node_release(struct qrtr_node *node)
+{
+ if (!node)
+ return;
+ kref_put_mutex(&node->ref, __qrtr_node_release, &qrtr_node_lock);
+}
+
+/* Pass an outgoing packet socket buffer to the endpoint driver. */
+static int qrtr_node_enqueue(struct qrtr_node *node, struct sk_buff *skb)
+{
+ int rc = -ENODEV;
+
+ mutex_lock(&node->ep_lock);
+ if (node->ep)
+ rc = node->ep->xmit(node->ep, skb);
+ else
+ kfree_skb(skb);
+ mutex_unlock(&node->ep_lock);
+
+ return rc;
+}
+
+/* Lookup node by id.
+ *
+ * callers must release with qrtr_node_release()
+ */
+static struct qrtr_node *qrtr_node_lookup(unsigned int nid)
+{
+ struct qrtr_node *node;
+
+ mutex_lock(&qrtr_node_lock);
+ node = radix_tree_lookup(&qrtr_nodes, nid);
+ node = qrtr_node_acquire(node);
+ mutex_unlock(&qrtr_node_lock);
+
+ return node;
+}
+
+/* Assign node id to node.
+ *
+ * This is mostly useful for automatic node id assignment, based on
+ * the source id in the incoming packet.
+ */
+static void qrtr_node_assign(struct qrtr_node *node, unsigned int nid)
+{
+ if (node->nid != QRTR_EP_NID_AUTO || nid == QRTR_EP_NID_AUTO)
+ return;
+
+ mutex_lock(&qrtr_node_lock);
+ radix_tree_insert(&qrtr_nodes, nid, node);
+ node->nid = nid;
+ mutex_unlock(&qrtr_node_lock);
+}
+
+/**
+ * qrtr_endpoint_post() - post incoming data
+ * @ep: endpoint handle
+ * @data: data pointer
+ * @len: size of data in bytes
+ *
+ * Return: 0 on success; negative error code on failure
+ */
+int qrtr_endpoint_post(struct qrtr_endpoint *ep, const void *data, size_t len)
+{
+ struct qrtr_node *node = ep->node;
+ const struct qrtr_hdr *phdr = data;
+ struct sk_buff *skb;
+ unsigned int psize;
+ unsigned int size;
+ unsigned int type;
+ unsigned int ver;
+ unsigned int dst;
+
+ if (len < QRTR_HDR_SIZE || len & 3)
+ return -EINVAL;
+
+ ver = le32_to_cpu(phdr->version);
+ size = le32_to_cpu(phdr->size);
+ type = le32_to_cpu(phdr->type);
+ dst = le32_to_cpu(phdr->dst_port_id);
+
+ psize = (size + 3) & ~3;
+
+ if (ver != QRTR_PROTO_VER)
+ return -EINVAL;
+
+ if (len != psize + QRTR_HDR_SIZE)
+ return -EINVAL;
+
+ if (dst != QRTR_PORT_CTRL && type != QRTR_TYPE_DATA)
+ return -EINVAL;
+
+ skb = netdev_alloc_skb(NULL, len);
+ if (!skb)
+ return -ENOMEM;
+
+ skb_reset_transport_header(skb);
+ memcpy(skb_put(skb, len), data, len);
+
+ skb_queue_tail(&node->rx_queue, skb);
+ schedule_work(&node->work);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(qrtr_endpoint_post);
+
+/* Allocate and construct a resume-tx packet. */
+static struct sk_buff *qrtr_alloc_resume_tx(u32 src_node,
+ u32 dst_node, u32 port)
+{
+ const int pkt_len = 20;
+ struct qrtr_hdr *hdr;
+ struct sk_buff *skb;
+ u32 *buf;
+
+ skb = alloc_skb(QRTR_HDR_SIZE + pkt_len, GFP_KERNEL);
+ if (!skb)
+ return NULL;
+ skb_reset_transport_header(skb);
+
+ hdr = (struct qrtr_hdr *)skb_put(skb, QRTR_HDR_SIZE);
+ hdr->version = cpu_to_le32(QRTR_PROTO_VER);
+ hdr->type = cpu_to_le32(QRTR_TYPE_RESUME_TX);
+ hdr->src_node_id = cpu_to_le32(src_node);
+ hdr->src_port_id = cpu_to_le32(QRTR_PORT_CTRL);
+ hdr->confirm_rx = cpu_to_le32(0);
+ hdr->size = cpu_to_le32(pkt_len);
+ hdr->dst_node_id = cpu_to_le32(dst_node);
+ hdr->dst_port_id = cpu_to_le32(QRTR_PORT_CTRL);
+
+ buf = (u32 *)skb_put(skb, pkt_len);
+ memset(buf, 0, pkt_len);
+ buf[0] = cpu_to_le32(QRTR_TYPE_RESUME_TX);
+ buf[1] = cpu_to_le32(src_node);
+ buf[2] = cpu_to_le32(port);
+
+ return skb;
+}
+
+static struct qrtr_sock *qrtr_port_lookup(int port);
+static void qrtr_port_put(struct qrtr_sock *ipc);
+
+/* Handle and route a received packet.
+ *
+ * This will auto-reply with resume-tx packet as necessary.
+ */
+static void qrtr_node_rx_work(struct work_struct *work)
+{
+ struct qrtr_node *node = container_of(work, struct qrtr_node, work);
+ struct sk_buff *skb;
+
+ while ((skb = skb_dequeue(&node->rx_queue)) != NULL) {
+ const struct qrtr_hdr *phdr;
+ u32 dst_node, dst_port;
+ struct qrtr_sock *ipc;
+ u32 src_node;
+ int confirm;
+
+ phdr = (const struct qrtr_hdr *)skb_transport_header(skb);
+ src_node = le32_to_cpu(phdr->src_node_id);
+ dst_node = le32_to_cpu(phdr->dst_node_id);
+ dst_port = le32_to_cpu(phdr->dst_port_id);
+ confirm = !!phdr->confirm_rx;
+
+ qrtr_node_assign(node, src_node);
+
+ ipc = qrtr_port_lookup(dst_port);
+ if (!ipc) {
+ kfree_skb(skb);
+ } else {
+ if (sock_queue_rcv_skb(&ipc->sk, skb))
+ kfree_skb(skb);
+
+ qrtr_port_put(ipc);
+ }
+
+ if (confirm) {
+ skb = qrtr_alloc_resume_tx(dst_node, node->nid, dst_port);
+ if (!skb)
+ break;
+ if (qrtr_node_enqueue(node, skb))
+ break;
+ }
+ }
+}
+
+/**
+ * qrtr_endpoint_register() - register a new endpoint
+ * @ep: endpoint to register
+ * @nid: desired node id; may be QRTR_EP_NID_AUTO for auto-assignment
+ * Return: 0 on success; negative error code on failure
+ *
+ * The specified endpoint must have the xmit function pointer set on call.
+ */
+int qrtr_endpoint_register(struct qrtr_endpoint *ep, unsigned int nid)
+{
+ struct qrtr_node *node;
+
+ if (!ep || !ep->xmit)
+ return -EINVAL;
+
+ node = kzalloc(sizeof(*node), GFP_KERNEL);
+ if (!node)
+ return -ENOMEM;
+
+ INIT_WORK(&node->work, qrtr_node_rx_work);
+ kref_init(&node->ref);
+ mutex_init(&node->ep_lock);
+ skb_queue_head_init(&node->rx_queue);
+ node->nid = QRTR_EP_NID_AUTO;
+ node->ep = ep;
+
+ qrtr_node_assign(node, nid);
+
+ mutex_lock(&qrtr_node_lock);
+ list_add(&node->item, &qrtr_all_nodes);
+ mutex_unlock(&qrtr_node_lock);
+ ep->node = node;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(qrtr_endpoint_register);
+
+/**
+ * qrtr_endpoint_unregister - unregister endpoint
+ * @ep: endpoint to unregister
+ */
+void qrtr_endpoint_unregister(struct qrtr_endpoint *ep)
+{
+ struct qrtr_node *node = ep->node;
+
+ mutex_lock(&node->ep_lock);
+ node->ep = NULL;
+ mutex_unlock(&node->ep_lock);
+
+ qrtr_node_release(node);
+ ep->node = NULL;
+}
+EXPORT_SYMBOL_GPL(qrtr_endpoint_unregister);
+
+/* Lookup socket by port.
+ *
+ * Callers must release with qrtr_port_put()
+ */
+static struct qrtr_sock *qrtr_port_lookup(int port)
+{
+ struct qrtr_sock *ipc;
+
+ if (port == QRTR_PORT_CTRL)
+ port = 0;
+
+ mutex_lock(&qrtr_port_lock);
+ ipc = idr_find(&qrtr_ports, port);
+ if (ipc)
+ sock_hold(&ipc->sk);
+ mutex_unlock(&qrtr_port_lock);
+
+ return ipc;
+}
+
+/* Release acquired socket. */
+static void qrtr_port_put(struct qrtr_sock *ipc)
+{
+ sock_put(&ipc->sk);
+}
+
+/* Remove port assignment. */
+static void qrtr_port_remove(struct qrtr_sock *ipc)
+{
+ int port = ipc->us.sq_port;
+
+ if (port == QRTR_PORT_CTRL)
+ port = 0;
+
+ __sock_put(&ipc->sk);
+
+ mutex_lock(&qrtr_port_lock);
+ idr_remove(&qrtr_ports, port);
+ mutex_unlock(&qrtr_port_lock);
+}
+
+/* Assign port number to socket.
+ *
+ * Specify port in the integer pointed to by port, and it will be adjusted
+ * on return as necesssary.
+ *
+ * Port may be:
+ * 0: Assign ephemeral port in [QRTR_MIN_EPH_SOCKET, QRTR_MAX_EPH_SOCKET]
+ * <QRTR_MIN_EPH_SOCKET: Specified; requires CAP_NET_ADMIN
+ * >QRTR_MIN_EPH_SOCKET: Specified; available to all
+ */
+static int qrtr_port_assign(struct qrtr_sock *ipc, int *port)
+{
+ int rc;
+
+ mutex_lock(&qrtr_port_lock);
+ if (!*port) {
+ rc = idr_alloc(&qrtr_ports, ipc,
+ QRTR_MIN_EPH_SOCKET, QRTR_MAX_EPH_SOCKET + 1,
+ GFP_ATOMIC);
+ if (rc >= 0)
+ *port = rc;
+ } else if (*port < QRTR_MIN_EPH_SOCKET && !capable(CAP_NET_ADMIN)) {
+ rc = -EACCES;
+ } else if (*port == QRTR_PORT_CTRL) {
+ rc = idr_alloc(&qrtr_ports, ipc, 0, 1, GFP_ATOMIC);
+ } else {
+ rc = idr_alloc(&qrtr_ports, ipc, *port, *port + 1, GFP_ATOMIC);
+ if (rc >= 0)
+ *port = rc;
+ }
+ mutex_unlock(&qrtr_port_lock);
+
+ if (rc == -ENOSPC)
+ return -EADDRINUSE;
+ else if (rc < 0)
+ return rc;
+
+ sock_hold(&ipc->sk);
+
+ return 0;
+}
+
+/* Bind socket to address.
+ *
+ * Socket should be locked upon call.
+ */
+static int __qrtr_bind(struct socket *sock,
+ const struct sockaddr_qrtr *addr, int zapped)
+{
+ struct qrtr_sock *ipc = qrtr_sk(sock->sk);
+ struct sock *sk = sock->sk;
+ int port;
+ int rc;
+
+ /* rebinding ok */
+ if (!zapped && addr->sq_port == ipc->us.sq_port)
+ return 0;
+
+ port = addr->sq_port;
+ rc = qrtr_port_assign(ipc, &port);
+ if (rc)
+ return rc;
+
+ /* unbind previous, if any */
+ if (!zapped)
+ qrtr_port_remove(ipc);
+ ipc->us.sq_port = port;
+
+ sock_reset_flag(sk, SOCK_ZAPPED);
+
+ return 0;
+}
+
+/* Auto bind to an ephemeral port. */
+static int qrtr_autobind(struct socket *sock)
+{
+ struct sock *sk = sock->sk;
+ struct sockaddr_qrtr addr;
+
+ if (!sock_flag(sk, SOCK_ZAPPED))
+ return 0;
+
+ addr.sq_family = AF_QIPCRTR;
+ addr.sq_node = qrtr_local_nid;
+ addr.sq_port = 0;
+
+ return __qrtr_bind(sock, &addr, 1);
+}
+
+/* Bind socket to specified sockaddr. */
+static int qrtr_bind(struct socket *sock, struct sockaddr *saddr, int len)
+{
+ DECLARE_SOCKADDR(struct sockaddr_qrtr *, addr, saddr);
+ struct qrtr_sock *ipc = qrtr_sk(sock->sk);
+ struct sock *sk = sock->sk;
+ int rc;
+
+ if (len < sizeof(*addr) || addr->sq_family != AF_QIPCRTR)
+ return -EINVAL;
+
+ if (addr->sq_node != ipc->us.sq_node)
+ return -EINVAL;
+
+ lock_sock(sk);
+ rc = __qrtr_bind(sock, addr, sock_flag(sk, SOCK_ZAPPED));
+ release_sock(sk);
+
+ return rc;
+}
+
+/* Queue packet to local peer socket. */
+static int qrtr_local_enqueue(struct qrtr_node *node, struct sk_buff *skb)
+{
+ const struct qrtr_hdr *phdr;
+ struct qrtr_sock *ipc;
+
+ phdr = (const struct qrtr_hdr *)skb_transport_header(skb);
+
+ ipc = qrtr_port_lookup(le32_to_cpu(phdr->dst_port_id));
+ if (!ipc || &ipc->sk == skb->sk) { /* do not send to self */
+ kfree_skb(skb);
+ return -ENODEV;
+ }
+
+ if (sock_queue_rcv_skb(&ipc->sk, skb)) {
+ qrtr_port_put(ipc);
+ kfree_skb(skb);
+ return -ENOSPC;
+ }
+
+ qrtr_port_put(ipc);
+
+ return 0;
+}
+
+/* Queue packet for broadcast. */
+static int qrtr_bcast_enqueue(struct qrtr_node *node, struct sk_buff *skb)
+{
+ struct sk_buff *skbn;
+
+ mutex_lock(&qrtr_node_lock);
+ list_for_each_entry(node, &qrtr_all_nodes, item) {
+ skbn = skb_clone(skb, GFP_KERNEL);
+ if (!skbn)
+ break;
+ skb_set_owner_w(skbn, skb->sk);
+ qrtr_node_enqueue(node, skbn);
+ }
+ mutex_unlock(&qrtr_node_lock);
+
+ qrtr_local_enqueue(node, skb);
+
+ return 0;
+}
+
+static int qrtr_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
+{
+ DECLARE_SOCKADDR(struct sockaddr_qrtr *, addr, msg->msg_name);
+ int (*enqueue_fn)(struct qrtr_node *, struct sk_buff *);
+ struct qrtr_sock *ipc = qrtr_sk(sock->sk);
+ struct sock *sk = sock->sk;
+ struct qrtr_node *node;
+ struct qrtr_hdr *hdr;
+ struct sk_buff *skb;
+ size_t plen;
+ int rc;
+
+ if (msg->msg_flags & ~(MSG_DONTWAIT))
+ return -EINVAL;
+
+ if (len > 65535)
+ return -EMSGSIZE;
+
+ lock_sock(sk);
+
+ if (addr) {
+ if (msg->msg_namelen < sizeof(*addr)) {
+ release_sock(sk);
+ return -EINVAL;
+ }
+
+ if (addr->sq_family != AF_QIPCRTR) {
+ release_sock(sk);
+ return -EINVAL;
+ }
+
+ rc = qrtr_autobind(sock);
+ if (rc) {
+ release_sock(sk);
+ return rc;
+ }
+ } else if (sk->sk_state == TCP_ESTABLISHED) {
+ addr = &ipc->peer;
+ } else {
+ release_sock(sk);
+ return -ENOTCONN;
+ }
+
+ node = NULL;
+ if (addr->sq_node == QRTR_NODE_BCAST) {
+ enqueue_fn = qrtr_bcast_enqueue;
+ } else if (addr->sq_node == ipc->us.sq_node) {
+ enqueue_fn = qrtr_local_enqueue;
+ } else {
+ enqueue_fn = qrtr_node_enqueue;
+ node = qrtr_node_lookup(addr->sq_node);
+ if (!node) {
+ release_sock(sk);
+ return -ECONNRESET;
+ }
+ }
+
+ plen = (len + 3) & ~3;
+ skb = sock_alloc_send_skb(sk, plen + QRTR_HDR_SIZE,
+ msg->msg_flags & MSG_DONTWAIT, &rc);
+ if (!skb)
+ goto out_node;
+
+ skb_reset_transport_header(skb);
+ skb_put(skb, len + QRTR_HDR_SIZE);
+
+ hdr = (struct qrtr_hdr *)skb_transport_header(skb);
+ hdr->version = cpu_to_le32(QRTR_PROTO_VER);
+ hdr->src_node_id = cpu_to_le32(ipc->us.sq_node);
+ hdr->src_port_id = cpu_to_le32(ipc->us.sq_port);
+ hdr->confirm_rx = cpu_to_le32(0);
+ hdr->size = cpu_to_le32(len);
+ hdr->dst_node_id = cpu_to_le32(addr->sq_node);
+ hdr->dst_port_id = cpu_to_le32(addr->sq_port);
+
+ rc = skb_copy_datagram_from_iter(skb, QRTR_HDR_SIZE,
+ &msg->msg_iter, len);
+ if (rc) {
+ kfree_skb(skb);
+ goto out_node;
+ }
+
+ if (plen != len) {
+ skb_pad(skb, plen - len);
+ skb_put(skb, plen - len);
+ }
+
+ if (ipc->us.sq_port == QRTR_PORT_CTRL) {
+ if (len < 4) {
+ rc = -EINVAL;
+ kfree_skb(skb);
+ goto out_node;
+ }
+
+ /* control messages already require the type as 'command' */
+ skb_copy_bits(skb, QRTR_HDR_SIZE, &hdr->type, 4);
+ } else {
+ hdr->type = cpu_to_le32(QRTR_TYPE_DATA);
+ }
+
+ rc = enqueue_fn(node, skb);
+ if (rc >= 0)
+ rc = len;
+
+out_node:
+ qrtr_node_release(node);
+ release_sock(sk);
+
+ return rc;
+}
+
+static int qrtr_recvmsg(struct socket *sock, struct msghdr *msg,
+ size_t size, int flags)
+{
+ DECLARE_SOCKADDR(struct sockaddr_qrtr *, addr, msg->msg_name);
+ const struct qrtr_hdr *phdr;
+ struct sock *sk = sock->sk;
+ struct sk_buff *skb;
+ int copied, rc;
+
+ lock_sock(sk);
+
+ if (sock_flag(sk, SOCK_ZAPPED)) {
+ release_sock(sk);
+ return -EADDRNOTAVAIL;
+ }
+
+ skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT,
+ flags & MSG_DONTWAIT, &rc);
+ if (!skb) {
+ release_sock(sk);
+ return rc;
+ }
+
+ phdr = (const struct qrtr_hdr *)skb_transport_header(skb);
+ copied = le32_to_cpu(phdr->size);
+ if (copied > size) {
+ copied = size;
+ msg->msg_flags |= MSG_TRUNC;
+ }
+
+ rc = skb_copy_datagram_msg(skb, QRTR_HDR_SIZE, msg, copied);
+ if (rc < 0)
+ goto out;
+ rc = copied;
+
+ if (addr) {
+ addr->sq_family = AF_QIPCRTR;
+ addr->sq_node = le32_to_cpu(phdr->src_node_id);
+ addr->sq_port = le32_to_cpu(phdr->src_port_id);
+ msg->msg_namelen = sizeof(*addr);
+ }
+
+out:
+ skb_free_datagram(sk, skb);
+ release_sock(sk);
+
+ return rc;
+}
+
+static int qrtr_connect(struct socket *sock, struct sockaddr *saddr,
+ int len, int flags)
+{
+ DECLARE_SOCKADDR(struct sockaddr_qrtr *, addr, saddr);
+ struct qrtr_sock *ipc = qrtr_sk(sock->sk);
+ struct sock *sk = sock->sk;
+ int rc;
+
+ if (len < sizeof(*addr) || addr->sq_family != AF_QIPCRTR)
+ return -EINVAL;
+
+ lock_sock(sk);
+
+ sk->sk_state = TCP_CLOSE;
+ sock->state = SS_UNCONNECTED;
+
+ rc = qrtr_autobind(sock);
+ if (rc) {
+ release_sock(sk);
+ return rc;
+ }
+
+ ipc->peer = *addr;
+ sock->state = SS_CONNECTED;
+ sk->sk_state = TCP_ESTABLISHED;
+
+ release_sock(sk);
+
+ return 0;
+}
+
+static int qrtr_getname(struct socket *sock, struct sockaddr *saddr,
+ int *len, int peer)
+{
+ struct qrtr_sock *ipc = qrtr_sk(sock->sk);
+ struct sockaddr_qrtr qaddr;
+ struct sock *sk = sock->sk;
+
+ lock_sock(sk);
+ if (peer) {
+ if (sk->sk_state != TCP_ESTABLISHED) {
+ release_sock(sk);
+ return -ENOTCONN;
+ }
+
+ qaddr = ipc->peer;
+ } else {
+ qaddr = ipc->us;
+ }
+ release_sock(sk);
+
+ *len = sizeof(qaddr);
+ qaddr.sq_family = AF_QIPCRTR;
+
+ memcpy(saddr, &qaddr, sizeof(qaddr));
+
+ return 0;
+}
+
+static int qrtr_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
+{
+ void __user *argp = (void __user *)arg;
+ struct qrtr_sock *ipc = qrtr_sk(sock->sk);
+ struct sock *sk = sock->sk;
+ struct sockaddr_qrtr *sq;
+ struct sk_buff *skb;
+ struct ifreq ifr;
+ long len = 0;
+ int rc = 0;
+
+ lock_sock(sk);
+
+ switch (cmd) {
+ case TIOCOUTQ:
+ len = sk->sk_sndbuf - sk_wmem_alloc_get(sk);
+ if (len < 0)
+ len = 0;
+ rc = put_user(len, (int __user *)argp);
+ break;
+ case TIOCINQ:
+ skb = skb_peek(&sk->sk_receive_queue);
+ if (skb)
+ len = skb->len - QRTR_HDR_SIZE;
+ rc = put_user(len, (int __user *)argp);
+ break;
+ case SIOCGIFADDR:
+ if (copy_from_user(&ifr, argp, sizeof(ifr))) {
+ rc = -EFAULT;
+ break;
+ }
+
+ sq = (struct sockaddr_qrtr *)&ifr.ifr_addr;
+ *sq = ipc->us;
+ if (copy_to_user(argp, &ifr, sizeof(ifr))) {
+ rc = -EFAULT;
+ break;
+ }
+ break;
+ case SIOCGSTAMP:
+ rc = sock_get_timestamp(sk, argp);
+ break;
+ case SIOCADDRT:
+ case SIOCDELRT:
+ case SIOCSIFADDR:
+ case SIOCGIFDSTADDR:
+ case SIOCSIFDSTADDR:
+ case SIOCGIFBRDADDR:
+ case SIOCSIFBRDADDR:
+ case SIOCGIFNETMASK:
+ case SIOCSIFNETMASK:
+ rc = -EINVAL;
+ break;
+ default:
+ rc = -ENOIOCTLCMD;
+ break;
+ }
+
+ release_sock(sk);
+
+ return rc;
+}
+
+static int qrtr_release(struct socket *sock)
+{
+ struct sock *sk = sock->sk;
+ struct qrtr_sock *ipc;
+
+ if (!sk)
+ return 0;
+
+ lock_sock(sk);
+
+ ipc = qrtr_sk(sk);
+ sk->sk_shutdown = SHUTDOWN_MASK;
+ if (!sock_flag(sk, SOCK_DEAD))
+ sk->sk_state_change(sk);
+
+ sock_set_flag(sk, SOCK_DEAD);
+ sock->sk = NULL;
+
+ if (!sock_flag(sk, SOCK_ZAPPED))
+ qrtr_port_remove(ipc);
+
+ skb_queue_purge(&sk->sk_receive_queue);
+
+ release_sock(sk);
+ sock_put(sk);
+
+ return 0;
+}
+
+static const struct proto_ops qrtr_proto_ops = {
+ .owner = THIS_MODULE,
+ .family = AF_QIPCRTR,
+ .bind = qrtr_bind,
+ .connect = qrtr_connect,
+ .socketpair = sock_no_socketpair,
+ .accept = sock_no_accept,
+ .listen = sock_no_listen,
+ .sendmsg = qrtr_sendmsg,
+ .recvmsg = qrtr_recvmsg,
+ .getname = qrtr_getname,
+ .ioctl = qrtr_ioctl,
+ .poll = datagram_poll,
+ .shutdown = sock_no_shutdown,
+ .setsockopt = sock_no_setsockopt,
+ .getsockopt = sock_no_getsockopt,
+ .release = qrtr_release,
+ .mmap = sock_no_mmap,
+ .sendpage = sock_no_sendpage,
+};
+
+static struct proto qrtr_proto = {
+ .name = "QIPCRTR",
+ .owner = THIS_MODULE,
+ .obj_size = sizeof(struct qrtr_sock),
+};
+
+static int qrtr_create(struct net *net, struct socket *sock,
+ int protocol, int kern)
+{
+ struct qrtr_sock *ipc;
+ struct sock *sk;
+
+ if (sock->type != SOCK_DGRAM)
+ return -EPROTOTYPE;
+
+ sk = sk_alloc(net, AF_QIPCRTR, GFP_KERNEL, &qrtr_proto, kern);
+ if (!sk)
+ return -ENOMEM;
+
+ sock_set_flag(sk, SOCK_ZAPPED);
+
+ sock_init_data(sock, sk);
+ sock->ops = &qrtr_proto_ops;
+
+ ipc = qrtr_sk(sk);
+ ipc->us.sq_family = AF_QIPCRTR;
+ ipc->us.sq_node = qrtr_local_nid;
+ ipc->us.sq_port = 0;
+
+ return 0;
+}
+
+static const struct nla_policy qrtr_policy[IFA_MAX + 1] = {
+ [IFA_LOCAL] = { .type = NLA_U32 },
+};
+
+static int qrtr_addr_doit(struct sk_buff *skb, struct nlmsghdr *nlh)
+{
+ struct nlattr *tb[IFA_MAX + 1];
+ struct ifaddrmsg *ifm;
+ int rc;
+
+ if (!netlink_capable(skb, CAP_NET_ADMIN))
+ return -EPERM;
+
+ if (!netlink_capable(skb, CAP_SYS_ADMIN))
+ return -EPERM;
+
+ ASSERT_RTNL();
+
+ rc = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, qrtr_policy);
+ if (rc < 0)
+ return rc;
+
+ ifm = nlmsg_data(nlh);
+ if (!tb[IFA_LOCAL])
+ return -EINVAL;
+
+ qrtr_local_nid = nla_get_u32(tb[IFA_LOCAL]);
+ return 0;
+}
+
+static const struct net_proto_family qrtr_family = {
+ .owner = THIS_MODULE,
+ .family = AF_QIPCRTR,
+ .create = qrtr_create,
+};
+
+static int __init qrtr_proto_init(void)
+{
+ int rc;
+
+ rc = proto_register(&qrtr_proto, 1);
+ if (rc)
+ return rc;
+
+ rc = sock_register(&qrtr_family);
+ if (rc) {
+ proto_unregister(&qrtr_proto);
+ return rc;
+ }
+
+ rtnl_register(PF_QIPCRTR, RTM_NEWADDR, qrtr_addr_doit, NULL, NULL);
+
+ return 0;
+}
+module_init(qrtr_proto_init);
+
+static void __exit qrtr_proto_fini(void)
+{
+ rtnl_unregister(PF_QIPCRTR, RTM_NEWADDR);
+ sock_unregister(qrtr_family.family);
+ proto_unregister(&qrtr_proto);
+}
+module_exit(qrtr_proto_fini);
+
+MODULE_DESCRIPTION("Qualcomm IPC-router driver");
+MODULE_LICENSE("GPL v2");
diff --git a/net/qrtr/qrtr.h b/net/qrtr/qrtr.h
new file mode 100644
index 000000000000..2b848718f8fe
--- /dev/null
+++ b/net/qrtr/qrtr.h
@@ -0,0 +1,31 @@
+#ifndef __QRTR_H_
+#define __QRTR_H_
+
+#include <linux/types.h>
+
+struct sk_buff;
+
+/* endpoint node id auto assignment */
+#define QRTR_EP_NID_AUTO (-1)
+
+/**
+ * struct qrtr_endpoint - endpoint handle
+ * @xmit: Callback for outgoing packets
+ *
+ * The socket buffer passed to the xmit function becomes owned by the endpoint
+ * driver. As such, when the driver is done with the buffer, it should
+ * call kfree_skb() on failure, or consume_skb() on success.
+ */
+struct qrtr_endpoint {
+ int (*xmit)(struct qrtr_endpoint *ep, struct sk_buff *skb);
+ /* private: not for endpoint use */
+ struct qrtr_node *node;
+};
+
+int qrtr_endpoint_register(struct qrtr_endpoint *ep, unsigned int nid);
+
+void qrtr_endpoint_unregister(struct qrtr_endpoint *ep);
+
+int qrtr_endpoint_post(struct qrtr_endpoint *ep, const void *data, size_t len);
+
+#endif
diff --git a/net/qrtr/smd.c b/net/qrtr/smd.c
new file mode 100644
index 000000000000..84ebce73aa23
--- /dev/null
+++ b/net/qrtr/smd.c
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2015, Sony Mobile Communications Inc.
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/soc/qcom/smd.h>
+
+#include "qrtr.h"
+
+struct qrtr_smd_dev {
+ struct qrtr_endpoint ep;
+ struct qcom_smd_channel *channel;
+};
+
+/* from smd to qrtr */
+static int qcom_smd_qrtr_callback(struct qcom_smd_device *sdev,
+ const void *data, size_t len)
+{
+ struct qrtr_smd_dev *qdev = dev_get_drvdata(&sdev->dev);
+ int rc;
+
+ if (!qdev)
+ return -EAGAIN;
+
+ rc = qrtr_endpoint_post(&qdev->ep, data, len);
+ if (rc == -EINVAL) {
+ dev_err(&sdev->dev, "invalid ipcrouter packet\n");
+ /* return 0 to let smd drop the packet */
+ rc = 0;
+ }
+
+ return rc;
+}
+
+/* from qrtr to smd */
+static int qcom_smd_qrtr_send(struct qrtr_endpoint *ep, struct sk_buff *skb)
+{
+ struct qrtr_smd_dev *qdev = container_of(ep, struct qrtr_smd_dev, ep);
+ int rc;
+
+ rc = skb_linearize(skb);
+ if (rc)
+ goto out;
+
+ rc = qcom_smd_send(qdev->channel, skb->data, skb->len);
+
+out:
+ if (rc)
+ kfree_skb(skb);
+ else
+ consume_skb(skb);
+ return rc;
+}
+
+static int qcom_smd_qrtr_probe(struct qcom_smd_device *sdev)
+{
+ struct qrtr_smd_dev *qdev;
+ int rc;
+
+ qdev = devm_kzalloc(&sdev->dev, sizeof(*qdev), GFP_KERNEL);
+ if (!qdev)
+ return -ENOMEM;
+
+ qdev->channel = sdev->channel;
+ qdev->ep.xmit = qcom_smd_qrtr_send;
+
+ rc = qrtr_endpoint_register(&qdev->ep, QRTR_EP_NID_AUTO);
+ if (rc)
+ return rc;
+
+ dev_set_drvdata(&sdev->dev, qdev);
+
+ dev_dbg(&sdev->dev, "Qualcomm SMD QRTR driver probed\n");
+
+ return 0;
+}
+
+static void qcom_smd_qrtr_remove(struct qcom_smd_device *sdev)
+{
+ struct qrtr_smd_dev *qdev = dev_get_drvdata(&sdev->dev);
+
+ qrtr_endpoint_unregister(&qdev->ep);
+
+ dev_set_drvdata(&sdev->dev, NULL);
+}
+
+static const struct qcom_smd_id qcom_smd_qrtr_smd_match[] = {
+ { "IPCRTR" },
+ {}
+};
+
+static struct qcom_smd_driver qcom_smd_qrtr_driver = {
+ .probe = qcom_smd_qrtr_probe,
+ .remove = qcom_smd_qrtr_remove,
+ .callback = qcom_smd_qrtr_callback,
+ .smd_match_table = qcom_smd_qrtr_smd_match,
+ .driver = {
+ .name = "qcom_smd_qrtr",
+ .owner = THIS_MODULE,
+ },
+};
+
+module_qcom_smd_driver(qcom_smd_qrtr_driver);
+
+MODULE_DESCRIPTION("Qualcomm IPC-Router SMD interface driver");
+MODULE_LICENSE("GPL v2");
--
2.5.0
^ permalink raw reply related
* Re: [PATCH 1/6] bus: Add shared MDIO bus framework
From: Anup Patel @ 2016-04-27 4:46 UTC (permalink / raw)
To: Andrew Lunn
Cc: Arnd Bergmann, Florian Fainelli, Pramod Kumar, Rob Herring,
Catalin Marinas, Will Deacon, Masahiro Yamada, Chen-Yu Tsai,
Mark Rutland, Device Tree, Pawel Moll, Suzuki K Poulose, netdev,
Punit Agrawal, Linux Kernel, BCM Kernel Feedback,
Linux ARM Kernel, Kishon Vijay Abraham I
In-Reply-To: <20160426194102.GF30107@lunn.ch>
On Wed, Apr 27, 2016 at 1:11 AM, Andrew Lunn <andrew@lunn.ch> wrote:
> On Tue, Apr 26, 2016 at 09:24:34PM +0200, Arnd Bergmann wrote:
>> On Tuesday 26 April 2016 20:23:35 Andrew Lunn wrote:
>> > > A more complex problem would be having a PHY driver for a device
>> > > that can be either an ethernet phy or some other phy.
>> >
>> > I doubt that ever happens. You can have up to 32 different devices on
>> > an MDIO bus. Since an Ethernet PHY and a "some other sort of PHY" are
>> > completely different things, why would a hardware engineer place them
>> > on the same address? It is like saying your ATA controller and VGA
>> > controller share the same slot on the PCI bus...
>>
>> To clarify: what I meant is a device that is designed as a PHY for
>> similar hardware (e.g. SATA, USB3 and PCIe) and that has a common
>> register set and a single driver, but that driver can operate
>> in multiple modes. You typically have multiple instances of
>> such hardware, with each instance linked to exactly one host
>> device, but one driver for all of them.
>>
>> See Documentation/devicetree/bindings/phy/apm-xgene-phy.txt
>> and drivers/phy/phy-xgene.c for one such example.
>
> Interesting. Also, that this lists SGMII. I assume this is a phy in
> the MAC in order to talk to the Ethernet PHY.
>
> I still don't see it being a big problem if a phy driver implements an
> Ethernet PHY. It just needs to call phy_device_create() and
> phy_device_register().
>
> Andrew
It is really interesting to see the evolution of MDIO bus:
1. Traditionally, MDIO controller used to be part of each ethernet controller
itself so each ethernet controller used to have it's own 2 wire MDIO bus
2. Next, we saw SoC with multiple ethernet controllers sharing same MDIO
bus. In other words, we saw multiple MDIO bus being muxed over single
MDIO bus with additional bus select lines (I think this is when
drivers/net/phy/mdio-mux.c APIs were implemented but at this point all
PHYs on muxed MDIO bus were ethernet PHYs).
3. Then, we saw SoC with ethernet switch devices also accessible over
shared MDIO bus (or Muxed MDIO bus) along with ethernet PHYs (I guess
this is why we have drivers/net/phy/mdio_device.c which adds
"mdio_device" for non-ethernet-PHY devices on MDIO bus).
4. Now, we have SoC with SATA PHYs, PCIe PHYs, USB PHYs, and Ethernet
PHYs all accessible over same shared MDIO bus (or Muxed MDIO bus). The
SATA PHYs and PCIe PHYs are registered to "Generic PHY framework". For
USB PHYs, we can either register to "Generic PHY framework" or "USB PHY
framework". For Ethernet PHYs, we register MDIO bus instance to "Ethernet
MDIO framework".
The devices on ARM64 SoC has to be within first 4GB and RAM has to start
from first 4GB to be ARM compliant because ARM64 CPUs have 32bit mode and
all devices and RAM should be available to 32bit mode with MMU disabled.
This means that we only have 4GB to fit all devices registers and some
portion of RAM. Some of these non-Ethernet PHYs have tons of registers so
as number of PHYs increase in a SoC they will eat-up lot of first 4GB
address space. Using same MDIO bus for all types of PHYs (SATA, PCIe, USB,
and Ethernet) is actually a good approach because it actually saves lot of
first 4GB address space. In future, more devices will be moved to a shared
MDIO bus which are less frequently accessed.
For Broadcom iProc SoCs, the design choice has already been made to use
shared MDIO bus for all PHYs. In fact, Broadcom iProc NS2 SoC already has
a shared MDIO bus for SATA PHYs, USB PHYs, PCIe PHYs, and Ethernet
PHYs and more Broadcom iProc SoCs are on their way. Of course, there are
few exceptions in iProc SoCs such as SATA PHYs where we also have memory
mapped registers to access PHYs but other PHYs don't have such memory
mapped registers.
Clearly from above, the traditional 2 wire MDIO bus is now a shared MDIO
bus with 2-wire plus additional select lines. Also, now we have SoCs (such
as Broadcom iProc SoCs) which has such shared MDIO bus and I think
in-future we will have SoCs with a shared MDIO bus for variety of devices.
For long term, we really need a clean solution to fit shared MDIO based
PHY drivers in Linux kernel. Also, shared MDIO based PHY drivers should
not be dependent on any particular IO subsystem (such as Linux Ethernet)
because there are lot of use-cases where people want strip down kernel
image by not-compiling IO subsystems which are not required.
IMHO, we have several options in front of us:
1. Use some light-weight framework (such as shared_mdio.c implemented
by this patchset) under drivers/bus
2. Extend "Generic PHY framework" to allow something like shared MDIO
bus (as-per Arnd's suggestion)
3. Move-out "MDIO-mux APIs" from drivers/net/phy to something like
drivers/mdio-mux and make it independent of "Linux Ethernet subsystem".
(... may be more options ...)
Regards,
Anup
^ permalink raw reply
* Re: [PATCH net-next] net-rfs: fix false sharing accessing sd->input_queue_head
From: David Miller @ 2016-04-27 4:31 UTC (permalink / raw)
To: eric.dumazet; +Cc: netdev
In-Reply-To: <1461709807.5535.55.camel@edumazet-glaptop3.roam.corp.google.com>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Tue, 26 Apr 2016 15:30:07 -0700
> From: Eric Dumazet <edumazet@google.com>
>
> sd->input_queue_head is incremented for each processed packet
> in process_backlog(), and read from other cpus performing
> Out Of Order avoidance in get_rps_cpu()
>
> Moving this field in a separate cache line keeps it mostly
> hot for the cpu in process_backlog(), as other cpus will
> only read it.
>
> In a stress test, process_backlog() was consuming 6.80 % of cpu cycles,
> and the patch reduced the cost to 0.65 %
>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
Applied, nice work Eric.
^ permalink raw reply
* Re: [PATCH -next] net: w5100: support W5500
From: David Miller @ 2016-04-27 4:31 UTC (permalink / raw)
To: akinobu.mita; +Cc: netdev, msink
In-Reply-To: <1461703428-8078-1-git-send-email-akinobu.mita@gmail.com>
From: Akinobu Mita <akinobu.mita@gmail.com>
Date: Wed, 27 Apr 2016 05:43:48 +0900
> This adds support for W5500 chip.
Applied, thanks.
^ permalink raw reply
* Re: [net-next 08/15] i40e: Allow user to change input set mask for flow director
From: David Miller @ 2016-04-27 3:48 UTC (permalink / raw)
To: jeffrey.t.kirsher; +Cc: kiran.patil, netdev, nhorman, sassmann, jogreene
In-Reply-To: <1461704148-114349-9-git-send-email-jeffrey.t.kirsher@intel.com>
From: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Date: Tue, 26 Apr 2016 13:55:41 -0700
> From: Kiran Patil <kiran.patil@intel.com>
>
> This patch implements feature, which allows user to change
> input set mask for flow director using side-band channel.
> This patch adds definition of FLOW_TYPE_MASK into the header file.
> With this patch, user can now specify less than 4 tuple(src ip, dsp ip,
> src port, dst port) for flow type TCP4/UDP4.
>
> Change-Id: I90052508f8c172c0da5a4b78b949704b4a59ea78
> Signed-off-by: Kiran Patil <kiran.patil@intel.com>
> Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
If you want to do this, you have to define the semantics generically
in include/uapi/linux/ethtool.h so that other drivers can implement
this too.
Please don't ever implement private, driver specific, interpretations
of the generic ethtool facilitites.
The semantics and interpretations of the values must absolutely be
consistent across all drivers in the tree.
Otherwise the user experience is terrible.
Thanks.
^ permalink raw reply
* Re: [PATCH v5 09/21] IB/hns: Add hca support
From: oulijun @ 2016-04-27 3:37 UTC (permalink / raw)
To: leon-DgEjT+Ai2ygdnm+yROfE0A
Cc: dledford-H+wXaHxf7aLQT0dZR+AlfA,
sean.hefty-ral2JQCrhuEAvxtiuMwx3w,
hal.rosenstock-Re5JQEeQqe8AvxtiuMwx3w,
davem-fT/PcQaiUtIeIZ0/mPfg9Q,
jeffrey.t.kirsher-ral2JQCrhuEAvxtiuMwx3w,
jiri-VPRAkNaXOzVWk0Htik3J/w, ogerlitz-VPRAkNaXOzVWk0Htik3J/w,
linuxarm-hv44wF8Li93QT0dZR+AlfA,
linux-rdma-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA,
gongyangming-hv44wF8Li93QT0dZR+AlfA,
xiaokun-hv44wF8Li93QT0dZR+AlfA,
tangchaofei-hv44wF8Li93QT0dZR+AlfA,
haifeng.wei-hv44wF8Li93QT0dZR+AlfA,
yisen.zhuang-hv44wF8Li93QT0dZR+AlfA,
yankejian-hv44wF8Li93QT0dZR+AlfA,
lisheng011-hv44wF8Li93QT0dZR+AlfA,
charles.chenxin-hv44wF8Li93QT0dZR+AlfA
In-Reply-To: <20160426141821.GJ7974-2ukJVAZIZ/Y@public.gmane.org>
On 2016/4/26 22:18, Leon Romanovsky wrote:
> On Tue, Apr 26, 2016 at 02:34:44PM +0800, oulijun wrote:
>> On 2016/4/24 15:54, Leon Romanovsky wrote:
>>> On Sat, Apr 23, 2016 at 06:26:47PM +0800, Lijun Ou wrote:
>>>> This patch mainly setup hca for RoCE. it will do a series of
>>>> initial works as follows:
>>>> 1. init uar table, allocate uar resource
>>>> 2. init pd table
>>>> 3. init cq table
>>>> 4. init mr table
>>>> 5. init qp table
>>>>
>>>> Signed-off-by: Lijun Ou <oulijun-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
>>>> Signed-off-by: Wei Hu(Xavier) <xavier.huwei-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
>>>> ---
>>>> drivers/infiniband/hw/hns/hns_roce_alloc.c | 104 ++++++++++++++++
>>>> drivers/infiniband/hw/hns/hns_roce_cq.c | 25 ++++
>>>> drivers/infiniband/hw/hns/hns_roce_device.h | 69 ++++++++++
>>>> drivers/infiniband/hw/hns/hns_roce_eq.c | 1 -
>>>> drivers/infiniband/hw/hns/hns_roce_icm.c | 88 +++++++++++++
>>>> drivers/infiniband/hw/hns/hns_roce_icm.h | 9 ++
>>>> drivers/infiniband/hw/hns/hns_roce_main.c | 79 ++++++++++++
>>>> drivers/infiniband/hw/hns/hns_roce_mr.c | 187 ++++++++++++++++++++++++++++
>>>> drivers/infiniband/hw/hns/hns_roce_pd.c | 65 ++++++++++
>>>> drivers/infiniband/hw/hns/hns_roce_qp.c | 30 +++++
>>>> 10 files changed, 656 insertions(+), 1 deletion(-)
>>>> create mode 100644 drivers/infiniband/hw/hns/hns_roce_alloc.c
>>>> create mode 100644 drivers/infiniband/hw/hns/hns_roce_mr.c
>>>> create mode 100644 drivers/infiniband/hw/hns/hns_roce_pd.c
>>>>
>>>> diff --git a/drivers/infiniband/hw/hns/hns_roce_alloc.c b/drivers/infiniband/hw/hns/hns_roce_alloc.c
>>>> new file mode 100644
>>>> index 0000000..0c76f1b
>>>> --- /dev/null
>>>> +++ b/drivers/infiniband/hw/hns/hns_roce_alloc.c
>>>> @@ -0,0 +1,104 @@
>>>> +/*
>>>> + * Copyright (c) 2016 Hisilicon Limited.
>>>> + *
>>>> + * This program is free software; you can redistribute it and/or modify
>>>> + * it under the terms of the GNU General Public License as published by
>>>> + * the Free Software Foundation; either version 2 of the License, or
>>>> + * (at your option) any later version.
>>>> + */
>>>> +
>>>> +#include <linux/bitmap.h>
>>>> +#include <linux/dma-mapping.h>
>>>> +#include <linux/errno.h>
>>>> +#include <linux/mm.h>
>>>> +#include <linux/slab.h>
>>>> +#include <linux/vmalloc.h>
>>>> +#include "hns_roce_device.h"
>>>> +
>>>> +int hns_roce_bitmap_alloc(struct hns_roce_bitmap *bitmap, u32 *obj)
>>>> +{
>>>> + int ret = 0;
>>>> +
>>>> + spin_lock(&bitmap->lock);
>>>> + *obj = find_next_zero_bit(bitmap->table, bitmap->max, bitmap->last);
>>>> + if (*obj >= bitmap->max) {
>>>> + bitmap->top = (bitmap->top + bitmap->max + bitmap->reserved_top)
>>>> + & bitmap->mask;
>>>> + *obj = find_first_zero_bit(bitmap->table, bitmap->max);
>>>
>>> find_first_zero_bit function returns "unsigned long" which may or may
>>> not be equal to u32 on some architectures.
>>>
>> Hi Leon,
>> I appreciate your keen eye. this code is meant for ARM64bit therefore should run corretly for 64-bit AARCH64.
>> I will consider changing it as part of good partice and better portability "
>> I will give a primary plan to modified it.
>> for example:
>> *obj = (u32)find_next_zero_bit(bitmap->table, bitmap->max, bitmap->last);
>> Beause the max size of bitmap->table is u32 in current version.
>>
>> int hns_roce_bitmap_init(struct hns_roce_bitmap *bitmap, u32 num, u32 mask,
>> u32 reserved_bot, u32 reserved_top)
>> {
>> u32 i;
>>
>> if (num != roundup_pow_of_two(num))
>> return -EINVAL;
>>
>> bitmap->last = 0;
>> bitmap->top = 0;
>> bitmap->max = num - reserved_top;
>> bitmap->mask = mask;
>> bitmap->reserved_top = reserved_top;
>> spin_lock_init(&bitmap->lock);
>> bitmap->table = kcalloc(BITS_TO_LONGS(bitmap->max), sizeof(long),
>> GFP_KERNEL);
>>
>> Is this plan ok?
>
> No,
> You are submitting new driver, please do it properly (without casting)
> from the beginning.
>
oh, i see. I will give a better plan to modify it.
Thanks
Lijun Ou
>>
>> Thanks
>> Lijun Ou
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
>> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v5 09/21] IB/hns: Add hca support
From: oulijun @ 2016-04-27 3:34 UTC (permalink / raw)
To: Jiri Pirko, Leon Romanovsky
Cc: dledford-H+wXaHxf7aLQT0dZR+AlfA,
sean.hefty-ral2JQCrhuEAvxtiuMwx3w,
hal.rosenstock-Re5JQEeQqe8AvxtiuMwx3w,
davem-fT/PcQaiUtIeIZ0/mPfg9Q,
jeffrey.t.kirsher-ral2JQCrhuEAvxtiuMwx3w,
jiri-VPRAkNaXOzVWk0Htik3J/w, ogerlitz-VPRAkNaXOzVWk0Htik3J/w,
linuxarm-hv44wF8Li93QT0dZR+AlfA,
linux-rdma-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA,
gongyangming-hv44wF8Li93QT0dZR+AlfA,
xiaokun-hv44wF8Li93QT0dZR+AlfA,
tangchaofei-hv44wF8Li93QT0dZR+AlfA,
haifeng.wei-hv44wF8Li93QT0dZR+AlfA,
yisen.zhuang-hv44wF8Li93QT0dZR+AlfA,
yankejian-hv44wF8Li93QT0dZR+AlfA,
lisheng011-hv44wF8Li93QT0dZR+AlfA,
charles.chenxin-hv44wF8Li93QT0dZR+AlfA
In-Reply-To: <20160426142517.GA1937-6KJVSR23iU488b5SBfVpbw@public.gmane.org>
On 2016/4/26 22:25, Jiri Pirko wrote:
> Tue, Apr 26, 2016 at 04:18:21PM CEST, leon-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org wrote:
>> On Tue, Apr 26, 2016 at 02:34:44PM +0800, oulijun wrote:
>>> On 2016/4/24 15:54, Leon Romanovsky wrote:
>
> <snip>
>
>>>>> +int hns_roce_bitmap_alloc(struct hns_roce_bitmap *bitmap, u32 *obj)
>>>>> +{
>>>>> + int ret = 0;
>>>>> +
>>>>> + spin_lock(&bitmap->lock);
>>>>> + *obj = find_next_zero_bit(bitmap->table, bitmap->max, bitmap->last);
>>>>> + if (*obj >= bitmap->max) {
>>>>> + bitmap->top = (bitmap->top + bitmap->max + bitmap->reserved_top)
>>>>> + & bitmap->mask;
>>>>> + *obj = find_first_zero_bit(bitmap->table, bitmap->max);
>>>>
>>>> find_first_zero_bit function returns "unsigned long" which may or may
>>>> not be equal to u32 on some architectures.
>>>>
>>> Hi Leon,
>>> I appreciate your keen eye. this code is meant for ARM64bit therefore should run corretly for 64-bit AARCH64.
>
> The driver should run correctly on any arch.
>
Hi Jiri Pirko,
Our driver run in ARM64 platform by depending on Kconfig. It will be configure in Kconfig file.
Thanks
Lijun Ou
>
>>> I will consider changing it as part of good partice and better portability "
>>> I will give a primary plan to modified it.
>>> for example:
>>> *obj = (u32)find_next_zero_bit(bitmap->table, bitmap->max, bitmap->last);
>>> Beause the max size of bitmap->table is u32 in current version.
>>>
>>> int hns_roce_bitmap_init(struct hns_roce_bitmap *bitmap, u32 num, u32 mask,
>>> u32 reserved_bot, u32 reserved_top)
>>> {
>>> u32 i;
>>>
>>> if (num != roundup_pow_of_two(num))
>>> return -EINVAL;
>>>
>>> bitmap->last = 0;
>>> bitmap->top = 0;
>>> bitmap->max = num - reserved_top;
>>> bitmap->mask = mask;
>>> bitmap->reserved_top = reserved_top;
>>> spin_lock_init(&bitmap->lock);
>>> bitmap->table = kcalloc(BITS_TO_LONGS(bitmap->max), sizeof(long),
>>> GFP_KERNEL);
>>>
>>> Is this plan ok?
>>
>> No,
>> You are submitting new driver, please do it properly (without casting)
>>from the beginning.
>>
>>>
>>> Thanks
>>> Lijun Ou
>>>
>>> --
>>> To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
>>> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
>>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
>
>
> .
>
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v2 net-next 11/13] Documentation: Bindings: Update DT binding for separating dsaf dev support
From: Yisen Zhuang @ 2016-04-27 3:33 UTC (permalink / raw)
To: Rob Herring, davem
Cc: mark.rutland, devicetree, salil.mehta, catalin.marinas,
xieqianqian, pawel.moll, ijc+devicetree, netdev, lipeng321,
will.deacon, linuxarm, xuwei5, huangdaode, galak, yankejian,
linux-arm-kernel, liguozhu
In-Reply-To: <20160426124847.GA26682@rob-hp-laptop>
Hi Rob and David,
Please see my comments inline.
David have merged this series to net-next, but we need to modify some codes according
to Rob's comments. I am not sure if i need to send V3 for this series, or separate
patches of documentation to independent series and generate a new patch for hns base
on current net-next?
Thanks,
Yisen
在 2016/4/26 20:48, Rob Herring 写道:
> On Sat, Apr 23, 2016 at 05:05:15PM +0800, Yisen Zhuang wrote:
>> Because debug dsaf port was separated from service dsaf port, this patch
>> updates the related information of DT binding.
>
> Separated when? New version of the h/w? If so, where's the new
> compatible string? This is quite a big binding change.
There isn't any change of h/w. I separated debug dsaf port from sevice dsaf
port to make the code more simple and readability.
>
>> Signed-off-by: Yisen Zhuang <yisen.zhuang@huawei.com>
>>
>> ---
>> .../devicetree/bindings/net/hisilicon-hns-dsaf.txt | 59 ++++++++++++++++++----
>> 1 file changed, 49 insertions(+), 10 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/net/hisilicon-hns-dsaf.txt b/Documentation/devicetree/bindings/net/hisilicon-hns-dsaf.txt
>> index ecacfa4..5ccd4f0 100644
>> --- a/Documentation/devicetree/bindings/net/hisilicon-hns-dsaf.txt
>> +++ b/Documentation/devicetree/bindings/net/hisilicon-hns-dsaf.txt
>> @@ -7,19 +7,47 @@ Required properties:
>> - mode: dsa fabric mode string. only support one of dsaf modes like these:
>> "2port-64vf",
>> "6port-16rss",
>> - "6port-16vf".
>> + "6port-16vf",
>> + "single-port".
>> - interrupt-parent: the interrupt parent of this device.
>> - interrupts: should contain the DSA Fabric and rcb interrupt.
>> - reg: specifies base physical address(es) and size of the device registers.
>> - The first region is external interface control register base and size.
>> - The second region is SerDes base register and size.
>> + The first region is external interface control register base and size(optional,
>> + only be used when subctrl-syscon is not exists). It is recommended using
>
> only used when subctrl-syscon does not exist
Agree, thanks.
>
>> + subctrl-syscon rather than this address.
>> + The second region is SerDes base register and size(optional, only be used when
>> + serdes-syscon in port node is not exists. It is recommended using
>
> similar rewording needed here.
Agree, thanks.
>
>> + serdes-syscon rather than this address.
>> The third region is the PPE register base and size.
>> - The fourth region is dsa fabric base register and size.
>> - The fifth region is cpld base register and size, it is not required if do not use cpld.
>> -- phy-handle: phy handle of physicl port, 0 if not any phy device. see ethernet.txt [1].
>> + The fourth region is dsa fabric base register and size. It is not required for
>> + single-port mode.
>> +- reg-names: may be ppe-base and(or) dsaf-base. It is used to find the
>> + corresponding reg's index.
>
> But you have up to 5 regions.
>
> The variable nature of what regions you have tells me you need more
> specific compatible strings for each chip.
we didn't add support of new h/w. We added these regions to make code simple and readability.
If we need to add support of next h/w version next time, we don't need to add many branches
for these attributes. So we didn't add a new compatible here.
>
>> +
>> +- phy-handle: phy handle of physicl port, 0 if not any phy device. It is optional
>
> s/physicl/physical/
Agree, thanks.
>
>> + attribute. If port node is exists, phy-handle in each port node will be used.
>> + see ethernet.txt [1].
>> +- subctrl-syscon: is syscon handle for external interface control register.
>> +- reset-field-offset: is offset of reset field. Its value depends on the hardware
>> + user manual.
>> - buf-size: rx buffer size, should be 16-1024.
>> - desc-num: number of description in TX and RX queue, should be 512, 1024, 2048 or 4096.
>>
>> +- port: subnodes of dsaf. A dsaf node may contain several port nodes(Depending
>> + on mode of dsaf). Port node contain some attributes listed below:
>> +- port-id: is physical port index in one dsaf.
>
> Indexes should generally be avoided. What does the number correspond
> to in h/w (if anything)?
port-id is index for a port in dsaf, it is correspond to index of PHY showed below.
CPU
|
-----------------------------------
| | |
---------------------------------------------- --------- ---------
| | | | | | | |
| PPE | | PPE | | PPE |
| | | | | | | | |
| | | | | | | | |
| crossbar | | | | | | |
| | | | | | | | |
| ---------------------------------- | | | | | | |
| | | | | | | | | | | | | |
| | | | | | | | | | | | | |
| MAC MAC MAC MAC MAC MAC | | MAC | | MAC |
| | | | | | | | | | | | | |
---------------------------------------------- --------- ---------
| | | | | | \ / | / |
PHY PHY PHY PHY PHY PHY \ / PHY / PHY
\ / /
\ / /
DSAF(three platform device)
>
>> +- phy-handle: phy handle of physicl port. It is not required if there isn't
>> + phy device. see ethernet.txt [1].
>> +- serdes-syscon: is syscon handle for SerDes register.
>> +- cpld-syscon: is syscon handle for cpld register. It is not required if there
>> + isn't cpld device.
>> +- cpld-ctrl-reg: is cpld register offset. It is not required if there isn't
>> + cpld-syscon.
>
> This would usually be a cell in the cpld-syscon property.
Agree, thanks.
>
>> +- port-rst-offset: is offset of reset field for each port in dsaf. Its value
>> + depends on the hardware user manual.
>> +- port-mode-offset: is offset of port mode field for each port in dsaf. Its
>> + value depends on the hardware user manual.
>
> Again, sounds like you need more specific compatible strings that imply
> this information.
>
>> +
>> [1] Documentation/devicetree/bindings/net/phy.txt
>>
>> Example:
>> @@ -28,11 +56,11 @@ dsaf0: dsa@c7000000 {
>> compatible = "hisilicon,hns-dsaf-v1";
>> mode = "6port-16rss";
>> interrupt-parent = <&mbigen_dsa>;
>> - reg = <0x0 0xC0000000 0x0 0x420000
>> - 0x0 0xC2000000 0x0 0x300000
>> - 0x0 0xc5000000 0x0 0x890000
>> + reg = <0x0 0xc5000000 0x0 0x890000
>> 0x0 0xc7000000 0x0 0x60000>;
>> - phy-handle = <0 0 0 0 &soc0_phy4 &soc0_phy5 0 0>;
>> + reg-names = "ppe-base", "dsaf-base";
>> + subctrl-syscon = <&subctrl>;
>> + reset-field-offset = 0;
>> interrupts = <131 4>,<132 4>, <133 4>,<134 4>,
>> <135 4>,<136 4>, <137 4>,<138 4>,
>> <139 4>,<140 4>, <141 4>,<142 4>,
>> @@ -43,4 +71,15 @@ dsaf0: dsa@c7000000 {
>> buf-size = <4096>;
>> desc-num = <1024>;
>> dma-coherent;
>> +
>> + prot@0 {
>
> port?
Agree, i am sorry for my carelessness and will pay more attention to it next time.
thank you very much.
>
>> + port-id = 0;
>> + phy-handle = <&phy0>;
>> + serdes-syscon = <&serdes>;
>> + };
>> +
>> + prot@1 {
>> + port-id = 1;
>> + serdes-syscon = <&serdes>;
>> + };
>> };
>> --
>> 1.9.1
>>
>
> .
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* RE: [PATCH v8 net-next 1/1] hv_sock: introduce Hyper-V Sockets
From: Dexuan Cui @ 2016-04-27 3:02 UTC (permalink / raw)
To: Cathy Avery, gregkh@linuxfoundation.org, davem@davemloft.net,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
devel@linuxdriverproject.org, olaf@aepfle.de, Jason Wang,
KY Srinivasan, Haiyang Zhang, vkuznets@redhat.com,
joe@perches.com
In-Reply-To: <571F94F9.6020204@redhat.com>
> From: Cathy Avery [mailto:cavery@redhat.com]
> Sent: Wednesday, April 27, 2016 0:19
> To: Dexuan Cui <decui@microsoft.com>; gregkh@linuxfoundation.org;
> davem@davemloft.net; netdev@vger.kernel.org; linux-kernel@vger.kernel.org;
> devel@linuxdriverproject.org; olaf@aepfle.de; Jason Wang
> <jasowang@redhat.com>; KY Srinivasan <kys@microsoft.com>; Haiyang Zhang
> <haiyangz@microsoft.com>; vkuznets@redhat.com; joe@perches.com
> Subject: Re: [PATCH v8 net-next 1/1] hv_sock: introduce Hyper-V Sockets
>
> Hi,
>
> I will be working with Dexuan to possibly port this functionality into RHEL.
>
> Here are my initial comments. Mostly stylistic. They are prefaced by CAA.
>
> Cathy Avery
Thank you very much, Cathy!
I'll take your pretty good suggestions and post a new version.
Thanks,
-- Dexuan
^ permalink raw reply
* Re: [PATCH] net: phy: at803x: only the AT8030 needs a hardware reset on link change
From: Florian Fainelli @ 2016-04-27 2:46 UTC (permalink / raw)
To: Timur Tabi, netdev, davem, marek.belisko, ujhelyi.m, zonque
In-Reply-To: <1461692658-1742-1-git-send-email-timur@codeaurora.org>
Le 26/04/2016 10:44, Timur Tabi a écrit :
> Commit 13a56b44 ("at803x: Add support for hardware reset") added a
> work-around for a hardware bug on the AT8030. However, the work-around
> was being called for all 803x PHYs, even those that don't need it.
> Function at803x_link_change_notify() checks to make sure that it only
> resets the PHY on the 8030, but it makes more sense to not call that
> function at all if it isn't needed.
>
> Signed-off-by: Timur Tabi <timur@codeaurora.org>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
This looks nicer indeed!
--
Florian
^ permalink raw reply
* linux-next: manual merge of the net-next tree with the net tree
From: Stephen Rothwell @ 2016-04-27 2:01 UTC (permalink / raw)
To: David Miller, netdev
Cc: linux-next, linux-kernel, Nicolas Dichtel, Sabrina Dubroca
Hi all,
Today's linux-next merge of the net-next tree got a conflict in:
drivers/net/macsec.c
between commit:
748164802c1b ("macsec: add missing macsec prefix in uapi")
from the net tree and commit:
f60d94c00968 ("macsec: use nla_put_u64_64bit()")
from the net-next tree.
I fixed it up (see below) and can carry the fix as necessary. This
is now fixed as far as linux-next is concerned, but any non trivial
conflicts should be mentioned to your upstream maintainer when your tree
is submitted for merging. You may also want to consider cooperating
with the maintainer of the conflicting tree to minimise any particularly
complex conflicts.
--
Cheers,
Stephen Rothwell
diff --cc drivers/net/macsec.c
index c6385617bfb2,a172a1ffa151..000000000000
--- a/drivers/net/macsec.c
+++ b/drivers/net/macsec.c
@@@ -2231,9 -2271,11 +2276,11 @@@ static int nla_put_secy(struct macsec_s
if (!secy_nest)
return 1;
- if (nla_put_sci(skb, MACSEC_SECY_ATTR_SCI, secy->sci) ||
- nla_put_u64(skb, MACSEC_SECY_ATTR_CIPHER_SUITE,
- MACSEC_DEFAULT_CIPHER_ID) ||
+ if (nla_put_sci(skb, MACSEC_SECY_ATTR_SCI, secy->sci,
+ MACSEC_SECY_ATTR_PAD) ||
+ nla_put_u64_64bit(skb, MACSEC_SECY_ATTR_CIPHER_SUITE,
- DEFAULT_CIPHER_ID,
++ MACSEC_DEFAULT_CIPHER_ID,
+ MACSEC_SECY_ATTR_PAD) ||
nla_put_u8(skb, MACSEC_SECY_ATTR_ICV_LEN, secy->icv_len) ||
nla_put_u8(skb, MACSEC_SECY_ATTR_OPER, secy->operational) ||
nla_put_u8(skb, MACSEC_SECY_ATTR_PROTECT, secy->protect_frames) ||
@@@ -3184,10 -3219,11 +3236,11 @@@ static int macsec_fill_info(struct sk_b
struct macsec_secy *secy = &macsec_priv(dev)->secy;
struct macsec_tx_sc *tx_sc = &secy->tx_sc;
- if (nla_put_sci(skb, IFLA_MACSEC_SCI, secy->sci) ||
+ if (nla_put_sci(skb, IFLA_MACSEC_SCI, secy->sci,
+ IFLA_MACSEC_PAD) ||
nla_put_u8(skb, IFLA_MACSEC_ICV_LEN, secy->icv_len) ||
- nla_put_u64(skb, IFLA_MACSEC_CIPHER_SUITE,
- MACSEC_DEFAULT_CIPHER_ID) ||
+ nla_put_u64_64bit(skb, IFLA_MACSEC_CIPHER_SUITE,
- DEFAULT_CIPHER_ID, IFLA_MACSEC_PAD) ||
++ MACSEC_DEFAULT_CIPHER_ID, IFLA_MACSEC_PAD) ||
nla_put_u8(skb, IFLA_MACSEC_ENCODING_SA, tx_sc->encoding_sa) ||
nla_put_u8(skb, IFLA_MACSEC_ENCRYPT, tx_sc->encrypt) ||
nla_put_u8(skb, IFLA_MACSEC_PROTECT, secy->protect_frames) ||
^ permalink raw reply
* linux-next: manual merge of the net-next tree with the net tree
From: Stephen Rothwell @ 2016-04-27 2:01 UTC (permalink / raw)
To: David Miller, netdev
Cc: linux-next, linux-kernel, Saeed Mahameed, Gal Pressman
Hi all,
Today's linux-next merge of the net-next tree got a conflict in:
drivers/net/ethernet/mellanox/mlx5/core/en_main.c
between commit:
d8edd2469ace ("et/mlx5e: Fix minimum MTU")
from the net tree and commit:
0e405443e803 ("net/mlx5e: Improve set features ndo resiliency")
from the net-next tree.
I fixed it up (see below) and can carry the fix as necessary. This
is now fixed as far as linux-next is concerned, but any non trivial
conflicts should be mentioned to your upstream maintainer when your tree
is submitted for merging. You may also want to consider cooperating
with the maintainer of the conflicting tree to minimise any particularly
complex conflicts.
--
Cheers,
Stephen Rothwell
diff --cc drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index 67d548b70e14,5bad17d37d7b..000000000000
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@@ -2025,9 -2214,49 +2240,52 @@@ static int set_feature_rx_vlan(struct n
return err;
}
+ static int mlx5e_handle_feature(struct net_device *netdev,
+ netdev_features_t wanted_features,
+ netdev_features_t feature,
+ mlx5e_feature_handler feature_handler)
+ {
+ netdev_features_t changes = wanted_features ^ netdev->features;
+ bool enable = !!(wanted_features & feature);
+ int err;
+
+ if (!(changes & feature))
+ return 0;
+
+ err = feature_handler(netdev, enable);
+ if (err) {
+ netdev_err(netdev, "%s feature 0x%llx failed err %d\n",
+ enable ? "Enable" : "Disable", feature, err);
+ return err;
+ }
+
+ MLX5E_SET_FEATURE(netdev, feature, enable);
+ return 0;
+ }
+
+ static int mlx5e_set_features(struct net_device *netdev,
+ netdev_features_t features)
+ {
+ int err;
+
+ err = mlx5e_handle_feature(netdev, features, NETIF_F_LRO,
+ set_feature_lro);
+ err |= mlx5e_handle_feature(netdev, features,
+ NETIF_F_HW_VLAN_CTAG_FILTER,
+ set_feature_vlan_filter);
+ err |= mlx5e_handle_feature(netdev, features, NETIF_F_HW_TC,
+ set_feature_tc_num_filters);
+ err |= mlx5e_handle_feature(netdev, features, NETIF_F_RXALL,
+ set_feature_rx_all);
+ err |= mlx5e_handle_feature(netdev, features, NETIF_F_HW_VLAN_CTAG_RX,
+ set_feature_rx_vlan);
+
+ return err ? -EINVAL : 0;
+ }
+
+#define MXL5_HW_MIN_MTU 64
+#define MXL5E_MIN_MTU (MXL5_HW_MIN_MTU + ETH_FCS_LEN)
+
static int mlx5e_change_mtu(struct net_device *netdev, int new_mtu)
{
struct mlx5e_priv *priv = netdev_priv(netdev);
@@@ -2633,18 -2966,10 +2997,19 @@@ static void mlx5e_destroy_netdev(struc
schedule_work(&priv->set_rx_mode_work);
mlx5e_disable_async_events(priv);
flush_scheduled_work();
- unregister_netdev(netdev);
+ if (test_bit(MLX5_INTERFACE_STATE_SHUTDOWN, &mdev->intf_state)) {
+ netif_device_detach(netdev);
+ mutex_lock(&priv->state_lock);
+ if (test_bit(MLX5E_STATE_OPENED, &priv->state))
+ mlx5e_close_locked(netdev);
+ mutex_unlock(&priv->state_lock);
+ } else {
+ unregister_netdev(netdev);
+ }
+
mlx5e_tc_cleanup(priv);
mlx5e_vxlan_cleanup(priv);
+ mlx5e_destroy_q_counter(priv);
mlx5e_destroy_flow_tables(priv);
mlx5e_destroy_tirs(priv);
mlx5e_destroy_rqt(priv, MLX5E_SINGLE_RQ_RQT);
^ permalink raw reply
* Re: [PATCH net-next 9/9] taskstats: use the libnl API to align nlattr on 64-bit
From: Balbir Singh @ 2016-04-27 1:14 UTC (permalink / raw)
To: Nicolas Dichtel, netdev-u79uwXL29TY76Z2rM5mHXA
Cc: dev-yBygre7rU0TnMu66kgdUjQ,
steffen.klassert-opNxpl+3fjRBDgjK7y7TUQ,
herbert-lOAM2aK0SrRLBo1qDEOMRrpzq4S04n8Q,
aar-bIcnvbaLZ9MEGnE8C9+IrQ, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
davem-fT/PcQaiUtIeIZ0/mPfg9Q, yoshfuji-VfPWfsRibaP+Ru+s062T9g,
netfilter-devel-u79uwXL29TY76Z2rM5mHXA,
kadlec-K40Dz/62t/MgiyqX0sVFJYdd74u8MsAO,
kuznet-v/Mj1YrvjDBInbfyfbPRSQ, jmorris-gx6/JNMH7DfYtjvyW6yDsg,
linux-wpan-u79uwXL29TY76Z2rM5mHXA, kaber-dcUjhNyLwpNeoWH0uzbU5w,
pablo-Cap9r6Oaw4JrovVCs/uTlw
In-Reply-To: <1461339084-3849-10-git-send-email-nicolas.dichtel-pdR9zngts4EAvxtiuMwx3w@public.gmane.org>
On 23/04/16 01:31, Nicolas Dichtel wrote:
> Goal of this patch is to use the new libnl API to align netlink attribute
> when needed.
> The layout of the netlink message will be a bit different after the patch,
> because the padattr (TASKSTATS_TYPE_STATS) will be inside the nested
> attribute instead of before it.
>
> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
The layout will change/break user space -- I've not tested the patch though..
Balbir Singh.
_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev
^ permalink raw reply
* [PATCH 3.2 085/115] veth: don’t modify ip_summed; doing so treats packets with bad checksums as good.
From: Ben Hutchings @ 2016-04-26 23:02 UTC (permalink / raw)
To: linux-kernel, stable
Cc: akpm, David S. Miller, Vijay Pandurangan, Cong Wang, netdev,
Evan Jones, Nicolas Dichtel, Phil Sutter, Toshiaki Makita
In-Reply-To: <lsq.1461711744.351546278@decadent.org.uk>
3.2.80-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Vijay Pandurangan <vijayp@vijayp.ca>
[ Upstream commit ce8c839b74e3017996fad4e1b7ba2e2625ede82f ]
Packets that arrive from real hardware devices have ip_summed ==
CHECKSUM_UNNECESSARY if the hardware verified the checksums, or
CHECKSUM_NONE if the packet is bad or it was unable to verify it. The
current version of veth will replace CHECKSUM_NONE with
CHECKSUM_UNNECESSARY, which causes corrupt packets routed from hardware to
a veth device to be delivered to the application. This caused applications
at Twitter to receive corrupt data when network hardware was corrupting
packets.
We believe this was added as an optimization to skip computing and
verifying checksums for communication between containers. However, locally
generated packets have ip_summed == CHECKSUM_PARTIAL, so the code as
written does nothing for them. As far as we can tell, after removing this
code, these packets are transmitted from one stack to another unmodified
(tcpdump shows invalid checksums on both sides, as expected), and they are
delivered correctly to applications. We didn’t test every possible network
configuration, but we tried a few common ones such as bridging containers,
using NAT between the host and a container, and routing from hardware
devices to containers. We have effectively deployed this in production at
Twitter (by disabling RX checksum offloading on veth devices).
This code dates back to the first version of the driver, commit
<e314dbdc1c0dc6a548ecf> ("[NET]: Virtual ethernet device driver"), so I
suspect this bug occurred mostly because the driver API has evolved
significantly since then. Commit <0b7967503dc97864f283a> ("net/veth: Fix
packet checksumming") (in December 2010) fixed this for packets that get
created locally and sent to hardware devices, by not changing
CHECKSUM_PARTIAL. However, the same issue still occurs for packets coming
in from hardware devices.
Co-authored-by: Evan Jones <ej@evanjones.ca>
Signed-off-by: Evan Jones <ej@evanjones.ca>
Cc: Nicolas Dichtel <nicolas.dichtel@6wind.com>
Cc: Phil Sutter <phil@nwl.cc>
Cc: Toshiaki Makita <makita.toshiaki@lab.ntt.co.jp>
Cc: netdev@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Vijay Pandurangan <vijayp@vijayp.ca>
Acked-by: Cong Wang <cwang@twopensource.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
drivers/net/veth.c | 6 ------
1 file changed, 6 deletions(-)
--- a/drivers/net/veth.c
+++ b/drivers/net/veth.c
@@ -126,11 +126,6 @@ static netdev_tx_t veth_xmit(struct sk_b
stats = this_cpu_ptr(priv->stats);
rcv_stats = this_cpu_ptr(rcv_priv->stats);
- /* don't change ip_summed == CHECKSUM_PARTIAL, as that
- will cause bad checksum on forwarded packets */
- if (skb->ip_summed == CHECKSUM_NONE &&
- rcv->features & NETIF_F_RXCSUM)
- skb->ip_summed = CHECKSUM_UNNECESSARY;
length = skb->len;
if (dev_forward_skb(rcv, skb) != NET_RX_SUCCESS)
^ permalink raw reply
* Re: [PATCH net-next] net-rfs: fix false sharing accessing sd->input_queue_head
From: Tom Herbert @ 2016-04-26 22:55 UTC (permalink / raw)
To: Eric Dumazet; +Cc: David Miller, netdev
In-Reply-To: <1461709807.5535.55.camel@edumazet-glaptop3.roam.corp.google.com>
On Tue, Apr 26, 2016 at 3:30 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> From: Eric Dumazet <edumazet@google.com>
>
> sd->input_queue_head is incremented for each processed packet
> in process_backlog(), and read from other cpus performing
> Out Of Order avoidance in get_rps_cpu()
>
> Moving this field in a separate cache line keeps it mostly
> hot for the cpu in process_backlog(), as other cpus will
> only read it.
>
> In a stress test, process_backlog() was consuming 6.80 % of cpu cycles,
> and the patch reduced the cost to 0.65 %
>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
Very nice!
Acked-by: Tom Herbert <tom@herbertland.com>
> ---
> include/linux/netdevice.h | 8 ++++++--
> 1 file changed, 6 insertions(+), 2 deletions(-)
>
> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
> index 18d8394f2e5d..934ca866562d 100644
> --- a/include/linux/netdevice.h
> +++ b/include/linux/netdevice.h
> @@ -2747,11 +2747,15 @@ struct softnet_data {
> struct sk_buff *completion_queue;
>
> #ifdef CONFIG_RPS
> - /* Elements below can be accessed between CPUs for RPS */
> + /* input_queue_head should be written by cpu owning this struct,
> + * and only read by other cpus. Worth using a cache line.
> + */
> + unsigned int input_queue_head ____cacheline_aligned_in_smp;
> +
> + /* Elements below can be accessed between CPUs for RPS/RFS */
> struct call_single_data csd ____cacheline_aligned_in_smp;
> struct softnet_data *rps_ipi_next;
> unsigned int cpu;
> - unsigned int input_queue_head;
> unsigned int input_queue_tail;
> #endif
> unsigned int dropped;
>
>
^ permalink raw reply
* [PATCH net-next 1/1] pch_gbe: replace private tx ring lock with common netif_tx_lock
From: Francois Romieu @ 2016-04-26 22:49 UTC (permalink / raw)
To: netdev; +Cc: davem
pch_gbe_tx_ring.tx_lock is only used in the hard_xmit handler and
in the transmit completion reaper called from NAPI context.
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
---
CONFIG_COMPILE_TESTed
drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe.h | 2 --
drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c | 10 ++--------
2 files changed, 2 insertions(+), 10 deletions(-)
diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe.h b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe.h
index 2a55d6d..8d710a3 100644
--- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe.h
+++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe.h
@@ -481,7 +481,6 @@ struct pch_gbe_buffer {
/**
* struct pch_gbe_tx_ring - tx ring information
- * @tx_lock: spinlock structs
* @desc: pointer to the descriptor ring memory
* @dma: physical address of the descriptor ring
* @size: length of descriptor ring in bytes
@@ -491,7 +490,6 @@ struct pch_gbe_buffer {
* @buffer_info: array of buffer information structs
*/
struct pch_gbe_tx_ring {
- spinlock_t tx_lock;
struct pch_gbe_tx_desc *desc;
dma_addr_t dma;
unsigned int size;
diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
index ca4add7..5c8e2f1 100644
--- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
+++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
@@ -1640,7 +1640,7 @@ pch_gbe_clean_tx(struct pch_gbe_adapter *adapter,
cleaned_count);
if (cleaned_count > 0) { /*skip this if nothing cleaned*/
/* Recover from running out of Tx resources in xmit_frame */
- spin_lock(&tx_ring->tx_lock);
+ netif_tx_lock(adapter->netdev);
if (unlikely(cleaned && (netif_queue_stopped(adapter->netdev))))
{
netif_wake_queue(adapter->netdev);
@@ -1652,7 +1652,7 @@ pch_gbe_clean_tx(struct pch_gbe_adapter *adapter,
netdev_dbg(adapter->netdev, "next_to_clean : %d\n",
tx_ring->next_to_clean);
- spin_unlock(&tx_ring->tx_lock);
+ netif_tx_lock(adapter->netdev);
}
return cleaned;
}
@@ -1805,7 +1805,6 @@ int pch_gbe_setup_tx_resources(struct pch_gbe_adapter *adapter,
tx_ring->next_to_use = 0;
tx_ring->next_to_clean = 0;
- spin_lock_init(&tx_ring->tx_lock);
for (desNo = 0; desNo < tx_ring->count; desNo++) {
tx_desc = PCH_GBE_TX_DESC(*tx_ring, desNo);
@@ -2135,13 +2134,9 @@ static int pch_gbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
{
struct pch_gbe_adapter *adapter = netdev_priv(netdev);
struct pch_gbe_tx_ring *tx_ring = adapter->tx_ring;
- unsigned long flags;
-
- spin_lock_irqsave(&tx_ring->tx_lock, flags);
if (unlikely(!PCH_GBE_DESC_UNUSED(tx_ring))) {
netif_stop_queue(netdev);
- spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
netdev_dbg(netdev,
"Return : BUSY next_to use : 0x%08x next_to clean : 0x%08x\n",
tx_ring->next_to_use, tx_ring->next_to_clean);
@@ -2150,7 +2145,6 @@ static int pch_gbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
/* CRC,ITAG no support */
pch_gbe_tx_queue(adapter, tx_ring, skb);
- spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
return NETDEV_TX_OK;
}
--
2.5.5
^ permalink raw reply related
* Re: [PATCH V3] net: stmmac: socfpga: Remove re-registration of reset controller
From: Marek Vasut @ 2016-04-26 22:33 UTC (permalink / raw)
To: Joachim Eastwood
Cc: netdev, peppe.cavallaro, alexandre.torgue, Matthew Gerlach,
Dinh Nguyen, David S . Miller
In-Reply-To: <CAGhQ9Vz2FSENtif66SfXsgZqaJaaKeiBsw4qCSevM_4XDnUPCg@mail.gmail.com>
On 04/26/2016 11:22 PM, Joachim Eastwood wrote:
> On 26 April 2016 at 14:47, Marek Vasut <marex@denx.de> wrote:
>> On 04/26/2016 02:26 PM, Joachim Eastwood wrote:
>>> On 26 April 2016 at 00:55, Marek Vasut <marex@denx.de> wrote:
>>>> On 04/25/2016 08:11 PM, Joachim Eastwood wrote:
>>>>> On 21 April 2016 at 14:11, Marek Vasut <marex@denx.de> wrote:
>>>>>>
>>>>>> Finally, plat_dat->exit and socfpga_dwmac_exit() is no longer necessary,
>>>>>> since the functionality is already performed by the stmmac core.
>>>>>
>>>>> I am trying to rebase my changes on top of your two patches and
>>>>> noticed a couple of things.
>>>>>
>>>>>> static int socfpga_dwmac_init(struct platform_device *pdev, void *priv)
>>>>>> {
>>>>>> - struct socfpga_dwmac *dwmac = priv;
>>>>>> + struct socfpga_dwmac *dwmac = priv;
>>>>>> struct net_device *ndev = platform_get_drvdata(pdev);
>>>>>> struct stmmac_priv *stpriv = NULL;
>>>>>> int ret = 0;
>>>>>>
>>>>>> - if (ndev)
>>>>>> - stpriv = netdev_priv(ndev);
>>>>>> + if (!ndev)
>>>>>> + return -EINVAL;
>>>>>
>>>>> ndev can never be NULL here. socfpga_dwmac_init() is only called if
>>>>> stmmac_dvr_probe() succeeds or we are running the resume callback. So
>>>>> I don't see how this could ever be NULL.
>>>>
>>>> That's a good point, this check can indeed be removed. While you're at
>>>> the patching, can you remove this one ?
>>>
>>> Yes, my patch will refactor the init() function so this will go away.
>>
>> Thanks!
>>
>>>>>> +
>>>>>> + stpriv = netdev_priv(ndev);
>>>>>
>>>>> It's not really nice to access 'stmmac_priv' as it should be private
>>>>> to the core driver, but I don't see any other good solution right now.
>>>>
>>>> I guess some stmmac_reset_assert() wrapper would be nicer, yes. What do
>>>> you think ?
>>>>
>>>>>> + if (!stpriv)
>>>>>> + return -EINVAL;
>>>>>>
>>>>>> /* Assert reset to the enet controller before changing the phy mode */
>>>>>> - if (dwmac->stmmac_rst)
>>>>>> - reset_control_assert(dwmac->stmmac_rst);
>>>>>> + if (stpriv->stmmac_rst)
>>>>>> + reset_control_assert(stpriv->stmmac_rst);
>>>>>>
>>>>>> /* Setup the phy mode in the system manager registers according to
>>>>>> * devicetree configuration
>>>>>> @@ -227,8 +210,8 @@ static int socfpga_dwmac_init(struct platform_device *pdev, void *priv)
>>>>>> /* Deassert reset for the phy configuration to be sampled by
>>>>>> * the enet controller, and operation to start in requested mode
>>>>>> */
>>>>>> - if (dwmac->stmmac_rst)
>>>>>> - reset_control_deassert(dwmac->stmmac_rst);
>>>>>> + if (stpriv->stmmac_rst)
>>>>>> + reset_control_deassert(stpriv->stmmac_rst);
>>>>>>
>>>>>> /* Before the enet controller is suspended, the phy is suspended.
>>>>>> * This causes the phy clock to be gated. The enet controller is
>>>>>> @@ -245,7 +228,7 @@ static int socfpga_dwmac_init(struct platform_device *pdev, void *priv)
>>>>>> * control register 0, and can be modified by the phy driver
>>>>>> * framework.
>>>>>> */
>>>>>> - if (stpriv && stpriv->phydev)
>>>>>> + if (stpriv->phydev)
>>>>>> phy_resume(stpriv->phydev);
>>>>>
>>>>> Before this change phy_resume() was only called during driver resume
>>>>> when , but your patches cause phy_resume() to called at probe time as
>>>>> well. Is this okey?
>>>>
>>>> I _hope_ it's OK. The cryptic comment above is not very helpful in this
>>>> aspect. Dinh ? :)
>>>
>>> My patches will move phy_resume() to the resume callback so it
>>> preserves the previous behavior. But if someone knows more about this
>>> that would be useful.
>>>
>>>
>>>> btw I wish you reviewed my patch a bit earlier to catch these bits.
>>>
>>> Sorry, about that. I have been really busy with other things lately.
>>
>> Oh I'm real happy someone is doing the refactoring :) I appreciate your
>> work, sorry if that was unclear.
>>
>>> My patches based on next from Friday can be found here now:
>>> https://github.com/manabian/linux-lpc/tree/net-socfpga-dwmac-on-next
>>>
>>> I had to add your latest patch as well since the next version I used
>>> didn't have it. I'll post the patches on netdev later today or
>>> tomorrow.
>>
>> Looks like next wasn't synced for a few days, yeah.
>>
>> You can add my:
>>
>> On SoCFPGA Cyclone V SoC (DENX MCVEVK):
>> Tested-by: Marek Vasut <marex@denx.de>
>>
>> to those patches
>
> Excellent. Thanks Marek.
>
> btw, did you also test suspend/resume?
No, I believe that is unsupported on SoCFPGA Cyclone V in general.
--
Best regards,
Marek Vasut
^ permalink raw reply
* [PATCH net-next] net-rfs: fix false sharing accessing sd->input_queue_head
From: Eric Dumazet @ 2016-04-26 22:30 UTC (permalink / raw)
To: David Miller; +Cc: netdev
From: Eric Dumazet <edumazet@google.com>
sd->input_queue_head is incremented for each processed packet
in process_backlog(), and read from other cpus performing
Out Of Order avoidance in get_rps_cpu()
Moving this field in a separate cache line keeps it mostly
hot for the cpu in process_backlog(), as other cpus will
only read it.
In a stress test, process_backlog() was consuming 6.80 % of cpu cycles,
and the patch reduced the cost to 0.65 %
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
include/linux/netdevice.h | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 18d8394f2e5d..934ca866562d 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -2747,11 +2747,15 @@ struct softnet_data {
struct sk_buff *completion_queue;
#ifdef CONFIG_RPS
- /* Elements below can be accessed between CPUs for RPS */
+ /* input_queue_head should be written by cpu owning this struct,
+ * and only read by other cpus. Worth using a cache line.
+ */
+ unsigned int input_queue_head ____cacheline_aligned_in_smp;
+
+ /* Elements below can be accessed between CPUs for RPS/RFS */
struct call_single_data csd ____cacheline_aligned_in_smp;
struct softnet_data *rps_ipi_next;
unsigned int cpu;
- unsigned int input_queue_head;
unsigned int input_queue_tail;
#endif
unsigned int dropped;
^ permalink raw reply related
* [GIT] Networking
From: David Miller @ 2016-04-26 21:58 UTC (permalink / raw)
To: torvalds; +Cc: akpm, netdev, linux-kernel
1) Handle v4/v6 mixed sockets properly in soreuseport, from Craig Gallak.
2) Bug fixes for the new macsec facility (missing kmalloc NULL checks,
missing locking around netdev list traversal, etc.) from Sabrina
Dubroca.
3) Fix handling of host routes on ifdown in ipv6, from David Ahern.
4) Fix double-fdput in bpf verifier. From Jann Horn.
Please pull, thanks a lot!
The following changes since commit 5f44abd041c5f3be76d57579ab254d78e601315b:
Merge tag 'rtc-4.6-3' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux (2016-04-21 15:41:13 -0700)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git
for you to fetch changes up to 8358b02bf67d3a5d8a825070e1aa73f25fb2e4c7:
bpf: fix double-fdput in replace_map_fd_with_map_ptr() (2016-04-26 17:37:21 -0400)
----------------------------------------------------------------
David Ahern (1):
net: ipv6: Delete host routes on an ifdown
David S. Miller (5):
Merge branch 'bridge-mdb-fixes'
Merge branch 'macsec-fixes'
Merge branch 'mlx5-fixes'
ipv6: Revert optional address flusing on ifdown.
Revert "ipv6: Revert optional address flusing on ifdown."
Elad Raz (3):
switchdev: Adding complete operation to deferred switchdev ops
bridge: mdb: Common function for mdb entry translation
bridge: mdb: Marking port-group as offloaded
Eli Cohen (1):
net/mlx5_core: Remove static from local variable
Eric Dumazet (1):
net/mlx4_en: fix spurious timestamping callbacks
Grygorii Strashko (1):
MAINTAINERS: net: add entry for TI Ethernet Switch drivers
Ivan Babrou (1):
net: dummy: remove note about being Y by default
Jann Horn (1):
bpf: fix double-fdput in replace_map_fd_with_map_ptr()
Jiri Benc (1):
cxgbi: fix uninitialized flowi6
Majd Dibbiny (2):
net/mlx5_core: Add ConnectX-5 to list of supported devices
net/mlx5: Add pci shutdown callback
Manish Chopra (1):
qlcnic: Update version to 5.3.64
Maor Gottlieb (1):
net/mlx5_core: Fix soft lockup in steering error flow
Marek Vasut (1):
net: stmmac: socfpga: Remove re-registration of reset controller
Paolo Abeni (1):
ipv4/fib: don't warn when primary address is missing if in_dev is dead
Rana Shahout (1):
net/mlx5e: Fix MLX5E_100BASE_T define
Sabrina Dubroca (9):
macsec: add missing NULL check after kmalloc
macsec: take rtnl lock before for_each_netdev
macsec: don't put a NULL rxsa
macsec: fix rx_sa refcounting with decrypt callback
macsec: add consistency check to netlink dumps
macsec: fix memory leaks around rx_handler (un)registration
macsec: fix SA leak if initialization fails
macsec: add missing macsec prefix in uapi
macsec: fix netlink attribute validation
Saeed Mahameed (3):
net/mlx5e: Device's mtu field is u16 and not int
net/mlx5e: Fix minimum MTU
net/mlx5e: Use vport MTU rather than physical port MTU
MAINTAINERS | 9 +++++
drivers/infiniband/hw/mlx5/main.c | 4 +--
drivers/net/Kconfig | 5 ++-
drivers/net/ethernet/mellanox/mlx4/en_tx.c | 6 ++--
drivers/net/ethernet/mellanox/mlx5/core/en.h | 2 +-
drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c | 8 ++---
drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 72 +++++++++++++++++++++++++++++--------
drivers/net/ethernet/mellanox/mlx5/core/fs_core.c | 48 ++++++++++---------------
drivers/net/ethernet/mellanox/mlx5/core/main.c | 25 ++++++++++---
drivers/net/ethernet/mellanox/mlx5/core/port.c | 10 +++---
drivers/net/ethernet/mellanox/mlx5/core/vport.c | 40 +++++++++++++++++++++
drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | 4 +--
drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c | 50 +++++++++-----------------
drivers/net/macsec.c | 65 ++++++++++++++++++++++------------
drivers/scsi/cxgbi/libcxgbi.c | 1 +
include/linux/mlx5/driver.h | 7 ++--
include/linux/mlx5/port.h | 6 ++--
include/linux/mlx5/vport.h | 2 ++
include/net/switchdev.h | 4 +++
include/uapi/linux/if_macsec.h | 4 +--
kernel/bpf/verifier.c | 1 -
net/bridge/br_mdb.c | 124 +++++++++++++++++++++++++++++++++++++++++-----------------------
net/bridge/br_multicast.c | 8 +++--
net/bridge/br_private.h | 4 +--
net/ipv4/fib_frontend.c | 6 +++-
net/ipv6/addrconf.c | 48 ++++++++-----------------
net/switchdev/switchdev.c | 6 ++++
27 files changed, 351 insertions(+), 218 deletions(-)
^ permalink raw reply
* Darlehen anbieten. Kontaktieren Sie uns für weitere Informationen
From: Kredit-Firma @ 2016-04-26 21:35 UTC (permalink / raw)
Guten Tag,
Wir möchten Sie darüber informieren, dass wir anbieten, Geschäftdarlehen, Projektfinanzierung und Immobilienfinanzierung bei 1% Jahreszins. Für weitere Informationen kontaktieren Sie uns bitte über unsere offizielle E-Mail: eurofinance19@gmail.com. Sie sind verpflichtet, Ihre Kreditanfrage mit Ihren vollständigen Namen, den Kreditbetrag erforderlich, Darlehenslaufzeit und Adresse / Telefonnummer zu senden. Wir werden Ihnen die Darlehensbedingungen und die Rückzahlung nach Erhalt Ihrer E-Mail senden. Bitte haben Sie Ihren Kreditantrag über unsere offizielle E-Mail einreichen: eurofinance19@gmail.com.
Grüße, Josef Pani
Este mensaje (y sus adjuntos), en adelante mensaje, ha sido enviado exclusivamente a su(s) destinatario(s) y es confidencial. Si usted recibe este mensaje por error, por favor b��rrelo y comunique inmediatamente al remitente. Toda utilizaci��n o publicaci��n, total o parcial, queda prohibida salvo autorizaci��n expresa. El MEDUCA no podr�� ser considerado responsable si el mensaje ha sido modificado y/o utilizado sin autorizaci��n. This message (and any attachments), are confidential intended solely for the people whose addresses appear. If you have received this message by error, please delete it and immediately notify the sender. Any use, dissemination or disclosure, either whole or partial, without formal approval is prohibited. The MEDUCA will not therefore be liable for the message if modified and/or used without approval.
^ permalink raw reply
* Quote Request
From: Al Waleed Co. @ 2016-04-26 21:45 UTC (permalink / raw)
To: netdev
Hi,
My name is Al Waleed From Al Waleed trading company Dubai we got you recommendation from one of your customer, so we decided to order a product from you.
Kindly get back to us if you can ship to us in Dubai so that we can get back to you with our products needed from you and other requirement Looking forward hearing back from you
Thank you,
Al Waleed trading company
Customer Service
^ permalink raw reply
* Quote Request
From: Al Waleed Co. @ 2016-04-26 21:45 UTC (permalink / raw)
To: netdev
Hi,
My name is Al Waleed From Al Waleed trading company Dubai we got you recommendation from one of your customer, so we decided to order a product from you.
Kindly get back to us if you can ship to us in Dubai so that we can get back to you with our products needed from you and other requirement Looking forward hearing back from you
Thank you,
Al Waleed trading company
Customer Service
^ permalink raw reply
* Quote Request
From: Al Waleed Co. @ 2016-04-26 21:45 UTC (permalink / raw)
To: netdev
Hi,
My name is Al Waleed From Al Waleed trading company Dubai we got you recommendation from one of your customer, so we decided to order a product from you.
Kindly get back to us if you can ship to us in Dubai so that we can get back to you with our products needed from you and other requirement Looking forward hearing back from you
Thank you,
Al Waleed trading company
Customer Service
^ 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