* [PATCH v2 1/4] dtb: Add SGMII based 1GbE node to APM X-Gene SoC device tree
From: Iyappan Subramanian @ 2014-10-14 0:05 UTC (permalink / raw)
To: davem, romieu, netdev, devicetree
Cc: linux-arm-kernel, patches, kchudgar, Iyappan Subramanian
In-Reply-To: <1413245135-2989-1-git-send-email-isubramanian@apm.com>
Signed-off-by: Iyappan Subramanian <isubramanian@apm.com>
Signed-off-by: Keyur Chudgar <kchudgar@apm.com>
---
arch/arm64/boot/dts/apm-mustang.dts | 4 ++++
arch/arm64/boot/dts/apm-storm.dtsi | 24 ++++++++++++++++++++++++
2 files changed, 28 insertions(+)
diff --git a/arch/arm64/boot/dts/apm-mustang.dts b/arch/arm64/boot/dts/apm-mustang.dts
index 2ae782b..71a1489 100644
--- a/arch/arm64/boot/dts/apm-mustang.dts
+++ b/arch/arm64/boot/dts/apm-mustang.dts
@@ -33,6 +33,10 @@
status = "ok";
};
+&sgenet0 {
+ status = "ok";
+};
+
&xgenet {
status = "ok";
};
diff --git a/arch/arm64/boot/dts/apm-storm.dtsi b/arch/arm64/boot/dts/apm-storm.dtsi
index d16cc03..f45bbfe 100644
--- a/arch/arm64/boot/dts/apm-storm.dtsi
+++ b/arch/arm64/boot/dts/apm-storm.dtsi
@@ -176,6 +176,16 @@
clock-output-names = "menetclk";
};
+ sge0clk: sge0clk@1f21c000 {
+ compatible = "apm,xgene-device-clock";
+ #clock-cells = <1>;
+ clocks = <&socplldiv2 0>;
+ reg = <0x0 0x1f21c000 0x0 0x1000>;
+ reg-names = "csr-reg";
+ csr-mask = <0x3>;
+ clock-output-names = "sge0clk";
+ };
+
xge0clk: xge0clk@1f61c000 {
compatible = "apm,xgene-device-clock";
#clock-cells = <1>;
@@ -446,6 +456,20 @@
};
};
+ sgenet0: ethernet@1f210000 {
+ compatible = "apm,xgene-enet";
+ status = "disabled";
+ reg = <0x0 0x1f210000 0x0 0x10000>,
+ <0x0 0x1f200000 0x0 0X10000>,
+ <0x0 0x1B000000 0x0 0X20000>;
+ reg-names = "enet_csr", "ring_csr", "ring_cmd";
+ interrupts = <0x0 0xA0 0x4>;
+ dma-coherent;
+ clocks = <&sge0clk 0>;
+ local-mac-address = [00 00 00 00 00 00];
+ phy-connection-type = "sgmii";
+ };
+
xgenet: ethernet@1f610000 {
compatible = "apm,xgene-enet";
status = "disabled";
--
1.9.1
^ permalink raw reply related
* [PATCH v2 2/4] drivers: net: xgene: Preparing for adding SGMII based 1GbE
From: Iyappan Subramanian @ 2014-10-14 0:05 UTC (permalink / raw)
To: davem, romieu, netdev, devicetree
Cc: linux-arm-kernel, patches, kchudgar, Iyappan Subramanian
In-Reply-To: <1413245135-2989-1-git-send-email-isubramanian@apm.com>
- Added link_state function pointer to the xgene__mac_ops structure
- Moved ring manager (pdata->rm) assignment to xgene_enet_setup_ops
- Removed unused variable (pdata->phy_addr) and macro (FULL_DUPLEX)
Signed-off-by: Iyappan Subramanian <isubramanian@apm.com>
Signed-off-by: Keyur Chudgar <kchudgar@apm.com>
---
drivers/net/ethernet/apm/xgene/xgene_enet_hw.c | 1 -
drivers/net/ethernet/apm/xgene/xgene_enet_hw.h | 1 -
drivers/net/ethernet/apm/xgene/xgene_enet_main.c | 8 +++++---
drivers/net/ethernet/apm/xgene/xgene_enet_main.h | 2 +-
drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c | 3 ++-
drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.h | 1 -
6 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c
index c8f3824..63ea194 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c
@@ -410,7 +410,6 @@ static void xgene_gmac_set_mac_addr(struct xgene_enet_pdata *pdata)
addr0 = (dev_addr[3] << 24) | (dev_addr[2] << 16) |
(dev_addr[1] << 8) | dev_addr[0];
addr1 = (dev_addr[5] << 24) | (dev_addr[4] << 16);
- addr1 |= pdata->phy_addr & 0xFFFF;
xgene_enet_wr_mcx_mac(pdata, STATION_ADDR0_ADDR, addr0);
xgene_enet_wr_mcx_mac(pdata, STATION_ADDR1_ADDR, addr1);
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h
index 15ec426..2efc4d9 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h
@@ -179,7 +179,6 @@ enum xgene_enet_rm {
#define TUND_ADDR 0x4a
#define TSO_IPPROTO_TCP 1
-#define FULL_DUPLEX 2
#define USERINFO_POS 0
#define USERINFO_LEN 32
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
index 9b85239..9e251ec 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
@@ -833,11 +833,9 @@ static int xgene_enet_get_resources(struct xgene_enet_pdata *pdata)
if (pdata->phy_mode == PHY_INTERFACE_MODE_RGMII) {
pdata->mcx_mac_addr = base_addr + BLOCK_ETH_MAC_OFFSET;
pdata->mcx_mac_csr_addr = base_addr + BLOCK_ETH_MAC_CSR_OFFSET;
- pdata->rm = RM3;
} else {
pdata->mcx_mac_addr = base_addr + BLOCK_AXG_MAC_OFFSET;
pdata->mcx_mac_csr_addr = base_addr + BLOCK_AXG_MAC_CSR_OFFSET;
- pdata->rm = RM0;
}
pdata->rx_buff_cnt = NUM_PKT_BUF;
@@ -881,10 +879,12 @@ static void xgene_enet_setup_ops(struct xgene_enet_pdata *pdata)
case PHY_INTERFACE_MODE_RGMII:
pdata->mac_ops = &xgene_gmac_ops;
pdata->port_ops = &xgene_gport_ops;
+ pdata->rm = RM3;
break;
default:
pdata->mac_ops = &xgene_xgmac_ops;
pdata->port_ops = &xgene_xgport_ops;
+ pdata->rm = RM0;
break;
}
}
@@ -895,6 +895,7 @@ static int xgene_enet_probe(struct platform_device *pdev)
struct xgene_enet_pdata *pdata;
struct device *dev = &pdev->dev;
struct napi_struct *napi;
+ struct xgene_mac_ops *mac_ops;
int ret;
ndev = alloc_etherdev(sizeof(struct xgene_enet_pdata));
@@ -937,10 +938,11 @@ static int xgene_enet_probe(struct platform_device *pdev)
napi = &pdata->rx_ring->napi;
netif_napi_add(ndev, napi, xgene_enet_napi, NAPI_POLL_WEIGHT);
+ mac_ops = pdata->mac_ops;
if (pdata->phy_mode == PHY_INTERFACE_MODE_RGMII)
ret = xgene_enet_mdio_config(pdata);
else
- INIT_DELAYED_WORK(&pdata->link_work, xgene_enet_link_state);
+ INIT_DELAYED_WORK(&pdata->link_work, mac_ops->link_state);
return ret;
err:
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.h b/drivers/net/ethernet/apm/xgene/xgene_enet_main.h
index 86cf68b..10b03a1 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.h
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.h
@@ -76,6 +76,7 @@ struct xgene_mac_ops {
void (*tx_disable)(struct xgene_enet_pdata *pdata);
void (*rx_disable)(struct xgene_enet_pdata *pdata);
void (*set_mac_addr)(struct xgene_enet_pdata *pdata);
+ void (*link_state)(struct work_struct *work);
};
struct xgene_port_ops {
@@ -109,7 +110,6 @@ struct xgene_enet_pdata {
void __iomem *base_addr;
void __iomem *ring_csr_addr;
void __iomem *ring_cmd_addr;
- u32 phy_addr;
int phy_mode;
enum xgene_enet_rm rm;
struct rtnl_link_stats64 stats;
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c b/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c
index cd64b9f..67d0720 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c
@@ -284,7 +284,7 @@ static void xgene_enet_shutdown(struct xgene_enet_pdata *pdata)
clk_disable_unprepare(pdata->clk);
}
-void xgene_enet_link_state(struct work_struct *work)
+static void xgene_enet_link_state(struct work_struct *work)
{
struct xgene_enet_pdata *pdata = container_of(to_delayed_work(work),
struct xgene_enet_pdata, link_work);
@@ -322,6 +322,7 @@ struct xgene_mac_ops xgene_xgmac_ops = {
.rx_disable = xgene_xgmac_rx_disable,
.tx_disable = xgene_xgmac_tx_disable,
.set_mac_addr = xgene_xgmac_set_mac_addr,
+ .link_state = xgene_enet_link_state
};
struct xgene_port_ops xgene_xgport_ops = {
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.h b/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.h
index d2d59e7..dcb2087 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.h
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.h
@@ -50,7 +50,6 @@
#define PHY_POLL_LINK_ON (10 * HZ)
#define PHY_POLL_LINK_OFF (PHY_POLL_LINK_ON / 5)
-void xgene_enet_link_state(struct work_struct *work);
extern struct xgene_mac_ops xgene_xgmac_ops;
extern struct xgene_port_ops xgene_xgport_ops;
--
1.9.1
^ permalink raw reply related
* [PATCH v2 3/4] drivers: net: xgene: Add SGMII based 1GbE support
From: Iyappan Subramanian @ 2014-10-14 0:05 UTC (permalink / raw)
To: davem, romieu, netdev, devicetree
Cc: linux-arm-kernel, patches, kchudgar, Iyappan Subramanian
In-Reply-To: <1413245135-2989-1-git-send-email-isubramanian@apm.com>
Signed-off-by: Iyappan Subramanian <isubramanian@apm.com>
Signed-off-by: Keyur Chudgar <kchudgar@apm.com>
---
drivers/net/ethernet/apm/xgene/Makefile | 2 +-
drivers/net/ethernet/apm/xgene/xgene_enet_hw.h | 3 +
drivers/net/ethernet/apm/xgene/xgene_enet_main.c | 10 +-
drivers/net/ethernet/apm/xgene/xgene_enet_main.h | 10 +
drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.c | 389 ++++++++++++++++++++++
drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.h | 41 +++
drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.h | 3 -
7 files changed, 453 insertions(+), 5 deletions(-)
create mode 100644 drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.c
create mode 100644 drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.h
diff --git a/drivers/net/ethernet/apm/xgene/Makefile b/drivers/net/ethernet/apm/xgene/Makefile
index 589b352..68be5655 100644
--- a/drivers/net/ethernet/apm/xgene/Makefile
+++ b/drivers/net/ethernet/apm/xgene/Makefile
@@ -2,6 +2,6 @@
# Makefile for APM X-Gene Ethernet Driver.
#
-xgene-enet-objs := xgene_enet_hw.o xgene_enet_xgmac.o \
+xgene-enet-objs := xgene_enet_hw.o xgene_enet_sgmac.o xgene_enet_xgmac.o \
xgene_enet_main.o xgene_enet_ethtool.o
obj-$(CONFIG_NET_XGENE) += xgene-enet.o
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h
index 2efc4d9..3855858 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h
@@ -44,6 +44,7 @@ static inline u32 xgene_get_bits(u32 val, u32 start, u32 end)
enum xgene_enet_rm {
RM0,
+ RM1,
RM3 = 3
};
@@ -143,6 +144,8 @@ enum xgene_enet_rm {
#define CFG_CLE_FPSEL0_SET(dst, val) xgene_set_bits(dst, val, 16, 4)
#define CFG_MACMODE_SET(dst, val) xgene_set_bits(dst, val, 18, 2)
#define CFG_WAITASYNCRD_SET(dst, val) xgene_set_bits(dst, val, 0, 16)
+#define CFG_CLE_DSTQID0(val) (val & GENMASK(11, 0))
+#define CFG_CLE_FPSEL0(val) ((val << 16) & GENMASK(19, 16))
#define ICM_CONFIG0_REG_0_ADDR 0x0400
#define ICM_CONFIG2_REG_0_ADDR 0x0410
#define RX_DV_GATE_REG_0_ADDR 0x05fc
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
index 9e251ec..3c208cc 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
@@ -21,6 +21,7 @@
#include "xgene_enet_main.h"
#include "xgene_enet_hw.h"
+#include "xgene_enet_sgmac.h"
#include "xgene_enet_xgmac.h"
static void xgene_enet_init_bufpool(struct xgene_enet_desc_ring *buf_pool)
@@ -813,6 +814,7 @@ static int xgene_enet_get_resources(struct xgene_enet_pdata *pdata)
return pdata->phy_mode;
}
if (pdata->phy_mode != PHY_INTERFACE_MODE_RGMII &&
+ pdata->phy_mode != PHY_INTERFACE_MODE_SGMII &&
pdata->phy_mode != PHY_INTERFACE_MODE_XGMII) {
dev_err(dev, "Incorrect phy-connection-type specified\n");
return -ENODEV;
@@ -830,7 +832,8 @@ static int xgene_enet_get_resources(struct xgene_enet_pdata *pdata)
pdata->eth_csr_addr = base_addr + BLOCK_ETH_CSR_OFFSET;
pdata->eth_ring_if_addr = base_addr + BLOCK_ETH_RING_IF_OFFSET;
pdata->eth_diag_csr_addr = base_addr + BLOCK_ETH_DIAG_CSR_OFFSET;
- if (pdata->phy_mode == PHY_INTERFACE_MODE_RGMII) {
+ if (pdata->phy_mode == PHY_INTERFACE_MODE_RGMII ||
+ pdata->phy_mode == PHY_INTERFACE_MODE_SGMII) {
pdata->mcx_mac_addr = base_addr + BLOCK_ETH_MAC_OFFSET;
pdata->mcx_mac_csr_addr = base_addr + BLOCK_ETH_MAC_CSR_OFFSET;
} else {
@@ -881,6 +884,11 @@ static void xgene_enet_setup_ops(struct xgene_enet_pdata *pdata)
pdata->port_ops = &xgene_gport_ops;
pdata->rm = RM3;
break;
+ case PHY_INTERFACE_MODE_SGMII:
+ pdata->mac_ops = &xgene_sgmac_ops;
+ pdata->port_ops = &xgene_sgport_ops;
+ pdata->rm = RM1;
+ break;
default:
pdata->mac_ops = &xgene_xgmac_ops;
pdata->port_ops = &xgene_xgport_ops;
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.h b/drivers/net/ethernet/apm/xgene/xgene_enet_main.h
index 10b03a1..874e5a0 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.h
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.h
@@ -39,6 +39,9 @@
#define NUM_PKT_BUF 64
#define NUM_BUFPOOL 32
+#define PHY_POLL_LINK_ON (10 * HZ)
+#define PHY_POLL_LINK_OFF (PHY_POLL_LINK_ON / 5)
+
/* software context of a descriptor ring */
struct xgene_enet_desc_ring {
struct net_device *ndev;
@@ -118,6 +121,13 @@ struct xgene_enet_pdata {
struct delayed_work link_work;
};
+struct xgene_indirect_ctl {
+ void __iomem *addr;
+ void __iomem *ctl;
+ void __iomem *cmd;
+ void __iomem *cmd_done;
+};
+
/* Set the specified value into a bit-field defined by its starting position
* and length within a single u64.
*/
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.c b/drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.c
new file mode 100644
index 0000000..e6d24c2
--- /dev/null
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.c
@@ -0,0 +1,389 @@
+/* Applied Micro X-Gene SoC Ethernet Driver
+ *
+ * Copyright (c) 2014, Applied Micro Circuits Corporation
+ * Authors: Iyappan Subramanian <isubramanian@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 as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "xgene_enet_main.h"
+#include "xgene_enet_hw.h"
+#include "xgene_enet_sgmac.h"
+
+static void xgene_enet_wr_csr(struct xgene_enet_pdata *p, u32 offset, u32 val)
+{
+ iowrite32(val, p->eth_csr_addr + offset);
+}
+
+static void xgene_enet_wr_ring_if(struct xgene_enet_pdata *p,
+ u32 offset, u32 val)
+{
+ iowrite32(val, p->eth_ring_if_addr + offset);
+}
+
+static void xgene_enet_wr_diag_csr(struct xgene_enet_pdata *p,
+ u32 offset, u32 val)
+{
+ iowrite32(val, p->eth_diag_csr_addr + offset);
+}
+
+static bool xgene_enet_wr_indirect(struct xgene_indirect_ctl *ctl,
+ u32 wr_addr, u32 wr_data)
+{
+ int i;
+
+ iowrite32(wr_addr, ctl->addr);
+ iowrite32(wr_data, ctl->ctl);
+ iowrite32(XGENE_ENET_WR_CMD, ctl->cmd);
+
+ /* wait for write command to complete */
+ for (i = 0; i < 10; i++) {
+ if (ioread32(ctl->cmd_done)) {
+ iowrite32(0, ctl->cmd);
+ return true;
+ }
+ udelay(1);
+ }
+
+ return false;
+}
+
+static void xgene_enet_wr_mac(struct xgene_enet_pdata *p,
+ u32 wr_addr, u32 wr_data)
+{
+ struct xgene_indirect_ctl ctl = {
+ .addr = p->mcx_mac_addr + MAC_ADDR_REG_OFFSET,
+ .ctl = p->mcx_mac_addr + MAC_WRITE_REG_OFFSET,
+ .cmd = p->mcx_mac_addr + MAC_COMMAND_REG_OFFSET,
+ .cmd_done = p->mcx_mac_addr + MAC_COMMAND_DONE_REG_OFFSET
+ };
+
+ if (!xgene_enet_wr_indirect(&ctl, wr_addr, wr_data))
+ netdev_err(p->ndev, "mac write failed, addr: %04x\n", wr_addr);
+}
+
+static u32 xgene_enet_rd_csr(struct xgene_enet_pdata *p, u32 offset)
+{
+ return ioread32(p->eth_csr_addr + offset);
+}
+
+static u32 xgene_enet_rd_diag_csr(struct xgene_enet_pdata *p, u32 offset)
+{
+ return ioread32(p->eth_diag_csr_addr + offset);
+}
+
+static u32 xgene_enet_rd_indirect(struct xgene_indirect_ctl *ctl, u32 rd_addr)
+{
+ u32 rd_data;
+ int i;
+
+ iowrite32(rd_addr, ctl->addr);
+ iowrite32(XGENE_ENET_RD_CMD, ctl->cmd);
+
+ /* wait for read command to complete */
+ for (i = 0; i < 10; i++) {
+ if (ioread32(ctl->cmd_done)) {
+ rd_data = ioread32(ctl->ctl);
+ iowrite32(0, ctl->cmd);
+
+ return rd_data;
+ }
+ udelay(1);
+ }
+
+ pr_err("%s: mac read failed, addr: %04x\n", __func__, rd_addr);
+
+ return 0;
+}
+
+static u32 xgene_enet_rd_mac(struct xgene_enet_pdata *p, u32 rd_addr)
+{
+ struct xgene_indirect_ctl ctl = {
+ .addr = p->mcx_mac_addr + MAC_ADDR_REG_OFFSET,
+ .ctl = p->mcx_mac_addr + MAC_READ_REG_OFFSET,
+ .cmd = p->mcx_mac_addr + MAC_COMMAND_REG_OFFSET,
+ .cmd_done = p->mcx_mac_addr + MAC_COMMAND_DONE_REG_OFFSET
+ };
+
+ return xgene_enet_rd_indirect(&ctl, rd_addr);
+}
+
+static int xgene_enet_ecc_init(struct xgene_enet_pdata *p)
+{
+ struct net_device *ndev = p->ndev;
+ u32 data;
+ int i;
+
+ xgene_enet_wr_diag_csr(p, ENET_CFG_MEM_RAM_SHUTDOWN_ADDR, 0);
+ for (i = 0; i < 10 && data != ~0U ; i++) {
+ usleep_range(100, 110);
+ data = xgene_enet_rd_diag_csr(p, ENET_BLOCK_MEM_RDY_ADDR);
+ }
+
+ if (data != ~0U) {
+ netdev_err(ndev, "Failed to release memory from shutdown\n");
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+static void xgene_enet_config_ring_if_assoc(struct xgene_enet_pdata *p)
+{
+ u32 val = 0xffffffff;
+
+ xgene_enet_wr_ring_if(p, ENET_CFGSSQMIWQASSOC_ADDR, val);
+ xgene_enet_wr_ring_if(p, ENET_CFGSSQMIFPQASSOC_ADDR, val);
+}
+
+static void xgene_mii_phy_write(struct xgene_enet_pdata *p, u8 phy_id,
+ u32 reg, u16 data)
+{
+ u32 addr, wr_data, done;
+ int i;
+
+ addr = PHY_ADDR(phy_id) | REG_ADDR(reg);
+ xgene_enet_wr_mac(p, MII_MGMT_ADDRESS_ADDR, addr);
+
+ wr_data = PHY_CONTROL(data);
+ xgene_enet_wr_mac(p, MII_MGMT_CONTROL_ADDR, wr_data);
+
+ for (i = 0; i < 10; i++) {
+ done = xgene_enet_rd_mac(p, MII_MGMT_INDICATORS_ADDR);
+ if (!(done & BUSY_MASK))
+ return;
+ usleep_range(10, 20);
+ }
+
+ netdev_err(p->ndev, "MII_MGMT write failed\n");
+}
+
+static u32 xgene_mii_phy_read(struct xgene_enet_pdata *p, u8 phy_id, u32 reg)
+{
+ u32 addr, data, done;
+ int i;
+
+ addr = PHY_ADDR(phy_id) | REG_ADDR(reg);
+ xgene_enet_wr_mac(p, MII_MGMT_ADDRESS_ADDR, addr);
+ xgene_enet_wr_mac(p, MII_MGMT_COMMAND_ADDR, READ_CYCLE_MASK);
+
+ for (i = 0; i < 10; i++) {
+ done = xgene_enet_rd_mac(p, MII_MGMT_INDICATORS_ADDR);
+ if (!(done & BUSY_MASK)) {
+ data = xgene_enet_rd_mac(p, MII_MGMT_STATUS_ADDR);
+ xgene_enet_wr_mac(p, MII_MGMT_COMMAND_ADDR, 0);
+
+ return data;
+ }
+ usleep_range(10, 20);
+ }
+
+ netdev_err(p->ndev, "MII_MGMT read failed\n");
+
+ return 0;
+}
+
+static void xgene_sgmac_reset(struct xgene_enet_pdata *p)
+{
+ xgene_enet_wr_mac(p, MAC_CONFIG_1_ADDR, SOFT_RESET1);
+ xgene_enet_wr_mac(p, MAC_CONFIG_1_ADDR, 0);
+}
+
+static void xgene_sgmac_set_mac_addr(struct xgene_enet_pdata *p)
+{
+ u32 addr0, addr1;
+ u8 *dev_addr = p->ndev->dev_addr;
+
+ addr0 = (dev_addr[3] << 24) | (dev_addr[2] << 16) |
+ (dev_addr[1] << 8) | dev_addr[0];
+ xgene_enet_wr_mac(p, STATION_ADDR0_ADDR, addr0);
+
+ addr1 = xgene_enet_rd_mac(p, STATION_ADDR1_ADDR);
+ addr1 |= (dev_addr[5] << 24) | (dev_addr[4] << 16);
+ xgene_enet_wr_mac(p, STATION_ADDR1_ADDR, addr1);
+}
+
+static u32 xgene_enet_link_status(struct xgene_enet_pdata *p)
+{
+ u32 data;
+
+ data = xgene_mii_phy_read(p, INT_PHY_ADDR,
+ SGMII_BASE_PAGE_ABILITY_ADDR >> 2);
+
+ return data & LINK_UP;
+}
+
+static void xgene_sgmac_init(struct xgene_enet_pdata *p)
+{
+ u32 data, loop = 10;
+
+ xgene_sgmac_reset(p);
+
+ /* Enable auto-negotiation */
+ xgene_mii_phy_write(p, INT_PHY_ADDR, SGMII_CONTROL_ADDR >> 2, 0x1000);
+ xgene_mii_phy_write(p, INT_PHY_ADDR, SGMII_TBI_CONTROL_ADDR >> 2, 0);
+
+ while (loop--) {
+ data = xgene_mii_phy_read(p, INT_PHY_ADDR,
+ SGMII_STATUS_ADDR >> 2);
+ if ((data & AUTO_NEG_COMPLETE) && (data & LINK_STATUS))
+ break;
+ usleep_range(10, 20);
+ }
+ if (!(data & AUTO_NEG_COMPLETE) || !(data & LINK_STATUS))
+ netdev_err(p->ndev, "Auto-negotiation failed\n");
+
+ data = xgene_enet_rd_mac(p, MAC_CONFIG_2_ADDR);
+ ENET_INTERFACE_MODE2_SET(&data, 2);
+ xgene_enet_wr_mac(p, MAC_CONFIG_2_ADDR, data | FULL_DUPLEX2);
+ xgene_enet_wr_mac(p, INTERFACE_CONTROL_ADDR, ENET_GHD_MODE);
+
+ data = xgene_enet_rd_csr(p, ENET_SPARE_CFG_REG_ADDR);
+ data |= MPA_IDLE_WITH_QMI_EMPTY;
+ xgene_enet_wr_csr(p, ENET_SPARE_CFG_REG_ADDR, data);
+
+ xgene_sgmac_set_mac_addr(p);
+
+ data = xgene_enet_rd_csr(p, DEBUG_REG_ADDR);
+ data |= CFG_BYPASS_UNISEC_TX | CFG_BYPASS_UNISEC_RX;
+ xgene_enet_wr_csr(p, DEBUG_REG_ADDR, data);
+
+ /* Adjust MDC clock frequency */
+ data = xgene_enet_rd_mac(p, MII_MGMT_CONFIG_ADDR);
+ MGMT_CLOCK_SEL_SET(&data, 7);
+ xgene_enet_wr_mac(p, MII_MGMT_CONFIG_ADDR, data);
+
+ /* Enable drop if bufpool not available */
+ data = xgene_enet_rd_csr(p, RSIF_CONFIG_REG_ADDR);
+ data |= CFG_RSIF_FPBUFF_TIMEOUT_EN;
+ xgene_enet_wr_csr(p, RSIF_CONFIG_REG_ADDR, data);
+
+ /* Rtype should be copied from FP */
+ xgene_enet_wr_csr(p, RSIF_RAM_DBG_REG0_ADDR, 0);
+
+ /* Bypass traffic gating */
+ xgene_enet_wr_csr(p, CFG_LINK_AGGR_RESUME_0_ADDR, TX_PORT0);
+ xgene_enet_wr_csr(p, CFG_BYPASS_ADDR, RESUME_TX);
+ xgene_enet_wr_csr(p, SG_RX_DV_GATE_REG_0_ADDR, RESUME_RX0);
+}
+
+static void xgene_sgmac_rxtx(struct xgene_enet_pdata *p, u32 bits, bool set)
+{
+ u32 data;
+
+ data = xgene_enet_rd_mac(p, MAC_CONFIG_1_ADDR);
+
+ if (set)
+ data |= bits;
+ else
+ data &= ~bits;
+
+ xgene_enet_wr_mac(p, MAC_CONFIG_1_ADDR, data);
+}
+
+static void xgene_sgmac_rx_enable(struct xgene_enet_pdata *p)
+{
+ xgene_sgmac_rxtx(p, RX_EN, true);
+}
+
+static void xgene_sgmac_tx_enable(struct xgene_enet_pdata *p)
+{
+ xgene_sgmac_rxtx(p, TX_EN, true);
+}
+
+static void xgene_sgmac_rx_disable(struct xgene_enet_pdata *p)
+{
+ xgene_sgmac_rxtx(p, RX_EN, false);
+}
+
+static void xgene_sgmac_tx_disable(struct xgene_enet_pdata *p)
+{
+ xgene_sgmac_rxtx(p, TX_EN, false);
+}
+
+static void xgene_enet_reset(struct xgene_enet_pdata *p)
+{
+ clk_prepare_enable(p->clk);
+ clk_disable_unprepare(p->clk);
+ clk_prepare_enable(p->clk);
+
+ xgene_enet_ecc_init(p);
+ xgene_enet_config_ring_if_assoc(p);
+}
+
+static void xgene_enet_cle_bypass(struct xgene_enet_pdata *p,
+ u32 dst_ring_num, u16 bufpool_id)
+{
+ u32 data, fpsel;
+
+ data = CFG_CLE_BYPASS_EN0;
+ xgene_enet_wr_csr(p, CLE_BYPASS_REG0_0_ADDR, data);
+
+ fpsel = xgene_enet_ring_bufnum(bufpool_id) - 0x20;
+ data = CFG_CLE_DSTQID0(dst_ring_num) | CFG_CLE_FPSEL0(fpsel);
+ xgene_enet_wr_csr(p, CLE_BYPASS_REG1_0_ADDR, data);
+}
+
+static void xgene_enet_shutdown(struct xgene_enet_pdata *p)
+{
+ clk_disable_unprepare(p->clk);
+}
+
+static void xgene_enet_link_state(struct work_struct *work)
+{
+ struct xgene_enet_pdata *p = container_of(to_delayed_work(work),
+ struct xgene_enet_pdata, link_work);
+ struct net_device *ndev = p->ndev;
+ u32 link, poll_interval;
+
+ link = xgene_enet_link_status(p);
+ if (link) {
+ if (!netif_carrier_ok(ndev)) {
+ netif_carrier_on(ndev);
+ xgene_sgmac_init(p);
+ xgene_sgmac_rx_enable(p);
+ xgene_sgmac_tx_enable(p);
+ netdev_info(ndev, "Link is Up - 1Gbps\n");
+ }
+ poll_interval = PHY_POLL_LINK_ON;
+ } else {
+ if (netif_carrier_ok(ndev)) {
+ xgene_sgmac_rx_disable(p);
+ xgene_sgmac_tx_disable(p);
+ netif_carrier_off(ndev);
+ netdev_info(ndev, "Link is Down\n");
+ }
+ poll_interval = PHY_POLL_LINK_OFF;
+ }
+
+ schedule_delayed_work(&p->link_work, poll_interval);
+}
+
+struct xgene_mac_ops xgene_sgmac_ops = {
+ .init = xgene_sgmac_init,
+ .reset = xgene_sgmac_reset,
+ .rx_enable = xgene_sgmac_rx_enable,
+ .tx_enable = xgene_sgmac_tx_enable,
+ .rx_disable = xgene_sgmac_rx_disable,
+ .tx_disable = xgene_sgmac_tx_disable,
+ .set_mac_addr = xgene_sgmac_set_mac_addr,
+ .link_state = xgene_enet_link_state
+};
+
+struct xgene_port_ops xgene_sgport_ops = {
+ .reset = xgene_enet_reset,
+ .cle_bypass = xgene_enet_cle_bypass,
+ .shutdown = xgene_enet_shutdown
+};
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.h b/drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.h
new file mode 100644
index 0000000..de43246
--- /dev/null
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.h
@@ -0,0 +1,41 @@
+/* Applied Micro X-Gene SoC Ethernet Driver
+ *
+ * Copyright (c) 2014, Applied Micro Circuits Corporation
+ * Authors: Iyappan Subramanian <isubramanian@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 as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __XGENE_ENET_SGMAC_H__
+#define __XGENE_ENET_SGMAC_H__
+
+#define PHY_ADDR(src) (((src)<<8) & GENMASK(12, 8))
+#define REG_ADDR(src) ((src) & GENMASK(4, 0))
+#define PHY_CONTROL(src) ((src) & GENMASK(15, 0))
+#define INT_PHY_ADDR 0x1e
+#define SGMII_TBI_CONTROL_ADDR 0x44
+#define SGMII_CONTROL_ADDR 0x00
+#define SGMII_STATUS_ADDR 0x04
+#define SGMII_BASE_PAGE_ABILITY_ADDR 0x14
+#define AUTO_NEG_COMPLETE BIT(5)
+#define LINK_STATUS BIT(2)
+#define LINK_UP BIT(15)
+#define MPA_IDLE_WITH_QMI_EMPTY BIT(12)
+#define SG_RX_DV_GATE_REG_0_ADDR 0x0dfc
+
+extern struct xgene_mac_ops xgene_sgmac_ops;
+extern struct xgene_port_ops xgene_sgport_ops;
+
+#endif /* __XGENE_ENET_SGMAC_H__ */
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.h b/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.h
index dcb2087..5a5296a 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.h
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.h
@@ -47,9 +47,6 @@
#define XG_ENET_SPARE_CFG_REG_1_ADDR 0x0410
#define XGENET_RX_DV_GATE_REG_0_ADDR 0x0804
-#define PHY_POLL_LINK_ON (10 * HZ)
-#define PHY_POLL_LINK_OFF (PHY_POLL_LINK_ON / 5)
-
extern struct xgene_mac_ops xgene_xgmac_ops;
extern struct xgene_port_ops xgene_xgport_ops;
--
1.9.1
^ permalink raw reply related
* [PATCH v2 4/4] drivers: net: xgene: Add SGMII based 1GbE ethtool support
From: Iyappan Subramanian @ 2014-10-14 0:05 UTC (permalink / raw)
To: davem, romieu, netdev, devicetree
Cc: linux-arm-kernel, patches, kchudgar, Iyappan Subramanian
In-Reply-To: <1413245135-2989-1-git-send-email-isubramanian@apm.com>
Signed-off-by: Iyappan Subramanian <isubramanian@apm.com>
Signed-off-by: Keyur Chudgar <kchudgar@apm.com>
---
.../net/ethernet/apm/xgene/xgene_enet_ethtool.c | 25 +++++++++++++++-------
1 file changed, 17 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_ethtool.c b/drivers/net/ethernet/apm/xgene/xgene_enet_ethtool.c
index c1c997b..416d6eb 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_ethtool.c
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_ethtool.c
@@ -64,16 +64,25 @@ static int xgene_get_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
return -ENODEV;
return phy_ethtool_gset(phydev, cmd);
+ } else if (pdata->phy_mode == PHY_INTERFACE_MODE_SGMII) {
+ cmd->supported = SUPPORTED_1000baseT_Full |
+ SUPPORTED_Autoneg | SUPPORTED_MII;
+ cmd->advertising = cmd->supported;
+ ethtool_cmd_speed_set(cmd, SPEED_1000);
+ cmd->duplex = DUPLEX_FULL;
+ cmd->port = PORT_MII;
+ cmd->transceiver = XCVR_INTERNAL;
+ cmd->autoneg = AUTONEG_ENABLE;
+ } else {
+ cmd->supported = SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE;
+ cmd->advertising = cmd->supported;
+ ethtool_cmd_speed_set(cmd, SPEED_10000);
+ cmd->duplex = DUPLEX_FULL;
+ cmd->port = PORT_FIBRE;
+ cmd->transceiver = XCVR_INTERNAL;
+ cmd->autoneg = AUTONEG_DISABLE;
}
- cmd->supported = SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE;
- cmd->advertising = cmd->supported;
- ethtool_cmd_speed_set(cmd, SPEED_10000);
- cmd->duplex = DUPLEX_FULL;
- cmd->port = PORT_FIBRE;
- cmd->transceiver = XCVR_EXTERNAL;
- cmd->autoneg = AUTONEG_DISABLE;
-
return 0;
}
--
1.9.1
^ permalink raw reply related
* Re: something is wrong in commit 971f10eca1 - tcp: better TCP_SKB_CB layout to reduce cache line misses
From: Cong Wang @ 2014-10-14 0:09 UTC (permalink / raw)
To: Eric Dumazet; +Cc: Krzysztof Kolasa, netdev, edumazet, David Miller
In-Reply-To: <CAHA+R7OWpjO0AbwteOAfxd1fej6BcjXR99xy+MnkZ8y+JZ8f4g@mail.gmail.com>
On Mon, Oct 13, 2014 at 4:59 PM, Cong Wang <cwang@twopensource.com> wrote:
> Probably not related with this bug, but with regarding to the
> offending commit, what's the point of the memmove() in tcp_v4_rcv()
> since ip_rcv() already clears IPCB()?
Oh, ip options are actually saved in ip_rcv_finish()... Hmm, looks scary
to play with variable-length array with memmove()....
^ permalink raw reply
* Re: [PATCH v4 04/25] virtio: defer config changed notifications
From: Rusty Russell @ 2014-10-14 0:31 UTC (permalink / raw)
To: Michael S. Tsirkin, linux-kernel
Cc: linux-s390, linux-scsi, kvm, Christian Borntraeger, netdev,
virtualization, Paolo Bonzini, Amit Shah, v9fs-developer,
David S. Miller
In-Reply-To: <1413114332-626-5-git-send-email-mst-v4@redhat.com>
"Michael S. Tsirkin" <mst@redhat.com> writes:
> Defer config changed notifications that arrive during
> probe/scan/freeze/restore.
>
> This will allow drivers to set DRIVER_OK earlier, without worrying about
> racing with config change interrupts.
>
> This change will also benefit old hypervisors (before 2009)
> that send interrupts without checking DRIVER_OK: previously,
> the callback could race with driver-specific initialization.
>
> This will also help simplify drivers.
But AFAICT you never *read* dev->config_changed.
You unconditionally trigger a config_changed event in
virtio_config_enable(). That's a bit weird, but probably OK.
How about the following change (on top of your patch). I
think the renaming is clearer, and note the added if() test in
virtio_config_enable().
If you approve, I'll fold it in.
Cheers,
Rusty.
diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
index 2536701b098b..df598dd8c5c8 100644
--- a/drivers/virtio/virtio.c
+++ b/drivers/virtio/virtio.c
@@ -122,7 +122,7 @@ static void __virtio_config_changed(struct virtio_device *dev)
struct virtio_driver *drv = drv_to_virtio(dev->dev.driver);
if (!dev->config_enabled)
- dev->config_changed = true;
+ dev->config_change_pending = true;
else if (drv && drv->config_changed)
drv->config_changed(dev);
}
@@ -148,8 +148,9 @@ static void virtio_config_enable(struct virtio_device *dev)
{
spin_lock_irq(&dev->config_lock);
dev->config_enabled = true;
- __virtio_config_changed(dev);
- dev->config_changed = false;
+ if (dev->config_change_pending)
+ __virtio_config_changed(dev);
+ dev->config_change_pending = false;
spin_unlock_irq(&dev->config_lock);
}
@@ -253,7 +254,7 @@ int register_virtio_device(struct virtio_device *dev)
spin_lock_init(&dev->config_lock);
dev->config_enabled = false;
- dev->config_changed = false;
+ dev->config_change_pending = false;
/* We always start by resetting the device, in case a previous
* driver messed it up. This also tests that code path a little. */
diff --git a/include/linux/virtio.h b/include/linux/virtio.h
index 5636b119dc25..65261a7244fc 100644
--- a/include/linux/virtio.h
+++ b/include/linux/virtio.h
@@ -80,7 +80,7 @@ bool virtqueue_is_broken(struct virtqueue *vq);
* @index: unique position on the virtio bus
* @failed: saved value for CONFIG_S_FAILED bit (for restore)
* @config_enabled: configuration change reporting enabled
- * @config_changed: configuration change reported while disabled
+ * @config_change_pending: configuration change reported while disabled
* @config_lock: protects configuration change reporting
* @dev: underlying device.
* @id: the device type identification (used to match it with a driver).
@@ -94,7 +94,7 @@ struct virtio_device {
int index;
bool failed;
bool config_enabled;
- bool config_changed;
+ bool config_change_pending;
spinlock_t config_lock;
struct device dev;
struct virtio_device_id id;
^ permalink raw reply related
* color box, display box, corrugated box, color card, blister card, color sleeve, hang tag, label
From: Jinghao Printing - CHINA @ 2014-10-14 1:54 UTC (permalink / raw)
Hi, this is David Wu from Shanghai, China.
We are a printing company, we can print color box, corrugated box,
label, hang tag etc.
Please let me know if you need these.
I will send you the website then.
Best regards,
David Wu
^ permalink raw reply
* Verify Your Account Else It Will Be Blocked
From: Webmaster @ 2014-10-14 2:18 UTC (permalink / raw)
--
Dear user,
We are undergoing maintenance therefore all accounts must be updated,
this is to reduce the number of dormant accounts.
Accounts not updated in 48 hours will be suspended.
Please follow the hyper link below to update your account
Click Here To Update Account.
http://zimbra1.my3gb.com/
Best Regards,
Administrator
^ permalink raw reply
* Re: [PATCH 1/3] virtio_net: pass well-formed sgs to virtqueue_add_*()
From: Rusty Russell @ 2014-10-14 2:21 UTC (permalink / raw)
To: Michael S. Tsirkin, Paolo Bonzini; +Cc: netdev, Andy Lutomirski, virtualization
In-Reply-To: <20140907072032.GA25143@redhat.com>
"Michael S. Tsirkin" <mst@redhat.com> writes:
> On Fri, Sep 05, 2014 at 12:40:50PM +0200, Paolo Bonzini wrote:
>> Il 03/09/2014 06:29, Rusty Russell ha scritto:
>> > + sg_init_table(rq->sg, MAX_SKB_FRAGS + 2);
>>
>> I think 2 is enough here. That said...
>>
>> > sg_set_buf(rq->sg, &hdr->hdr, sizeof hdr->hdr);
>> > -
>> > skb_to_sgvec(skb, rq->sg + 1, 0, skb->len);
>> >
>> > err = virtqueue_add_inbuf(rq->vq, rq->sg, 2, skb, gfp);
>>
>> ... skb_to_sgvec will already make the sg well formed, so the
>> sg_init_table is _almost_ redundant; it is only there to remove
>> intermediate end marks. The block layer takes care to remove
>> them, but skb_to_sgvec doesn't.
sg_init_table is still needed if CONFIG_DEBUG_SG, so I don't
think it's worth it.
Thanks,
Rusty.
^ permalink raw reply
* Re: [ovs-dev] [PATCH/RFC repost 7/8] ofproto: translate datapath select group action
From: Simon Horman @ 2014-10-14 4:54 UTC (permalink / raw)
To: Ben Pfaff; +Cc: Simon Horman, dev, netdev
In-Reply-To: <20141013204624.GD6806@nicira.com>
On Mon, Oct 13, 2014 at 01:46:24PM -0700, Ben Pfaff wrote:
> On Thu, Oct 09, 2014 at 10:14:36AM +0900, Simon Horman wrote:
> > On Fri, Sep 26, 2014 at 04:57:25PM -0700, Ben Pfaff wrote:
> > > On Thu, Sep 18, 2014 at 10:55:10AM +0900, Simon Horman wrote:
> > > > This patch is a prototype and has several limitations:
> > > >
> > > > * It assumes that no actions follow a select group action
> > > > because the resulting packet after a select group action may
> > > > differ depending on the bucket used. It may be possible
> > > > to address this problem using recirculation. Or to not use
> > > > the datapath select group in such situations. In any case
> > > > this patch does not solve this problem or even prevent it
> > > > from occurring.
> > >
> > > It seems like this limitation in particular is a pretty big one. Do
> > > you have a good plan in mind for how to resolve it?
> >
> > Hi Ben,
> >
> > it seems to me that this would be somewhat difficult to resolve in the
> > datapath so I propose not doing so. And I have two ideas on how to
> > resolve this problem outside of the datapath.
> >
> > 1. Recirculation
> >
> > It seems to me that it ought to be possible to handle this by
> > recirculating if actions occur after an ODP select group action.
> >
> > This could be made slightly more selective by only recirculating
> > if the execution different buckets may result in different packet
> > contents and the actions after the ODP select group action rely on
> > the packet contents (e.g. set actions do but output actions do not).
> >
> > My feeling is that this could be implemented by adding a small amount
> > of extra state to action translation in ovs-vswitchd.
> >
> > 2. Fall back to selecting buckets in ovs-vswtichd
> >
> > The idea here is to detect cases where there would be a problem
> > executing actions after an ODP select group action and in that
> > case to select buckets in ovs-vswtichd: that is use the existing bucket
> > translation code in ovs-vswtichd.
> >
> > Though this seems conceptually simpler than recirculation it
> > seems to me that it would be somewhat more difficult to implement
> > as it implies a two stage translation process: e.g. one stage to
> > determine if an ODP select group may be used; and one to perform
> > the translation.
> >
> > I seem to recall trying various two stage translation processes
> > as part some earlier unrelated work. And my recollection is that
> > the result of my previous efforts were not pretty.
> >
> > Both of the above more or less negate any benefits of ODP select group
> > action. In particular lowering flow setup cost and potentially allowing
> > complete offload of select groups from the datapath to hardware. However I
> > think that this case is not a common one as it requires both of the
> > following. And I think they are both not usual use cases.
> >
> > * Different buckets modifying packets in different ways
> > - My expectation is that it is common for buckets to be homogeneous in
> > regards to packet modifications. But perhaps this is na??ve in the
> > context of VLANs, MPLS, and similar tags that can be pushed and popped.
> > * Actions that rely on packet contents after
> > - My expectation is that it is common to use a select group to output
> > packets and that is the final action performed.
>
> I am glad that you have thought about it. Your ideas seem like a good
> start to me. Personally, approach #2, of falling back to selecting
> buckets in ovs-vswitchd, seems like a clean solution to me, although
> if it really takes multiple stages in translation then that is
> undesirable, so I hope that some clean and simple approach works out.
Thanks. I'll focus on #2 and see how far I can get.
> I think that we probably need a solution before we can apply the patch
> series, because otherwise we end up with half-working code.
Yes, I agree. It needs to be solved before it can be merged.
^ permalink raw reply
* [PATCH v2] ipv4: dst_entry leak in ip_append_data()
From: Vasily Averin @ 2014-10-14 4:57 UTC (permalink / raw)
To: netdev, David S. Miller
Cc: Alexey Kuznetsov, James Morris, Hideaki YOSHIFUJI,
Patrick McHardy, Eric Dumazet
v2: adjust the indentation of the arguments __ip_append_data() call
Fixes: 2e77d89b2fa8 ("net: avoid a pair of dst_hold()/dst_release() in ip_append_data()")
If sk_write_queue is empty ip_append_data() executes ip_setup_cork()
that "steals" dst entry from rt to cork. Later it calls __ip_append_data()
that creates skb and adds it to sk_write_queue.
If skb was added successfully following ip_push_pending_frames() call
reassign dst entries from cork to skb, and kfree_skb frees dst_entry.
However nobody frees stolen dst_entry if skb was not added into sk_write_queue.
Signed-off-by: Vasily Averin <vvs@parallels.com>
---
net/ipv4/ip_output.c | 29 +++++++++++++++++------------
1 file changed, 17 insertions(+), 12 deletions(-)
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index e35b712..3ba2291 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -1120,6 +1120,15 @@ static int ip_setup_cork(struct sock *sk, struct inet_cork *cork,
return 0;
}
+static void ip_cork_release(struct inet_cork *cork)
+{
+ cork->flags &= ~IPCORK_OPT;
+ kfree(cork->opt);
+ cork->opt = NULL;
+ dst_release(cork->dst);
+ cork->dst = NULL;
+}
+
/*
* ip_append_data() and ip_append_page() can make one large IP datagram
* from many pieces of data. Each pieces will be holded on the socket
@@ -1152,9 +1161,14 @@ int ip_append_data(struct sock *sk, struct flowi4 *fl4,
transhdrlen = 0;
}
- return __ip_append_data(sk, fl4, &sk->sk_write_queue, &inet->cork.base,
- sk_page_frag(sk), getfrag,
- from, length, transhdrlen, flags);
+ err = __ip_append_data(sk, fl4, &sk->sk_write_queue, &inet->cork.base,
+ sk_page_frag(sk), getfrag,
+ from, length, transhdrlen, flags);
+
+ if (skb_queue_empty(&sk->sk_write_queue))
+ ip_cork_release(&inet->cork.base);
+
+ return err;
}
ssize_t ip_append_page(struct sock *sk, struct flowi4 *fl4, struct page *page,
@@ -1304,15 +1318,6 @@ error:
return err;
}
-static void ip_cork_release(struct inet_cork *cork)
-{
- cork->flags &= ~IPCORK_OPT;
- kfree(cork->opt);
- cork->opt = NULL;
- dst_release(cork->dst);
- cork->dst = NULL;
-}
-
/*
* Combined all pending IP fragments on the socket as one IP datagram
* and push them out.
--
1.9.1
^ permalink raw reply related
* [PATCH] net: fec: ptp: fix convergence issue to support LinuxPTP stack
From: Fugang Duan @ 2014-10-14 5:39 UTC (permalink / raw)
To: davem; +Cc: netdev, bhutchings, b20596, b38611
IEEE 1588 module has one hw issue in capturing the ATVR register. According
to the user manual it is:
ENET0->ATCR |= ENET_ATCR_CAPTURE_MASK;
while(ENET0->ATCR & ENET_ATCR_CAPTURE_MASK);
ts_counter_ns = ENET0->ATVR;
Incorrect behavior for ENET_ATCR[Capture and Restart Bits]. These bits will always
read a value zero. According to SPEC, when these bits are set to 1'b1, these should
hold value 1'b1 until the counter value is capture in the register clock domain.
Unfortunately there is a bug with the way the bit "ENET_ATCR_CAPTURE" clears.
So need something like:
ENET0->ATCR |= ENET_ATCR_CAPTURE_MASK;
wait();
ts_counter_ns = ENET0->ATVR;
The wait-time to be at least 6 clock cycle of the slower clock between the register
clock and the 1588 clock. The 1588 ts_clk is 25Mhz, register clock is 66Mhz, so the
wait-time must be greater than 240ns (40ns * 6). The workaround is that adding 1us
delay before read ATVR.
Signed-off-by: Fugang Duan <B38611@freescale.com>
---
drivers/net/ethernet/freescale/fec.h | 47 +++++++++++++++++++++++++++++
drivers/net/ethernet/freescale/fec_main.c | 43 +-------------------------
drivers/net/ethernet/freescale/fec_ptp.c | 5 +++
3 files changed, 53 insertions(+), 42 deletions(-)
diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h
index 1d5e182..b4dccec 100644
--- a/drivers/net/ethernet/freescale/fec.h
+++ b/drivers/net/ethernet/freescale/fec.h
@@ -367,6 +367,53 @@ struct bufdesc_ex {
#define FEC_VLAN_TAG_LEN 0x04
#define FEC_ETHTYPE_LEN 0x02
+/* Controller is ENET-MAC */
+#define FEC_QUIRK_ENET_MAC (1 << 0)
+/* Controller needs driver to swap frame */
+#define FEC_QUIRK_SWAP_FRAME (1 << 1)
+/* Controller uses gasket */
+#define FEC_QUIRK_USE_GASKET (1 << 2)
+/* Controller has GBIT support */
+#define FEC_QUIRK_HAS_GBIT (1 << 3)
+/* Controller has extend desc buffer */
+#define FEC_QUIRK_HAS_BUFDESC_EX (1 << 4)
+/* Controller has hardware checksum support */
+#define FEC_QUIRK_HAS_CSUM (1 << 5)
+/* Controller has hardware vlan support */
+#define FEC_QUIRK_HAS_VLAN (1 << 6)
+/* ENET IP errata ERR006358
+ *
+ * If the ready bit in the transmit buffer descriptor (TxBD[R]) is previously
+ * detected as not set during a prior frame transmission, then the
+ * ENET_TDAR[TDAR] bit is cleared at a later time, even if additional TxBDs
+ * were added to the ring and the ENET_TDAR[TDAR] bit is set. This results in
+ * frames not being transmitted until there is a 0-to-1 transition on
+ * ENET_TDAR[TDAR].
+ */
+#define FEC_QUIRK_ERR006358 (1 << 7)
+/* ENET IP hw AVB
+ *
+ * i.MX6SX ENET IP add Audio Video Bridging (AVB) feature support.
+ * - Two class indicators on receive with configurable priority
+ * - Two class indicators and line speed timer on transmit allowing
+ * implementation class credit based shapers externally
+ * - Additional DMA registers provisioned to allow managing up to 3
+ * independent rings
+ */
+#define FEC_QUIRK_HAS_AVB (1 << 8)
+/* There is a TDAR race condition for mutliQ when the software sets TDAR
+ * and the UDMA clears TDAR simultaneously or in a small window (2-4 cycles).
+ * This will cause the udma_tx and udma_tx_arbiter state machines to hang.
+ * The issue exist at i.MX6SX enet IP.
+ */
+#define FEC_QUIRK_ERR007885 (1 << 9)
+/* ENET Block Guide/ Chapter for the iMX6SLX (PELE) address one issue:
+ * Incorrect behavior for ENET_ATCR[Capture and Restart Bits]. These bits will
+ * always read a value zero. When these bits are set to 1'b1, these should hold
+ * value 1'b1 until the counter value is capture in the register clock domain.
+ */
+#define FEC_QUIRK_BUG_CAPTURE (1 << 10)
+
struct fec_enet_priv_tx_q {
int index;
unsigned char *tx_bounce[TX_RING_SIZE];
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 7a8209e..26d0525 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -78,47 +78,6 @@ static void fec_enet_itr_coal_init(struct net_device *ndev);
#define FEC_ENET_RAFL_V 0x8
#define FEC_ENET_OPD_V 0xFFF0
-/* Controller is ENET-MAC */
-#define FEC_QUIRK_ENET_MAC (1 << 0)
-/* Controller needs driver to swap frame */
-#define FEC_QUIRK_SWAP_FRAME (1 << 1)
-/* Controller uses gasket */
-#define FEC_QUIRK_USE_GASKET (1 << 2)
-/* Controller has GBIT support */
-#define FEC_QUIRK_HAS_GBIT (1 << 3)
-/* Controller has extend desc buffer */
-#define FEC_QUIRK_HAS_BUFDESC_EX (1 << 4)
-/* Controller has hardware checksum support */
-#define FEC_QUIRK_HAS_CSUM (1 << 5)
-/* Controller has hardware vlan support */
-#define FEC_QUIRK_HAS_VLAN (1 << 6)
-/* ENET IP errata ERR006358
- *
- * If the ready bit in the transmit buffer descriptor (TxBD[R]) is previously
- * detected as not set during a prior frame transmission, then the
- * ENET_TDAR[TDAR] bit is cleared at a later time, even if additional TxBDs
- * were added to the ring and the ENET_TDAR[TDAR] bit is set. This results in
- * frames not being transmitted until there is a 0-to-1 transition on
- * ENET_TDAR[TDAR].
- */
-#define FEC_QUIRK_ERR006358 (1 << 7)
-/* ENET IP hw AVB
- *
- * i.MX6SX ENET IP add Audio Video Bridging (AVB) feature support.
- * - Two class indicators on receive with configurable priority
- * - Two class indicators and line speed timer on transmit allowing
- * implementation class credit based shapers externally
- * - Additional DMA registers provisioned to allow managing up to 3
- * independent rings
- */
-#define FEC_QUIRK_HAS_AVB (1 << 8)
-/* There is a TDAR race condition for mutliQ when the software sets TDAR
- * and the UDMA clears TDAR simultaneously or in a small window (2-4 cycles).
- * This will cause the udma_tx and udma_tx_arbiter state machines to hang.
- * The issue exist at i.MX6SX enet IP.
- */
-#define FEC_QUIRK_ERR007885 (1 << 9)
-
static struct platform_device_id fec_devtype[] = {
{
/* keep it for coldfire */
@@ -146,7 +105,7 @@ static struct platform_device_id fec_devtype[] = {
.driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_GBIT |
FEC_QUIRK_HAS_BUFDESC_EX | FEC_QUIRK_HAS_CSUM |
FEC_QUIRK_HAS_VLAN | FEC_QUIRK_HAS_AVB |
- FEC_QUIRK_ERR007885,
+ FEC_QUIRK_ERR007885 | FEC_QUIRK_BUG_CAPTURE,
}, {
/* sentinel */
}
diff --git a/drivers/net/ethernet/freescale/fec_ptp.c b/drivers/net/ethernet/freescale/fec_ptp.c
index cca3617..380bb10 100644
--- a/drivers/net/ethernet/freescale/fec_ptp.c
+++ b/drivers/net/ethernet/freescale/fec_ptp.c
@@ -82,12 +82,17 @@ static cycle_t fec_ptp_read(const struct cyclecounter *cc)
{
struct fec_enet_private *fep =
container_of(cc, struct fec_enet_private, cc);
+ const struct platform_device_id *id_entry =
+ platform_get_device_id(fep->pdev);
u32 tempval;
tempval = readl(fep->hwp + FEC_ATIME_CTRL);
tempval |= FEC_T_CTRL_CAPTURE;
writel(tempval, fep->hwp + FEC_ATIME_CTRL);
+ if (id_entry->driver_data & FEC_QUIRK_BUG_CAPTURE)
+ udelay(1);
+
return readl(fep->hwp + FEC_ATIME);
}
--
1.7.8
^ permalink raw reply related
* [PATCH (net.git)] stmmac: platform: fix FIXED_PHY support.
From: Giuseppe Cavallaro @ 2014-10-14 6:11 UTC (permalink / raw)
To: netdev; +Cc: Giuseppe Cavallaro
On several STi platforms: e.g. stihxxx-b2120 an Ethernet switch is
embedded and connected to the stmmac via RGMII mode. So this is managed
by using the FIXED_PHY. In that case, the support in the platform needs
to be fixed to allow the stmmac to dialog with the switch via fixed-link
by using phy_bus_name property.
Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
---
.../net/ethernet/stmicro/stmmac/stmmac_platform.c | 15 ++++++++++-----
1 files changed, 10 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
index 6521717..4894500 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
@@ -160,11 +160,16 @@ static int stmmac_probe_config_dt(struct platform_device *pdev,
if (of_property_read_u32(np, "snps,phy-addr", &plat->phy_addr) == 0)
dev_warn(&pdev->dev, "snps,phy-addr property is deprecated\n");
- plat->mdio_bus_data = devm_kzalloc(&pdev->dev,
- sizeof(struct stmmac_mdio_bus_data),
- GFP_KERNEL);
-
- plat->force_sf_dma_mode = of_property_read_bool(np, "snps,force_sf_dma_mode");
+ if (plat->phy_bus_name)
+ plat->mdio_bus_data = NULL;
+ else
+ plat->mdio_bus_data =
+ devm_kzalloc(&pdev->dev,
+ sizeof(struct stmmac_mdio_bus_data),
+ GFP_KERNEL);
+
+ plat->force_sf_dma_mode =
+ of_property_read_bool(np, "snps,force_sf_dma_mode");
/* Set the maxmtu to a default of JUMBO_LEN in case the
* parameter is not present in the device tree.
--
1.7.4.4
^ permalink raw reply related
* [PATCH (net.git) 0/2] stmmac: review and fix the dwmac-sti glue-logic
From: Giuseppe Cavallaro @ 2014-10-14 6:12 UTC (permalink / raw)
To: netdev; +Cc: maxime.coquelin, Giuseppe Cavallaro
This patch is to review the whole glue logic adopted on STi SoCs that
was bugged.
In the old glue-logic there was a lot of confusion when setup the
retiming especially for STiD127 where, for example, the bits 6 and 7
(in the GMAC control register) have a different meaning of what is
used for STiH4xx SoCs. So we cannot adopt the same glue for all these
SoCs.
Moreover, GiGa on STiD127 didn't work and, for all the SoCs, the RGMII
couldn't run when the speed was 10Mbps (because the clock was not properly
managed).
Note that the phy clock needs to be provided by the platform as well as
documented in the related binding file (updated as consequence).
The old code supported too many configurations never adopted and validated.
This made the code very complex to maintain and debug in case of issues.
The patch simplifies all the configurations as commented in the tables
inside the file and obviously it has been tested on all the boards
based on the SoCs mentioned.
With this patch, the dwmac-sti is also ready to support new configurations that
will be available on next SoC generations.
Giuseppe Cavallaro (2):
stmmac: make the STi Layer compatible to STiH407
stmmac: dwmac-sti: review the glue-logic for STi4xx and STiD127 SoCs
.../devicetree/bindings/net/sti-dwmac.txt | 91 +++---
drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c | 374 +++++++++++---------
.../net/ethernet/stmicro/stmmac/stmmac_platform.c | 1 +
3 files changed, 255 insertions(+), 211 deletions(-)
--
1.7.4.4
^ permalink raw reply
* [PATCH (net.git) 1/2] stmmac: make the STi Layer compatible to STiH407
From: Giuseppe Cavallaro @ 2014-10-14 6:12 UTC (permalink / raw)
To: netdev; +Cc: maxime.coquelin, Giuseppe Cavallaro
In-Reply-To: <1413267176-325-1-git-send-email-peppe.cavallaro@st.com>
This adds the missing compatibility to the STiH407 SoC.
Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
---
.../devicetree/bindings/net/sti-dwmac.txt | 4 ++--
.../net/ethernet/stmicro/stmmac/stmmac_platform.c | 1 +
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/Documentation/devicetree/bindings/net/sti-dwmac.txt b/Documentation/devicetree/bindings/net/sti-dwmac.txt
index 3dd3d0b..8c84d9a 100644
--- a/Documentation/devicetree/bindings/net/sti-dwmac.txt
+++ b/Documentation/devicetree/bindings/net/sti-dwmac.txt
@@ -3,8 +3,8 @@ STMicroelectronics SoC DWMAC glue layer controller
The device node has following properties.
Required properties:
- - compatible : Can be "st,stih415-dwmac", "st,stih416-dwmac" or
- "st,stid127-dwmac".
+ - compatible : Can be "st,stih415-dwmac", "st,stih416-dwmac",
+ "st,stid127-dwmac", "st,stih407-dwmac".
- reg : Offset of the glue configuration register map in system
configuration regmap pointed by st,syscon property and size.
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
index 4894500..0d6b9ad 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
@@ -40,6 +40,7 @@ static const struct of_device_id stmmac_dt_ids[] = {
{ .compatible = "st,stih415-dwmac", .data = &sti_gmac_data},
{ .compatible = "st,stih416-dwmac", .data = &sti_gmac_data},
{ .compatible = "st,stid127-dwmac", .data = &sti_gmac_data},
+ { .compatible = "st,stih407-dwmac", .data = &sti_gmac_data},
#endif
#ifdef CONFIG_DWMAC_SOCFPGA
{ .compatible = "altr,socfpga-stmmac", .data = &socfpga_gmac_data },
--
1.7.4.4
^ permalink raw reply related
* [PATCH (net.git) 2/2] stmmac: dwmac-sti: review the glue-logic for STi4xx and STiD127 SoCs
From: Giuseppe Cavallaro @ 2014-10-14 6:12 UTC (permalink / raw)
To: netdev; +Cc: maxime.coquelin, Giuseppe Cavallaro, Srinivas Kandagatla
In-Reply-To: <1413267176-325-1-git-send-email-peppe.cavallaro@st.com>
This patch is to review the whole glue logic adopted on STi SoCs that
was bugged.
In the old glue-logic there was a lot of confusion when setup the
retiming especially for STiD127 where, for example, the bits 6 and 7
(in the GMAC control register) have a different meaning of what is
used for STiH4xx SoCs. So we cannot adopt the same glue for all these
SoCs.
Moreover, GiGa on STiD127 didn't work and, for all the SoCs, the RGMII
couldn't run when the speed was 10Mbps (because the clock was not properly
managed).
Note that the phy clock needs to be provided by the platform as well as
documented in the related binding file (updated as consequence).
The old code supported too many configurations never adopted and validated.
This made the code very complex to maintain and debug in case of issues.
The patch simplifies all the configurations as commented in the tables
inside the file and obviously it has been tested on all the boards
based on the SoCs mentioned.
With this patch, the dwmac-sti is also ready to support new configurations that
will be available on next SoC generations.
Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
Cc: Srinivas Kandagatla <srinivas.kandagatla@st.com>
---
.../devicetree/bindings/net/sti-dwmac.txt | 89 +++---
drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c | 374 +++++++++++---------
2 files changed, 253 insertions(+), 210 deletions(-)
diff --git a/Documentation/devicetree/bindings/net/sti-dwmac.txt b/Documentation/devicetree/bindings/net/sti-dwmac.txt
index 8c84d9a..6762a6b 100644
--- a/Documentation/devicetree/bindings/net/sti-dwmac.txt
+++ b/Documentation/devicetree/bindings/net/sti-dwmac.txt
@@ -1,58 +1,65 @@
STMicroelectronics SoC DWMAC glue layer controller
+This file documents differences between the core properties in
+Documentation/devicetree/bindings/net/stmmac.txt
+and what is needed on STi platforms to program the stmmac glue logic.
+
The device node has following properties.
Required properties:
- compatible : Can be "st,stih415-dwmac", "st,stih416-dwmac",
- "st,stid127-dwmac", "st,stih407-dwmac".
- - reg : Offset of the glue configuration register map in system
+ "st,stih407-dwmac", "st,stid127-dwmac".
+ - reg : Offset of the glue configuration register map in system
configuration regmap pointed by st,syscon property and size.
-
- - reg-names : Should be "sti-ethconf".
-
- - st,syscon : Should be phandle to system configuration node which
+ - st,syscon : Should be phandle to system configuration node which
encompases this glue registers.
+ - st,gmac_en: this is to enable the gmac into a dedicated sysctl control
+ register available on STiH407 SoC.
+ - sti-ethconf: this is the gmac glue logic register to enable the GMAC,
+ select among the different modes and program the clk retiming.
+ - pinctrl-0: pin-control for all the MII mode supported.
- - st,tx-retime-src: On STi Parts for Giga bit speeds, 125Mhz clocks can be
- wired up in from different sources. One via TXCLK pin and other via CLK_125
- pin. This wiring is totally board dependent. However the retiming glue
- logic should be configured accordingly. Possible values for this property
-
- "txclk" - if 125Mhz clock is wired up via txclk line.
- "clk_125" - if 125Mhz clock is wired up via clk_125 line.
-
- This property is only valid for Giga bit setup( GMII, RGMII), and it is
- un-used for non-giga bit (MII and RMII) setups. Also note that internal
- clockgen can not generate stable 125Mhz clock.
-
- - st,ext-phyclk: This boolean property indicates who is generating the clock
- for tx and rx. This property is only valid for RMII case where the clock can
- be generated from the MAC or PHY.
-
- - clock-names: should be "sti-ethclk".
- - clocks: Should point to ethernet clockgen which can generate phyclk.
-
+Optional properties:
+ - resets : phandle pointing to the system reset controller with correct
+ reset line index for ethernet reset.
+ - st,ext-phyclk: valid only for RMII where PHY can generate 50MHz clock or
+ MAC can generate it.
+ - st,tx-retime-src: This specifies which clk is wired up to the mac for
+ retimeing tx lines. This is totally board dependent and can take one of the
+ posssible values from "txclk", "clk_125" or "clkgen".
+ If not passed, the internal clock will be used by default.
+ - sti-ethclk: this is the phy clock.
+ - sti-clkconf: this is an extra sysconfig register, available in new SoCs,
+ to program the clk retiming.
+ - st,gmac_en: to enable the GMAC, this only is present in some SoCs; e.g.
+ STiH407.
Example:
-ethernet0: dwmac@fe810000 {
- device_type = "network";
- compatible = "st,stih416-dwmac", "snps,dwmac", "snps,dwmac-3.710";
- reg = <0xfe810000 0x8000>, <0x8bc 0x4>;
- reg-names = "stmmaceth", "sti-ethconf";
- interrupts = <0 133 0>, <0 134 0>, <0 135 0>;
- interrupt-names = "macirq", "eth_wake_irq", "eth_lpi";
- phy-mode = "mii";
+ethernet0: dwmac@9630000 {
+ device_type = "network";
+ status = "disabled";
+ compatible = "st,stih407-dwmac", "snps,dwmac", "snps,dwmac-3.710";
+ reg = <0x9630000 0x8000>, <0x80 0x4>;
+ reg-names = "stmmaceth", "sti-ethconf";
- st,syscon = <&syscfg_rear>;
+ st,syscon = <&syscfg_sbc_reg>;
+ st,gmac_en;
+ resets = <&softreset STIH407_ETH1_SOFTRESET>;
+ reset-names = "stmmaceth";
- snps,pbl = <32>;
+ interrupts = <GIC_SPI 98 IRQ_TYPE_NONE>,
+ <GIC_SPI 99 IRQ_TYPE_NONE>,
+ <GIC_SPI 100 IRQ_TYPE_NONE>;
+ interrupt-names = "macirq", "eth_wake_irq", "eth_lpi";
+
+ snps,pbl = <32>;
snps,mixed-burst;
- resets = <&softreset STIH416_ETH0_SOFTRESET>;
- reset-names = "stmmaceth";
- pinctrl-0 = <&pinctrl_mii0>;
- pinctrl-names = "default";
- clocks = <&CLK_S_GMAC0_PHY>;
- clock-names = "stmmaceth";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_rgmii1>;
+
+ clock-names = "stmmaceth", "sti-ethclk";
+ clocks = <&CLK_S_C0_FLEXGEN CLK_EXT2F_A9>,
+ <&CLK_S_C0_FLEXGEN CLK_ETH_PHY>;
};
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c
index 552bbc1..ccfe7e5 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c
@@ -3,7 +3,7 @@
*
* Copyright (C) 2003-2014 STMicroelectronics (R&D) Limited
* Author: Srinivas Kandagatla <srinivas.kandagatla@st.com>
- *
+ * Contributors: Giuseppe Cavallaro <peppe.cavallaro@st.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -22,45 +22,22 @@
#include <linux/of.h>
#include <linux/of_net.h>
+#define DWMAC_125MHZ 125000000
+#define DWMAC_50MHZ 50000000
+#define DWMAC_25MHZ 25000000
+#define DWMAC_2_5MHZ 2500000
+
+#define IS_PHY_IF_MODE_RGMII(iface) (iface == PHY_INTERFACE_MODE_RGMII || \
+ iface == PHY_INTERFACE_MODE_RGMII_ID || \
+ iface == PHY_INTERFACE_MODE_RGMII_RXID || \
+ iface == PHY_INTERFACE_MODE_RGMII_TXID)
+
+#define IS_PHY_IF_MODE_GBIT(iface) (IS_PHY_IF_MODE_RGMII(iface) || \
+ iface == PHY_INTERFACE_MODE_GMII)
+
+/* STiH4xx register definitions (STiH415/STiH416/STiH407/STiH410 families) */
+
/**
- * STi GMAC glue logic.
- * --------------------
- *
- * _
- * | \
- * --------|0 \ ETH_SEL_INTERNAL_NOTEXT_PHYCLK
- * phyclk | |___________________________________________
- * | | | (phyclk-in)
- * --------|1 / |
- * int-clk |_ / |
- * | _
- * | | \
- * |_______|1 \ ETH_SEL_TX_RETIME_CLK
- * | |___________________________
- * | | (tx-retime-clk)
- * _______|0 /
- * | |_ /
- * _ |
- * | \ |
- * --------|0 \ |
- * clk_125 | |__|
- * | | ETH_SEL_TXCLK_NOT_CLK125
- * --------|1 /
- * txclk |_ /
- *
- *
- * ETH_SEL_INTERNAL_NOTEXT_PHYCLK is valid only for RMII where PHY can
- * generate 50MHz clock or MAC can generate it.
- * This bit is configured by "st,ext-phyclk" property.
- *
- * ETH_SEL_TXCLK_NOT_CLK125 is only valid for gigabit modes, where the 125Mhz
- * clock either comes from clk-125 pin or txclk pin. This configuration is
- * totally driven by the board wiring. This bit is configured by
- * "st,tx-retime-src" property.
- *
- * TXCLK configuration is different for different phy interface modes
- * and changes according to link speed in modes like RGMII.
- *
* Below table summarizes the clock requirement and clock sources for
* supported phy interface modes with link speeds.
* ________________________________________________
@@ -74,44 +51,58 @@
* ------------------------------------------------
*| RGMII | 125Mhz | 25Mhz |
*| | clk-125/txclk | clkgen |
+ *| | clkgen | |
* ------------------------------------------------
*| RMII | n/a | 25Mhz |
*| | |clkgen/phyclk-in |
* ------------------------------------------------
*
- * TX lines are always retimed with a clk, which can vary depending
- * on the board configuration. Below is the table of these bits
- * in eth configuration register depending on source of retime clk.
- *
- *---------------------------------------------------------------
- * src | tx_rt_clk | int_not_ext_phyclk | txclk_n_clk125|
- *---------------------------------------------------------------
- * txclk | 0 | n/a | 1 |
- *---------------------------------------------------------------
- * ck_125| 0 | n/a | 0 |
- *---------------------------------------------------------------
- * phyclk| 1 | 0 | n/a |
- *---------------------------------------------------------------
- * clkgen| 1 | 1 | n/a |
- *---------------------------------------------------------------
+ * Register Configuration
+ *-------------------------------
+ * src |BIT(8)| BIT(7)| BIT(6)|
+ *-------------------------------
+ * txclk | 0 | n/a | 1 |
+ *-------------------------------
+ * ck_125| 0 | n/a | 0 |
+ *-------------------------------
+ * phyclk| 1 | 0 | n/a |
+ *-------------------------------
+ * clkgen| 1 | 1 | n/a |
+ *-------------------------------
*/
- /* Register definition */
+#define STIH4XX_RETIME_SRC_MASK GENMASK(8, 6)
+#define STIH4XX_ETH_SEL_TX_RETIME_CLK BIT(8)
+#define STIH4XX_ETH_SEL_INTERNAL_NOTEXT_PHYCLK BIT(7)
+#define STIH4XX_ETH_SEL_TXCLK_NOT_CLK125 BIT(6)
+
+/* STiD127 register definitions */
- /* 3 bits [8:6]
- * [6:6] ETH_SEL_TXCLK_NOT_CLK125
- * [7:7] ETH_SEL_INTERNAL_NOTEXT_PHYCLK
- * [8:8] ETH_SEL_TX_RETIME_CLK
- *
- */
+/**
+ *-----------------------
+ * src |BIT(6)| BIT(7)|
+ *-----------------------
+ * MII | 1 | n/a |
+ *-----------------------
+ * RMII | n/a | 1 |
+ * clkgen| | |
+ *-----------------------
+ * RMII | n/a | 0 |
+ * phyclk| | |
+ *-----------------------
+ * RGMII | 1 | n/a |
+ * clkgen| | |
+ *-----------------------
+ */
-#define TX_RETIME_SRC_MASK GENMASK(8, 6)
-#define ETH_SEL_TX_RETIME_CLK BIT(8)
-#define ETH_SEL_INTERNAL_NOTEXT_PHYCLK BIT(7)
-#define ETH_SEL_TXCLK_NOT_CLK125 BIT(6)
+#define STID127_RETIME_SRC_MASK GENMASK(7, 6)
+#define STID127_ETH_SEL_INTERNAL_NOTEXT_PHYCLK BIT(7)
+#define STID127_ETH_SEL_INTERNAL_NOTEXT_TXCLK BIT(6)
-#define ENMII_MASK GENMASK(5, 5)
-#define ENMII BIT(5)
+#define ENMII_MASK GENMASK(5, 5)
+#define ENMII BIT(5)
+#define EN_MASK GENMASK(1, 1)
+#define EN BIT(1)
/**
* 3 bits [4:2]
@@ -120,29 +111,23 @@
* 010-SGMII
* 100-RMII
*/
-#define MII_PHY_SEL_MASK GENMASK(4, 2)
-#define ETH_PHY_SEL_RMII BIT(4)
-#define ETH_PHY_SEL_SGMII BIT(3)
-#define ETH_PHY_SEL_RGMII BIT(2)
-#define ETH_PHY_SEL_GMII 0x0
-#define ETH_PHY_SEL_MII 0x0
-
-#define IS_PHY_IF_MODE_RGMII(iface) (iface == PHY_INTERFACE_MODE_RGMII || \
- iface == PHY_INTERFACE_MODE_RGMII_ID || \
- iface == PHY_INTERFACE_MODE_RGMII_RXID || \
- iface == PHY_INTERFACE_MODE_RGMII_TXID)
-
-#define IS_PHY_IF_MODE_GBIT(iface) (IS_PHY_IF_MODE_RGMII(iface) || \
- iface == PHY_INTERFACE_MODE_GMII)
+#define MII_PHY_SEL_MASK GENMASK(4, 2)
+#define ETH_PHY_SEL_RMII BIT(4)
+#define ETH_PHY_SEL_SGMII BIT(3)
+#define ETH_PHY_SEL_RGMII BIT(2)
+#define ETH_PHY_SEL_GMII 0x0
+#define ETH_PHY_SEL_MII 0x0
struct sti_dwmac {
- int interface;
- bool ext_phyclk;
- bool is_tx_retime_src_clk_125;
- struct clk *clk;
- int reg;
+ int interface; /* MII interface */
+ bool ext_phyclk; /* Clock from external PHY */
+ u32 tx_retime_src; /* TXCLK Retiming*/
+ struct clk *clk; /* PHY clock */
+ int ctrl_reg; /* GMAC glue-logic control register */
+ int clk_sel_reg; /* GMAC ext clk selection register */
struct device *dev;
struct regmap *regmap;
+ u32 speed;
};
static u32 phy_intf_sels[] = {
@@ -162,74 +147,133 @@ enum {
TX_RETIME_SRC_CLKGEN,
};
-static const char *const tx_retime_srcs[] = {
- [TX_RETIME_SRC_NA] = "",
- [TX_RETIME_SRC_TXCLK] = "txclk",
- [TX_RETIME_SRC_CLK_125] = "clk_125",
- [TX_RETIME_SRC_PHYCLK] = "phyclk",
- [TX_RETIME_SRC_CLKGEN] = "clkgen",
-};
-
-static u32 tx_retime_val[] = {
- [TX_RETIME_SRC_TXCLK] = ETH_SEL_TXCLK_NOT_CLK125,
+static u32 stih4xx_tx_retime_val[] = {
+ [TX_RETIME_SRC_TXCLK] = STIH4XX_ETH_SEL_TXCLK_NOT_CLK125,
[TX_RETIME_SRC_CLK_125] = 0x0,
- [TX_RETIME_SRC_PHYCLK] = ETH_SEL_TX_RETIME_CLK,
- [TX_RETIME_SRC_CLKGEN] = ETH_SEL_TX_RETIME_CLK |
- ETH_SEL_INTERNAL_NOTEXT_PHYCLK,
+ [TX_RETIME_SRC_PHYCLK] = STIH4XX_ETH_SEL_TX_RETIME_CLK,
+ [TX_RETIME_SRC_CLKGEN] = STIH4XX_ETH_SEL_TX_RETIME_CLK
+ | STIH4XX_ETH_SEL_INTERNAL_NOTEXT_PHYCLK,
};
-static void setup_retime_src(struct sti_dwmac *dwmac, u32 spd)
+static void stih4xx_fix_retime_src(void *priv, u32 spd)
{
- u32 src = 0, freq = 0;
-
- if (spd == SPEED_100) {
- if (dwmac->interface == PHY_INTERFACE_MODE_MII ||
- dwmac->interface == PHY_INTERFACE_MODE_GMII) {
- src = TX_RETIME_SRC_TXCLK;
- } else if (dwmac->interface == PHY_INTERFACE_MODE_RMII) {
- if (dwmac->ext_phyclk) {
- src = TX_RETIME_SRC_PHYCLK;
- } else {
- src = TX_RETIME_SRC_CLKGEN;
- freq = 50000000;
- }
-
- } else if (IS_PHY_IF_MODE_RGMII(dwmac->interface)) {
+ struct sti_dwmac *dwmac = priv;
+ u32 src = dwmac->tx_retime_src;
+ u32 reg = dwmac->ctrl_reg;
+ u32 freq = 0;
+
+ if (dwmac->interface == PHY_INTERFACE_MODE_MII) {
+ src = TX_RETIME_SRC_TXCLK;
+ } else if (dwmac->interface == PHY_INTERFACE_MODE_RMII) {
+ if (dwmac->ext_phyclk) {
+ src = TX_RETIME_SRC_PHYCLK;
+ } else {
src = TX_RETIME_SRC_CLKGEN;
- freq = 25000000;
+ freq = DWMAC_50MHZ;
}
+ } else if (IS_PHY_IF_MODE_RGMII(dwmac->interface)) {
+ /* On GiGa clk source can be either ext or from clkgen */
+ if (spd == SPEED_1000) {
+ freq = DWMAC_125MHZ;
+ } else {
+ /* Switch to clkgen for these speeds */
+ src = TX_RETIME_SRC_CLKGEN;
+ if (spd == SPEED_100)
+ freq = DWMAC_25MHZ;
+ else if (spd == SPEED_10)
+ freq = DWMAC_2_5MHZ;
+ }
+ }
- if (src == TX_RETIME_SRC_CLKGEN && dwmac->clk)
- clk_set_rate(dwmac->clk, freq);
+ if (src == TX_RETIME_SRC_CLKGEN && dwmac->clk && freq)
+ clk_set_rate(dwmac->clk, freq);
- } else if (spd == SPEED_1000) {
- if (dwmac->is_tx_retime_src_clk_125)
- src = TX_RETIME_SRC_CLK_125;
- else
- src = TX_RETIME_SRC_TXCLK;
+ regmap_update_bits(dwmac->regmap, reg, STIH4XX_RETIME_SRC_MASK,
+ stih4xx_tx_retime_val[src]);
+}
+
+static void stid127_fix_retime_src(void *priv, u32 spd)
+{
+ struct sti_dwmac *dwmac = priv;
+ u32 reg = dwmac->ctrl_reg;
+ u32 freq = 0;
+ u32 val = 0;
+
+ if (dwmac->interface == PHY_INTERFACE_MODE_MII) {
+ val = STID127_ETH_SEL_INTERNAL_NOTEXT_TXCLK;
+ } else if (dwmac->interface == PHY_INTERFACE_MODE_RMII) {
+ if (!dwmac->ext_phyclk) {
+ val = STID127_ETH_SEL_INTERNAL_NOTEXT_PHYCLK;
+ freq = DWMAC_50MHZ;
+ }
+ } else if (IS_PHY_IF_MODE_RGMII(dwmac->interface)) {
+ val = STID127_ETH_SEL_INTERNAL_NOTEXT_TXCLK;
+ if (spd == SPEED_1000)
+ freq = DWMAC_125MHZ;
+ else if (spd == SPEED_100)
+ freq = DWMAC_25MHZ;
+ else if (spd == SPEED_10)
+ freq = DWMAC_2_5MHZ;
}
- regmap_update_bits(dwmac->regmap, dwmac->reg,
- TX_RETIME_SRC_MASK, tx_retime_val[src]);
+ if (dwmac->clk && freq)
+ clk_set_rate(dwmac->clk, freq);
+
+ regmap_update_bits(dwmac->regmap, reg, STID127_RETIME_SRC_MASK, val);
}
-static void sti_dwmac_exit(struct platform_device *pdev, void *priv)
+static void sti_dwmac_ctrl_init(struct sti_dwmac *dwmac)
{
- struct sti_dwmac *dwmac = priv;
+ struct regmap *regmap = dwmac->regmap;
+ int iface = dwmac->interface;
+ struct device *dev = dwmac->dev;
+ struct device_node *np = dev->of_node;
+ u32 reg = dwmac->ctrl_reg;
+ u32 val;
if (dwmac->clk)
- clk_disable_unprepare(dwmac->clk);
+ clk_prepare_enable(dwmac->clk);
+
+ if (of_property_read_bool(np, "st,gmac_en"))
+ regmap_update_bits(regmap, reg, EN_MASK, EN);
+
+ regmap_update_bits(regmap, reg, MII_PHY_SEL_MASK, phy_intf_sels[iface]);
+
+ val = (iface == PHY_INTERFACE_MODE_REVMII) ? 0 : ENMII;
+ regmap_update_bits(regmap, reg, ENMII_MASK, val);
+}
+
+static int stix4xx_init(struct platform_device *pdev, void *priv)
+{
+ struct sti_dwmac *dwmac = priv;
+ u32 spd = dwmac->speed;
+
+ sti_dwmac_ctrl_init(dwmac);
+
+ stih4xx_fix_retime_src(priv, spd);
+
+ return 0;
}
-static void sti_fix_mac_speed(void *priv, unsigned int spd)
+static int stid127_init(struct platform_device *pdev, void *priv)
{
struct sti_dwmac *dwmac = priv;
+ u32 spd = dwmac->speed;
- setup_retime_src(dwmac, spd);
+ sti_dwmac_ctrl_init(dwmac);
- return;
+ stid127_fix_retime_src(priv, spd);
+
+ return 0;
}
+static void sti_dwmac_exit(struct platform_device *pdev, void *priv)
+{
+ struct sti_dwmac *dwmac = priv;
+
+ if (dwmac->clk)
+ clk_disable_unprepare(dwmac->clk);
+}
static int sti_dwmac_parse_data(struct sti_dwmac *dwmac,
struct platform_device *pdev)
{
@@ -245,6 +289,13 @@ static int sti_dwmac_parse_data(struct sti_dwmac *dwmac,
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sti-ethconf");
if (!res)
return -ENODATA;
+ dwmac->ctrl_reg = res->start;
+
+ /* clk selection from extra syscfg register */
+ dwmac->clk_sel_reg = -ENXIO;
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sti-clkconf");
+ if (res)
+ dwmac->clk_sel_reg = res->start;
regmap = syscon_regmap_lookup_by_phandle(np, "st,syscon");
if (IS_ERR(regmap))
@@ -253,53 +304,31 @@ static int sti_dwmac_parse_data(struct sti_dwmac *dwmac,
dwmac->dev = dev;
dwmac->interface = of_get_phy_mode(np);
dwmac->regmap = regmap;
- dwmac->reg = res->start;
dwmac->ext_phyclk = of_property_read_bool(np, "st,ext-phyclk");
- dwmac->is_tx_retime_src_clk_125 = false;
+ dwmac->tx_retime_src = TX_RETIME_SRC_NA;
+ dwmac->speed = SPEED_100;
if (IS_PHY_IF_MODE_GBIT(dwmac->interface)) {
const char *rs;
+ dwmac->tx_retime_src = TX_RETIME_SRC_CLKGEN;
err = of_property_read_string(np, "st,tx-retime-src", &rs);
- if (err < 0) {
- dev_err(dev, "st,tx-retime-src not specified\n");
- return err;
- }
+ if (err < 0)
+ dev_warn(dev, "Use internal clock source\n");
if (!strcasecmp(rs, "clk_125"))
- dwmac->is_tx_retime_src_clk_125 = true;
+ dwmac->tx_retime_src = TX_RETIME_SRC_CLK_125;
+ else if (!strcasecmp(rs, "txclk"))
+ dwmac->tx_retime_src = TX_RETIME_SRC_TXCLK;
+
+ dwmac->speed = SPEED_1000;
}
dwmac->clk = devm_clk_get(dev, "sti-ethclk");
-
- if (IS_ERR(dwmac->clk))
+ if (IS_ERR(dwmac->clk)) {
+ dev_warn(dev, "No phy clock provided...\n");
dwmac->clk = NULL;
-
- return 0;
-}
-
-static int sti_dwmac_init(struct platform_device *pdev, void *priv)
-{
- struct sti_dwmac *dwmac = priv;
- struct regmap *regmap = dwmac->regmap;
- int iface = dwmac->interface;
- u32 reg = dwmac->reg;
- u32 val, spd;
-
- if (dwmac->clk)
- clk_prepare_enable(dwmac->clk);
-
- regmap_update_bits(regmap, reg, MII_PHY_SEL_MASK, phy_intf_sels[iface]);
-
- val = (iface == PHY_INTERFACE_MODE_REVMII) ? 0 : ENMII;
- regmap_update_bits(regmap, reg, ENMII_MASK, val);
-
- if (IS_PHY_IF_MODE_GBIT(iface))
- spd = SPEED_1000;
- else
- spd = SPEED_100;
-
- setup_retime_src(dwmac, spd);
+ }
return 0;
}
@@ -322,9 +351,16 @@ static void *sti_dwmac_setup(struct platform_device *pdev)
return dwmac;
}
-const struct stmmac_of_data sti_gmac_data = {
- .fix_mac_speed = sti_fix_mac_speed,
+const struct stmmac_of_data stih4xx_dwmac_data = {
+ .fix_mac_speed = stih4xx_fix_retime_src,
+ .setup = sti_dwmac_setup,
+ .init = stix4xx_init,
+ .exit = sti_dwmac_exit,
+};
+
+const struct stmmac_of_data stid127_dwmac_data = {
+ .fix_mac_speed = stid127_fix_retime_src,
.setup = sti_dwmac_setup,
- .init = sti_dwmac_init,
+ .init = stid127_init,
.exit = sti_dwmac_exit,
};
--
1.7.4.4
^ permalink raw reply related
* Re: [PATCH v9 net-next 2/4] net: filter: split filter.h and expose eBPF to user space
From: Daniel Borkmann @ 2014-10-14 7:34 UTC (permalink / raw)
To: Alexei Starovoitov
Cc: David S. Miller, Ingo Molnar, Linus Torvalds, Andy Lutomirski,
Steven Rostedt, Hannes Frederic Sowa, Chema Gonzalez,
Eric Dumazet, Peter Zijlstra, H. Peter Anvin, Andrew Morton,
Kees Cook, Linux API, Network Development, LKML
In-Reply-To: <CAMEtUuw-iAGiYqmcN0AOkku0+Wto7810JJo9HEQvQN-2F=baTA@mail.gmail.com>
On 10/13/2014 11:49 PM, Alexei Starovoitov wrote:
> On Mon, Oct 13, 2014 at 10:21 AM, Daniel Borkmann <dborkman@redhat.com> wrote:
>> On 09/03/2014 05:46 PM, Daniel Borkmann wrote:
>> ...
>>>
>>> Ok, given you post the remaining two RFCs later on this window as
>>> you indicate, I have no objections:
>>>
>>> Acked-by: Daniel Borkmann <dborkman@redhat.com>
>>
>> Ping, Alexei, are you still sending the patch for bpf_common.h or
>> do you want me to take care of this?
>
> It's not forgotten.
> I'm not sending it only because net-next is closed
> and it seems to be -next material.
Well, the point was since it's UAPI you're modifying, that it needs
to be shipped before it first gets exposed to user land ...
I think that should be reason enough ... there's no point in doing
this at a later point in time.
^ permalink raw reply
* Re: nf_reject_ipv4: module license 'unspecified' taints kernel
From: Dave Young @ 2014-10-14 8:11 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: davem, netdev, linux-kernel, netfilter-devel
In-Reply-To: <20141010095520.GA3126@salvia>
On 10/10/14 at 11:56am, Pablo Neira Ayuso wrote:
> On Fri, Oct 10, 2014 at 05:19:04PM +0800, Dave Young wrote:
> > Hi,
> >
> > With today's linus tree, I got below kmsg:
> > [ 23.545204] nf_reject_ipv4: module license 'unspecified' taints kernel.
> >
> > It could be caused by below commit:
> >
> > commit c8d7b98bec43faaa6583c3135030be5eb4693acb
> > Author: Pablo Neira Ayuso <pablo@netfilter.org>
> > Date: Fri Sep 26 14:35:15 2014 +0200
> >
> > netfilter: move nf_send_resetX() code to nf_reject_ipvX modules
> >
> > Move nf_send_reset() and nf_send_reset6() to nf_reject_ipv4 and
> > nf_reject_ipv6 respectively. This code is shared by x_tables and
> > nf_tables.
> >
> > Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
>
> Patch attached, thanks for reporting.
Tested-by: Dave Young <dyoung@redhat.com>
>
> P.S: Please, Cc netfilter-devel@vger.kernel.org in future reports, so
> we make sure things don't get lost.
Sure. Thanks.
> From d4358bcf64ba7a64d4de4e1dc5533c4c8f88ea82 Mon Sep 17 00:00:00 2001
> From: Pablo Neira Ayuso <pablo@netfilter.org>
> Date: Fri, 10 Oct 2014 11:25:20 +0200
> Subject: [PATCH] netfilter: missing module license in the nf_reject_ipvX
> modules
>
> [ 23.545204] nf_reject_ipv4: module license 'unspecified' taints kernel.
>
> Reported-by: Dave Young <dyoung@redhat.com>
> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
> ---
> net/ipv4/netfilter/nf_reject_ipv4.c | 3 +++
> net/ipv6/netfilter/nf_reject_ipv6.c | 4 ++++
> 2 files changed, 7 insertions(+)
>
> diff --git a/net/ipv4/netfilter/nf_reject_ipv4.c b/net/ipv4/netfilter/nf_reject_ipv4.c
> index b023b4e..92b303d 100644
> --- a/net/ipv4/netfilter/nf_reject_ipv4.c
> +++ b/net/ipv4/netfilter/nf_reject_ipv4.c
> @@ -6,6 +6,7 @@
> * published by the Free Software Foundation.
> */
>
> +#include <linux/module.h>
> #include <net/ip.h>
> #include <net/tcp.h>
> #include <net/route.h>
> @@ -125,3 +126,5 @@ void nf_send_reset(struct sk_buff *oldskb, int hook)
> kfree_skb(nskb);
> }
> EXPORT_SYMBOL_GPL(nf_send_reset);
> +
> +MODULE_LICENSE("GPL");
> diff --git a/net/ipv6/netfilter/nf_reject_ipv6.c b/net/ipv6/netfilter/nf_reject_ipv6.c
> index 5f5f043..20d9def 100644
> --- a/net/ipv6/netfilter/nf_reject_ipv6.c
> +++ b/net/ipv6/netfilter/nf_reject_ipv6.c
> @@ -5,6 +5,8 @@
> * it under the terms of the GNU General Public License version 2 as
> * published by the Free Software Foundation.
> */
> +
> +#include <linux/module.h>
> #include <net/ipv6.h>
> #include <net/ip6_route.h>
> #include <net/ip6_fib.h>
> @@ -161,3 +163,5 @@ void nf_send_reset6(struct net *net, struct sk_buff *oldskb, int hook)
> ip6_local_out(nskb);
> }
> EXPORT_SYMBOL_GPL(nf_send_reset6);
> +
> +MODULE_LICENSE("GPL");
> --
> 1.7.10.4
>
^ permalink raw reply
* Re: nf_reject_ipv4: module license 'unspecified' taints kernel
From: 'Dave Young' @ 2014-10-14 8:12 UTC (permalink / raw)
To: David Laight
Cc: pablo@netfilter.org, davem@davemloft.net, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org
In-Reply-To: <063D6719AE5E284EB5DD2968C1650D6D174C8305@AcuExch.aculab.com>
On 10/10/14 at 09:53am, David Laight wrote:
> From: Dave Young
> > With today's linus tree, I got below kmsg:
> > [ 23.545204] nf_reject_ipv4: module license 'unspecified' taints kernel.
> > [ 23.551886] Disabling lock debugging due to kernel taint
> ...
>
> Not 100% related, but why does loading a non-GPL module disable
> lock debugging?
> (Is 'lock debugging' actually useful?)
I believe that we can not trust the debugging any more because kernel taint..
Thanks
Dave
^ permalink raw reply
* Re: [PATCH v9 net-next 2/4] net: filter: split filter.h and expose eBPF to user space
From: Alexei Starovoitov @ 2014-10-14 8:43 UTC (permalink / raw)
To: Daniel Borkmann
Cc: David S. Miller, Ingo Molnar, Linus Torvalds, Andy Lutomirski,
Steven Rostedt, Hannes Frederic Sowa, Chema Gonzalez,
Eric Dumazet, Peter Zijlstra, H. Peter Anvin, Andrew Morton,
Kees Cook, Linux API, Network Development, LKML
In-Reply-To: <543CD206.709@redhat.com>
On Tue, Oct 14, 2014 at 12:34 AM, Daniel Borkmann <dborkman@redhat.com> wrote:
> On 10/13/2014 11:49 PM, Alexei Starovoitov wrote:
>>
>> On Mon, Oct 13, 2014 at 10:21 AM, Daniel Borkmann <dborkman@redhat.com>
>> wrote:
>>>
>>> On 09/03/2014 05:46 PM, Daniel Borkmann wrote:
>>> ...
>>>>
>>>>
>>>> Ok, given you post the remaining two RFCs later on this window as
>>>> you indicate, I have no objections:
>>>>
>>>> Acked-by: Daniel Borkmann <dborkman@redhat.com>
>>>
>>>
>>> Ping, Alexei, are you still sending the patch for bpf_common.h or
>>> do you want me to take care of this?
>>
>>
>> It's not forgotten.
>> I'm not sending it only because net-next is closed
>> and it seems to be -next material.
>
>
> Well, the point was since it's UAPI you're modifying, that it needs
> to be shipped before it first gets exposed to user land ...
>
> I think that should be reason enough ... there's no point in doing
> this at a later point in time.
Moving common #defines from filter.h into bpf_common.h can
be done at any point in time. For the sake of argument if
there is an app that includes both filter.h and bpf.h, it will
continue to work just fine.
Anyway, since you insist, I will send it now, though it definitely
can wait.
^ permalink raw reply
* Re: [PATCH v4 04/25] virtio: defer config changed notifications
From: Michael S. Tsirkin @ 2014-10-14 8:59 UTC (permalink / raw)
To: Rusty Russell
Cc: linux-s390, kvm, linux-scsi, Christian Borntraeger, netdev,
linux-kernel, virtualization, Paolo Bonzini, Amit Shah,
v9fs-developer, David S. Miller
In-Reply-To: <87lhojcx0v.fsf@rustcorp.com.au>
On Tue, Oct 14, 2014 at 11:01:12AM +1030, Rusty Russell wrote:
> "Michael S. Tsirkin" <mst@redhat.com> writes:
> > Defer config changed notifications that arrive during
> > probe/scan/freeze/restore.
> >
> > This will allow drivers to set DRIVER_OK earlier, without worrying about
> > racing with config change interrupts.
> >
> > This change will also benefit old hypervisors (before 2009)
> > that send interrupts without checking DRIVER_OK: previously,
> > the callback could race with driver-specific initialization.
> >
> > This will also help simplify drivers.
>
> But AFAICT you never *read* dev->config_changed.
>
> You unconditionally trigger a config_changed event in
> virtio_config_enable(). That's a bit weird, but probably OK.
>
> How about the following change (on top of your patch). I
> think the renaming is clearer, and note the added if() test in
> virtio_config_enable().
>
> If you approve, I'll fold it in.
>
> Cheers,
> Rusty.
Hi Rusty,
I'm okay with both changes.
You can fold it in if you prefer, or just make it a patch on top.
> diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
> index 2536701b098b..df598dd8c5c8 100644
> --- a/drivers/virtio/virtio.c
> +++ b/drivers/virtio/virtio.c
> @@ -122,7 +122,7 @@ static void __virtio_config_changed(struct virtio_device *dev)
> struct virtio_driver *drv = drv_to_virtio(dev->dev.driver);
>
> if (!dev->config_enabled)
> - dev->config_changed = true;
> + dev->config_change_pending = true;
> else if (drv && drv->config_changed)
> drv->config_changed(dev);
> }
> @@ -148,8 +148,9 @@ static void virtio_config_enable(struct virtio_device *dev)
> {
> spin_lock_irq(&dev->config_lock);
> dev->config_enabled = true;
> - __virtio_config_changed(dev);
> - dev->config_changed = false;
> + if (dev->config_change_pending)
> + __virtio_config_changed(dev);
> + dev->config_change_pending = false;
> spin_unlock_irq(&dev->config_lock);
> }
>
> @@ -253,7 +254,7 @@ int register_virtio_device(struct virtio_device *dev)
>
> spin_lock_init(&dev->config_lock);
> dev->config_enabled = false;
> - dev->config_changed = false;
> + dev->config_change_pending = false;
>
> /* We always start by resetting the device, in case a previous
> * driver messed it up. This also tests that code path a little. */
> diff --git a/include/linux/virtio.h b/include/linux/virtio.h
> index 5636b119dc25..65261a7244fc 100644
> --- a/include/linux/virtio.h
> +++ b/include/linux/virtio.h
> @@ -80,7 +80,7 @@ bool virtqueue_is_broken(struct virtqueue *vq);
> * @index: unique position on the virtio bus
> * @failed: saved value for CONFIG_S_FAILED bit (for restore)
> * @config_enabled: configuration change reporting enabled
> - * @config_changed: configuration change reported while disabled
> + * @config_change_pending: configuration change reported while disabled
> * @config_lock: protects configuration change reporting
> * @dev: underlying device.
> * @id: the device type identification (used to match it with a driver).
> @@ -94,7 +94,7 @@ struct virtio_device {
> int index;
> bool failed;
> bool config_enabled;
> - bool config_changed;
> + bool config_change_pending;
> spinlock_t config_lock;
> struct device dev;
> struct virtio_device_id id;
^ permalink raw reply
* [PATCH net] net: filter: move common defines into bpf_common.h
From: Alexei Starovoitov @ 2014-10-14 9:08 UTC (permalink / raw)
To: David S. Miller
Cc: Ingo Molnar, Linus Torvalds, Andy Lutomirski, Steven Rostedt,
Daniel Borkmann, Hannes Frederic Sowa, Chema Gonzalez,
Eric Dumazet, Peter Zijlstra, H. Peter Anvin, Andrew Morton,
Kees Cook, linux-api-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
userspace programs that use eBPF instruction macros need to include two files:
uapi/linux/filter.h and uapi/linux/bpf.h
Move common macro definitions that are shared between classic BPF and eBPF
into uapi/linux/bpf_common.h, so that user app can include only one bpf.h file
Cc: Daniel Borkmann <dborkman-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Alexei Starovoitov <ast-uqk4Ao+rVK5Wk0Htik3J/w@public.gmane.org>
---
Daniel believes that this patch has to be done for this merge window.
I think it can wait till next, but it won't hurt now either.
include/uapi/linux/Kbuild | 1 +
include/uapi/linux/bpf.h | 1 +
include/uapi/linux/bpf_common.h | 55 ++++++++++++++++++++++++++++++++++++++
include/uapi/linux/filter.h | 56 +--------------------------------------
4 files changed, 58 insertions(+), 55 deletions(-)
create mode 100644 include/uapi/linux/bpf_common.h
diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild
index 70e150e..1115d68 100644
--- a/include/uapi/linux/Kbuild
+++ b/include/uapi/linux/Kbuild
@@ -68,6 +68,7 @@ header-y += binfmts.h
header-y += blkpg.h
header-y += blktrace_api.h
header-y += bpf.h
+header-y += bpf_common.h
header-y += bpqether.h
header-y += bsg.h
header-y += btrfs.h
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index 31b0ac2..d18316f 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -8,6 +8,7 @@
#define _UAPI__LINUX_BPF_H__
#include <linux/types.h>
+#include <linux/bpf_common.h>
/* Extended instruction set based on top of classic BPF */
diff --git a/include/uapi/linux/bpf_common.h b/include/uapi/linux/bpf_common.h
new file mode 100644
index 0000000..a5c220e
--- /dev/null
+++ b/include/uapi/linux/bpf_common.h
@@ -0,0 +1,55 @@
+#ifndef _UAPI__LINUX_BPF_COMMON_H__
+#define _UAPI__LINUX_BPF_COMMON_H__
+
+/* Instruction classes */
+#define BPF_CLASS(code) ((code) & 0x07)
+#define BPF_LD 0x00
+#define BPF_LDX 0x01
+#define BPF_ST 0x02
+#define BPF_STX 0x03
+#define BPF_ALU 0x04
+#define BPF_JMP 0x05
+#define BPF_RET 0x06
+#define BPF_MISC 0x07
+
+/* ld/ldx fields */
+#define BPF_SIZE(code) ((code) & 0x18)
+#define BPF_W 0x00
+#define BPF_H 0x08
+#define BPF_B 0x10
+#define BPF_MODE(code) ((code) & 0xe0)
+#define BPF_IMM 0x00
+#define BPF_ABS 0x20
+#define BPF_IND 0x40
+#define BPF_MEM 0x60
+#define BPF_LEN 0x80
+#define BPF_MSH 0xa0
+
+/* alu/jmp fields */
+#define BPF_OP(code) ((code) & 0xf0)
+#define BPF_ADD 0x00
+#define BPF_SUB 0x10
+#define BPF_MUL 0x20
+#define BPF_DIV 0x30
+#define BPF_OR 0x40
+#define BPF_AND 0x50
+#define BPF_LSH 0x60
+#define BPF_RSH 0x70
+#define BPF_NEG 0x80
+#define BPF_MOD 0x90
+#define BPF_XOR 0xa0
+
+#define BPF_JA 0x00
+#define BPF_JEQ 0x10
+#define BPF_JGT 0x20
+#define BPF_JGE 0x30
+#define BPF_JSET 0x40
+#define BPF_SRC(code) ((code) & 0x08)
+#define BPF_K 0x00
+#define BPF_X 0x08
+
+#ifndef BPF_MAXINSNS
+#define BPF_MAXINSNS 4096
+#endif
+
+#endif /* _UAPI__LINUX_BPF_COMMON_H__ */
diff --git a/include/uapi/linux/filter.h b/include/uapi/linux/filter.h
index 253b4d4..47785d5 100644
--- a/include/uapi/linux/filter.h
+++ b/include/uapi/linux/filter.h
@@ -7,7 +7,7 @@
#include <linux/compiler.h>
#include <linux/types.h>
-
+#include <linux/bpf_common.h>
/*
* Current version of the filter code architecture.
@@ -32,56 +32,6 @@ struct sock_fprog { /* Required for SO_ATTACH_FILTER. */
struct sock_filter __user *filter;
};
-/*
- * Instruction classes
- */
-
-#define BPF_CLASS(code) ((code) & 0x07)
-#define BPF_LD 0x00
-#define BPF_LDX 0x01
-#define BPF_ST 0x02
-#define BPF_STX 0x03
-#define BPF_ALU 0x04
-#define BPF_JMP 0x05
-#define BPF_RET 0x06
-#define BPF_MISC 0x07
-
-/* ld/ldx fields */
-#define BPF_SIZE(code) ((code) & 0x18)
-#define BPF_W 0x00
-#define BPF_H 0x08
-#define BPF_B 0x10
-#define BPF_MODE(code) ((code) & 0xe0)
-#define BPF_IMM 0x00
-#define BPF_ABS 0x20
-#define BPF_IND 0x40
-#define BPF_MEM 0x60
-#define BPF_LEN 0x80
-#define BPF_MSH 0xa0
-
-/* alu/jmp fields */
-#define BPF_OP(code) ((code) & 0xf0)
-#define BPF_ADD 0x00
-#define BPF_SUB 0x10
-#define BPF_MUL 0x20
-#define BPF_DIV 0x30
-#define BPF_OR 0x40
-#define BPF_AND 0x50
-#define BPF_LSH 0x60
-#define BPF_RSH 0x70
-#define BPF_NEG 0x80
-#define BPF_MOD 0x90
-#define BPF_XOR 0xa0
-
-#define BPF_JA 0x00
-#define BPF_JEQ 0x10
-#define BPF_JGT 0x20
-#define BPF_JGE 0x30
-#define BPF_JSET 0x40
-#define BPF_SRC(code) ((code) & 0x08)
-#define BPF_K 0x00
-#define BPF_X 0x08
-
/* ret - BPF_K and BPF_X also apply */
#define BPF_RVAL(code) ((code) & 0x18)
#define BPF_A 0x10
@@ -91,10 +41,6 @@ struct sock_fprog { /* Required for SO_ATTACH_FILTER. */
#define BPF_TAX 0x00
#define BPF_TXA 0x80
-#ifndef BPF_MAXINSNS
-#define BPF_MAXINSNS 4096
-#endif
-
/*
* Macros for filter block array initializers.
*/
--
1.7.9.5
^ permalink raw reply related
* Re: [PATCH] netfilter: release skbuf when nlmsg put fail
From: Houcheng Lin @ 2014-10-14 9:39 UTC (permalink / raw)
To: Florian Westphal
Cc: pablo, Patrick McHardy, kadlec, davem, netfilter-devel, coreteam,
netdev, Linux Kernel Mailing List
In-Reply-To: <20141013114256.GB6560@breakpoint.cc>
Hi Florian:
Please see my replies below.
2014-10-13 19:42 GMT+08:00 Florian Westphal <fw@strlen.de>:
> Houcheng Lin <houcheng@gmail.com> wrote:
>> When system is under heavy loading, the __nfulnl_send() may may failed
>> to put nlmsg into skbuf of nfulnl_instance. If not clear the skbuff on failed,
>> the __nfulnl_send() will still try to put next nlmsg onto this half-full skbuf
>> and cause the user program can never receive packet.
>>
>> This patch fix this issue by releasing skbuf immediately after nlmst put
>> failed.
>
> Did you observe such problem or is this based on code reading?
> I ask because nflog should make sure we always have enough room left in
> skb to append a done message, see nfulnl_log_packet():
I observe this problem as my user mode program can not received any packet
on receive() function after bursts of packets. After this patch, my user mode
program can always receive packet.
>
> if (inst->skb &&
> size > skb_tailroom(inst->skb) - sizeof(struct nfgenmsg)) {
> /* flush skb */
I agree with you. The code had check skb lefting space before sending.
Not sure where was wrong.
>
> Your patch fixes such 'can never send' skb condition by leaking the
> skb. So at the very least you would need to call kfree_skb(), and
> perhaps also add WARN_ON() so we catch this and can fix up the size
> accounting?
Sorry for not releasing the skb buffer. I modified my code to call kfree_skb on
put failure and call a WARN_ON(1).
A) Below is WARN_ON log that repeatly inserted into syslog when heavy loading:
[ 531.877328] ------------[ cut here ]------------
[ 531.877338] WARNING: CPU: 2 PID: 4133 at
net/netfilter/nfnetlink_log.c:357 __nfulnl_send+0x91/0xb0
[nfnetlink_log]()
[ 531.877340] Modules linked in: nfnetlink_log ebt_nflog ebt_ip
ebtable_filter vhost_net vhost tun ebtable_nat kvm_intel kvm r8169
[ 531.877352] CPU: 2 PID: 4133 Comm: vhost-4131 Tainted: G W
3.17.0-rc6+ #3
[ 531.877354] Hardware name: Gigabyte Technology Co., Ltd.
EP43-UD3L/EP43-UD3L, BIOS F6 08/31/2009
[ 531.877356] 0000000000000165 ffff88023fd038a8 ffffffff8183177b
0000000000000007
[ 531.877359] 0000000000000000 ffff88023fd038e8 ffffffff8104c877
ffff8802361b4000
[ 531.877362] ffff8802213bc600 0000000000000338 ffff88023fd03b6c
ffff8800834a7e00
[ 531.877366] Call Trace:
[ 531.877368] <IRQ> [<ffffffff8183177b>] dump_stack+0x46/0x58
[ 531.877377] [<ffffffff8104c877>] warn_slowpath_common+0x87/0xb0
[ 531.877380] [<ffffffff8104c8b5>] warn_slowpath_null+0x15/0x20
[ 531.877384] [<ffffffffa00e4161>] __nfulnl_send+0x91/0xb0 [nfnetlink_log]
[ 531.877387] [<ffffffffa00e4508>] __nfulnl_flush+0x28/0x40 [nfnetlink_log]
[ 531.877390] [<ffffffffa00e4dbe>] nfulnl_log_packet+0x2ce/0x84c
[nfnetlink_log]
[ 531.877395] [<ffffffff81693d9a>] nf_log_packet+0xda/0x110
[ 531.877400] [<ffffffff8130f029>] ? map_single+0x19/0x20
[ 531.877403] [<ffffffff8130f1e3>] ? swiotlb_map_page+0x93/0x160
[ 531.877408] [<ffffffffa0008c23>] ? rtl8169_start_xmit+0x1c3/0x7c0 [r8169]
[ 531.877412] [<ffffffffa00e0088>] ebt_nflog_tg+0x68/0x7c [ebt_nflog]
[ 531.877417] [<ffffffff81773afa>] ebt_do_table+0x53a/0x700
[ 531.877421] [<ffffffff81765660>] ? br_dev_queue_push_xmit+0x60/0x60
[ 531.877424] [<ffffffffa00d80ba>] ebt_in_hook+0x1a/0x1c [ebtable_filter]
[ 531.877428] [<ffffffff816934c6>] nf_iterate+0x86/0xc0
[ 531.877431] [<ffffffff81765660>] ? br_dev_queue_push_xmit+0x60/0x60
[ 531.877434] [<ffffffff81693575>] nf_hook_slow+0x75/0x150
[ 531.877437] [<ffffffff81765660>] ? br_dev_queue_push_xmit+0x60/0x60
[ 531.877440] [<ffffffff8176573d>] __br_forward+0x7d/0xc0
[ 531.877443] [<ffffffff817658f5>] br_forward+0x55/0x60
[ 531.877446] [<ffffffff81766637>] br_handle_frame_finish+0x147/0x350
[ 531.877449] [<ffffffff817669d8>] br_handle_frame+0x198/0x250
[ 531.877452] [<ffffffff81766840>] ? br_handle_frame_finish+0x350/0x350
[ 531.877456] [<ffffffff816633b6>] __netif_receive_skb_core+0x196/0x700
[ 531.877459] [<ffffffff8109f639>] ? enqueue_hrtimer+0x39/0xc0
[ 531.877462] [<ffffffff81663941>] __netif_receive_skb+0x21/0x70
[ 531.877465] [<ffffffff81663a0f>] process_backlog+0x7f/0x150
[ 531.877468] [<ffffffff816641c9>] net_rx_action+0x109/0x200
[ 531.877471] [<ffffffff8104fe08>] __do_softirq+0xe8/0x2e0
[ 531.877476] [<ffffffff8183cddc>] do_softirq_own_stack+0x1c/0x30
[ 531.877477] <EOI> [<ffffffff81050075>] do_softirq+0x35/0x40
[ 531.877482] [<ffffffff81662ed1>] netif_rx_ni+0x41/0x90
[ 531.877486] [<ffffffffa00bf96c>] tun_get_user+0x3dc/0x860 [tun]
[ 531.877490] [<ffffffffa00c9483>] ? vhost_get_vq_desc+0x223/0x3e0 [vhost]
[ 531.877494] [<ffffffffa00bfe42>] tun_sendmsg+0x52/0x80 [tun]
[ 531.877497] [<ffffffffa00d1d80>] handle_tx+0x240/0x420 [vhost_net]
[ 531.877501] [<ffffffffa00d1f90>] handle_tx_kick+0x10/0x20 [vhost_net]
[ 531.877505] [<ffffffffa00c8a6f>] vhost_worker+0xff/0x1c0 [vhost]
[ 531.877508] [<ffffffffa00c8970>] ?
vhost_attach_cgroups_work+0x30/0x30 [vhost]
[ 531.877511] [<ffffffff810679e4>] kthread+0xc4/0xe0
[ 531.877515] [<ffffffff81067920>] ? flush_kthread_worker+0x90/0x90
[ 531.877518] [<ffffffff8183b46c>] ret_from_fork+0x7c/0xb0
[ 531.877521] [<ffffffff81067920>] ? flush_kthread_worker+0x90/0x90
[ 531.877523] ---[ end trace 4e280f9febf1c04d ]---
B) My ebtable settings to trigger this bug:
-p IPv4 --ip-src 192.168.122.229 --ip-proto tcp --nflog-prefix
"11111"--nflog-group 1 --nflog-range 65535 --nflog-threshold 20 -j
ACCEPT
-p IPv4 --ip-dst 192.168.122.229 --ip-proto tcp --nflog-prefix
"11111"--nflog-group 1 --nflog-range 65535 --nflog-threshold 20 -j
ACCEPT
-p IPv4 --ip-src 192.168.122.222 --ip-proto tcp --nflog-prefix
"11111"--nflog-group 1 --nflog-range 65535 --nflog-threshold 20 -j
ACCEPT
-p IPv4 --ip-dst 192.168.122.222 --ip-proto tcp --nflog-prefix
"11111"--nflog-group 1 --nflog-range 65535 --nflog-threshold 20 -j
ACCEPT
-p IPv4 --ip-src 192.168.122.221 --ip-proto tcp --nflog-prefix
"11111"--nflog-group 1 --nflog-range 65535 --nflog-threshold 20 -j
ACCEPT
-p IPv4 --ip-dst 192.168.122.221 --ip-proto tcp --nflog-prefix
"11111"--nflog-group 1 --nflog-range 65535 --nflog-threshold 20 -j
ACCEPT
C) These IP (229, 222, 221) are actually assigned to 3 VM running on
the same box
--
Best regards,
Houcheng Lin
^ permalink raw reply
* [PATCH v2] netfilter: release skbuf when nlmsg put fail
From: Houcheng Lin @ 2014-10-14 9:42 UTC (permalink / raw)
To: pablo, Patrick McHardy, kadlec, davem, netfilter-devel,
Florian Westphal
Cc: coreteam, netdev, Linux Kernel Mailing List
When system is under heavy loading, the __nfulnl_send() may may failed
to put nlmsg into skbuf of nfulnl_instance. If not clear the skbuff on failed,
the __nfulnl_send() will still try to put next nlmsg onto this half-full skbuf
and cause the user program can never receive packet.
This patch fix this issue by releasing skbuf immediately after nlmst put
failed.
Signed-off-by: Houcheng Lin <houcheng@gmail.com>
---
net/netfilter/nfnetlink_log.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index a11c5ff..0ad5d32 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -353,15 +353,17 @@ __nfulnl_send(struct nfulnl_instance *inst)
NLMSG_DONE,
sizeof(struct nfgenmsg),
0);
- if (!nlh)
+ if (!nlh) {
+ WARN_ON(1);
+ kfree_skb(inst->skb);
goto out;
+ }
}
status = nfnetlink_unicast(inst->skb, inst->net, inst->peer_portid,
MSG_DONTWAIT);
-
+out:
inst->qlen = 0;
inst->skb = NULL;
-out:
return status;
}
--
1.7.9.5
^ permalink raw reply related
* Re: [PATCH] net: fec: ptp: fix convergence issue to support LinuxPTP stack
From: Richard Cochran @ 2014-10-14 10:36 UTC (permalink / raw)
To: Fugang Duan; +Cc: davem, netdev, bhutchings, b20596
In-Reply-To: <1413265187-5228-1-git-send-email-b38611@freescale.com>
On Tue, Oct 14, 2014 at 01:39:47PM +0800, Fugang Duan wrote:
> IEEE 1588 module has one hw issue in capturing the ATVR register. According
> to the user manual it is:
> ENET0->ATCR |= ENET_ATCR_CAPTURE_MASK;
> while(ENET0->ATCR & ENET_ATCR_CAPTURE_MASK);
> ts_counter_ns = ENET0->ATVR;
...
> diff --git a/drivers/net/ethernet/freescale/fec_ptp.c b/drivers/net/ethernet/freescale/fec_ptp.c
> index cca3617..380bb10 100644
> --- a/drivers/net/ethernet/freescale/fec_ptp.c
> +++ b/drivers/net/ethernet/freescale/fec_ptp.c
> @@ -82,12 +82,17 @@ static cycle_t fec_ptp_read(const struct cyclecounter *cc)
> {
> struct fec_enet_private *fep =
> container_of(cc, struct fec_enet_private, cc);
> + const struct platform_device_id *id_entry =
> + platform_get_device_id(fep->pdev);
> u32 tempval;
>
> tempval = readl(fep->hwp + FEC_ATIME_CTRL);
> tempval |= FEC_T_CTRL_CAPTURE;
> writel(tempval, fep->hwp + FEC_ATIME_CTRL);
>
> + if (id_entry->driver_data & FEC_QUIRK_BUG_CAPTURE)
> + udelay(1);
> +
What? You never had
while(ENET0->ATCR & ENET_ATCR_CAPTURE_MASK);
in the first place. Maybe you should try that.
Did this code ever work? I guess not.
> return readl(fep->hwp + FEC_ATIME);
> }
Thanks,
Richard
^ 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