* [PATCH V3 3/4] mailbox: xgene: base driver for APM X-Gene SoC QMTM
From: Ravi Patel @ 2014-02-15 2:22 UTC (permalink / raw)
To: arnd, gregkh, davem
Cc: netdev, linux-kernel, devicetree, linux-arm-kernel, jcm, patches,
Ravi Patel, Keyur Chudgar
In-Reply-To: <1392430922-24643-1-git-send-email-rapatel@apm.com>
This patch adds APM X-Gene SoC Queue Manager/Traffic Manager base driver.
QMTM is requried by Ethernet, PktDMA (XOR Engine) and Security subsystems.
Signed-off-by: Ravi Patel <rapatel@apm.com>
Signed-off-by: Keyur Chudgar <kchudgar@apm.com>
---
MAINTAINERS | 9 +
drivers/mailbox/Kconfig | 2 +
drivers/mailbox/Makefile | 1 +
drivers/mailbox/xgene/Kconfig | 9 +
drivers/mailbox/xgene/Makefile | 7 +
drivers/mailbox/xgene/xgene_qmtm_main.c | 516 ++++++++++++++++++++++++++++++
drivers/mailbox/xgene/xgene_qmtm_main.h | 112 +++++++
drivers/mailbox/xgene/xgene_qmtm_storm.c | 358 +++++++++++++++++++++
include/linux/platform_data/xgene_qmtm.h | 300 +++++++++++++++++
9 files changed, 1314 insertions(+)
create mode 100644 drivers/mailbox/xgene/Kconfig
create mode 100644 drivers/mailbox/xgene/Makefile
create mode 100644 drivers/mailbox/xgene/xgene_qmtm_main.c
create mode 100644 drivers/mailbox/xgene/xgene_qmtm_main.h
create mode 100644 drivers/mailbox/xgene/xgene_qmtm_storm.c
create mode 100644 include/linux/platform_data/xgene_qmtm.h
diff --git a/MAINTAINERS b/MAINTAINERS
index 2507f38..3e09f39 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -678,6 +678,15 @@ S: Maintained
F: drivers/net/appletalk/
F: net/appletalk/
+APPLIEDMICRO (APM) X-GENE SOC QUEUE MANAGER/TRAFFIC MANAGER (QMTM) DRIVER
+M: Ravi Patel <rapatel@apm.com>
+M: Keyur Chudgar <kchudgar@apm.com>
+S: Maintained
+F: drivers/mailbox/xgene/
+F: include/linux/platform_data/xgene_qmtm.h
+F: Documentation/devicetree/bindings/mailbox/apm-xgene-qmtm.txt
+F: Documentation/mailbox/apm-xgene-qmtm
+
APTINA CAMERA SENSOR PLL
M: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
L: linux-media@vger.kernel.org
diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
index c8b5c13..52653d4 100644
--- a/drivers/mailbox/Kconfig
+++ b/drivers/mailbox/Kconfig
@@ -50,4 +50,6 @@ config OMAP_MBOX_KFIFO_SIZE
Specify the default size of mailbox's kfifo buffers (bytes).
This can also be changed at runtime (via the mbox_kfifo_size
module parameter).
+
+source "drivers/mailbox/xgene/Kconfig"
endif
diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
index e0facb3..6faee7e 100644
--- a/drivers/mailbox/Makefile
+++ b/drivers/mailbox/Makefile
@@ -5,3 +5,4 @@ obj-$(CONFIG_OMAP1_MBOX) += mailbox_omap1.o
mailbox_omap1-objs := mailbox-omap1.o
obj-$(CONFIG_OMAP2PLUS_MBOX) += mailbox_omap2.o
mailbox_omap2-objs := mailbox-omap2.o
+obj-$(CONFIG_XGENE_MBOX) += xgene/
diff --git a/drivers/mailbox/xgene/Kconfig b/drivers/mailbox/xgene/Kconfig
new file mode 100644
index 0000000..0843303
--- /dev/null
+++ b/drivers/mailbox/xgene/Kconfig
@@ -0,0 +1,9 @@
+config XGENE_MBOX
+ tristate "APM X-Gene Queue Manager/Traffic Manager Mailbox"
+ depends on ARM64 || COMPILE_TEST
+ default y
+ help
+ This option enables APM X-Gene Queue Manager Traffic Manager (QMTM)
+ mailbox support.
+ QMTM is required for Ethernet, PktDMA (XOR Engine) and Security
+ Engine.
diff --git a/drivers/mailbox/xgene/Makefile b/drivers/mailbox/xgene/Makefile
new file mode 100644
index 0000000..574e1b8
--- /dev/null
+++ b/drivers/mailbox/xgene/Makefile
@@ -0,0 +1,7 @@
+#
+# Makefile for APM X-GENE Queue Manager Traffic Manager mailbox
+#
+
+obj-$(CONFIG_XGENE_MBOX) += xgene-qmtm.o
+
+xgene-qmtm-objs := xgene_qmtm_main.o xgene_qmtm_storm.o
diff --git a/drivers/mailbox/xgene/xgene_qmtm_main.c b/drivers/mailbox/xgene/xgene_qmtm_main.c
new file mode 100644
index 0000000..bc50cd9
--- /dev/null
+++ b/drivers/mailbox/xgene/xgene_qmtm_main.c
@@ -0,0 +1,516 @@
+/*
+ * AppliedMicro X-Gene SoC Queue Manager/Traffic Manager driver
+ *
+ * Copyright (c) 2013 Applied Micro Circuits Corporation.
+ * Author: Ravi Patel <rapatel@apm.com>
+ * Keyur Chudgar <kchudgar@apm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License 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/io.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/dma-mapping.h>
+#include "xgene_qmtm_main.h"
+
+#define XGENE_QMTM_DRIVER_VER "1.0"
+#define XGENE_QMTM_DRIVER_NAME "xgene-qmtm"
+#define XGENE_QMTM_DRIVER_DESC "APM X-Gene QMTM driver"
+
+/* CSR Address Macros */
+#define CSR_QM_CONFIG_ADDR 0x00000004
+#define QM_ENABLE_WR(src) (((u32)(src)<<31) & 0x80000000)
+
+#define CSR_PBM_ADDR 0x00000008
+#define OVERWRITE_WR(src) (((u32)(src)<<31) & 0x80000000)
+#define SLVID_PBN_WR(src) (((u32)(src)) & 0x000003ff)
+
+#define CSR_PBM_BUF_WR_ADDR 0x0000000c
+#define CSR_PBM_BUF_RD_ADDR 0x00000010
+#define PB_SIZE_WR(src) (((u32)(src)<<31) & 0x80000000)
+#define PREFETCH_BUF_EN_SET(dst, src) \
+ (((dst) & ~0x00200000) | (((u32)(src)<<21) & 0x00200000))
+#define IS_FREE_POOL_SET(dst, src) \
+ (((dst) & ~0x00100000) | (((u32)(src)<<20) & 0x00100000))
+#define TLVQ_SET(dst, src) \
+ (((dst) & ~0x00080000) | (((u32)(src)<<19) & 0x00080000))
+#define CORRESPONDING_QNUM_SET(dst, src) \
+ (((dst) & ~0x0007fe00) | (((u32)(src)<<9) & 0x0007fe00))
+
+#define CSR_THRESHOLD0_SET1_ADDR 0x00000030
+#define CSR_THRESHOLD1_SET1_ADDR 0x00000034
+#define CSR_HYSTERESIS_ADDR 0x00000068
+#define CSR_QM_MBOX_NE_INT_MODE_ADDR 0x0000017c
+#define CSR_QMLITE_PBN_MAP_0_ADDR 0x00000228
+
+#define CSR_RECOMB_CTRL_0_ADDR 0x00000230
+#define RECOMB_EN0_SET(dst, src) \
+ (((dst) & ~0x00000001) | (((u32)(src)) & 0x00000001))
+
+/* QMTM Diag CSR */
+#define QM_GLBL_DIAG_CSR_BASE_ADDR_OFFSET 0xd000
+#define QM_CFG_MEM_RAM_SHUTDOWN_ADDR 0x00000070
+#define QM_CFG_MEM_RAM_SHUTDOWN_DEFAULT 0xffffffff
+
+static struct of_device_id xgene_qmtm_match[] = {
+ {
+ .compatible = "apm,xgene-qmtm",
+ .data = &storm_qmtm_ops,
+ },
+ {}
+};
+MODULE_DEVICE_TABLE(of, xgene_qmtm_match);
+
+void xgene_qmtm_wr32(struct xgene_qmtm *qmtm, u32 offset, u32 data)
+{
+ writel(data, qmtm->csr_vaddr + offset);
+}
+
+void xgene_qmtm_rd32(struct xgene_qmtm *qmtm, u32 offset, u32 *data)
+{
+ *data = readl(qmtm->csr_vaddr + offset);
+}
+
+static void xgene_qmtm_pbm_get(struct xgene_mbox *mbox)
+{
+ u16 is_fp = QMTM_QTYPE_FP(mbox);
+ u16 is_vq = QMTM_QTYPE_VQ(mbox);
+ u32 val = 0;
+ u32 pbm = SLVID_PBN_WR(mbox->pbm) | OVERWRITE_WR(1);
+
+ if (mbox->qmtm->qmtm_ip == QMTM0 || mbox->qmtm->qmtm_ip == QMTM2)
+ val |= PB_SIZE_WR(1);
+
+ val = CORRESPONDING_QNUM_SET(val, mbox->qid);
+ val = IS_FREE_POOL_SET(val, is_fp);
+ val = TLVQ_SET(val, is_vq);
+ val = PREFETCH_BUF_EN_SET(val, 1);
+ xgene_qmtm_wr32(mbox->qmtm, CSR_PBM_ADDR, pbm);
+ xgene_qmtm_wr32(mbox->qmtm, CSR_PBM_BUF_WR_ADDR, val);
+}
+
+static void xgene_qmtm_pbm_put(struct xgene_mbox *mbox)
+{
+ u32 pbm = SLVID_PBN_WR(mbox->pbm) | OVERWRITE_WR(1);
+ xgene_qmtm_wr32(mbox->qmtm, CSR_PBM_ADDR, pbm);
+ xgene_qmtm_wr32(mbox->qmtm, CSR_PBM_BUF_WR_ADDR, 0);
+}
+
+/**
+ * xgene_mbox_get - Create and configure a queue
+ * @dev: device that requests this queue
+ * @s: the queue name string as given in the dt data
+ *
+ * This API will be called by APM X-Gene SoC Ethernet, PktDMA (XOR Engine),
+ * and Security Engine subsystems to create and configure a queue.
+ *
+ * Returns the mbox associated with the given phandle value,
+ * after getting a refcount to it, -ENODEV if there is no such queue,
+ * -ENOMEM if out of memory or -EINVAL for other error conditions.
+ * The caller is responsible for calling xgene_mbox_put() to release
+ * that count.
+ */
+struct xgene_mbox *xgene_mbox_get(struct device *dev, const char *s)
+{
+ struct module *module = THIS_MODULE;
+ struct xgene_mbox *mbox = ERR_PTR(-EINVAL);
+ struct xgene_qmtm *qmtm;
+ int ret;
+ struct of_phandle_args args;
+ u64 qfabric_paddr;
+ u32 qsize = 0;
+ u16 qid = 0;
+ u8 cfgqsize;
+
+ if (!dev->of_node) {
+ dev_err(dev, "Invalid device tree\n");
+ goto _err_mbox_get;
+ }
+
+ ret = of_property_match_string(dev->of_node, "mailbox-names", s);
+ if (ret < 0) {
+ mbox = ERR_PTR(-ENODEV);
+ goto _err_mbox_get;
+ }
+
+ memset(&args, 0, sizeof(args));
+ ret = of_parse_phandle_with_args(dev->of_node, "mailboxes",
+ "#mailbox-cells", ret, &args);
+ if (ret || !args.np) {
+ dev_err(dev, "failed to get mailbox in %s node\n",
+ dev->of_node->full_name);
+ goto _err_mbox_get;
+ }
+
+ if (!try_module_get(module))
+ goto _err_mbox_get;
+
+ qmtm = platform_get_drvdata(of_find_device_by_node(args.np));
+ if (qmtm == NULL) {
+ dev_err(dev, "failed to get QMTM for %s node\n",
+ dev->of_node->full_name);
+ goto _module_put;
+ }
+
+ qfabric_paddr = ((u64)args.args[0] << 32) | args.args[1];
+ if (qfabric_paddr > (qmtm->fabric_paddr |
+ ((u64)(QMTM_MAX_QUEUES - 1) << 6)) ||
+ qfabric_paddr < qmtm->fabric_paddr) {
+ dev_err(dev, "Invalid qfabric address for %s node\n",
+ dev->of_node->full_name);
+ goto _module_put;
+ }
+ qid = (qfabric_paddr - qmtm->fabric_paddr) >> 6;
+
+ qsize = args.args[2];
+ switch (qsize) {
+ case 0x00200:
+ cfgqsize = QSIZE_512B;
+ break;
+ case 0x00800:
+ cfgqsize = QSIZE_2KB;
+ break;
+ case 0x04000:
+ cfgqsize = QSIZE_16KB;
+ break;
+ case 0x10000:
+ cfgqsize = QSIZE_64KB;
+ break;
+ case 0x80000:
+ cfgqsize = QSIZE_512KB;
+ break;
+ default:
+ dev_err(dev, "Unsupported queue size %d\n", qsize);
+ goto _module_put;
+ }
+
+ mbox = kzalloc(sizeof(struct xgene_mbox), GFP_KERNEL);
+ if (mbox == NULL) {
+ dev_err(dev, "Unable to allocate mbox\n");
+ goto _module_put;
+ }
+
+ mbox->qaddr = dma_zalloc_coherent(&qmtm->pdev->dev, qsize,
+ &mbox->dma, GFP_KERNEL);
+ if (mbox->qaddr == NULL) {
+ dev_err(dev, "Unable to allocate qaddr\n");
+ kfree(mbox);
+ mbox = NULL;
+ goto _module_put;
+ }
+ mbox->qsize = qsize;
+ mbox->pbm = args.args[3];
+ mbox->qid = qid;
+ mbox->slots = cfgqsize;
+ mbox->qfabric = qmtm->fabric_vaddr + (qid << 6);
+ mbox->level = mbox->qfabric + 0x2C;
+ mbox->qmtm = qmtm;
+ qmtm->ops.set_qstate(mbox);
+ xgene_qmtm_pbm_get(mbox);
+ mbox->slots = QMTM_QTYPE_FP(mbox) ? qsize / 16 : qsize / 32;
+ mbox->qstate[6] = qmtm->qmtm_ip;
+
+ if (QMTM_SLAVE_ID(mbox) == QMTM_SLAVE_ID_CPU &&
+ !QMTM_QTYPE_FP(mbox) &&
+ !QMTM_QTYPE_VQ(mbox)) {
+ u32 s, data;
+ for (s = 0; s < mbox->slots; s++) {
+ u32 *slot = (u32 *)&mbox->msg32[s];
+ slot[EMPTY_SLOT_INDEX] = EMPTY_SLOT;
+ }
+ xgene_qmtm_rd32(qmtm, CSR_QM_MBOX_NE_INT_MODE_ADDR, &data);
+ data |= (u32) (1 << (31 - QMTM_PBN(mbox)));
+ xgene_qmtm_wr32(qmtm, CSR_QM_MBOX_NE_INT_MODE_ADDR, data);
+ mbox->irq = qmtm->dequeue_irq[QMTM_PBN(mbox)];
+ }
+
+ qmtm->mbox[qid] = mbox;
+ return mbox;
+
+_module_put:
+ module_put(module);
+
+_err_mbox_get:
+ return mbox;
+}
+EXPORT_SYMBOL_GPL(xgene_mbox_get);
+
+/**
+ * xgene_mbox_put - Unconfigure and delete a queue
+ * @mbox: the mbox returned by xgene_mbox_get()
+ *
+ * This API will be called by APM X-Gene SoC Ethernet, PktDMA (XOR Engine),
+ * and Security Engine subsystems to unconfigure and delete a queue.
+ *
+ * Releases a refcount the caller received from xgene_mbox_get().
+ */
+void xgene_mbox_put(struct xgene_mbox *mbox)
+{
+ struct xgene_qmtm *qmtm = mbox->qmtm;
+ struct module *module = THIS_MODULE;
+
+ if (QMTM_SLAVE_ID(mbox) == QMTM_SLAVE_ID_CPU &&
+ !QMTM_QTYPE_FP(mbox) &&
+ !QMTM_QTYPE_VQ(mbox)) {
+ u32 data;
+ xgene_qmtm_rd32(qmtm, CSR_QM_MBOX_NE_INT_MODE_ADDR, &data);
+ data &= ~(u32) (1 << (31 - QMTM_PBN(mbox)));
+ xgene_qmtm_wr32(qmtm, CSR_QM_MBOX_NE_INT_MODE_ADDR, data);
+ }
+
+ xgene_qmtm_pbm_put(mbox);
+ qmtm->ops.clr_qstate(mbox);
+ dma_free_coherent(&qmtm->pdev->dev, mbox->qsize,
+ mbox->qaddr, mbox->dma);
+ qmtm->mbox[mbox->qid] = NULL;
+ kfree(mbox);
+ module_put(module);
+}
+EXPORT_SYMBOL_GPL(xgene_mbox_put);
+
+/**
+ * xgene_mbox_level - Read number of message in queue
+ * @mbox: read number of message for mbox
+ *
+ * This API will be called by APM X-Gene SoC Ethernet, PktDMA (XOR Engine),
+ * and Security Engine subsystems to read number of message for mbox.
+ *
+ * Returns number of messages in mbox
+ */
+u32 xgene_mbox_level(struct xgene_mbox *mbox)
+{
+ return mbox->qmtm->ops.read_level(mbox->qfabric);
+}
+EXPORT_SYMBOL_GPL(xgene_mbox_level);
+
+static int xgene_qmtm_enable(struct xgene_qmtm *qmtm)
+{
+ struct xgene_mbox mbox;
+ struct device *dev = &qmtm->pdev->dev;
+ int rc, mwait = 0, inum = 1;
+ u32 val;
+ u32 qid;
+
+ qmtm->clk = devm_clk_get(dev, NULL);
+ if (IS_ERR(qmtm->clk)) {
+ dev_err(dev, "can't get clock\n");
+ return PTR_ERR(qmtm->clk);
+ }
+
+ rc = clk_prepare_enable(qmtm->clk);
+ if (rc < 0) {
+ dev_err(dev, "clock prepare enable failed\n");
+ return rc;
+ }
+
+ xgene_qmtm_wr32(qmtm, QM_GLBL_DIAG_CSR_BASE_ADDR_OFFSET +
+ QM_CFG_MEM_RAM_SHUTDOWN_ADDR, 0);
+ do {
+ /* Wait for Memory to come out of shutdown */
+ usleep_range(1000, 2000);
+ xgene_qmtm_rd32(qmtm, QM_GLBL_DIAG_CSR_BASE_ADDR_OFFSET +
+ QM_CFG_MEM_RAM_SHUTDOWN_ADDR, &val);
+
+ if (mwait++ >= 1000) {
+ rc = -EIO;
+ dev_err(dev, "RAM not out of shutdown %d\n", rc);
+ clk_disable_unprepare(qmtm->clk);
+ return rc;
+ }
+ } while (val == QM_CFG_MEM_RAM_SHUTDOWN_DEFAULT);
+
+ rc = qmtm->ops.init(qmtm);
+ if (rc < 0) {
+ dev_err(dev, "not supported on your system\n");
+ return rc;
+ }
+
+ for (inum = qmtm->irq_start; inum < (qmtm->irq_start +
+ qmtm->irq_count); inum++) {
+ int irq = platform_get_irq(qmtm->pdev,
+ inum - qmtm->irq_start + 1);
+ if (irq < 0) {
+ dev_err(dev, "Failed to map QMTM%d PBN %d IRQ\n",
+ qmtm->qmtm_ip, inum);
+ continue;
+ }
+ qmtm->dequeue_irq[inum] = irq;
+ }
+
+ switch (qmtm->qmtm_ip) {
+ case QMTM0:
+ case QMTM2:
+ xgene_qmtm_rd32(qmtm, CSR_RECOMB_CTRL_0_ADDR, &val);
+ val = RECOMB_EN0_SET(val, 1);
+ xgene_qmtm_wr32(qmtm, CSR_RECOMB_CTRL_0_ADDR, val);
+ break;
+ case QMTM3:
+ xgene_qmtm_wr32(qmtm, CSR_QMLITE_PBN_MAP_0_ADDR, 0x00000000);
+ }
+
+ /* program threshold set 1 and all hysteresis */
+ xgene_qmtm_wr32(qmtm, CSR_THRESHOLD0_SET1_ADDR, 100);
+ xgene_qmtm_wr32(qmtm, CSR_THRESHOLD1_SET1_ADDR, 200);
+ xgene_qmtm_wr32(qmtm, CSR_HYSTERESIS_ADDR, 0xFFFFFFFF);
+
+ /* Enable QPcore */
+ xgene_qmtm_wr32(qmtm, CSR_QM_CONFIG_ADDR, QM_ENABLE_WR(1));
+
+ /* Clear all HW queue state in case they were not de-activated */
+ memset(&mbox, 0, sizeof(mbox));
+ mbox.qmtm = qmtm;
+
+ for (qid = 0; qid < QMTM_MAX_QUEUES; qid++) {
+ mbox.qid = qid;
+ qmtm->ops.clr_qstate(&mbox);
+ }
+
+ return rc;
+}
+
+static int xgene_qmtm_disable(struct xgene_qmtm *qmtm)
+{
+ u32 qid;
+
+ for (qid = 0; qid < QMTM_MAX_QUEUES; qid++) {
+ if (qmtm->mbox[qid]) {
+ dev_err(&qmtm->pdev->dev,
+ "QMTM %d Queue ID %d Resource in use\n",
+ qmtm->qmtm_ip, qid);
+ return -EAGAIN;
+ }
+ }
+
+ /* Disable QPcore */
+ xgene_qmtm_wr32(qmtm, CSR_QM_CONFIG_ADDR, QM_ENABLE_WR(0));
+ clk_disable_unprepare(qmtm->clk);
+
+ return 0;
+}
+
+static struct xgene_qmtm *xgene_alloc_qmtm(struct platform_device *pdev)
+{
+ struct xgene_qmtm *qmtm;
+
+ qmtm = devm_kzalloc(&pdev->dev, sizeof(struct xgene_qmtm), GFP_KERNEL);
+ if (qmtm == NULL) {
+ dev_err(&pdev->dev, "Unable to allocate QMTM context\n");
+ return NULL;
+ }
+
+ qmtm->pdev = pdev;
+ platform_set_drvdata(pdev, qmtm);
+ qmtm->mbox = devm_kzalloc(&pdev->dev,
+ QMTM_MAX_QUEUES * (sizeof(struct xgene_qmtm_info *)),
+ GFP_KERNEL);
+ if (qmtm->mbox == NULL) {
+ dev_err(&pdev->dev, "Unable to allocate QMTM Queue context\n");
+ return NULL;
+ }
+
+ return qmtm;
+}
+
+static int xgene_get_qmtm(struct xgene_qmtm *qmtm)
+{
+ struct platform_device *pdev = qmtm->pdev;
+ const struct of_device_id *match;
+ struct resource *res;
+
+ /* Get Match Table */
+ match = of_match_device(xgene_qmtm_match, &pdev->dev);
+ if (!match)
+ return -EINVAL;
+ memcpy(&qmtm->ops, match->data, sizeof(struct xgene_qmtm_ops));
+
+ /* Retrieve QM CSR register address and size */
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "Failed to get QMTM CSR region\n");
+ return -ENODEV;
+ }
+
+ qmtm->csr_vaddr = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(qmtm->csr_vaddr)) {
+ dev_err(&pdev->dev, "Invalid QMTM CSR region\n");
+ return PTR_ERR(qmtm->csr_vaddr);
+ }
+
+ /* Retrieve Primary Fabric address and size */
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (!res) {
+ dev_err(&pdev->dev, "Failed to get QMTM Fabric region\n");
+ return -ENODEV;
+ }
+
+ qmtm->fabric_vaddr = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(qmtm->fabric_vaddr)) {
+ dev_err(&pdev->dev, "Invalid QMTM Fabric region\n");
+ return PTR_ERR(qmtm->fabric_vaddr);
+ }
+ qmtm->fabric_paddr = res->start;
+
+ if (dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)))
+ return dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
+
+ return 0;
+}
+
+static int xgene_qmtm_probe(struct platform_device *pdev)
+{
+ struct xgene_qmtm *qmtm;
+ int rc;
+
+ qmtm = xgene_alloc_qmtm(pdev);
+ if (qmtm == NULL)
+ return -ENOMEM;
+
+ rc = xgene_get_qmtm(qmtm);
+ if (rc)
+ return rc;
+
+ return xgene_qmtm_enable(qmtm);
+}
+
+static int xgene_qmtm_remove(struct platform_device *pdev)
+{
+ struct xgene_qmtm *qmtm = platform_get_drvdata(pdev);
+ return xgene_qmtm_disable(qmtm);
+}
+
+static struct platform_driver xgene_qmtm_driver = {
+ .driver = {
+ .name = XGENE_QMTM_DRIVER_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = xgene_qmtm_match,
+ },
+ .probe = xgene_qmtm_probe,
+ .remove = xgene_qmtm_remove,
+};
+
+static int __init xgene_qmtm_init(void)
+{
+ return platform_driver_register(&xgene_qmtm_driver);
+}
+subsys_initcall(xgene_qmtm_init);
+
+static void __exit xgene_qmtm_exit(void)
+{
+ platform_driver_unregister(&xgene_qmtm_driver);
+}
+module_exit(xgene_qmtm_exit);
+
+MODULE_VERSION(XGENE_QMTM_DRIVER_VER);
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Ravi Patel <rapatel@apm.com>");
+MODULE_DESCRIPTION(XGENE_QMTM_DRIVER_DESC);
diff --git a/drivers/mailbox/xgene/xgene_qmtm_main.h b/drivers/mailbox/xgene/xgene_qmtm_main.h
new file mode 100644
index 0000000..1a9de03
--- /dev/null
+++ b/drivers/mailbox/xgene/xgene_qmtm_main.h
@@ -0,0 +1,112 @@
+/*
+ * AppliedMicro X-Gene SoC Queue Manager/Traffic Manager driver
+ *
+ * Copyright (c) 2013 Applied Micro Circuits Corporation.
+ * Author: Ravi Patel <rapatel@apm.com>
+ * Keyur Chudgar <kchudgar@apm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License 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.
+ */
+
+#ifndef __XGENE_QMTM_MAIN_H__
+#define __XGENE_QMTM_MAIN_H__
+
+#include <linux/of_platform.h>
+#include <linux/platform_data/xgene_qmtm.h>
+
+/* QMTM IP Blocks */
+enum xgene_qmtm_ip {
+ QMTM0,
+ QMTM1,
+ QMTM2,
+ QMTM3,
+};
+
+#define QMTM_MAX_QUEUES 1024
+#define QMTM_MAX_PBN 32
+
+/* QMTM Queue types */
+enum xgene_qmtm_qtype {
+ QTYPE_DISABLED, /* Queue Type is un-configured or disabled */
+ QTYPE_PQ, /* Queue Type is Physical Work Queue */
+ QTYPE_FP, /* Queue Type is Free Pool Queue */
+ QTYPE_VQ, /* Queue Type is Virtual Queue */
+};
+
+/* QMTM Queue possible sizes */
+enum xgene_qmtm_qsize {
+ QSIZE_512B,
+ QSIZE_2KB,
+ QSIZE_16KB,
+ QSIZE_64KB,
+ QSIZE_512KB,
+ QSIZE_MAX,
+};
+
+struct xgene_qmtm_ops {
+ int (*init)(struct xgene_qmtm *qmtm);
+ void (*set_qstate)(struct xgene_mbox *mbox);
+ void (*clr_qstate)(struct xgene_mbox *mbox);
+ u32 (*read_level)(void *qfabric);
+};
+
+struct xgene_qmtm {
+ struct xgene_qmtm_ops ops;
+ void *csr_vaddr;
+ void *fabric_vaddr;
+ u64 fabric_paddr;
+ u16 qmtm_ip; /* qmtm_ip, see xgene_qmtm_ip */
+ u16 irq_start;
+ u16 irq_count;
+ u16 error_irq;
+ u16 dequeue_irq[QMTM_MAX_PBN];
+ char error_irq_s[16];
+ char error_queue_irq_s[16];
+ struct xgene_mbox *(*mbox);
+ struct xgene_mbox *error_mbox;
+ struct clk *clk;
+ struct platform_device *pdev;
+};
+
+/* QMTM Slave IDs */
+enum xgene_qmtm_slave_id {
+ QMTM_SLAVE_ID_ETH0,
+ QMTM_SLAVE_ID_ETH1,
+ QMTM_SLAVE_ID_RES2,
+ QMTM_SLAVE_ID_PKTDMA,
+ QMTM_SLAVE_ID_CTX,
+ QMTM_SLAVE_ID_SEC,
+ QMTM_SLAVE_ID_CLASS,
+ QMTM_SLAVE_ID_MSLIM,
+ QMTM_SLAVE_ID_RES8,
+ QMTM_SLAVE_ID_RES9,
+ QMTM_SLAVE_ID_RESA,
+ QMTM_SLAVE_ID_RESB,
+ QMTM_SLAVE_ID_RESC,
+ QMTM_SLAVE_ID_PMPRO,
+ QMTM_SLAVE_ID_SMPRO,
+ QMTM_SLAVE_ID_CPU,
+ QMTM_SLAVE_ID_MAX,
+};
+
+/* QMTM Free Pool Queue modes */
+enum xgene_qmtm_fp_mode {
+ MSG_NO_CHANGE,
+ ROUND_ADDR,
+ REDUCE_LEN,
+ CHANGE_LEN,
+};
+
+extern struct xgene_qmtm_ops storm_qmtm_ops;
+/* QMTM CSR read/write routine */
+void xgene_qmtm_wr32(struct xgene_qmtm *qmtm, u32 offset, u32 data);
+void xgene_qmtm_rd32(struct xgene_qmtm *qmtm, u32 offset, u32 *data);
+
+#endif /* __XGENE_QMTM_MAIN_H__ */
diff --git a/drivers/mailbox/xgene/xgene_qmtm_storm.c b/drivers/mailbox/xgene/xgene_qmtm_storm.c
new file mode 100644
index 0000000..e214d28
--- /dev/null
+++ b/drivers/mailbox/xgene/xgene_qmtm_storm.c
@@ -0,0 +1,358 @@
+/**
+ * AppliedMicro X-Gene SOC Queue Manager/Traffic Manager driver
+ *
+ * Copyright (c) 2013 Applied Micro Circuits Corporation.
+ * Author: Ravi Patel <rapatel@apm.com>
+ * Keyur Chudgar <kchudgar@apm.com>
+ * Fushen Chen <fchen@apm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License 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/slab.h>
+#include "xgene_qmtm_main.h"
+
+#define CSR_IPBRR_ADDR 0x00000000
+#define CSR_IPBRR_QMTM0_DEFAULT 0x00000520
+#define CSR_IPBRR_QMTM1_DEFAULT 0x00000521
+#define CSR_IPBRR_QMTM2_DEFAULT 0x00000522
+#define CSR_IPBRR_QMTM3_DEFAULT 0x000005E0
+
+#define CSR_QSTATE_ADDR 0x0000006c
+#define QNUMBER_WR(src) (((u32)(src)) & 0x000003ff)
+
+#define CSR_QSTATE_WR_0_ADDR 0x00000070
+#define CSR_QSTATE_WR_1_ADDR 0x00000074
+#define CSR_QSTATE_WR_2_ADDR 0x00000078
+#define CSR_QSTATE_WR_3_ADDR 0x0000007c
+#define CSR_QSTATE_WR_4_ADDR 0x00000080
+
+/* QMTM Queue State */
+struct storm_qmtm_csr_qstate {
+ u32 w0;
+ u32 w1;
+ u32 w2;
+ u32 w3;
+ u32 w4;
+} __packed;
+
+/*
+ * Physical or free pool queue state (pq or fp)
+ */
+struct storm_qmtm_pq_fp_qstate {
+#ifdef CONFIG_CPU_BIG_ENDIAN
+ /* register word 0 (bit 31:0) */
+ u32 cpu_notify:8; /* 31:24 */
+ u32 cfgsaben:1; /* 23 enable SAB broadcasting */
+ u32 cfgtmvq:10; /* 22:13 parent vq */
+ u32 cfgtmvqen:1; /* 12 enable pq to belong to vq */
+ u32 resize_done:1; /* 11 */
+ u32 resize_start:1; /* 10 */
+ u32 resize_qid:10; /* 9:0 */
+
+ /* register word 1 (bit 63:32) */
+ u32 headptr:15; /* 63:49 */
+ u32 nummsg:16; /* 48:33 */
+ u32 cfgnotifyqne:1; /* 32 enable Q not empty intr */
+
+ /* register word 2 (bit 95:64) */
+ u32 cfgstartaddrL:27; /* 95:69 split 7/27 */
+ u32 qcoherent:1; /* 68 */
+ u32 rid:3; /* 67:65 */
+ u32 cfgcrid:1; /* 64 */
+
+ /* register word 3 (bit 127:96) */
+ u32 cfgRecombBufTimeoutL:4; /* 127:124 split 3/4 */
+ u32 cfgRecombBuf:1; /* 123 */
+ u32 qstatelock:1; /* 122 */
+ u32 cfgqsize:3; /* 121:119 queue size */
+ u32 fp_mode:3; /* 118:116 free pool mode */
+ u32 cfgacceptlerr:1; /* 115 */
+ u32 reserved_0:1; /* 114 */
+ u32 stashing:1; /* 113 */
+ u32 slot_pending:8; /* 112:105 */
+ u32 vc_chanid:2; /* 104:103 */
+ u32 cfgstartaddrH:7; /* 102:96 split 7/27 */
+
+ /* register word 4 (bit 159:128) */
+ u32 resv1:11; /* 159:149 */
+ u32 cfgqtype:2; /* 148:147 queue type */
+ u32 resv2:5; /* 146:142 */
+ u32 half_64B_override:3; /* 141:139 */
+ u32 resv3:4; /* 138:135 */
+ u32 CfgSupressCmpl:1; /* 134 */
+ u32 cfgselthrsh:3; /* 133:131 associated threshold set */
+ u32 cfgRecombBufTimeoutH:3; /* 130:128 split 3/4 */
+#else
+ /* register word 0 (bit 31:0) */
+ u32 resize_qid:10; /* 9:0 */
+ u32 resize_start:1; /* 10 */
+ u32 resize_done:1; /* 11 */
+ u32 cfgtmvqen:1; /* 12 enable pq to belong to vq */
+ u32 cfgtmvq:10; /* 22:13 parent vq */
+ u32 cfgsaben:1; /* 23 enable SAB broadcasting */
+ u32 cpu_notify:8; /* 31:24 */
+
+ /* register word 1 (bit 63:32) */
+ u32 cfgnotifyqne:1; /* 32 enable Q not empty intr */
+ u32 nummsg:16; /* 48:33 */
+ u32 headptr:15; /* 63:49 */
+
+ /* register word 2 (bit 95:64) */
+ u32 cfgcrid:1; /* 64 */
+ u32 rid:3; /* 67:65 */
+ u32 qcoherent:1; /* 68 */
+ u32 cfgstartaddrL:27; /* 95:69 split 7/27 */
+
+ /* register word 3 (bit 127:96) */
+ u32 cfgstartaddrH:7; /* 102:96 split 7/27 */
+ u32 vc_chanid:2; /* 104:103 */
+ u32 slot_pending:8; /* 112:105 */
+ u32 stashing:1; /* 113 */
+ u32 reserved_0:1; /* 114 */
+ u32 cfgacceptlerr:1; /* 115 */
+ u32 fp_mode:3; /* 118:116 free pool mode */
+ u32 cfgqsize:3; /* 121:119 queue size */
+ u32 qstatelock:1; /* 122 */
+ u32 cfgRecombBuf:1; /* 123 */
+ u32 cfgRecombBufTimeoutL:4; /* 127:124 split 3/4 */
+
+ /* register word 4 (bit 159:128) */
+ u32 cfgRecombBufTimeoutH:3; /* 130:128 split 3/4 */
+ u32 cfgselthrsh:3; /* 133:131 associated threshold set */
+ u32 CfgSupressCmpl:1; /* 134 */
+ u32 resv3:4; /* 138:135 */
+ u32 half_64B_override:3; /* 141:139 */
+ u32 resv2:5; /* 146:142 */
+ u32 cfgqtype:2; /* 148:147 queue type */
+ u32 resv1:11; /* 159:149 */
+#endif
+} __packed;
+
+/*
+ * Virtual queue state (vq)
+ */
+struct storm_qmtm_vq_qstate {
+#ifdef CONFIG_CPU_BIG_ENDIAN
+ /* register word 0 (bit 31:0) */
+ u32 rid:3; /* 31:29 */
+ u32 cpu_notify:8; /* 28:21 */
+ u32 cfgcrid:1; /* 20 critical rid config */
+ u32 cfgnotifyqne:1; /* 19 enable Q not empty intr */
+ u32 cfgsaben:1; /* 18 enable SAB broadcasting */
+ u32 nummsg:18; /* 17:0 */
+
+ /* register word 1 (bit 63:32) */
+ u32 q5reqvld:1; /* 63 */
+ u32 q5txallowed:1; /* 62 */
+ u32 q5selarb:2; /* 61:60 */
+ u32 q6_sel:10; /* 59:50 */
+ u32 q6reqvld:1; /* 49 */
+ u32 q6txallowed:1; /* 48 */
+ u32 q6selarb:2; /* 47:46 */
+ u32 q7_sel:10; /* 45:36 */
+ u32 q7reqvld:1; /* 35 */
+ u32 q7txallowed:1; /* 34 */
+ u32 q7selarb:2; /* 33:32 */
+
+ /* register word 2 (bit 95:64) */
+ u32 q3_selL:4; /* 95:92 split 4/6 */
+ u32 q3reqvld:1; /* 91 */
+ u32 q3txallowed:1; /* 90 */
+ u32 q3selarb:2; /* 89:88 */
+ u32 q4_sel:10; /* 87:78 */
+ u32 q4reqvld:1; /* 77 */
+ u32 q4txallowed:1; /* 76 */
+ u32 q4selarb:2; /* 75:74 */
+ u32 q5_sel:10; /* 73:64 */
+
+ /* register word 3 (bit 127:96) */
+ u32 q1_selL:8; /* 127:120 split 2/8 */
+ u32 q1reqvld:1; /* 119 */
+ u32 q1txallowed:1; /* 118 */
+ u32 q1selarb:2; /* 117:116 */
+ u32 q2_sel:10; /* 115:106 */
+ u32 q2reqvld:1; /* 105 */
+ u32 q2txallowed:1; /* 104 */
+ u32 q2selarb:2; /* 103:102 */
+ u32 q3_selH:6; /* 101:96 split 4/6 */
+
+ /* register word 4 (bit 159:128) */
+ u32 resv1:11; /* 159:149 */
+ u32 cfgqtype:2; /* 148:147 queue type */
+ u32 cfgselthrsh:3; /* 146:144 associated threshold set */
+ u32 q0_sel:10; /* 143:134 */
+ u32 q0reqvld:1; /* 133 */
+ u32 q0txallowed:1; /* 132 */
+ u32 q0selarb:2; /* 131:130 */
+ u32 q1_selH:2; /* 129:128 split 2/8 */
+#else
+ /* register word 0 (bit 31:0) */
+ u32 nummsg:18; /* 17:0 */
+ u32 cfgsaben:1; /* 18 enable SAB broadcasting */
+ u32 cfgnotifyqne:1; /* 19 enable Q not empty intr */
+ u32 cfgcrid:1; /* 20 critical rid config */
+ u32 cpu_notify:8; /* 28:21 */
+ u32 rid:3; /* 31:29 */
+
+ /* register word 1 (bit 63:32) */
+ u32 q7selarb:2; /* 33:32 */
+ u32 q7txallowed:1; /* 34 */
+ u32 q7reqvld:1; /* 35 */
+ u32 q7_sel:10; /* 45:36 */
+ u32 q6selarb:2; /* 47:46 */
+ u32 q6txallowed:1; /* 48 */
+ u32 q6reqvld:1; /* 49 */
+ u32 q6_sel:10; /* 59:50 */
+ u32 q5selarb:2; /* 61:60 */
+ u32 q5txallowed:1; /* 62 */
+ u32 q5reqvld:1; /* 63 */
+
+ /* register word 2 (bit 95:64) */
+ u32 q5_sel:10; /* 73:64 */
+ u32 q4selarb:2; /* 75:74 */
+ u32 q4txallowed:1; /* 76 */
+ u32 q4reqvld:1; /* 77 */
+ u32 q4_sel:10; /* 87:78 */
+ u32 q3selarb:2; /* 89:88 */
+ u32 q3txallowed:1; /* 90 */
+ u32 q3reqvld:1; /* 91 */
+ u32 q3_selL:4; /* 95:92 split 4/6 */
+
+ /* register word 3 (bit 127:96) */
+ u32 q3_selH:6; /* 101:96 split 4/6 */
+ u32 q2selarb:2; /* 103:102 */
+ u32 q2txallowed:1; /* 104 */
+ u32 q2reqvld:1; /* 105 */
+ u32 q2_sel:10; /* 115:106 */
+ u32 q1selarb:2; /* 117:116 */
+ u32 q1txallowed:1; /* 118 */
+ u32 q1reqvld:1; /* 119 */
+ u32 q1_selL:8; /* 127:120 split 2/8 */
+
+ /* register word 4 (bit 159:128) */
+ u32 q1_selH:2; /* 129:128 split 2/8 */
+ u32 q0selarb:2; /* 131:130 */
+ u32 q0txallowed:1; /* 132 */
+ u32 q0reqvld:1; /* 133 */
+ u32 q0_sel:10; /* 143:134 */
+ u32 cfgselthrsh:3; /* 146:144 associated threshold set */
+ u32 cfgqtype:2; /* 148:147 queue type */
+ u32 resv1:11; /* 159:149 */
+#endif
+} __packed;
+
+union storm_qmtm_qstate {
+ struct storm_qmtm_csr_qstate csr;
+ struct storm_qmtm_pq_fp_qstate pq;
+ struct storm_qmtm_pq_fp_qstate fp;
+ struct storm_qmtm_vq_qstate vq;
+} __packed;
+
+/* Storm QMTM operations */
+static void storm_qmtm_write_qstate(struct xgene_mbox *mbox)
+{
+ struct xgene_qmtm *qmtm = mbox->qmtm;
+ struct storm_qmtm_csr_qstate *csr_qstate =
+ &((union storm_qmtm_qstate *)mbox->qstate)->csr;
+
+ /* write queue number */
+ xgene_qmtm_wr32(qmtm, CSR_QSTATE_ADDR, QNUMBER_WR(mbox->qid));
+
+ /* write queue state */
+ xgene_qmtm_wr32(qmtm, CSR_QSTATE_WR_0_ADDR, csr_qstate->w0);
+ xgene_qmtm_wr32(qmtm, CSR_QSTATE_WR_1_ADDR, csr_qstate->w1);
+ xgene_qmtm_wr32(qmtm, CSR_QSTATE_WR_2_ADDR, csr_qstate->w2);
+ xgene_qmtm_wr32(qmtm, CSR_QSTATE_WR_3_ADDR, csr_qstate->w3);
+ xgene_qmtm_wr32(qmtm, CSR_QSTATE_WR_4_ADDR, csr_qstate->w4);
+}
+
+static void storm_qmtm_set_qstate(struct xgene_mbox *mbox)
+{
+ struct storm_qmtm_pq_fp_qstate *pq_fp =
+ &((union storm_qmtm_qstate *)(mbox->qstate))->pq;
+
+ if (QMTM_QTYPE_VQ(mbox))
+ pq_fp->cfgqtype = QTYPE_VQ;
+ else if (QMTM_QTYPE_FP(mbox))
+ pq_fp->cfgqtype = QTYPE_FP;
+ else
+ pq_fp->cfgqtype = QTYPE_PQ;
+
+ /* if its a free queue, ask QMTM to set len to 0 when dealloc */
+ if (pq_fp->cfgqtype == QTYPE_FP)
+ pq_fp->fp_mode = CHANGE_LEN;
+
+ if (QMTM_SLAVE_ID(mbox) == QMTM_SLAVE_ID_ETH0 ||
+ QMTM_SLAVE_ID(mbox) == QMTM_SLAVE_ID_ETH1) {
+ pq_fp->cfgRecombBuf = 1;
+ pq_fp->cfgRecombBufTimeoutL = 0xf;
+ pq_fp->cfgRecombBufTimeoutH = 0x7;
+ }
+
+ pq_fp->cfgselthrsh = 1;
+ /* Allow the queue to accept message with non-zero LErr */
+ pq_fp->cfgacceptlerr = 1;
+ pq_fp->qcoherent = 1;
+ pq_fp->cfgstartaddrL = (u32)((mbox->dma >> 8) & (u32)(BIT(27) - 1));
+ pq_fp->cfgstartaddrH = (u32)(mbox->dma >> 35);
+ pq_fp->cfgqsize = mbox->slots;
+ storm_qmtm_write_qstate(mbox);
+}
+
+static void storm_qmtm_clr_qstate(struct xgene_mbox *mbox)
+{
+ memset(mbox->qstate, 0, sizeof(union storm_qmtm_qstate));
+ storm_qmtm_write_qstate(mbox);
+}
+
+static u32 storm_qmtm_read_level(void *qfabric)
+{
+ return (readl(&(((u32 *)qfabric)[1])) & 0x1fffe) >> 1;
+}
+
+static int storm_qmtm_init(struct xgene_qmtm *qmtm)
+{
+ int ret = 0, val;
+ xgene_qmtm_rd32(qmtm, CSR_IPBRR_ADDR, &val);
+ switch (val) {
+ case CSR_IPBRR_QMTM0_DEFAULT:
+ qmtm->qmtm_ip = QMTM0;
+ qmtm->irq_start = 0;
+ qmtm->irq_count = 16;
+ break;
+ case CSR_IPBRR_QMTM1_DEFAULT:
+ qmtm->qmtm_ip = QMTM1;
+ qmtm->irq_start = 0;
+ qmtm->irq_count = 32;
+ break;
+ case CSR_IPBRR_QMTM2_DEFAULT:
+ qmtm->qmtm_ip = QMTM2;
+ qmtm->irq_start = 16;
+ qmtm->irq_count = 16;
+ break;
+ case CSR_IPBRR_QMTM3_DEFAULT:
+ qmtm->qmtm_ip = QMTM3;
+ qmtm->irq_start = 0;
+ qmtm->irq_count = 1;
+ break;
+ default:
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+struct xgene_qmtm_ops storm_qmtm_ops = {
+ .init = storm_qmtm_init,
+ .set_qstate = storm_qmtm_set_qstate,
+ .clr_qstate = storm_qmtm_clr_qstate,
+ .read_level = storm_qmtm_read_level,
+};
diff --git a/include/linux/platform_data/xgene_qmtm.h b/include/linux/platform_data/xgene_qmtm.h
new file mode 100644
index 0000000..23e630c
--- /dev/null
+++ b/include/linux/platform_data/xgene_qmtm.h
@@ -0,0 +1,300 @@
+/*
+ * AppliedMicro X-Gene SoC Queue Manager/Traffic Manager driver
+ *
+ * Copyright (c) 2013 Applied Micro Circuits Corporation.
+ * Author: Ravi Patel <rapatel@apm.com>
+ * Keyur Chudgar <kchudgar@apm.com>
+ * Fushen Chen <fchen@apm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License 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.
+ */
+
+#ifndef __XGENE_QMTM_H__
+#define __XGENE_QMTM_H__
+
+/* QMTM Data Length encoded as per QM message format */
+enum xgene_mbox_data_len {
+ DATA_LEN_256B = 0x0100,
+ DATA_LEN_1K = 0x0400,
+ DATA_LEN_2K = 0x0800,
+ DATA_LEN_4K = 0x1000,
+ DATA_LEN_16K = 0x4000,
+};
+
+enum xgene_mbox_mask_len {
+ MASK_LEN_256B = (DATA_LEN_256B - 1),
+ MASK_LEN_1K = (DATA_LEN_1K - 1),
+ MASK_LEN_2K = (DATA_LEN_2K - 1),
+ MASK_LEN_4K = (DATA_LEN_4K - 1),
+ MASK_LEN_16K = (DATA_LEN_16K - 1),
+};
+
+/* QMTM Buffer Length encoded as per QM message format */
+enum xgene_mbox_buf_len {
+ BUF_LEN_256B = 0x7000,
+ BUF_LEN_1K = 0x6000,
+ BUF_LEN_2K = 0x5000,
+ BUF_LEN_4K = 0x4000,
+ BUF_LEN_16K = 0x0000,
+};
+
+/* QMTM messaging structures */
+/* 16 byte QMTM message format */
+struct xgene_mbox_msg16 {
+#ifdef CONFIG_CPU_BIG_ENDIAN
+ /* memory word 0 (bit 31:0) */
+ u32 UserInfo;
+
+ /* memory word 1 (bit 63:32) */
+ u32 HL:1;
+ u32 LErr:3;
+ u32 RType:4;
+ u32 IN:1;
+ u32 Rv:1;
+ u32 HB:1;
+ u32 PB:1;
+ u32 LL:1;
+ u32 NV:1;
+ u32 LEI:2;
+ u32 ELErr:2;
+ u32 Rv2:2;
+ u32 FPQNum:12;
+
+ /* memory word 2 (bit 95:64) */
+ u32 DataAddrL; /* split 10/32 */
+
+ /* memory word 3 (bit 127:96) */
+ u32 C:1;
+ u32 BufDataLen:15;
+ u32 Rv6:6;
+ u32 DataAddrH:10; /* split 10/32 */
+#else
+ /* memory word 0 (bit 31:0) */
+ u32 UserInfo;
+
+ /* memory word 1 (bit 63:32) */
+ u32 FPQNum:12;
+ u32 Rv2:2;
+ u32 ELErr:2;
+ u32 LEI:2;
+ u32 NV:1;
+ u32 LL:1;
+ u32 PB:1;
+ u32 HB:1;
+ u32 Rv:1;
+ u32 IN:1;
+ u32 RType:4;
+ u32 LErr:3;
+ u32 HL:1;
+
+ /* memory word 2 (bit 95:64) */
+ u32 DataAddrL; /* split 10/32 */
+
+ /* memory word 3 (bit 127:96) */
+ u32 DataAddrH:10; /* split 10/32 */
+ u32 Rv6:6;
+ u32 BufDataLen:15;
+ u32 C:1;
+#endif
+} __packed;
+
+/* Higher 16 byte portion of 32 byte of QMTM message format */
+struct xgene_mbox_msg16H {
+#ifdef CONFIG_CPU_BIG_ENDIAN
+ /* memory word 4 (bit 159:128) */
+ u32 H0Info_msbL; /* split 16/32 */
+
+ /* memory word 5 (bit 191:160) */
+ u32 HR:1;
+ u32 Rv0:1;
+ u32 DR:1;
+ u32 Rv1:1;
+ u32 TotDataLengthLinkListLSBs:12;
+ u16 H0Info_msbH; /* split 16/32 */
+
+ /* memory word 6 (bit 223:192) */
+ u32 H0Info_lsbL; /* split 16/32 */
+
+ /* memory word 7 (bit 255:224) */
+ u32 H0FPSel:4;
+ u32 H0Enq_Num:12;
+ u16 H0Info_lsbH; /* split 16/32 */
+#else
+ /* memory word 4 (bit 159:128) */
+ u32 H0Info_msbL; /* split 16/32 */
+
+ /* memory word 5 (bit 191:160) */
+ u16 H0Info_msbH; /* split 16/32 */
+ u32 TotDataLengthLinkListLSBs:12;
+ u32 Rv1:1;
+ u32 DR:1;
+ u32 Rv0:1;
+ u32 HR:1;
+
+ /* memory word 6 (bit 223:192) */
+ u32 H0Info_lsbL; /* split 16/32 */
+
+ /* memory word 7 (bit 255:224) */
+ u16 H0Info_lsbH; /* split 16/32 */
+ u32 H0Enq_Num:12;
+ u32 H0FPSel:4;
+#endif
+} __packed;
+
+/* 8 byte portion of QMTM extended (64B) message format */
+struct xgene_mbox_msg8 {
+#ifdef CONFIG_CPU_BIG_ENDIAN
+ u32 NxtDataAddrL;
+ u32 Rv1:1;
+ u32 NxtBufDataLength:15;
+ u32 NxtFPQNum:4;
+ u32 Rv2:2;
+ u32 NxtDataAddrH:10;
+#else
+ u32 NxtDataAddrL;
+ u32 NxtDataAddrH:10;
+ u32 Rv2:2;
+ u32 NxtFPQNum:4;
+ u32 NxtBufDataLength:15;
+ u32 Rv1:1;
+#endif
+} __packed;
+
+/* 8 byte Link list portion of QMTM extended (64B) message format */
+struct xgene_mbox_msg8_list {
+#ifdef CONFIG_CPU_BIG_ENDIAN
+ u32 NxtDataPtrL;
+ u8 TotDataLengthLinkListMSBs;
+ u8 NxtLinkListength;
+ u32 NxtFPQNum:4;
+ u32 Rv2:2;
+ u32 NxtDataPtrH:10;
+#else
+ u32 NxtDataPtrL;
+ u32 NxtDataPtrH:10;
+ u32 Rv2:2;
+ u32 NxtFPQNum:4;
+ u8 NxtLinkListength;
+ u8 TotDataLengthLinkListMSBs;
+#endif
+} __packed;
+
+/* This structure represents 32 byte QMTM message format */
+struct xgene_mbox_msg32 {
+ struct xgene_mbox_msg16 msg16;
+ struct xgene_mbox_msg16H msg16H;
+} __packed;
+
+ /* Higher 32 byte of QMTM extended (64B) message format */
+struct xgene_mbox_msg32H {
+ struct xgene_mbox_msg8 msg8_2;
+ struct xgene_mbox_msg8 msg8_1;
+ union {
+ struct xgene_mbox_msg8 msg8_4;
+ struct xgene_mbox_msg8_list msg8_list;
+ };
+ struct xgene_mbox_msg8 msg8_3;
+} __packed;
+
+/* 64 byte QMTM message format */
+struct xgene_mbox_msg64 {
+ struct xgene_mbox_msg32 msg32;
+ struct xgene_mbox_msg32H msg32H;
+} __packed;
+
+#ifdef CONFIG_CPU_BIG_ENDIAN
+#define xgene_mbox_msg_le32(word, words) \
+ do { \
+ int w; \
+ for (w = 0; w < words; w++) \
+ *(word + w) = cpu_to_le32(*(word + w)); \
+ } while (0)
+#else
+#define xgene_mbox_msg_le32(word, words) \
+ do {} while (0)
+#endif
+
+/* Empty Slot Soft Signature */
+#define EMPTY_SLOT_INDEX 7
+#define EMPTY_SLOT 0x22222222
+
+/* Encoding Destination QMTM (2 MSB) and Queue ID */
+#define QMTM_QUEUE_ID(q) (((u16)(q->qstate[6]) << 10) | q->qid)
+
+/* Decoding PBM signal */
+#define QMTM_PBN(q) (q->pbm & 0x003F)
+#define QMTM_SLAVE_ID(q) ((q->pbm & 0x03C0) >> 6)
+#define QMTM_QTYPE_FP(q) (q->pbm & 0x0020)
+#define QMTM_QTYPE_VQ(q) (q->pbm & 0x0400)
+
+/* Per queue state database */
+struct xgene_mbox {
+ u16 pbm;
+ u16 qid;
+ u16 qhead;
+ u16 qtail;
+ u16 slots;
+ u16 irq;
+ u32 qsize;
+ u32 pbm_state;
+ u32 qstate[7];
+ void *qfabric;
+ void *level;
+ dma_addr_t dma;
+ union {
+ void *qaddr;
+ struct xgene_mbox_msg16 *msg16;
+ struct xgene_mbox_msg32 *msg32;
+ };
+ struct xgene_qmtm *qmtm;
+};
+
+static inline u16 xgene_mbox_encode_bufdatalen(u32 len)
+{
+ if (len <= DATA_LEN_256B)
+ return BUF_LEN_256B | (len & MASK_LEN_256B);
+ else if (len <= DATA_LEN_1K)
+ return BUF_LEN_1K | (len & MASK_LEN_1K);
+ else if (len <= DATA_LEN_2K)
+ return BUF_LEN_2K | (len & MASK_LEN_2K);
+ else if (len <= DATA_LEN_4K)
+ return BUF_LEN_4K | (len & MASK_LEN_4K);
+ else if (len < DATA_LEN_16K)
+ return BUF_LEN_16K | (len & MASK_LEN_16K);
+ else
+ return BUF_LEN_16K;
+}
+
+static inline u16 xgene_mbox_encode_datalen(u32 len)
+{
+ return len & MASK_LEN_16K;
+}
+
+static inline u32 xgene_mbox_decode_datalen(u16 bufdatalen)
+{
+ switch (bufdatalen & BUF_LEN_256B) {
+ case BUF_LEN_256B:
+ return bufdatalen & MASK_LEN_256B ? : DATA_LEN_256B;
+ case BUF_LEN_1K:
+ return bufdatalen & MASK_LEN_1K ? : DATA_LEN_1K;
+ case BUF_LEN_2K:
+ return bufdatalen & MASK_LEN_2K ? : DATA_LEN_2K;
+ case BUF_LEN_4K:
+ return bufdatalen & MASK_LEN_4K ? : DATA_LEN_4K;
+ default:
+ return bufdatalen & MASK_LEN_16K ? : DATA_LEN_16K;
+ };
+}
+
+struct xgene_mbox *xgene_mbox_get(struct device *dev, const char *s);
+void xgene_mbox_put(struct xgene_mbox *mbox);
+u32 xgene_mbox_level(struct xgene_mbox *mbox);
+
+#endif /* __XGENE_QMTM_H__ */
--
1.7.9.5
^ permalink raw reply related
* [PATCH V3 4/4] arm64: boot: dts: entries for APM X-Gene SoC QMTM
From: Ravi Patel @ 2014-02-15 2:22 UTC (permalink / raw)
To: arnd, gregkh, davem
Cc: netdev, linux-kernel, devicetree, linux-arm-kernel, jcm, patches,
Ravi Patel, Keyur Chudgar
In-Reply-To: <1392430922-24643-1-git-send-email-rapatel@apm.com>
This patch adds APM X-Gene SoC Queue Manager/Traffic Manager DTS entries.
Signed-off-by: Ravi Patel <rapatel@apm.com>
Signed-off-by: Keyur Chudgar <kchudgar@apm.com>
---
arch/arm64/boot/dts/apm-storm.dtsi | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/apm-storm.dtsi b/arch/arm64/boot/dts/apm-storm.dtsi
index d37d736..70b2725 100644
--- a/arch/arm64/boot/dts/apm-storm.dtsi
+++ b/arch/arm64/boot/dts/apm-storm.dtsi
@@ -148,10 +148,15 @@
compatible = "apm,xgene-device-clock";
#clock-cells = <1>;
clocks = <&socplldiv2 0>;
- clock-names = "qmlclk";
+ clock-names = "socplldiv2";
reg = <0x0 0x1703C000 0x0 0x1000>;
reg-names = "csr-reg";
clock-output-names = "qmlclk";
+ status = "ok";
+ csr-offset = <0x0>;
+ csr-mask = <0x3>;
+ enable-offset = <0x8>;
+ enable-mask = <0x3>;
};
ethclk: ethclk {
@@ -187,5 +192,16 @@
interrupt-parent = <&gic>;
interrupts = <0x0 0x4c 0x4>;
};
+
+ qmlite: mailbox@17030000 {
+ compatible = "apm,xgene-qmtm";
+ #mailbox-cells = <4>;
+ status = "ok";
+ reg = <0x0 0x17030000 0x0 0x10000>,
+ <0x0 0x10000000 0x0 0x400000>;
+ interrupts = <0x0 0x40 0x4>,
+ <0x0 0x3c 0x4>;
+ clocks = <&qmlclk 0>;
+ };
};
};
--
1.7.9.5
^ permalink raw reply related
* Re: [PATCH net-next 0/7] clear old options when old qdisc's replaced
From: Eric Dumazet @ 2014-02-15 2:53 UTC (permalink / raw)
To: Yang Yingliang; +Cc: netdev, davem, stephen
In-Reply-To: <52FECEF6.2070605@huawei.com>
On Sat, 2014-02-15 at 10:20 +0800, Yang Yingliang wrote:
> On 2014/2/14 20:44, Eric Dumazet wrote:
> > On Fri, 2014-02-14 at 16:36 +0800, Yang Yingliang wrote:
> >> I've added a netem qdisc with rate option, then I replace this qdisc
> >> without rate option but with latency option. The rate option is still
> >> there.
> >>
> >> E.g.
> >> # tc qdisc add dev eth4 handle 1: root netem rate 10mbit
> >> # tc qdisc show
> >> qdisc netem 1: dev eth4 root refcnt 2 limit 1000 rate 10Mbit
> >>
> >> # tc qdisc replace dev eth4 handle 1: root netem latency 10ms
> >> # tc qdisc show
> >> qdisc netem 1: dev eth4 root refcnt 2 limit 1000 delay 10.0ms rate 10Mbit
> >>
> >> The old options need be cleared after the qdisc is replaced.
> >
> > Not at all. Test your changes with "tc qdisc change ... "
> >
> >
> With "tc qdisc change ... ", it will only change the options that specified in command.
> It's proper, I think.
>
> # tc qdisc add dev eth4 handle 1: root netem rate 10mbit
> # tc qdisc show
> qdisc netem 1: dev eth4 root refcnt 2 limit 1000 rate 10Mbit
>
> # tc qdisc replace dev eth4 handle 1: root netem latency 10ms
> # tc qdisc show
> qdisc netem 1: dev eth4 root refcnt 2 limit 1000 delay 10.0ms rate 10Mbit
>
> "rate" is not cleared.
>
> But with other qdiscs, such as tbf and htb etc, their usage not complete same as netem's,
> when we use "tc qdisc change ... ", the old options will be cleared. Maybe we should make
> their useages of "change" same as netem's?
qdisc change should only change the parameters you specified in the
command line.
For example, if I want to change my fq qdisc pacing I use :
tc qdisc change dev eth0 root fq pacing
or
tc qdisc change dev eth0 root fq nopacing
In your patches, you for example clear ecn if not specified, its wrong.
if (tb[TCA_NETEM_ECN])
q->ecn = nla_get_u32(tb[TCA_NETEM_ECN]);
+ else
+ q->ecn = 0;
^ permalink raw reply
* [RFC v2 0/4] net: bridge / ip optimizations for virtual net backends
From: Luis R. Rodriguez @ 2014-02-15 2:59 UTC (permalink / raw)
To: netdev; +Cc: xen-devel, kvm, linux-kernel, Luis R. Rodriguez
From: "Luis R. Rodriguez" <mcgrof@suse.com>
This v2 series changes the approach from my original virtualization
multicast patch series [0] by abandoning completely the multicast
issues and instead generalizing an approach for virtualization
backends. There are two things in common with virtualization
backends:
0) they should not become the root bridge
1) they don't need ipv4 / ipv6 interfaces
Both qemu's usage of TAP interfaces and xen-netback's driver
avoid getting their interfaces added to the root bridge by
using a high MAC address. Lets just generalize the solution
by making this a flag.
The skipping of IPv4 / IPv6 interfaces is an optimization
I observed possible while studying the xen-netback in a
shared physical bridge environment. I haven't been able
to test the NAT environment so I appreciate it if someone
can test these patches for that case if I don't get to it
eventually.
The same flags can be embraced by TAP interfaces when needed,
I tested this as a temporary patch as follows:
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 44c4db8..19b967e 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -940,6 +940,7 @@ static void tun_net_init(struct net_device *dev)
ether_setup(dev);
dev->priv_flags &= ~IFF_TX_SKB_SHARING;
dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
+ dev->priv_flags |= IFF_BRIDGE_NON_ROOT | IFF_SKIP_IP;
eth_hw_addr_random(dev);
a proper followup would be to specify the flags during open() or any
way prior, just to register_netdevice(). Before that is done we'd
need to evaluate all qemu use cases of the TAP interfaces both
for the xen HVM case (which tests fine for me) and for KVM's
use cases on both shared physical and in the NAT case. That is,
test the above patch and this series for all KVM / xen use cases.
[0] http://marc.info/?l=linux-netdev&m=139207142110536&w=2
Luis R. Rodriguez (4):
bridge: enable interfaces to opt out from becoming the root bridge
net: enables interface option to skip IP
xen-netback: use a random MAC address
xen-netback: skip IPv4 and IPv6 interfaces
drivers/net/xen-netback/interface.c | 14 +++++---------
include/uapi/linux/if.h | 2 ++
net/bridge/br_if.c | 2 ++
net/bridge/br_private.h | 1 +
net/bridge/br_stp_if.c | 2 ++
net/ipv4/devinet.c | 3 +++
net/ipv6/addrconf.c | 6 ++++++
7 files changed, 21 insertions(+), 9 deletions(-)
--
1.8.5.2
^ permalink raw reply related
* [RFC v2 1/4] bridge: enable interfaces to opt out from becoming the root bridge
From: Luis R. Rodriguez @ 2014-02-15 2:59 UTC (permalink / raw)
To: netdev
Cc: kvm, Luis R. Rodriguez, bridge, linux-kernel, Stephen Hemminger,
xen-devel
In-Reply-To: <1392433180-16052-1-git-send-email-mcgrof@do-not-panic.com>
From: "Luis R. Rodriguez" <mcgrof@suse.com>
It doesn't make sense for some interfaces to become a root bridge
at any point in time. One example is virtual backend interfaces
which rely on other entities on the bridge for actual physical
connectivity. They only provide virtual access.
Device drivers that know they should never become part of the
root bridge have been using a trick of setting their MAC address
to a high broadcast MAC address such as FE:FF:FF:FF:FF:FF. Instead
of using these hacks lets the interfaces annotate its intent and
generalizes a solution for multiple drivers, while letting the
drivers use a random MAC address or one prefixed with a proper OUI.
This sort of hack is used by both qemu and xen for their backend
interfaces.
Cc: Stephen Hemminger <stephen@networkplumber.org>
Cc: bridge@lists.linux-foundation.org
Cc: netdev@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Luis R. Rodriguez <mcgrof@suse.com>
---
include/uapi/linux/if.h | 1 +
net/bridge/br_if.c | 2 ++
net/bridge/br_private.h | 1 +
net/bridge/br_stp_if.c | 2 ++
4 files changed, 6 insertions(+)
diff --git a/include/uapi/linux/if.h b/include/uapi/linux/if.h
index d758163..8d10382 100644
--- a/include/uapi/linux/if.h
+++ b/include/uapi/linux/if.h
@@ -84,6 +84,7 @@
#define IFF_LIVE_ADDR_CHANGE 0x100000 /* device supports hardware address
* change when it's running */
#define IFF_MACVLAN 0x200000 /* Macvlan device */
+#define IFF_BRIDGE_NON_ROOT 0x400000 /* Don't consider for root bridge */
#define IF_GET_IFACE 0x0001 /* for querying only */
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index 4bf02ad..a745415 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -228,6 +228,8 @@ static struct net_bridge_port *new_nbp(struct net_bridge *br,
br_init_port(p);
p->state = BR_STATE_DISABLED;
br_stp_port_timer_init(p);
+ if (dev->priv_flags & IFF_BRIDGE_NON_ROOT)
+ p->flags |= BR_DONT_ROOT;
br_multicast_add_port(p);
return p;
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 045d56e..a89e8ad 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -173,6 +173,7 @@ struct net_bridge_port
#define BR_ADMIN_COST 0x00000010
#define BR_LEARNING 0x00000020
#define BR_FLOOD 0x00000040
+#define BR_DONT_ROOT 0x00000080
#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
struct bridge_mcast_query ip4_query;
diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c
index 656a6f3..12fd848 100644
--- a/net/bridge/br_stp_if.c
+++ b/net/bridge/br_stp_if.c
@@ -228,6 +228,8 @@ bool br_stp_recalculate_bridge_id(struct net_bridge *br)
return false;
list_for_each_entry(p, &br->port_list, list) {
+ if (p->flags & BR_DONT_ROOT)
+ continue;
if (addr == br_mac_zero ||
memcmp(p->dev->dev_addr, addr, ETH_ALEN) < 0)
addr = p->dev->dev_addr;
--
1.8.5.2
^ permalink raw reply related
* [RFC v2 2/4] net: enables interface option to skip IP
From: Luis R. Rodriguez @ 2014-02-15 2:59 UTC (permalink / raw)
To: netdev
Cc: kvm, Patrick McHardy, Hideaki YOSHIFUJI, Luis R. Rodriguez,
linux-kernel, James Morris, Alexey Kuznetsov, xen-devel,
David S. Miller
In-Reply-To: <1392433180-16052-1-git-send-email-mcgrof@do-not-panic.com>
From: "Luis R. Rodriguez" <mcgrof@suse.com>
Some interfaces do not need to have any IPv4 or IPv6
addresses, so enable an option to specify this. One
example where this is observed are virtualization
backend interfaces which just use the net_device
constructs to help with their respective frontends.
This should optimize boot time and complexity on
virtualization environments for each backend interface
while also avoiding triggering SLAAC and DAD, which is
simply pointless for these type of interfaces.
Cc: "David S. Miller" <davem@davemloft.net>
cC: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
Cc: James Morris <jmorris@namei.org>
Cc: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org>
Cc: Patrick McHardy <kaber@trash.net>
Cc: netdev@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Luis R. Rodriguez <mcgrof@suse.com>
---
include/uapi/linux/if.h | 1 +
net/ipv4/devinet.c | 3 +++
net/ipv6/addrconf.c | 6 ++++++
3 files changed, 10 insertions(+)
diff --git a/include/uapi/linux/if.h b/include/uapi/linux/if.h
index 8d10382..566d856 100644
--- a/include/uapi/linux/if.h
+++ b/include/uapi/linux/if.h
@@ -85,6 +85,7 @@
* change when it's running */
#define IFF_MACVLAN 0x200000 /* Macvlan device */
#define IFF_BRIDGE_NON_ROOT 0x400000 /* Don't consider for root bridge */
+#define IFF_SKIP_IP 0x800000 /* Skip IPv4, IPv6 */
#define IF_GET_IFACE 0x0001 /* for querying only */
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index a1b5bcb..8e9ef07 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -1342,6 +1342,9 @@ static int inetdev_event(struct notifier_block *this, unsigned long event,
ASSERT_RTNL();
+ if (dev->priv_flags & IFF_SKIP_IP)
+ goto out;
+
if (!in_dev) {
if (event == NETDEV_REGISTER) {
in_dev = inetdev_init(dev);
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 4b6b720..57f58e3 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -314,6 +314,9 @@ static struct inet6_dev *ipv6_add_dev(struct net_device *dev)
ASSERT_RTNL();
+ if (dev->priv_flags & IFF_SKIP_IP)
+ return NULL;
+
if (dev->mtu < IPV6_MIN_MTU)
return NULL;
@@ -2749,6 +2752,9 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
int run_pending = 0;
int err;
+ if (dev->priv_flags & IFF_SKIP_IP)
+ return NOTIFY_OK;
+
switch (event) {
case NETDEV_REGISTER:
if (!idev && dev->mtu >= IPV6_MIN_MTU) {
--
1.8.5.2
^ permalink raw reply related
* [RFC v2 3/4] xen-netback: use a random MAC address
From: Luis R. Rodriguez @ 2014-02-15 2:59 UTC (permalink / raw)
To: netdev
Cc: xen-devel, kvm, linux-kernel, Luis R. Rodriguez, Paul Durrant,
Ian Campbell, Wei Liu
In-Reply-To: <1392433180-16052-1-git-send-email-mcgrof@do-not-panic.com>
From: "Luis R. Rodriguez" <mcgrof@suse.com>
The purpose of using a static MAC address of FE:FF:FF:FF:FF:FF
was to prevent our backend interfaces from being used by the
bridge and nominating our interface as a root bridge. This was
possible given that the bridge code will use the lowest MAC
address for a port once a new interface gets added to the bridge.
The bridge code has a generic feature now to allow interfaces
to opt out from root bridge nominations, use that instead.
Cc: Paul Durrant <Paul.Durrant@citrix.com>
Cc: Ian Campbell <ian.campbell@citrix.com>
Cc: Wei Liu <wei.liu2@citrix.com>
Cc: xen-devel@lists.xenproject.org
Cc: netdev@vger.kernel.org
Signed-off-by: Luis R. Rodriguez <mcgrof@suse.com>
---
drivers/net/xen-netback/interface.c | 14 +++++---------
1 file changed, 5 insertions(+), 9 deletions(-)
diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c
index fff8cdd..d380e3f 100644
--- a/drivers/net/xen-netback/interface.c
+++ b/drivers/net/xen-netback/interface.c
@@ -42,6 +42,8 @@
#define XENVIF_QUEUE_LENGTH 32
#define XENVIF_NAPI_WEIGHT 64
+static const u8 xen_oui[3] = { 0x00, 0x16, 0x3e };
+
int xenvif_schedulable(struct xenvif *vif)
{
return netif_running(vif->dev) && netif_carrier_ok(vif->dev);
@@ -347,15 +349,9 @@ struct xenvif *xenvif_alloc(struct device *parent, domid_t domid,
for (i = 0; i < MAX_PENDING_REQS; i++)
vif->mmap_pages[i] = NULL;
- /*
- * Initialise a dummy MAC address. We choose the numerically
- * largest non-broadcast address to prevent the address getting
- * stolen by an Ethernet bridge for STP purposes.
- * (FE:FF:FF:FF:FF:FF)
- */
- memset(dev->dev_addr, 0xFF, ETH_ALEN);
- dev->dev_addr[0] &= ~0x01;
-
+ eth_hw_addr_random(dev);
+ memcpy(dev->dev_addr, xen_oui, 3);
+ dev->priv_flags |= IFF_BRIDGE_NON_ROOT;
netif_napi_add(dev, &vif->napi, xenvif_poll, XENVIF_NAPI_WEIGHT);
netif_carrier_off(dev);
--
1.8.5.2
^ permalink raw reply related
* [RFC v2 4/4] xen-netback: skip IPv4 and IPv6 interfaces
From: Luis R. Rodriguez @ 2014-02-15 2:59 UTC (permalink / raw)
To: netdev
Cc: xen-devel, kvm, linux-kernel, Luis R. Rodriguez, Paul Durrant,
Ian Campbell, Wei Liu
In-Reply-To: <1392433180-16052-1-git-send-email-mcgrof@do-not-panic.com>
From: "Luis R. Rodriguez" <mcgrof@suse.com>
The xen-netback driver is used only to provide a backend
interface for the frontend. The link is the only thing we
use, and that is used internally for letting us know when the
xen-netfront is ready, when it switches to XenbusStateConnected.
Note that only when the both the xen-netfront and xen-netback
are both in state XenbusStateConnected will xen-netback allow
userspace on the host (backend) to bring up the interface. Enabling
and disabling the interface will simply enable or disable NAPI
respectively, and that's used for IRQ communication set up with
the xen event channels.
Cc: Paul Durrant <Paul.Durrant@citrix.com>
Cc: Ian Campbell <ian.campbell@citrix.com>
Cc: Wei Liu <wei.liu2@citrix.com>
Cc: xen-devel@lists.xenproject.org
Cc: netdev@vger.kernel.org
Signed-off-by: Luis R. Rodriguez <mcgrof@suse.com>
---
drivers/net/xen-netback/interface.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c
index d380e3f..07e6fd2 100644
--- a/drivers/net/xen-netback/interface.c
+++ b/drivers/net/xen-netback/interface.c
@@ -351,7 +351,7 @@ struct xenvif *xenvif_alloc(struct device *parent, domid_t domid,
eth_hw_addr_random(dev);
memcpy(dev->dev_addr, xen_oui, 3);
- dev->priv_flags |= IFF_BRIDGE_NON_ROOT;
+ dev->priv_flags |= IFF_BRIDGE_NON_ROOT | IFF_SKIP_IP;
netif_napi_add(dev, &vif->napi, xenvif_poll, XENVIF_NAPI_WEIGHT);
netif_carrier_off(dev);
--
1.8.5.2
^ permalink raw reply related
* Re: [Patch net-next] openvswitch: rename ->sync to ->syncp
From: David Miller @ 2014-02-15 7:06 UTC (permalink / raw)
To: xiyou.wangcong; +Cc: netdev
In-Reply-To: <1392419446-4559-1-git-send-email-xiyou.wangcong@gmail.com>
From: Cong Wang <xiyou.wangcong@gmail.com>
Date: Fri, 14 Feb 2014 15:10:46 -0800
> Openvswitch defines u64_stats_sync as ->sync rather than ->syncp,
> so fails to compile with netdev_alloc_pcpu_stats(). So just rename it to ->syncp.
>
> Reported-by: kbuild test robot <fengguang.wu@intel.com>
> Fixes: 1c213bd24ad04f4430031 (net: introduce netdev_alloc_pcpu_stats() for drivers)
> Cc: David S. Miller <davem@davemloft.net>
> Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
Applied, thanks.
^ permalink raw reply
* [PATCH 3/3] caif: delete unnecessary field initialization
From: Julia Lawall @ 2014-02-15 7:36 UTC (permalink / raw)
To: Dmitry Tarnyagin; +Cc: kernel-janitors, netdev, linux-kernel
From: Julia Lawall <Julia.Lawall@lip6.fr>
On success, the function netdev_alloc_skb initializes the dev field of its
result to its first argument, so this doesn't have to be done in the
calling context.
The semantic patch that fixes this problem is as follows:
(http://coccinelle.lip6.fr/)
// <smpl>
@@
expression skb,privn,e;
@@
skb = netdev_alloc_skb(privn,...);
... when strict
(
-skb->dev = privn;
|
?skb = e
)
// </smpl>
Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr>
---
drivers/net/caif/caif_serial.c | 1 -
drivers/net/caif/caif_spi.c | 1 -
2 files changed, 2 deletions(-)
diff --git a/drivers/net/caif/caif_serial.c b/drivers/net/caif/caif_serial.c
index 88a6a58..fc73865 100644
--- a/drivers/net/caif/caif_serial.c
+++ b/drivers/net/caif/caif_serial.c
@@ -204,7 +204,6 @@ static void ldisc_receive(struct tty_struct *tty, const u8 *data,
skb->protocol = htons(ETH_P_CAIF);
skb_reset_mac_header(skb);
- skb->dev = ser->dev;
debugfs_rx(ser, data, count);
/* Push received packet up the stack. */
ret = netif_rx_ni(skb);
diff --git a/drivers/net/caif/caif_spi.c b/drivers/net/caif/caif_spi.c
index 155db68..ff54c0e 100644
--- a/drivers/net/caif/caif_spi.c
+++ b/drivers/net/caif/caif_spi.c
@@ -554,7 +554,6 @@ int cfspi_rxfrm(struct cfspi *cfspi, u8 *buf, size_t len)
skb->protocol = htons(ETH_P_CAIF);
skb_reset_mac_header(skb);
- skb->dev = cfspi->ndev;
/*
* Push received packet up the stack.
^ permalink raw reply related
* Re: fe80::/64 route missing on GRE tunnels
From: Hannes Frederic Sowa @ 2014-02-15 7:45 UTC (permalink / raw)
To: netdev, itk-intern
In-Reply-To: <20140211215928.GA7862@sesse.net>
On Tue, Feb 11, 2014 at 10:59:28PM +0100, Steinar H. Gunderson wrote:
> On Tue, Feb 11, 2014 at 10:55:11PM +0100, Steinar H. Gunderson wrote:
> > but on 3.13.1, no such route shows up. I can add it manually, though.
>
> Correction; I can add it manually, but only to one GRE device at a time:
>
> root@altersex:~$ ip -6 route add fe80::/64 dev k_molvenfinnoy
> root@altersex:~$ ip -6 route add fe80::/64 dev k_sessesveits
> RTNETLINK answers: File exists
> root@altersex:~$ ip -6 route del fe80::/64 dev k_molvenfinnoy
> root@altersex:~$ ip -6 route add fe80::/64 dev k_sessesveits
> root@altersex:~$
Sorry for the long delay, I was busy with other stuff...
So basically a workaround you can do for the time being is to add the tunnel
with a local address:
ip tunnel add foo mode gre local 4.3.2.1 remote 1.2.3.4 ttl 64
The reason is that link local address generation fails in ipv6/addrconf as
long as dev->dev_addr is zero.
I have not yet found the change which causes this change in behaviour, but
will do so soon.
Bye,
Hannes
^ permalink raw reply
* Re: [PATCH 10/13] staging: r8188eu: Remove wrapper _enter_critical_mutex()
From: Dan Carpenter @ 2014-02-15 10:41 UTC (permalink / raw)
To: Larry Finger; +Cc: gregkh, devel, netdev
In-Reply-To: <1392418457-3203-11-git-send-email-Larry.Finger@lwfinger.net>
On Fri, Feb 14, 2014 at 04:54:14PM -0600, Larry Finger wrote:
> diff --git a/drivers/staging/rtl8188eu/hal/usb_ops_linux.c b/drivers/staging/rtl8188eu/hal/usb_ops_linux.c
> index 1fa5370..d5f6a32 100644
> --- a/drivers/staging/rtl8188eu/hal/usb_ops_linux.c
> +++ b/drivers/staging/rtl8188eu/hal/usb_ops_linux.c
> @@ -49,7 +49,9 @@ static int usbctrl_vendorreq(struct intf_hdl *pintfhdl, u8 request, u16 value, u
> goto exit;
> }
>
> - _enter_critical_mutex(&dvobjpriv->usb_vendor_req_mutex, NULL);
> + if (mutex_lock_interruptible(&dvobjpriv->usb_vendor_req_mutex))
> + status = -ENOMEM;
> + goto exit;
>
Missing curly braces.
regards,
dan carpenter
^ permalink raw reply
* [PATCH] Drivers: net: wireless: mac80211_hwim fixed coding style issues
From: Justin van Wijngaarden @ 2014-02-15 11:55 UTC (permalink / raw)
To: linville; +Cc: netdev, linux-kernel, linux-wireless, Justin van Wijngaarden
Fixed a few coding style issues, things like comments and braces.
Signed-off-by: Justin van Wijngaarden <justinvanwijngaarden@gmail.com>
---
drivers/net/wireless/mac80211_hwsim.c | 101 ++++++++++++++++------------------
1 file changed, 47 insertions(+), 54 deletions(-)
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 69d4c31..4a1ce5b 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -1,19 +1,17 @@
-/*
- * mac80211_hwsim - software simulator of 802.11 radio(s) for mac80211
+/* mac80211_hwsim - software simulator of 802.11 radio(s) for mac80211
* Copyright (c) 2008, Jouni Malinen <j@w1.fi>
* Copyright (c) 2011, Javier Lopez <jlopex@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
- */
+*/
-/*
- * TODO:
+/* TODO:
* - Add TSF sync and fix IBSS beacon transmission by adding
* competition for "air time" at TBTT
* - RX filtering based on filter configuration (data->rx_filter)
- */
+*/
#include <linux/list.h>
#include <linux/slab.h>
@@ -49,11 +47,11 @@ static int channels = 1;
module_param(channels, int, 0444);
MODULE_PARM_DESC(channels, "Number of concurrent channels");
-static bool paged_rx = false;
+static bool paged_rx;
module_param(paged_rx, bool, 0644);
MODULE_PARM_DESC(paged_rx, "Use paged SKBs for RX instead of linear ones");
-static bool rctbl = false;
+static bool rctbl;
module_param(rctbl, bool, 0444);
MODULE_PARM_DESC(rctbl, "Handle rate control table");
@@ -70,27 +68,27 @@ MODULE_PARM_DESC(rctbl, "Handle rate control table");
* and all possible combinations.
*
* @HWSIM_REGTEST_DISABLED: No regulatory tests are performed,
- * this is the default value.
+ * this is the default value.
* @HWSIM_REGTEST_DRIVER_REG_FOLLOW: Used for testing the driver regulatory
* hint, only one driver regulatory hint will be sent as such the
- * secondary radios are expected to follow.
+ * secondary radios are expected to follow.
* @HWSIM_REGTEST_DRIVER_REG_ALL: Used for testing the driver regulatory
- * request with all radios reporting the same regulatory domain.
+ * request with all radios reporting the same regulatory domain.
* @HWSIM_REGTEST_DIFF_COUNTRY: Used for testing the drivers calling
- * different regulatory domains requests. Expected behaviour is for
- * an intersection to occur but each device will still use their
- * respective regulatory requested domains. Subsequent radios will
- * use the resulting intersection.
+ * different regulatory domains requests. Expected behaviour is for
+ * an intersection to occur but each device will still use their
+ * respective regulatory requested domains. Subsequent radios will
+ * use the resulting intersection.
* @HWSIM_REGTEST_WORLD_ROAM: Used for testing the world roaming. We accomplish
* this by using a custom beacon-capable regulatory domain for the first
* radio. All other device world roam.
* @HWSIM_REGTEST_CUSTOM_WORLD: Used for testing the custom world regulatory
- * domain requests. All radios will adhere to this custom world regulatory
- * domain.
+ * domain requests. All radios will adhere to this custom world regulatory
+ * domain.
* @HWSIM_REGTEST_CUSTOM_WORLD_2: Used for testing 2 custom world regulatory
- * domain requests. The first radio will adhere to the first custom world
- * regulatory domain, the second one to the second custom world regulatory
- * domain. All other devices will world roam.
+ * domain requests. The first radio will adhere to the first custom world
+ * regulatory domain, the second one to the second custom world regulatory
+ * domain. All other devices will world roam.
* @HWSIM_REGTEST_STRICT_FOLLOW_: Used for testing strict regulatory domain
* settings, only the first radio will send a regulatory domain request
* and use strict settings. The rest of the radios are expected to follow.
@@ -104,15 +102,15 @@ MODULE_PARM_DESC(rctbl, "Handle rate control table");
* other devices should follow the intersection created between the
* first two.
* @HWSIM_REGTEST_ALL: Used for testing every possible mix. You will need
- * at least 6 radios for a complete test. We will test in this order:
- * 1 - driver custom world regulatory domain
- * 2 - second custom world regulatory domain
- * 3 - first driver regulatory domain request
- * 4 - second driver regulatory domain request
- * 5 - strict regulatory domain settings using the third driver regulatory
- * domain request
- * 6 and on - should follow the intersection of the 3rd, 4rth and 5th radio
- * regulatory requests.
+ * at least 6 radios for a complete test. We will test in this order:
+ * 1 - driver custom world regulatory domain
+ * 2 - second custom world regulatory domain
+ * 3 - first driver regulatory domain request
+ * 4 - second driver regulatory domain request
+ * 5 - strict regulatory domain settings using the third driver regulatory
+ * domain request
+ * 6 and on - should follow the intersection of the 3rd, 4rth and 5th radio
+ * regulatory requests.
*/
enum hwsim_regtest {
HWSIM_REGTEST_DISABLED = 0,
@@ -406,8 +404,7 @@ struct mac80211_hwsim_data {
struct dentry *debugfs;
struct sk_buff_head pending; /* packets pending */
- /*
- * Only radios in the same group can communicate together (the
+ /* Only radios in the same group can communicate together (the
* channel has to match too). Each bit represents a group. A
* radio can be in more then one group.
*/
@@ -764,11 +761,13 @@ static bool hwsim_ps_rx_ok(struct mac80211_hwsim_data *data,
return false;
case PS_AUTO_POLL:
/* TODO: accept (some) Beacons by default and other frames only
- * if pending PS-Poll has been sent */
+ * if pending PS-Poll has been sent
+ */
return true;
case PS_MANUAL_POLL:
/* Allow unicast frames to own address if there is a pending
- * PS-Poll */
+ * PS-Poll
+ */
if (data->ps_poll_pending &&
memcmp(data->hw->wiphy->perm_addr, skb->data + 4,
ETH_ALEN) == 0) {
@@ -856,7 +855,8 @@ static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw,
goto nla_put_failure;
/* We get the flags for this transmission, and we translate them to
- wmediumd flags */
+ * wmediumd flags
+ */
if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS)
hwsim_flags |= HWSIM_TX_CTL_REQ_TX_STATUS;
@@ -966,8 +966,7 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw,
secpath_reset(skb);
nf_reset(skb);
- /*
- * Get absolute mactime here so all HWs RX at the "same time", and
+ /* Get absolute mactime here so all HWs RX at the "same time", and
* absolute TX time for beacon mactime so the timestamp matches.
* Giving beacons a different mactime than non-beacons looks messy, but
* it helps the Toffset be exact and a ~10us mactime discrepancy
@@ -1007,8 +1006,7 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw,
continue;
}
- /*
- * reserve some space for our vendor and the normal
+ /* reserve some space for our vendor and the normal
* radiotap header, since we're copying anyway
*/
if (skb->len < PAGE_SIZE && paged_rx) {
@@ -1036,8 +1034,7 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw,
rx_status.mactime = now + data2->tsf_offset;
#if 0
- /*
- * Don't enable this code by default as the OUI 00:00:00
+ /* Don't enable this code by default as the OUI 00:00:00
* is registered to Xerox so we shouldn't use it here, it
* might find its way into pcap files.
* Note that this code requires the headroom in the SKB
@@ -1047,8 +1044,7 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw,
rx_status.vendor_radiotap_oui[1] = 0x00;
rx_status.vendor_radiotap_oui[2] = 0x00;
rx_status.vendor_radiotap_subns = 127;
- /*
- * Radiotap vendor namespaces can (and should) also be
+ /* Radiotap vendor namespaces can (and should) also be
* split into fields by using the standard radiotap
* presence bitmap mechanism. Use just BIT(0) here for
* the presence bitmap.
@@ -1197,8 +1193,7 @@ static int mac80211_hwsim_change_interface(struct ieee80211_hw *hw,
newtype, vif->addr);
hwsim_check_magic(vif);
- /*
- * interface may change from non-AP to AP in
+ /* interface may change from non-AP to AP in
* which case this needs to be set up again
*/
vif->cab_queue = 0;
@@ -1371,7 +1366,7 @@ static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed)
static void mac80211_hwsim_configure_filter(struct ieee80211_hw *hw,
unsigned int changed_flags,
- unsigned int *total_flags,u64 multicast)
+ unsigned int *total_flags, u64 multicast)
{
struct mac80211_hwsim_data *data = hw->priv;
@@ -1465,9 +1460,8 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw,
info->use_short_preamble);
}
- if (changed & BSS_CHANGED_ERP_SLOT) {
+ if (changed & BSS_CHANGED_ERP_SLOT)
wiphy_debug(hw->wiphy, " ERP_SLOT: %d\n", info->use_short_slot);
- }
if (changed & BSS_CHANGED_HT) {
wiphy_debug(hw->wiphy, " HT: op_mode=0x%x\n",
@@ -1556,8 +1550,7 @@ static int mac80211_hwsim_get_survey(
/* Current channel */
survey->channel = conf->chandef.chan;
- /*
- * Magically conjured noise level --- this is only ok for simulated hardware.
+ /* Magically conjured noise level --- this is only ok for simulated hardware.
*
* A real driver which cannot determine the real channel noise MUST NOT
* report any noise, especially not a magically conjured one :-)
@@ -1569,8 +1562,7 @@ static int mac80211_hwsim_get_survey(
}
#ifdef CONFIG_NL80211_TESTMODE
-/*
- * This section contains example code for using netlink
+/* This section contains example code for using netlink
* attributes with the testmode command in nl80211.
*/
@@ -2191,9 +2183,9 @@ static void mac80211_hwsim_free(void)
}
static const struct net_device_ops hwsim_netdev_ops = {
- .ndo_start_xmit = hwsim_mon_xmit,
+ .ndo_start_xmit = hwsim_mon_xmit,
.ndo_change_mtu = eth_change_mtu,
- .ndo_set_mac_address = eth_mac_addr,
+ .ndo_set_mac_address = eth_mac_addr,
.ndo_validate_addr = eth_validate_addr,
};
@@ -2274,7 +2266,8 @@ static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2,
goto out;
/* Tx info received because the frame was broadcasted on user space,
- so we get all the necessary info: tx attempts and skb control buff */
+ * so we get all the necessary info: tx attempts and skb control buff
+ */
tx_attempts = (struct hwsim_tx_rate *)nla_data(
info->attrs[HWSIM_ATTR_TX_INFO]);
--
1.9.rc1
^ permalink raw reply related
* Re: fe80::/64 route missing on GRE tunnels
From: Hannes Frederic Sowa @ 2014-02-15 12:10 UTC (permalink / raw)
To: nicolas.dichtel; +Cc: netdev, itk-intern, sesse
In-Reply-To: <20140215074559.GA8634@order.stressinduktion.org>
Hi Nicolas!
On Sat, Feb 15, 2014 at 08:45:59AM +0100, Hannes Frederic Sowa wrote:
> On Tue, Feb 11, 2014 at 10:59:28PM +0100, Steinar H. Gunderson wrote:
> > On Tue, Feb 11, 2014 at 10:55:11PM +0100, Steinar H. Gunderson wrote:
> > > but on 3.13.1, no such route shows up. I can add it manually, though.
> >
> > Correction; I can add it manually, but only to one GRE device at a time:
> >
> > root@altersex:~$ ip -6 route add fe80::/64 dev k_molvenfinnoy
> > root@altersex:~$ ip -6 route add fe80::/64 dev k_sessesveits
> > RTNETLINK answers: File exists
> > root@altersex:~$ ip -6 route del fe80::/64 dev k_molvenfinnoy
> > root@altersex:~$ ip -6 route add fe80::/64 dev k_sessesveits
> > root@altersex:~$
>
> Sorry for the long delay, I was busy with other stuff...
>
> So basically a workaround you can do for the time being is to add the tunnel
> with a local address:
>
> ip tunnel add foo mode gre local 4.3.2.1 remote 1.2.3.4 ttl 64
>
> The reason is that link local address generation fails in ipv6/addrconf as
> long as dev->dev_addr is zero.
>
> I have not yet found the change which causes this change in behaviour, but
> will do so soon.
f7cb8886335dea ("sit/gre6: don't try to add the same route two times") causes
this problem, because dev->dev_addr will never get initialized and thus
ipv6_generate_eui64 and addrconf_add_linklocal will never get called.
Ok for revert or do you have a better idea?
Greetings,
Hannes
^ permalink raw reply
* [PATCH] csum_partial_copy_from_user: clean up inconsistencies in implementations
From: Mikulas Patocka @ 2014-02-15 15:49 UTC (permalink / raw)
To: David S. Miller, netdev
Cc: linux-kernel, Michael Cree, Matt Turner, Mathieu Desnoyers,
Jay Estabrook
Hi
Here I'm sending a patch for networking to clean up inconsistent
implementations of csum_partial_copy_from_user in various architectures.
This patch doesn't fix any bug, but the confusion in implementations
caused a bug in the past. The patch should be queued for the kernel 3.15.
Mikulas
From: Mikulas Patocka <mpatocka@redhat.com>
csum_partial_copy_from_user is called only from csum_and_copy_from_user in
include/net/checksum.h. csum_and_copy_from_user verifies the userspace
range with access_ok, so there is no need to repeat access_ok in the
implementation of csum_partial_copy_from_user.
Some architectures repeat the acces_ok check anyway, sometimes people were
adding this check blindly (see patch
3ddc5b46a8e90f3c9251338b60191d0a804b0d92 that adds it for the alpha
architecture) and that caused serious network breakage because in the
alpha implementation, csum_partial_copy_from_user is also used when
copying from kernel space (called from the function
csum_partial_copy_nocheck) and that access_ok check broke it.
There were follow-up patches to fix the alpha breakage
(5cfe8f1ba5eebe6f4b6e5858cdb1a5be4f3272a6 and
0ef38d70d4118b2ce1a538d14357be5ff9dc2bbd), however these patches just add
junk to the code - the best thing would be to not perform access_ok in
csum_partial_copy_from_user in the first place.
This patch reverts the access_ok part of
3ddc5b46a8e90f3c9251338b60191d0a804b0d92, reverts the patches
5cfe8f1ba5eebe6f4b6e5858cdb1a5be4f3272a6 and
0ef38d70d4118b2ce1a538d14357be5ff9dc2bbd completely, and drops the check
for access_ok from other architectures that were performing the check.
This patch also changes all the implementations of
csum_partial_copy_from_user so that they don't zero the destination buffer
on page fault - csum_and_copy_from_user is not zeroing the buffer when the
access_ok fails, so it is pointless to zero the buffer in
csum_partial_copy_from_user.
The purpose of this patch is to make all the implementations of
csum_partial_copy_from_user consistent, so that people will keep them
consistent in the future.
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
---
arch/alpha/lib/csum_partial_copy.c | 22 ++++++----------------
arch/c6x/lib/checksum.c | 5 ++---
arch/frv/lib/checksum.c | 11 +++--------
arch/m32r/lib/csum_partial_copy.c | 6 +++---
arch/metag/lib/checksum.c | 5 ++---
arch/mn10300/lib/checksum.c | 4 ++--
arch/parisc/lib/checksum.c | 4 ++--
arch/s390/include/asm/checksum.h | 4 ++--
arch/score/lib/checksum_copy.c | 4 ++--
arch/x86/lib/csum-wrappers_64.c | 12 ------------
arch/x86/um/asm/checksum.h | 2 +-
lib/checksum.c | 5 ++---
12 files changed, 27 insertions(+), 57 deletions(-)
Index: linux-3.14-rc2/arch/alpha/lib/csum_partial_copy.c
===================================================================
--- linux-3.14-rc2.orig/arch/alpha/lib/csum_partial_copy.c 2014-02-13 19:38:09.000000000 +0100
+++ linux-3.14-rc2/arch/alpha/lib/csum_partial_copy.c 2014-02-13 19:41:23.000000000 +0100
@@ -130,7 +130,7 @@ csum_partial_cfu_aligned(const unsigned
*dst = word | tmp;
checksum += carry;
}
- if (err && errp) *errp = err;
+ if (err) *errp = err;
return checksum;
}
@@ -185,7 +185,7 @@ csum_partial_cfu_dest_aligned(const unsi
*dst = word | tmp;
checksum += carry;
}
- if (err && errp) *errp = err;
+ if (err) *errp = err;
return checksum;
}
@@ -242,7 +242,7 @@ csum_partial_cfu_src_aligned(const unsig
stq_u(partial_dest | second_dest, dst);
out:
checksum += carry;
- if (err && errp) *errp = err;
+ if (err) *errp = err;
return checksum;
}
@@ -325,7 +325,7 @@ csum_partial_cfu_unaligned(const unsigne
stq_u(partial_dest | word | second_dest, dst);
checksum += carry;
}
- if (err && errp) *errp = err;
+ if (err) *errp = err;
return checksum;
}
@@ -338,11 +338,6 @@ csum_partial_copy_from_user(const void _
unsigned long doff = 7 & (unsigned long) dst;
if (len) {
- if (!access_ok(VERIFY_READ, src, len)) {
- if (errp) *errp = -EFAULT;
- memset(dst, 0, len);
- return sum;
- }
if (!doff) {
if (!soff)
checksum = csum_partial_cfu_aligned(
@@ -378,11 +373,6 @@ csum_partial_copy_from_user(const void _
__wsum
csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum)
{
- __wsum checksum;
- mm_segment_t oldfs = get_fs();
- set_fs(KERNEL_DS);
- checksum = csum_partial_copy_from_user((__force const void __user *)src,
- dst, len, sum, NULL);
- set_fs(oldfs);
- return checksum;
+ return csum_partial_copy_from_user((__force const void __user *)src,
+ dst, len, sum, NULL);
}
Index: linux-3.14-rc2/arch/c6x/lib/checksum.c
===================================================================
--- linux-3.14-rc2.orig/arch/c6x/lib/checksum.c 2014-02-13 19:57:44.000000000 +0100
+++ linux-3.14-rc2/arch/c6x/lib/checksum.c 2014-02-13 19:58:09.000000000 +0100
@@ -20,10 +20,9 @@ csum_partial_copy_from_user(const void _
missing = __copy_from_user(dst, src, len);
if (missing) {
- memset(dst + len - missing, 0, missing);
*csum_err = -EFAULT;
- } else
- *csum_err = 0;
+ return (__force __wsum)-1;
+ }
return csum_partial(dst, len, sum);
}
Index: linux-3.14-rc2/arch/frv/lib/checksum.c
===================================================================
--- linux-3.14-rc2.orig/arch/frv/lib/checksum.c 2014-02-13 20:02:28.000000000 +0100
+++ linux-3.14-rc2/arch/frv/lib/checksum.c 2014-02-13 20:02:54.000000000 +0100
@@ -137,15 +137,10 @@ csum_partial_copy_from_user(const void _
{
int rem;
- if (csum_err)
- *csum_err = 0;
-
- rem = copy_from_user(dst, src, len);
+ rem = __copy_from_user(dst, src, len);
if (rem != 0) {
- if (csum_err)
- *csum_err = -EFAULT;
- memset(dst + len - rem, 0, rem);
- len = rem;
+ *csum_err = -EFAULT;
+ return (__force __wsum)-1;
}
return csum_partial(dst, len, sum);
Index: linux-3.14-rc2/arch/m32r/lib/csum_partial_copy.c
===================================================================
--- linux-3.14-rc2.orig/arch/m32r/lib/csum_partial_copy.c 2014-02-13 20:00:12.000000000 +0100
+++ linux-3.14-rc2/arch/m32r/lib/csum_partial_copy.c 2014-02-13 20:00:36.000000000 +0100
@@ -47,13 +47,13 @@ csum_partial_copy_from_user (const void
{
int missing;
- missing = copy_from_user(dst, src, len);
+ missing = __copy_from_user(dst, src, len);
if (missing) {
- memset(dst + len - missing, 0, missing);
*err_ptr = -EFAULT;
+ return (__force __wsum)-1;
}
- return csum_partial(dst, len-missing, sum);
+ return csum_partial(dst, len, sum);
}
EXPORT_SYMBOL(csum_partial_copy_from_user);
EXPORT_SYMBOL(csum_partial);
Index: linux-3.14-rc2/arch/metag/lib/checksum.c
===================================================================
--- linux-3.14-rc2.orig/arch/metag/lib/checksum.c 2014-02-13 20:00:55.000000000 +0100
+++ linux-3.14-rc2/arch/metag/lib/checksum.c 2014-02-13 20:01:23.000000000 +0100
@@ -146,10 +146,9 @@ csum_partial_copy_from_user(const void _
missing = __copy_from_user(dst, src, len);
if (missing) {
- memset(dst + len - missing, 0, missing);
*csum_err = -EFAULT;
- } else
- *csum_err = 0;
+ return (__force __wsum)-1;
+ }
return csum_partial(dst, len, sum);
}
Index: linux-3.14-rc2/arch/mn10300/lib/checksum.c
===================================================================
--- linux-3.14-rc2.orig/arch/mn10300/lib/checksum.c 2014-02-13 19:59:09.000000000 +0100
+++ linux-3.14-rc2/arch/mn10300/lib/checksum.c 2014-02-13 19:59:31.000000000 +0100
@@ -73,10 +73,10 @@ __wsum csum_partial_copy_from_user(const
{
int missing;
- missing = copy_from_user(dst, src, len);
+ missing = __copy_from_user(dst, src, len);
if (missing) {
- memset(dst + len - missing, 0, missing);
*err_ptr = -EFAULT;
+ return (__force __wsum)-1;
}
return csum_partial(dst, len, sum);
Index: linux-3.14-rc2/arch/parisc/lib/checksum.c
===================================================================
--- linux-3.14-rc2.orig/arch/parisc/lib/checksum.c 2014-02-13 19:58:19.000000000 +0100
+++ linux-3.14-rc2/arch/parisc/lib/checksum.c 2014-02-13 19:58:36.000000000 +0100
@@ -138,10 +138,10 @@ __wsum csum_partial_copy_from_user(const
{
int missing;
- missing = copy_from_user(dst, src, len);
+ missing = __copy_from_user(dst, src, len);
if (missing) {
- memset(dst + len - missing, 0, missing);
*err_ptr = -EFAULT;
+ return (__force __wsum)-1;
}
return csum_partial(dst, len, sum);
Index: linux-3.14-rc2/arch/s390/include/asm/checksum.h
===================================================================
--- linux-3.14-rc2.orig/arch/s390/include/asm/checksum.h 2014-02-13 19:56:37.000000000 +0100
+++ linux-3.14-rc2/arch/s390/include/asm/checksum.h 2014-02-13 19:57:16.000000000 +0100
@@ -54,10 +54,10 @@ csum_partial_copy_from_user(const void _
{
int missing;
- missing = copy_from_user(dst, src, len);
+ missing = __copy_from_user(dst, src, len);
if (missing) {
- memset(dst + len - missing, 0, missing);
*err_ptr = -EFAULT;
+ return (__force __wsum)-1;
}
return csum_partial(dst, len, sum);
Index: linux-3.14-rc2/arch/score/lib/checksum_copy.c
===================================================================
--- linux-3.14-rc2.orig/arch/score/lib/checksum_copy.c 2014-02-13 19:55:29.000000000 +0100
+++ linux-3.14-rc2/arch/score/lib/checksum_copy.c 2014-02-13 19:55:54.000000000 +0100
@@ -42,10 +42,10 @@ unsigned int csum_partial_copy_from_user
{
int missing;
- missing = copy_from_user(dst, src, len);
+ missing = __copy_from_user(dst, src, len);
if (missing) {
- memset(dst + len - missing, 0, missing);
*err_ptr = -EFAULT;
+ return -1;
}
return csum_partial(dst, len, sum);
Index: linux-3.14-rc2/arch/x86/lib/csum-wrappers_64.c
===================================================================
--- linux-3.14-rc2.orig/arch/x86/lib/csum-wrappers_64.c 2014-02-13 19:49:53.000000000 +0100
+++ linux-3.14-rc2/arch/x86/lib/csum-wrappers_64.c 2014-02-13 19:50:15.000000000 +0100
@@ -24,10 +24,6 @@ csum_partial_copy_from_user(const void _
int len, __wsum isum, int *errp)
{
might_sleep();
- *errp = 0;
-
- if (!likely(access_ok(VERIFY_READ, src, len)))
- goto out_err;
/*
* Why 6, not 7? To handle odd addresses aligned we
@@ -57,14 +53,6 @@ csum_partial_copy_from_user(const void _
isum = csum_partial_copy_generic((__force const void *)src,
dst, len, isum, errp, NULL);
clac();
- if (unlikely(*errp))
- goto out_err;
-
- return isum;
-
-out_err:
- *errp = -EFAULT;
- memset(dst, 0, len);
return isum;
}
Index: linux-3.14-rc2/arch/x86/um/asm/checksum.h
===================================================================
--- linux-3.14-rc2.orig/arch/x86/um/asm/checksum.h 2014-02-13 19:54:28.000000000 +0100
+++ linux-3.14-rc2/arch/x86/um/asm/checksum.h 2014-02-13 19:54:47.000000000 +0100
@@ -46,7 +46,7 @@ static __inline__
__wsum csum_partial_copy_from_user(const void __user *src, void *dst,
int len, __wsum sum, int *err_ptr)
{
- if (copy_from_user(dst, src, len)) {
+ if (__copy_from_user(dst, src, len)) {
*err_ptr = -EFAULT;
return (__force __wsum)-1;
}
Index: linux-3.14-rc2/lib/checksum.c
===================================================================
--- linux-3.14-rc2.orig/lib/checksum.c 2014-02-13 20:21:02.000000000 +0100
+++ linux-3.14-rc2/lib/checksum.c 2014-02-13 20:21:06.000000000 +0100
@@ -160,10 +160,9 @@ csum_partial_copy_from_user(const void _
missing = __copy_from_user(dst, src, len);
if (missing) {
- memset(dst + len - missing, 0, missing);
*csum_err = -EFAULT;
- } else
- *csum_err = 0;
+ return (__force __wsum)-1;
+ }
return csum_partial(dst, len, sum);
}
^ permalink raw reply
* Re: [RFC PATCH v2 tip 0/7] 64-bit BPF insn set and tracing filters
From: Daniel Borkmann @ 2014-02-15 16:13 UTC (permalink / raw)
To: Alexei Starovoitov
Cc: Ingo Molnar, David S. Miller, Steven Rostedt, Peter Zijlstra,
H. Peter Anvin, Thomas Gleixner, Masami Hiramatsu, Tom Zanussi,
Jovi Zhangwei, Eric Dumazet, Linus Torvalds, Andrew Morton,
Frederic Weisbecker, Arnaldo Carvalho de Melo, Pekka Enberg,
Arjan van de Ven, Christoph Hellwig, linux-kernel, netdev
In-Reply-To: <CAMEtUuyZtE1hSBP5xXOjTy1sed2iV1JK8pEGQATiwmxsj+GUFw@mail.gmail.com>
On 02/14/2014 06:55 PM, Alexei Starovoitov wrote:
> On Fri, Feb 14, 2014 at 9:02 AM, Daniel Borkmann <dborkman@redhat.com> wrote:
>> On 02/14/2014 01:59 AM, Alexei Starovoitov wrote:
>> ...
>>>>
>>>> I'm very curious, do you also have any performance numbers, e.g. for
>>>>
>>>> networking by taking JIT'ed/non-JIT'ed BPF filters and compare them
>>>> against
>>>> JIT'ed/non-JIT'ed eBPF filters to see how many pps we gain or loose e.g.
>>>> for a scenario with a middle box running cls_bpf .. or some other macro/
>>>> micro benchmark just to get a picture where both stand in terms of
>>>> performance? Who knows, maybe it would outperform nftables engine as
>>>> well? ;-) How would that look on a 32bit arch with eBPF that is 64bit?
>>>
>>> I don't have jited/non-jited numbers, but I suspect for micro-benchmarks
>>> the gap should be big. I was shooting for near native performance after
>>> JIT.
>>
>> Ohh, I meant it would be interesting to see a comparison of e.g. common
>> libpcap
>> high-level filters that are in 32bit BPF + JIT (current code) vs 64bit BPF +
>> JIT
>> (new code). I'm wondering how 32bit-only archs should be handled to not
>> regress
>> in evaluation performance to the current code.
>
> Agreed. If we want to rip off old bpf interpreter and replace it with old->new
> converter + new bpf interpreter, the performance of it should be very close.
> In grand scheme some differences are ok, since libpcap bpf filters are not hot.
> So much is happening before and after that tcpdump won't notice whether
> filter was jited or not. cls_bpf is a different story, though I don't know what
> specific use case you have there.
> Could you define a bpf micro benchmark ? cls_bpf with pktgen?
Well, that's just one example, it's not necessarily about cls_bpf, e.g. just
a modified pktgen where skb goes through new/old BPF filters on local output
path and the remote machine queries nic counters (e.g. ifpps, an ixia box or
something else suitable). There's probably even something more simple and
suitable for comparing both, so it doesn't necessarily has to be this scenario.
It's just to have a basic comparison to see where we would stand e.g. in case
of 32/64bit architectures. Otherwise, regarding your other email, sounds like
convergence at least to _me_. Details can then still be discussed at particular
steps, but integrating this step by step into the existing architecture would
be a good start, imho.
^ permalink raw reply
* BOURSE SUISSE (2014-2015)
From: BOURSE D’ÉTUDE SUISSE @ 2014-02-15 16:10 UTC (permalink / raw)
PAR L'INTERMEDIAIRE DE LA COMMISSION FEDERALE DES BOURSES ETRANGERES (CFBE-SUISSE) , LE SECRETARIAT D'ETAT D'ETUDE ET A LA RECHERCHE DE LA CONFEDERATION LANCE UN APPEL A LA CANDIDATURE POUR 500 BOURSES D'ETUDES SUISSES AU TITRE DE L'ANNEE ACADEMIQUE 2014 - 2015 CES BOURSES SONT DESTINEES AUX RESSORTISSANTS DES PAYS
DE LA CATEGORIE A
(pays industrialisés européens, et extra-européens)
ET CEUX DES PAYS DE LA CATEGORIE B
( pays en developpement, du tiers monde et extra - européens).
ELLES DOIVENT LEUR PERMETTRE DE POURSUIVRE LEURS ETUDES, DE PARFAIRE LEURS CONNAISSANCES POUR LES TRAVAUX DE RECHERCHES DANS LES DOMAINES AUXQUELS LES UNIVERSITES SUISSES ACCORDENT UNE ATTENTION PARTICULIERE.
DUREE DE LA BOURSE
LES BOURSES COUVRENT LA PERIODE D'UN CYCLE DE FORMATION OU AU MAXIMUM SIX (06) SEMESTRES .
FRAIS DE VOYAGE
LES BILLETS D'AVION ALLER-RETOUR ( PAYS DE PROVENANCE -GENEVE) , SONT PRIS EN CHARGE PAR LA COMMISSION FEDERALE DES BOURSES ETRANGERES.
CONDITIONS PREALABLES A LA CANDIDATURE
EN REGLE GENERALE, LES CANDIDATS AUX BOURSES ETRANGERES SUISSES DOIVENT:
- AVOIR AU MAXIMUM 18 ANS a 45 ANS ;
- COMPRENDRE ET PARLER CORRECTEMENT L'UNE DES LANGUES D'ENSEIGNEMENT EN SUISSE
( ESPAGNOL, ALLEMAND, ANGLAIS, ITALIE, FRANCAIS) ;
- AVOIR UN DIPLOME EQUIVALENT AU BREVET D'ETUDE DE PREMIER CYCLE D'ENSEIGNEMENT, AU BACCALAUREAT OU AU BREVET D'APTITUDE PROFESSIONELLE DES PAYS DE L'UNION EUROPEENNE.
PROCEDURE DE SELECTION
- RETIRER AUPRES DE LA COMMISSION FEDERALE DES BOURSES ETRANGERES SUISSEs(CFBES)LE FORMULAIRE DE DEMANDE DE
BOURSE VIA
A LEUR ADRESSE EMAIL: cfbesavis01@nokiamail.com- REMPLIR ET ENVOYER PAR PIECE JOINTE LE FORMULAIRE.
- LA COMMISSION FEDERALE DES BOURSES ETRANGERES FERA ETUDIER VOTRE DOSSIER PAR LA REPRESENTATION SUISSE DELEGUEE
DE VOTRE ZONE ET CATEGORIE DE PAYS.
- - LES CANDIDATS RETENUS RECEVRONT UNE ATTESTATION DU SECRETARIAT D'ETAT A L'ETUDE ET A LA RECHERCHE POUR NOTIFICATION DE LA BOURSE. LES CANDIDATS DESIREUX DE PARTICIPER AUX BOURSES D'ETUDES 2014 - 2015 DOIVENT RETIRER LEUR FORMULAIRE A REMPLIR AUPRES DE LA CFBES: A LEUR ADRESSE EMAIL: cfbesavis01@nokiamail.com
DATE LIMITE DE DEPÖT DES DOSSIERS
LA DATE LIMITE DE DEPÖT DES DOSSIERS EST PREVUE POUR LE
15 Mars 2014.
CEPENDANT, LA COMMISSION FEDERALE DES BOURSES ETRANGERES SUISSEs(CFBES) SE RESERVE LE DROIT DE CLOTURER L'OCTROI DES BOURSES A CONCURRENCE DES BOURSES DISPONIBLES.
LE PRESIDENT DE LA COMMISSION FEDERALE
DES BOURSES ETRANGERES SUISSES
^ permalink raw reply
* Re: socket bind to local address ::ffff:127.0.0.1 question
From: Hannes Frederic Sowa @ 2014-02-15 17:10 UTC (permalink / raw)
To: Vincent Li; +Cc: netdev@vger.kernel.org
In-Reply-To: <CAK3+h2zzx5AocGeJxu9cW0kNkiRew6GNDMrbsNq-7H8co=T0_Q@mail.gmail.com>
On Wed, Feb 12, 2014 at 12:41:21PM -0800, Vincent Li wrote:
> we have a traffic path like <BIGIP monitor userland process on Linux>
> <------> router<------->pool/real server
>
> there is a weird issue that intermittently, a socket is bound to
> loopback address '::ffff:127.0.0.1' which caused issue for us because
> remote end host can't SYN+ACK the SYN source from 127.0.0.1, strace
> the userland process shows:
>
> 6797 12:36:48.815296 connect(11, {sa_family=AF_INET6,
> sin6_port=htons(8180), inet_pton(AF_INET6, "::ffff:172.16.3.165",
> &sin6_addr), sin6_flowinfo=0, sin6_scope_id=875638834}, 28) = -1
> EINPROGRESS (Operation now in progress)
Have you checked the connect operation completed successfully in this
case? Error state would be interesting to see (SO_ERROR).
> 6797 12:36:48.815464 gettimeofday({1391744208, 815499}, NULL) = 0
> 6797 12:36:48.815552 time(NULL) = 1391744208
> 6797 12:36:48.815657 stat64("/etc/localtime", {st_mode=S_IFREG|0644,
> st_size=331, ...}) = 0
> ...................
> 6797 12:36:48.816948 getsockname(11, {sa_family=AF_INET6,
> sin6_port=htons(45621), inet_pton(AF_INET6, "::ffff:127.0.0.1",
> &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0},
> [18433145657494601756]) = 0
^^^
Urks!
What kernel version are you using?
Do you have a reproducer, sample code in C where this problem sometimes
happens or could you expand the strace listings a bit (maybe setsockopts,
bindv6only settings)?
Also you seem to not initialize your struct sockaddr_in6 given to connect, as
the sin6_scope_id seems bogus (uninitialized memory?). But should not
matter with v4mapped addresses though.
Greetings,
Hannes
^ permalink raw reply
* Re: [PATCH 10/13] staging: r8188eu: Remove wrapper _enter_critical_mutex()
From: Larry Finger @ 2014-02-15 17:23 UTC (permalink / raw)
To: Dan Carpenter; +Cc: devel, gregkh, netdev
In-Reply-To: <20140215104155.GC26776@mwanda>
On 02/15/2014 04:41 AM, Dan Carpenter wrote:
> On Fri, Feb 14, 2014 at 04:54:14PM -0600, Larry Finger wrote:
>> diff --git a/drivers/staging/rtl8188eu/hal/usb_ops_linux.c b/drivers/staging/rtl8188eu/hal/usb_ops_linux.c
>> index 1fa5370..d5f6a32 100644
>> --- a/drivers/staging/rtl8188eu/hal/usb_ops_linux.c
>> +++ b/drivers/staging/rtl8188eu/hal/usb_ops_linux.c
>> @@ -49,7 +49,9 @@ static int usbctrl_vendorreq(struct intf_hdl *pintfhdl, u8 request, u16 value, u
>> goto exit;
>> }
>>
>> - _enter_critical_mutex(&dvobjpriv->usb_vendor_req_mutex, NULL);
>> + if (mutex_lock_interruptible(&dvobjpriv->usb_vendor_req_mutex))
>> + status = -ENOMEM;
>> + goto exit;
>>
>
> Missing curly braces.
Thanks for seeing this. Fixing this also removes the uninitialized variable
warnings, which should have been a clue. Perhaps my wife is right, and I am
getting senile!
Actually a simple "return -ENOMEM" is sufficient as nothing happens at label
exit other than "return status".
Larry
^ permalink raw reply
* Netdev stable patches status
From: Oliver Hartkopp @ 2014-02-15 17:42 UTC (permalink / raw)
To: David Miller; +Cc: linux-can@vger.kernel.org, Linux Netdev List
In-Reply-To: <52EE9C88.1010902@hartkopp.net>
Hello Dave,
there are many patches queued up for stable but not hitting the stable kernels
for a while now (even when they're already upstream).
http://patchwork.ozlabs.org/bundle/davem/stable/?state=*
Regards,
Oliver
On 02.02.2014 20:29, Oliver Hartkopp wrote:
> On 02.02.2014 19:00, Luis Henriques wrote:
>
>> I've just checked David Miller's net -stable queue[1] and it looks like he
>> has in fact already queued it. We usually pick his stable patches when he
>> sends them to the stable mailing list, so I guess we'll just wait for this
>> to happen.
>>
>> [1] http://patchwork.ozlabs.org/bundle/davem/stable/?state=*
>
> Hi Luis,
>
> I was not aware about Daves stable queue URL and especially not about the
> process for the end-of-life kernels. Good to know that you check the lists
> yourself for potential relevant stuff :-)
>
> Many thanks for your work!
>
> Best regards,
> Oliver
>
^ permalink raw reply
* Re: [PATCH] Drivers: net: wireless: mac80211_hwim fixed coding style issues
From: Johannes Berg @ 2014-02-15 18:13 UTC (permalink / raw)
To: Justin van Wijngaarden; +Cc: linville, netdev, linux-kernel, linux-wireless
In-Reply-To: <1392465312-3780-1-git-send-email-justinvanwijngaarden@gmail.com>
On Sat, 2014-02-15 at 12:55 +0100, Justin van Wijngaarden wrote:
> @@ -1,19 +1,17 @@
> -/*
> - * mac80211_hwsim - software simulator of 802.11 radio(s) for mac80211
> +/* mac80211_hwsim - software simulator of 802.11 radio(s) for mac80211
I don't see any point in this - lots of code exists both ways, that's
really just fluff. The difference isn't even interesting enough to be
worth fixing up.
> * published by the Free Software Foundation.
> - */
> +*/
That's just wrong.
In any case, your patch won't apply anyway since we've since
changed/removed code that you're modifying.
There's very little in this patch that I'd be willing to apply, and most
of that you actually got the coding style wrong so it's not an
improvement at all.
johannes
^ permalink raw reply
* Re: [PATCH] Drivers: net: wireless: mac80211_hwim fixed coding style issues
From: Antonio Quartulli @ 2014-02-15 19:53 UTC (permalink / raw)
To: Johannes Berg, Justin van Wijngaarden
Cc: linville, netdev, linux-kernel, linux-wireless
In-Reply-To: <1392488030.4298.5.camel@jlt4.sipsolutions.net>
[-- Attachment #1: Type: text/plain, Size: 686 bytes --]
On 15/02/14 19:13, Johannes Berg wrote:
> On Sat, 2014-02-15 at 12:55 +0100, Justin van Wijngaarden wrote:
>
>> @@ -1,19 +1,17 @@
>> -/*
>> - * mac80211_hwsim - software simulator of 802.11 radio(s) for mac80211
>> +/* mac80211_hwsim - software simulator of 802.11 radio(s) for mac80211
>
> I don't see any point in this - lots of code exists both ways, that's
> really just fluff. The difference isn't even interesting enough to be
> worth fixing up.
This is how David S. Miller wants multiline comments to start in files
within the networking subsystem......but I know you don't like it ;)
(I just wanted to justify Justin).
Cheers,
--
Antonio Quartulli
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* Re: [BUG] unable to handle kernel NULL pointer dereference
From: John @ 2014-02-15 20:08 UTC (permalink / raw)
To: lkml, netdev@vger.kernel.org
Cc: da_audiophile@yahoo.com, stephen@networkplumber.org,
mlindner@marvell.com
In-Reply-To: <1392466251.41282.YahooMailNeo@web140003.mail.bf1.yahoo.com>
> When booting into linux v3.13.3, I am unable to mount an nfs share on this
> particular hardware. I get the same problem using v3.12.11. Only the 3.10.x
> series allows normal operation. Partial dmesg output shown inline, additional
> logs available upon request.
>
> PLEASE cc me on my replies as I am not subscribed to lkml.
>
> Hardware: Athlon XP 3200+ on an NVIDIA nForce2 Ultra 400 motherboard.
> Distro: Arch Linux i686.
>
> % dmesg
> ...
> [ 137.616014] NFS: Registering the id_resolver key type
> [ 137.616036] Key type id_resolver registered
> [ 137.616038] Key type id_legacy registered
> [ 137.686758] BUG: unable to handle kernel NULL pointer dereference at 00000858
> [ 137.689996] IP: [<f8aa2d99>] put_pipe_version+0x19/0x60 [auth_rpcgss]
> [ 137.689996] *pde = 00000000
> [ 137.689996] Oops: 0000 [#1] PREEMPT SMP
> [ 137.689996] Modules linked in: rpcsec_gss_krb5 auth_rpcgss oid_registry nfsv4
> asb100 hwmon_vid snd_wavefront ir_mce_kbd_decoder ir_lirc_codec
> ir_rc5_sz_decoder ir_sony_decoder lirc_dev ir_rc5_decoder ir_jvc_decoder
> ir_sanyo_decoder ir_rc6_decoder ir_nec_decoder rc_streamzap streamzap mousedev
> snd_cs4236 rc_core snd_intel8x0 snd_wss_lib snd_opl3_lib snd_hwdep
> snd_ac97_codec evdev snd_mpu401 ac97_bus snd_mpu401_uart snd_pcm snd_rawmidi
> snd_page_alloc snd_seq_device snd_timer snd pcspkr skge shpchp i2c_nforce2
> i2c_core soundcore ns558 gameport processor button nvidia_agp agpgart nfs lockd
> sunrpc fscache ext4 crc16 mbcache jbd2 hid_generic usbhid hid sr_mod cdrom
> sd_mod ata_generic pata_acpi sata_sil pata_amd libata ehci_pci ohci_pci ohci_hcd
> ehci_hcd scsi_mod usbcore usb_common
> [ 137.689996] CPU: 0 PID: 534 Comm: rpc.gssd Not tainted 3.13.3-1-ARCH #1
> [ 137.689996] Hardware name: ASUSTeK Computer INC. A7N8X-E/A7N8X-E, BIOS ASUS
> A7N8X-E Deluxe ACPI BIOS Rev 1013 11/12/2004
> [ 137.689996] task: f4633210 ti: f568e000 task.ti: f568e000
> [ 137.689996] EIP: 0060:[<f8aa2d99>] EFLAGS: 00010202 CPU: 0
> [ 137.689996] EIP is at put_pipe_version+0x19/0x60 [auth_rpcgss]
> [ 137.689996] EAX: f4633210 EBX: 00000001 ECX: f56efca8 EDX: 00000296
> [ 137.689996] ESI: 00000000 EDI: f56efc00 EBP: f568fee8 ESP: f568fee0
> [ 137.689996] DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068
> [ 137.689996] CR0: 8005003b CR2: 00000858 CR3: 34523000 CR4: 000007d0
> [ 137.689996] Stack:
> [ 137.689996] f56efc00 f6c64f78 f568fef4 f8aa2e05 00000010 f568ff40 f8aa3b38
> 00000374
> [ 137.689996] 00000080 b74dde40 f4644a80 f568ff30 00000246 f8ac1080 ffff41c9
> f6c64f78
> [ 137.689996] fffffff3 00000010 f4460140 f44d5820 f44d5810 f53df7ec f57595a0
> f8aa93e8
> [ 137.689996] Call Trace:
> [ 137.689996] [<f8aa2e05>] gss_release_msg+0x25/0x70 [auth_rpcgss]
> [ 137.689996] [<f8aa3b38>] gss_pipe_downcall+0x208/0x4b0 [auth_rpcgss]
> [ 137.689996] [<f8a2f9ab>] rpc_pipe_write+0x3b/0x60 [sunrpc]
> [ 137.689996] [<f8a2f970>] ? rpc_pipe_poll+0x90/0x90 [sunrpc]
> [ 137.689996] [<c1156bd5>] vfs_write+0x95/0x1c0
> [ 137.689996] [<c11572a1>] SyS_write+0x51/0x90
> [ 137.689996] [<c145cc0d>] sysenter_do_call+0x12/0x28
> [ 137.689996] Code: f8 e8 4f b8 9a c8 31 c0 eb c6 90 8d b4 26 00 00 00 00 55 89
> e5 56 53 3e 8d 74 26 00 8b 1d 28 e9 a3 f8 89 c6 e8 59 64 5f c8 85 db <8b>
> 86 58 08 00 00 74 3a 3b 18 77 36 8b 5c 98 08 e8 32 66 5f c8
> [ 137.689996] EIP: [<f8aa2d99>] put_pipe_version+0x19/0x60 [auth_rpcgss]
> SS:ESP 0068:f568fee0
> [ 137.689996] CR2: 0000000000000858
> [ 138.578433] ---[ end trace 3dcb8d5c35b64fbd ]---
> [ 142.979263] type=1006 audit(1392415950.632:4): pid=540 uid=0 old
> auid=4294967295 new auid=1000 old ses=4294967295 new ses=3 res=1
I should add that if I test the same kernel version (v3.13.3 compiled for i686) on a similar machine of the same vintage, there is not a problem. When I looked into the `lspci -v` output on the machine that has the problems, I found that it seems to be related to the skge driver as shown below; the similar machine that does not have the problem is using the forcedeth driver so I am hypothesizing that the error is with the skge driver.
01:04.0 Ethernet controller: Marvell Technology Group Ltd. 88E8001 Gigabit Ethernet Controller (rev 13)
Subsystem: ASUSTeK Computer Inc. Marvell 88E8001 Gigabit Ethernet Controller (Asus)
Flags: bus master, 66MHz, medium devsel, latency 32, IRQ 17
Memory at d5000000 (32-bit, non-prefetchable) [size=16K]
I/O ports at a000 [size=256]
[virtual] Expansion ROM at 80080000 [disabled] [size=128K]
Capabilities: [48] Power Management version 2
Capabilities: [50] Vital Product Data
Kernel driver in use: skge
Kernel modules: skge
^ permalink raw reply
* Re: [BUG] unable to handle kernel NULL pointer dereference
From: Borislav Petkov @ 2014-02-15 20:30 UTC (permalink / raw)
To: John
Cc: lkml, netdev@vger.kernel.org, stephen@networkplumber.org,
mlindner@marvell.com, Trond Myklebust, J. Bruce Fields
In-Reply-To: <1392494917.71728.YahooMailNeo@web140002.mail.bf1.yahoo.com>
If I'd have to guess, that's trying to rcu deref that struct net_generic
*ng in net_generic() but this is only guesswork as I don't have your
.config.
Anyway, adding some more people to CC.
[ 137.689996] Code: f8 e8 4f b8 9a c8 31 c0 eb c6 90 8d b4 26 00 00 00 00 55 89 e5 56 53 3e 8d 74 26 00 8b 1d 28 e9 a3 f8 89 c6 e8 59 64 5f c8 85 db <8b> 86 58 08 00 00 74 3a 3b 18 77 36 8b 5c 98 08 e8 32 66 5f c8
All code
========
0: f8 clc
1: e8 4f b8 9a c8 call 0xc89ab855
6: 31 c0 xor %eax,%eax
8: eb c6 jmp 0xffffffd0
a: 90 nop
b: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi
12: 55 push %ebp
13: 89 e5 mov %esp,%ebp
15: 56 push %esi
16: 53 push %ebx
17: 3e 8d 74 26 00 lea %ds:0x0(%esi,%eiz,1),%esi
1c: 8b 1d 28 e9 a3 f8 mov 0xf8a3e928,%ebx
22: 89 c6 mov %eax,%esi
24: e8 59 64 5f c8 call 0xc85f6482
29: 85 db test %ebx,%ebx
2b:* 8b 86 58 08 00 00 mov 0x858(%esi),%eax <-- trapping instruction
31: 74 3a je 0x6d
33: 3b 18 cmp (%eax),%ebx
35: 77 36 ja 0x6d
37: 8b 5c 98 08 mov 0x8(%eax,%ebx,4),%ebx
3b: e8 32 66 5f c8 call 0xc85f6672
Code starting with the faulting instruction
===========================================
0: 8b 86 58 08 00 00 mov 0x858(%esi),%eax
6: 74 3a je 0x42
8: 3b 18 cmp (%eax),%ebx
a: 77 36 ja 0x42
c: 8b 5c 98 08 mov 0x8(%eax,%ebx,4),%ebx
10: e8 32 66 5f c8 call 0xc85f6647
On Sat, Feb 15, 2014 at 12:08:37PM -0800, John wrote:
> > When booting into linux v3.13.3, I am unable to mount an nfs share on this
>
> > particular hardware. I get the same problem using v3.12.11. Only the 3.10.x
> > series allows normal operation. Partial dmesg output shown inline, additional
> > logs available upon request.
> >
> > PLEASE cc me on my replies as I am not subscribed to lkml.
> >
> > Hardware: Athlon XP 3200+ on an NVIDIA nForce2 Ultra 400 motherboard.
> > Distro: Arch Linux i686.
> >
> > % dmesg
> > ...
> > [ 137.616014] NFS: Registering the id_resolver key type
> > [ 137.616036] Key type id_resolver registered
> > [ 137.616038] Key type id_legacy registered
> > [ 137.686758] BUG: unable to handle kernel NULL pointer dereference at 00000858
> > [ 137.689996] IP: [<f8aa2d99>] put_pipe_version+0x19/0x60 [auth_rpcgss]
> > [ 137.689996] *pde = 00000000
> > [ 137.689996] Oops: 0000 [#1] PREEMPT SMP
> > [ 137.689996] Modules linked in: rpcsec_gss_krb5 auth_rpcgss oid_registry nfsv4
> > asb100 hwmon_vid snd_wavefront ir_mce_kbd_decoder ir_lirc_codec
> > ir_rc5_sz_decoder ir_sony_decoder lirc_dev ir_rc5_decoder ir_jvc_decoder
> > ir_sanyo_decoder ir_rc6_decoder ir_nec_decoder rc_streamzap streamzap mousedev
> > snd_cs4236 rc_core snd_intel8x0 snd_wss_lib snd_opl3_lib snd_hwdep
> > snd_ac97_codec evdev snd_mpu401 ac97_bus snd_mpu401_uart snd_pcm snd_rawmidi
> > snd_page_alloc snd_seq_device snd_timer snd pcspkr skge shpchp i2c_nforce2
> > i2c_core soundcore ns558 gameport processor button nvidia_agp agpgart nfs lockd
> > sunrpc fscache ext4 crc16 mbcache jbd2 hid_generic usbhid hid sr_mod cdrom
> > sd_mod ata_generic pata_acpi sata_sil pata_amd libata ehci_pci ohci_pci ohci_hcd
> > ehci_hcd scsi_mod usbcore usb_common
> > [ 137.689996] CPU: 0 PID: 534 Comm: rpc.gssd Not tainted 3.13.3-1-ARCH #1
> > [ 137.689996] Hardware name: ASUSTeK Computer INC. A7N8X-E/A7N8X-E, BIOS ASUS
> > A7N8X-E Deluxe ACPI BIOS Rev 1013 11/12/2004
> > [ 137.689996] task: f4633210 ti: f568e000 task.ti: f568e000
> > [ 137.689996] EIP: 0060:[<f8aa2d99>] EFLAGS: 00010202 CPU: 0
> > [ 137.689996] EIP is at put_pipe_version+0x19/0x60 [auth_rpcgss]
> > [ 137.689996] EAX: f4633210 EBX: 00000001 ECX: f56efca8 EDX: 00000296
> > [ 137.689996] ESI: 00000000 EDI: f56efc00 EBP: f568fee8 ESP: f568fee0
> > [ 137.689996] DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068
> > [ 137.689996] CR0: 8005003b CR2: 00000858 CR3: 34523000 CR4: 000007d0
> > [ 137.689996] Stack:
> > [ 137.689996] f56efc00 f6c64f78 f568fef4 f8aa2e05 00000010 f568ff40 f8aa3b38
> > 00000374
> > [ 137.689996] 00000080 b74dde40 f4644a80 f568ff30 00000246 f8ac1080 ffff41c9
> > f6c64f78
> > [ 137.689996] fffffff3 00000010 f4460140 f44d5820 f44d5810 f53df7ec f57595a0
> > f8aa93e8
> > [ 137.689996] Call Trace:
> > [ 137.689996] [<f8aa2e05>] gss_release_msg+0x25/0x70 [auth_rpcgss]
> > [ 137.689996] [<f8aa3b38>] gss_pipe_downcall+0x208/0x4b0 [auth_rpcgss]
> > [ 137.689996] [<f8a2f9ab>] rpc_pipe_write+0x3b/0x60 [sunrpc]
> > [ 137.689996] [<f8a2f970>] ? rpc_pipe_poll+0x90/0x90 [sunrpc]
> > [ 137.689996] [<c1156bd5>] vfs_write+0x95/0x1c0
> > [ 137.689996] [<c11572a1>] SyS_write+0x51/0x90
> > [ 137.689996] [<c145cc0d>] sysenter_do_call+0x12/0x28
> > [ 137.689996] Code: f8 e8 4f b8 9a c8 31 c0 eb c6 90 8d b4 26 00 00 00 00 55 89
> > e5 56 53 3e 8d 74 26 00 8b 1d 28 e9 a3 f8 89 c6 e8 59 64 5f c8 85 db <8b>
> > 86 58 08 00 00 74 3a 3b 18 77 36 8b 5c 98 08 e8 32 66 5f c8
> > [ 137.689996] EIP: [<f8aa2d99>] put_pipe_version+0x19/0x60 [auth_rpcgss]
> > SS:ESP 0068:f568fee0
> > [ 137.689996] CR2: 0000000000000858
> > [ 138.578433] ---[ end trace 3dcb8d5c35b64fbd ]---
> > [ 142.979263] type=1006 audit(1392415950.632:4): pid=540 uid=0 old
> > auid=4294967295 new auid=1000 old ses=4294967295 new ses=3 res=1
>
>
> I should add that if I test the same kernel version (v3.13.3 compiled for i686) on a similar machine of the same vintage, there is not a problem. When I looked into the `lspci -v` output on the machine that has the problems, I found that it seems to be related to the skge driver as shown below; the similar machine that does not have the problem is using the forcedeth driver so I am hypothesizing that the error is with the skge driver.
>
> 01:04.0 Ethernet controller: Marvell Technology Group Ltd. 88E8001 Gigabit Ethernet Controller (rev 13)
> Subsystem: ASUSTeK Computer Inc. Marvell 88E8001 Gigabit Ethernet Controller (Asus)
> Flags: bus master, 66MHz, medium devsel, latency 32, IRQ 17
> Memory at d5000000 (32-bit, non-prefetchable) [size=16K]
> I/O ports at a000 [size=256]
> [virtual] Expansion ROM at 80080000 [disabled] [size=128K]
> Capabilities: [48] Power Management version 2
> Capabilities: [50] Vital Product Data
> Kernel driver in use: skge
> Kernel modules: skge
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
>
--
Regards/Gruss,
Boris.
Sent from a fat crate under my desk. Formatting is fine.
--
^ permalink raw reply
* Re: [PATCH 10/13] staging: r8188eu: Remove wrapper _enter_critical_mutex()
From: Greg KH @ 2014-02-15 20:38 UTC (permalink / raw)
To: Larry Finger; +Cc: devel, netdev
In-Reply-To: <1392418457-3203-11-git-send-email-Larry.Finger@lwfinger.net>
On Fri, Feb 14, 2014 at 04:54:14PM -0600, Larry Finger wrote:
> This wrapper returned the result of mutex_lock_interruptible(); however,
> none of the callers checked the returned value.
Then why is the code logic changing?
>
> As a result of a gcc upgrade to version 4.8.1, two false unitialized variable
> warnings appeared. To silence the warnings, they are initialized to 0.
>
> Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
> ---
> drivers/staging/rtl8188eu/core/rtw_mlme_ext.c | 3 ++-
> drivers/staging/rtl8188eu/hal/usb_ops_linux.c | 8 +++++---
> drivers/staging/rtl8188eu/include/osdep_service.h | 9 ---------
> drivers/staging/rtl8188eu/os_dep/os_intfs.c | 3 ++-
> 4 files changed, 9 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c
> index c197b22..e95a1ba 100644
> --- a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c
> +++ b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c
> @@ -4429,7 +4429,8 @@ s32 dump_mgntframe_and_wait_ack(struct adapter *padapter, struct xmit_frame *pmg
> if (padapter->bSurpriseRemoved || padapter->bDriverStopped)
> return -1;
>
> - _enter_critical_mutex(&pxmitpriv->ack_tx_mutex, NULL);
> + if (mutex_lock_interruptible(&pxmitpriv->ack_tx_mutex))
> + return -1;
That's not what the original code did, so this change could cause
problems, right?
> -static inline int _enter_critical_mutex(struct mutex *pmutex,
> - unsigned long *pirqL)
> -{
> - int ret;
> -
> - ret = mutex_lock_interruptible(pmutex);
> - return ret;
> -}
This didn't affect the caller function's code path...
I've applied this series up to here.
thanks,
greg k-h
^ 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