Netdev List
 help / color / mirror / Atom feed
* Re: eth_get_headlen() and unaligned accesses...
From: Alexander Duyck @ 2014-10-10  3:10 UTC (permalink / raw)
  To: David Miller, netdev
In-Reply-To: <20141009.201248.1210454965155680255.davem@davemloft.net>

On 10/09/2014 05:12 PM, David Miller wrote:
> So, we have a bit of a problem, this is on sparc64:
>
> [423475.740836] Kernel unaligned access at TPC[81d330] __skb_flow_get_ports+0x70/0xe0
> [423475.755756] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 3.17.0+ #2
> [423475.767854] Call Trace:
> [423475.772877]  [0000000000433288] kernel_unaligned_trap+0x368/0x5c0
> [423475.785203]  [000000000042a824] sun4v_do_mna+0x84/0xa0
> [423475.795624]  [0000000000406cd0] sun4v_mna+0x5c/0x68
> [423475.805521]  [000000000081d330] __skb_flow_get_ports+0x70/0xe0
> [423475.817323]  [000000000081d6ac] __skb_flow_dissect+0x1ac/0x460
> [423475.829128]  [0000000000843c98] eth_get_headlen+0x38/0xa0
> [423475.840083]  [0000000010064d54] igb_poll+0x8d4/0xf60 [igb]
> [423475.851184]  [00000000008243c8] net_rx_action+0xa8/0x1c0
>
> The chip DMA's to the beginning of a frag page and (unless timestamps
> are enabled) that's where the ethernet header begins.
>
> So any larger than 16-bit access to the IP and later headers will be
> unaligned.
>
> We have various ways we can deal with this based upon the capabilities
> of the chips involved.  Can we configure the IGB to put 2 "don't care"
> bytes at the beginning of the packet?

The problem is the igb part expects to be able to use 2K buffers which 
means it will always try to use the full half of a page.  I had 
forgotten that the function this replaced had worked with unaligned 
accesses as all of the fields I was pulling were only 16b in width.  I 
think I assumed that this function was already setup to handle that.

Actually the fix should be pretty simple.  Just do what we already 
appear to be doing for the iph_to_flow_copy_addrs.  We can use memcpy to 
copy the 4 bytes for the port data instead of doing the direct assignment.

I'll try to submit a patch, just need to see if I have a tree setup as 
it has been a couple weeks.

Thanks,

Alex

^ permalink raw reply

* [PATCH v4 6/6] drivers: net: xgene: Add 10GbE ethtool support
From: Iyappan Subramanian @ 2014-10-10  1:32 UTC (permalink / raw)
  To: davem, netdev, devicetree
  Cc: linux-arm-kernel, patches, kchudgar, Iyappan Subramanian
In-Reply-To: <1412904727-23485-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    | 28 +++++++++++++++++-----
 1 file changed, 22 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_ethtool.c b/drivers/net/ethernet/apm/xgene/xgene_enet_ethtool.c
index 63f2aa5..c1c997b 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_ethtool.c
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_ethtool.c
@@ -59,10 +59,22 @@ static int xgene_get_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
 	struct xgene_enet_pdata *pdata = netdev_priv(ndev);
 	struct phy_device *phydev = pdata->phy_dev;
 
-	if (phydev == NULL)
-		return -ENODEV;
+	if (pdata->phy_mode == PHY_INTERFACE_MODE_RGMII) {
+		if (phydev == NULL)
+			return -ENODEV;
 
-	return phy_ethtool_gset(phydev, cmd);
+		return phy_ethtool_gset(phydev, cmd);
+	}
+
+	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;
 }
 
 static int xgene_set_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
@@ -70,10 +82,14 @@ static int xgene_set_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
 	struct xgene_enet_pdata *pdata = netdev_priv(ndev);
 	struct phy_device *phydev = pdata->phy_dev;
 
-	if (phydev == NULL)
-		return -ENODEV;
+	if (pdata->phy_mode == PHY_INTERFACE_MODE_RGMII) {
+		if (phydev == NULL)
+			return -ENODEV;
+
+		return phy_ethtool_sset(phydev, cmd);
+	}
 
-	return phy_ethtool_sset(phydev, cmd);
+	return -EINVAL;
 }
 
 static void xgene_get_strings(struct net_device *ndev, u32 stringset, u8 *data)
-- 
1.9.1

^ permalink raw reply related

* [PATCH v4 5/6] drivers: net: xgene: Add 10GbE support
From: Iyappan Subramanian @ 2014-10-10  1:32 UTC (permalink / raw)
  To: davem, netdev, devicetree
  Cc: linux-arm-kernel, patches, kchudgar, Iyappan Subramanian
In-Reply-To: <1412904727-23485-1-git-send-email-isubramanian@apm.com>

- Added 10GbE support
- Removed unused macros/variables
- Moved mac_init call to the end of hardware init

Signed-off-by: Iyappan Subramanian <isubramanian@apm.com>
Signed-off-by: Keyur Chudgar <kchudgar@apm.com>
---
 drivers/net/ethernet/apm/xgene/Makefile           |   3 +-
 drivers/net/ethernet/apm/xgene/xgene_enet_hw.h    |  14 +-
 drivers/net/ethernet/apm/xgene/xgene_enet_main.c  |  58 ++--
 drivers/net/ethernet/apm/xgene/xgene_enet_main.h  |   5 +-
 drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c | 331 ++++++++++++++++++++++
 drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.h |  57 ++++
 6 files changed, 438 insertions(+), 30 deletions(-)
 create mode 100644 drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c
 create mode 100644 drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.h

diff --git a/drivers/net/ethernet/apm/xgene/Makefile b/drivers/net/ethernet/apm/xgene/Makefile
index c643e8a..589b352 100644
--- a/drivers/net/ethernet/apm/xgene/Makefile
+++ b/drivers/net/ethernet/apm/xgene/Makefile
@@ -2,5 +2,6 @@
 # Makefile for APM X-Gene Ethernet Driver.
 #
 
-xgene-enet-objs := xgene_enet_hw.o xgene_enet_main.o xgene_enet_ethtool.o
+xgene-enet-objs := xgene_enet_hw.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 084ac68..15ec426 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h
@@ -42,6 +42,11 @@ static inline u32 xgene_get_bits(u32 val, u32 start, u32 end)
 	return (val & GENMASK(end, start)) >> start;
 }
 
+enum xgene_enet_rm {
+	RM0,
+	RM3 = 3
+};
+
 #define CSR_RING_ID		0x0008
 #define OVERWRITE		BIT(31)
 #define IS_BUFFER_POOL		BIT(20)
@@ -52,7 +57,6 @@ static inline u32 xgene_get_bits(u32 val, u32 start, u32 end)
 #define CSR_RING_WR_BASE	0x0070
 #define NUM_RING_CONFIG		5
 #define BUFPOOL_MODE		3
-#define RM3			3
 #define INC_DEC_CMD_ADDR	0x002c
 #define UDP_HDR_SIZE		2
 #define BUF_LEN_CODE_2K		0x5000
@@ -94,11 +98,9 @@ static inline u32 xgene_get_bits(u32 val, u32 start, u32 end)
 
 #define BLOCK_ETH_CSR_OFFSET		0x2000
 #define BLOCK_ETH_RING_IF_OFFSET	0x9000
-#define BLOCK_ETH_CLKRST_CSR_OFFSET	0xC000
 #define BLOCK_ETH_DIAG_CSR_OFFSET	0xD000
 
 #define BLOCK_ETH_MAC_OFFSET		0x0000
-#define BLOCK_ETH_STATS_OFFSET		0x0014
 #define BLOCK_ETH_MAC_CSR_OFFSET	0x2800
 
 #define MAC_ADDR_REG_OFFSET		0x00
@@ -107,12 +109,6 @@ static inline u32 xgene_get_bits(u32 val, u32 start, u32 end)
 #define MAC_READ_REG_OFFSET		0x0c
 #define MAC_COMMAND_DONE_REG_OFFSET	0x10
 
-#define STAT_ADDR_REG_OFFSET		0x00
-#define STAT_COMMAND_REG_OFFSET		0x04
-#define STAT_WRITE_REG_OFFSET		0x08
-#define STAT_READ_REG_OFFSET		0x0c
-#define STAT_COMMAND_DONE_REG_OFFSET	0x10
-
 #define MII_MGMT_CONFIG_ADDR		0x20
 #define MII_MGMT_COMMAND_ADDR		0x24
 #define MII_MGMT_ADDRESS_ADDR		0x28
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
index c432644..9b85239 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_xgmac.h"
 
 static void xgene_enet_init_bufpool(struct xgene_enet_desc_ring *buf_pool)
 {
@@ -390,7 +391,7 @@ static int xgene_enet_process_ring(struct xgene_enet_desc_ring *ring,
 		}
 	}
 
-	return budget;
+	return count;
 }
 
 static int xgene_enet_napi(struct napi_struct *napi, const int budget)
@@ -456,8 +457,10 @@ static int xgene_enet_open(struct net_device *ndev)
 		return ret;
 	napi_enable(&pdata->rx_ring->napi);
 
-	if (pdata->phy_dev)
+	if (pdata->phy_mode == PHY_INTERFACE_MODE_RGMII)
 		phy_start(pdata->phy_dev);
+	else
+		schedule_delayed_work(&pdata->link_work, PHY_POLL_LINK_OFF);
 
 	netif_start_queue(ndev);
 
@@ -471,8 +474,10 @@ static int xgene_enet_close(struct net_device *ndev)
 
 	netif_stop_queue(ndev);
 
-	if (pdata->phy_dev)
+	if (pdata->phy_mode == PHY_INTERFACE_MODE_RGMII)
 		phy_stop(pdata->phy_dev);
+	else
+		cancel_delayed_work_sync(&pdata->link_work);
 
 	napi_disable(&pdata->rx_ring->napi);
 	xgene_enet_free_irq(ndev);
@@ -615,7 +620,6 @@ static struct xgene_enet_desc_ring *xgene_enet_create_desc_ring(
 
 	ring->cmd_base = pdata->ring_cmd_addr + (ring->num << 6);
 	ring->cmd = ring->cmd_base + INC_DEC_CMD_ADDR;
-	pdata->rm = RM3;
 	ring = xgene_enet_setup_ring(ring);
 	netdev_dbg(ndev, "ring info: num=%d  size=%d  id=%d  slots=%d\n",
 		   ring->num, ring->size, ring->id, ring->slots);
@@ -805,8 +809,13 @@ static int xgene_enet_get_resources(struct xgene_enet_pdata *pdata)
 
 	pdata->phy_mode = of_get_phy_mode(pdev->dev.of_node);
 	if (pdata->phy_mode < 0) {
-		dev_err(dev, "Incorrect phy-connection-type in DTS\n");
-		return -EINVAL;
+		dev_err(dev, "Unable to get phy-connection-type\n");
+		return pdata->phy_mode;
+	}
+	if (pdata->phy_mode != PHY_INTERFACE_MODE_RGMII &&
+	    pdata->phy_mode != PHY_INTERFACE_MODE_XGMII) {
+		dev_err(dev, "Incorrect phy-connection-type specified\n");
+		return -ENODEV;
 	}
 
 	pdata->clk = devm_clk_get(&pdev->dev, NULL);
@@ -821,12 +830,18 @@ 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;
-	pdata->mcx_mac_addr = base_addr + BLOCK_ETH_MAC_OFFSET;
-	pdata->mcx_stats_addr = base_addr + BLOCK_ETH_STATS_OFFSET;
-	pdata->mcx_mac_csr_addr = base_addr + BLOCK_ETH_MAC_CSR_OFFSET;
+	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;
 
-	return ret;
+	return 0;
 }
 
 static int xgene_enet_init_hw(struct xgene_enet_pdata *pdata)
@@ -836,8 +851,7 @@ static int xgene_enet_init_hw(struct xgene_enet_pdata *pdata)
 	u16 dst_ring_num;
 	int ret;
 
-	pdata->mac_ops->tx_disable(pdata);
-	pdata->mac_ops->rx_disable(pdata);
+	pdata->port_ops->reset(pdata);
 
 	ret = xgene_enet_create_desc_rings(ndev);
 	if (ret) {
@@ -856,14 +870,23 @@ static int xgene_enet_init_hw(struct xgene_enet_pdata *pdata)
 
 	dst_ring_num = xgene_enet_dst_ring_num(pdata->rx_ring);
 	pdata->port_ops->cle_bypass(pdata, dst_ring_num, buf_pool->id);
+	pdata->mac_ops->init(pdata);
 
 	return ret;
 }
 
 static void xgene_enet_setup_ops(struct xgene_enet_pdata *pdata)
 {
-	pdata->mac_ops = &xgene_gmac_ops;
-	pdata->port_ops = &xgene_gport_ops;
+	switch (pdata->phy_mode) {
+	case PHY_INTERFACE_MODE_RGMII:
+		pdata->mac_ops = &xgene_gmac_ops;
+		pdata->port_ops = &xgene_gport_ops;
+		break;
+	default:
+		pdata->mac_ops = &xgene_xgmac_ops;
+		pdata->port_ops = &xgene_xgport_ops;
+		break;
+	}
 }
 
 static int xgene_enet_probe(struct platform_device *pdev)
@@ -895,8 +918,6 @@ static int xgene_enet_probe(struct platform_device *pdev)
 		goto err;
 
 	xgene_enet_setup_ops(pdata);
-	pdata->port_ops->reset(pdata);
-	pdata->mac_ops->init(pdata);
 
 	ret = register_netdev(ndev);
 	if (ret) {
@@ -916,7 +937,10 @@ 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);
-	ret = xgene_enet_mdio_config(pdata);
+	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);
 
 	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 ac180f9..86cf68b 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.h
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.h
@@ -105,18 +105,17 @@ struct xgene_enet_pdata {
 	void __iomem *eth_ring_if_addr;
 	void __iomem *eth_diag_csr_addr;
 	void __iomem *mcx_mac_addr;
-	void __iomem *mcx_stats_addr;
 	void __iomem *mcx_mac_csr_addr;
 	void __iomem *base_addr;
 	void __iomem *ring_csr_addr;
 	void __iomem *ring_cmd_addr;
 	u32 phy_addr;
 	int phy_mode;
-	u32 speed;
-	u16 rm;
+	enum xgene_enet_rm rm;
 	struct rtnl_link_stats64 stats;
 	struct xgene_mac_ops *mac_ops;
 	struct xgene_port_ops *port_ops;
+	struct delayed_work link_work;
 };
 
 /* Set the specified value into a bit-field defined by its starting position
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c b/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c
new file mode 100644
index 0000000..cd64b9f
--- /dev/null
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c
@@ -0,0 +1,331 @@
+/* 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_xgmac.h"
+
+static void xgene_enet_wr_csr(struct xgene_enet_pdata *pdata,
+			      u32 offset, u32 val)
+{
+	void __iomem *addr = pdata->eth_csr_addr + offset;
+
+	iowrite32(val, addr);
+}
+
+static void xgene_enet_wr_ring_if(struct xgene_enet_pdata *pdata,
+				  u32 offset, u32 val)
+{
+	void __iomem *addr = pdata->eth_ring_if_addr + offset;
+
+	iowrite32(val, addr);
+}
+
+static void xgene_enet_wr_diag_csr(struct xgene_enet_pdata *pdata,
+				   u32 offset, u32 val)
+{
+	void __iomem *addr = pdata->eth_diag_csr_addr + offset;
+
+	iowrite32(val, addr);
+}
+
+static bool xgene_enet_wr_indirect(void __iomem *addr, void __iomem *wr,
+				   void __iomem *cmd, void __iomem *cmd_done,
+				   u32 wr_addr, u32 wr_data)
+{
+	u32 done;
+	u8 wait = 10;
+
+	iowrite32(wr_addr, addr);
+	iowrite32(wr_data, wr);
+	iowrite32(XGENE_ENET_WR_CMD, cmd);
+
+	/* wait for write command to complete */
+	while (!(done = ioread32(cmd_done)) && wait--)
+		udelay(1);
+
+	if (!done)
+		return false;
+
+	iowrite32(0, cmd);
+
+	return true;
+}
+
+static void xgene_enet_wr_mac(struct xgene_enet_pdata *pdata,
+			      u32 wr_addr, u32 wr_data)
+{
+	void __iomem *addr, *wr, *cmd, *cmd_done;
+
+	addr = pdata->mcx_mac_addr + MAC_ADDR_REG_OFFSET;
+	wr = pdata->mcx_mac_addr + MAC_WRITE_REG_OFFSET;
+	cmd = pdata->mcx_mac_addr + MAC_COMMAND_REG_OFFSET;
+	cmd_done = pdata->mcx_mac_addr + MAC_COMMAND_DONE_REG_OFFSET;
+
+	if (!xgene_enet_wr_indirect(addr, wr, cmd, cmd_done, wr_addr, wr_data))
+		netdev_err(pdata->ndev, "MCX mac write failed, addr: %04x\n",
+			   wr_addr);
+}
+
+static void xgene_enet_rd_csr(struct xgene_enet_pdata *pdata,
+			      u32 offset, u32 *val)
+{
+	void __iomem *addr = pdata->eth_csr_addr + offset;
+
+	*val = ioread32(addr);
+}
+
+static void xgene_enet_rd_diag_csr(struct xgene_enet_pdata *pdata,
+				   u32 offset, u32 *val)
+{
+	void __iomem *addr = pdata->eth_diag_csr_addr + offset;
+
+	*val = ioread32(addr);
+}
+
+static bool xgene_enet_rd_indirect(void __iomem *addr, void __iomem *rd,
+				   void __iomem *cmd, void __iomem *cmd_done,
+				   u32 rd_addr, u32 *rd_data)
+{
+	u32 done;
+	u8 wait = 10;
+
+	iowrite32(rd_addr, addr);
+	iowrite32(XGENE_ENET_RD_CMD, cmd);
+
+	/* wait for read command to complete */
+	while (!(done = ioread32(cmd_done)) && wait--)
+		udelay(1);
+
+	if (!done)
+		return false;
+
+	*rd_data = ioread32(rd);
+	iowrite32(0, cmd);
+
+	return true;
+}
+
+static void xgene_enet_rd_mac(struct xgene_enet_pdata *pdata,
+			      u32 rd_addr, u32 *rd_data)
+{
+	void __iomem *addr, *rd, *cmd, *cmd_done;
+
+	addr = pdata->mcx_mac_addr + MAC_ADDR_REG_OFFSET;
+	rd = pdata->mcx_mac_addr + MAC_READ_REG_OFFSET;
+	cmd = pdata->mcx_mac_addr + MAC_COMMAND_REG_OFFSET;
+	cmd_done = pdata->mcx_mac_addr + MAC_COMMAND_DONE_REG_OFFSET;
+
+	if (!xgene_enet_rd_indirect(addr, rd, cmd, cmd_done, rd_addr, rd_data))
+		netdev_err(pdata->ndev, "MCX mac read failed, addr: %04x\n",
+			   rd_addr);
+}
+
+static int xgene_enet_ecc_init(struct xgene_enet_pdata *pdata)
+{
+	struct net_device *ndev = pdata->ndev;
+	u32 data;
+	u8 wait = 10;
+
+	xgene_enet_wr_diag_csr(pdata, ENET_CFG_MEM_RAM_SHUTDOWN_ADDR, 0x0);
+	do {
+		usleep_range(100, 110);
+		xgene_enet_rd_diag_csr(pdata, ENET_BLOCK_MEM_RDY_ADDR, &data);
+	} while ((data != 0xffffffff) && wait--);
+
+	if (data != 0xffffffff) {
+		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 *pdata)
+{
+	xgene_enet_wr_ring_if(pdata, ENET_CFGSSQMIWQASSOC_ADDR, 0);
+	xgene_enet_wr_ring_if(pdata, ENET_CFGSSQMIFPQASSOC_ADDR, 0);
+	xgene_enet_wr_ring_if(pdata, ENET_CFGSSQMIQMLITEWQASSOC_ADDR, 0);
+	xgene_enet_wr_ring_if(pdata, ENET_CFGSSQMIQMLITEFPQASSOC_ADDR, 0);
+}
+
+static void xgene_xgmac_reset(struct xgene_enet_pdata *pdata)
+{
+	xgene_enet_wr_mac(pdata, AXGMAC_CONFIG_0, HSTMACRST);
+	xgene_enet_wr_mac(pdata, AXGMAC_CONFIG_0, 0);
+}
+
+static void xgene_xgmac_set_mac_addr(struct xgene_enet_pdata *pdata)
+{
+	u32 addr0, addr1;
+	u8 *dev_addr = pdata->ndev->dev_addr;
+
+	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);
+
+	xgene_enet_wr_mac(pdata, HSTMACADR_LSW_ADDR, addr0);
+	xgene_enet_wr_mac(pdata, HSTMACADR_MSW_ADDR, addr1);
+}
+
+static u32 xgene_enet_link_status(struct xgene_enet_pdata *pdata)
+{
+	u32 data;
+
+	xgene_enet_rd_csr(pdata, XG_LINK_STATUS_ADDR, &data);
+
+	return data;
+}
+
+static void xgene_xgmac_init(struct xgene_enet_pdata *pdata)
+{
+	u32 data;
+
+	xgene_xgmac_reset(pdata);
+
+	xgene_enet_rd_mac(pdata, AXGMAC_CONFIG_1, &data);
+	data |= HSTPPEN;
+	data &= ~HSTLENCHK;
+	xgene_enet_wr_mac(pdata, AXGMAC_CONFIG_1, data);
+
+	xgene_enet_wr_mac(pdata, HSTMAXFRAME_LENGTH_ADDR, 0x06000600);
+	xgene_xgmac_set_mac_addr(pdata);
+
+	xgene_enet_rd_csr(pdata, XG_RSIF_CONFIG_REG_ADDR, &data);
+	data |= CFG_RSIF_FPBUFF_TIMEOUT_EN;
+	xgene_enet_wr_csr(pdata, XG_RSIF_CONFIG_REG_ADDR, data);
+
+	xgene_enet_wr_csr(pdata, XG_CFG_BYPASS_ADDR, RESUME_TX);
+	xgene_enet_wr_csr(pdata, XGENET_RX_DV_GATE_REG_0_ADDR, 0);
+	xgene_enet_rd_csr(pdata, XG_ENET_SPARE_CFG_REG_ADDR, &data);
+	data |= BIT(12);
+	xgene_enet_wr_csr(pdata, XG_ENET_SPARE_CFG_REG_ADDR, data);
+	xgene_enet_wr_csr(pdata, XG_ENET_SPARE_CFG_REG_1_ADDR, 0x82);
+}
+
+static void xgene_xgmac_rx_enable(struct xgene_enet_pdata *pdata)
+{
+	u32 data;
+
+	xgene_enet_rd_mac(pdata, AXGMAC_CONFIG_1, &data);
+	xgene_enet_wr_mac(pdata, AXGMAC_CONFIG_1, data | HSTRFEN);
+}
+
+static void xgene_xgmac_tx_enable(struct xgene_enet_pdata *pdata)
+{
+	u32 data;
+
+	xgene_enet_rd_mac(pdata, AXGMAC_CONFIG_1, &data);
+	xgene_enet_wr_mac(pdata, AXGMAC_CONFIG_1, data | HSTTFEN);
+}
+
+static void xgene_xgmac_rx_disable(struct xgene_enet_pdata *pdata)
+{
+	u32 data;
+
+	xgene_enet_rd_mac(pdata, AXGMAC_CONFIG_1, &data);
+	xgene_enet_wr_mac(pdata, AXGMAC_CONFIG_1, data & ~HSTRFEN);
+}
+
+static void xgene_xgmac_tx_disable(struct xgene_enet_pdata *pdata)
+{
+	u32 data;
+
+	xgene_enet_rd_mac(pdata, AXGMAC_CONFIG_1, &data);
+	xgene_enet_wr_mac(pdata, AXGMAC_CONFIG_1, data & ~HSTTFEN);
+}
+
+static void xgene_enet_reset(struct xgene_enet_pdata *pdata)
+{
+	clk_prepare_enable(pdata->clk);
+	clk_disable_unprepare(pdata->clk);
+	clk_prepare_enable(pdata->clk);
+
+	xgene_enet_ecc_init(pdata);
+	xgene_enet_config_ring_if_assoc(pdata);
+}
+
+static void xgene_enet_xgcle_bypass(struct xgene_enet_pdata *pdata,
+				    u32 dst_ring_num, u16 bufpool_id)
+{
+	u32 cb, fpsel;
+
+	xgene_enet_rd_csr(pdata, XCLE_BYPASS_REG0_ADDR, &cb);
+	cb |= CFG_CLE_BYPASS_EN0;
+	CFG_CLE_IP_PROTOCOL0_SET(&cb, 3);
+	xgene_enet_wr_csr(pdata, XCLE_BYPASS_REG0_ADDR, cb);
+
+	fpsel = xgene_enet_ring_bufnum(bufpool_id) - 0x20;
+	xgene_enet_rd_csr(pdata, XCLE_BYPASS_REG1_ADDR, &cb);
+	CFG_CLE_DSTQID0_SET(&cb, dst_ring_num);
+	CFG_CLE_FPSEL0_SET(&cb, fpsel);
+	xgene_enet_wr_csr(pdata, XCLE_BYPASS_REG1_ADDR, cb);
+}
+
+static void xgene_enet_shutdown(struct xgene_enet_pdata *pdata)
+{
+	clk_disable_unprepare(pdata->clk);
+}
+
+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);
+	struct net_device *ndev = pdata->ndev;
+	u32 link_status, poll_interval;
+
+	link_status = xgene_enet_link_status(pdata);
+	if (link_status) {
+		if (!netif_carrier_ok(ndev)) {
+			netif_carrier_on(ndev);
+			xgene_xgmac_init(pdata);
+			xgene_xgmac_rx_enable(pdata);
+			xgene_xgmac_tx_enable(pdata);
+			netdev_info(ndev, "Link is Up - 10Gbps\n");
+		}
+		poll_interval = PHY_POLL_LINK_ON;
+	} else {
+		if (netif_carrier_ok(ndev)) {
+			xgene_xgmac_rx_disable(pdata);
+			xgene_xgmac_tx_disable(pdata);
+			netif_carrier_off(ndev);
+			netdev_info(ndev, "Link is Down\n");
+		}
+		poll_interval = PHY_POLL_LINK_OFF;
+	}
+
+	schedule_delayed_work(&pdata->link_work, poll_interval);
+}
+
+struct xgene_mac_ops xgene_xgmac_ops = {
+	.init = xgene_xgmac_init,
+	.reset = xgene_xgmac_reset,
+	.rx_enable = xgene_xgmac_rx_enable,
+	.tx_enable = xgene_xgmac_tx_enable,
+	.rx_disable = xgene_xgmac_rx_disable,
+	.tx_disable = xgene_xgmac_tx_disable,
+	.set_mac_addr = xgene_xgmac_set_mac_addr,
+};
+
+struct xgene_port_ops xgene_xgport_ops = {
+	.reset = xgene_enet_reset,
+	.cle_bypass = xgene_enet_xgcle_bypass,
+	.shutdown = xgene_enet_shutdown,
+};
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.h b/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.h
new file mode 100644
index 0000000..d2d59e7
--- /dev/null
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.h
@@ -0,0 +1,57 @@
+/* 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_XGMAC_H__
+#define __XGENE_ENET_XGMAC_H__
+
+#define BLOCK_AXG_MAC_OFFSET		0x0800
+#define BLOCK_AXG_MAC_CSR_OFFSET	0x2000
+
+#define AXGMAC_CONFIG_0			0x0000
+#define AXGMAC_CONFIG_1			0x0004
+#define HSTMACRST			BIT(31)
+#define HSTTCTLEN			BIT(31)
+#define HSTTFEN				BIT(30)
+#define HSTRCTLEN			BIT(29)
+#define HSTRFEN				BIT(28)
+#define HSTPPEN				BIT(7)
+#define HSTDRPLT64			BIT(5)
+#define HSTLENCHK			BIT(3)
+#define HSTMACADR_LSW_ADDR		0x0010
+#define HSTMACADR_MSW_ADDR		0x0014
+#define HSTMAXFRAME_LENGTH_ADDR		0x0020
+
+#define XG_RSIF_CONFIG_REG_ADDR		0x00a0
+#define XCLE_BYPASS_REG0_ADDR           0x0160
+#define XCLE_BYPASS_REG1_ADDR           0x0164
+#define XG_CFG_BYPASS_ADDR		0x0204
+#define XG_LINK_STATUS_ADDR		0x0228
+#define XG_ENET_SPARE_CFG_REG_ADDR	0x040c
+#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)
+
+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;
+
+#endif /* __XGENE_ENET_XGMAC_H__ */
-- 
1.9.1

^ permalink raw reply related

* [PATCH v4 4/6] drivers: net: xgene: Preparing for adding 10GbE support
From: Iyappan Subramanian @ 2014-10-10  1:32 UTC (permalink / raw)
  To: davem, netdev, devicetree
  Cc: linux-arm-kernel, patches, kchudgar, Iyappan Subramanian
In-Reply-To: <1412904727-23485-1-git-send-email-isubramanian@apm.com>

- Rearranged code to pave the way for adding 10GbE support
- Added mac_ops structure containing function pointers for mac specific functions
- Added port_ops structure containing function pointers for port specific functions

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   | 44 ++++++++++++++++--------
 drivers/net/ethernet/apm/xgene/xgene_enet_hw.h   | 16 ++-------
 drivers/net/ethernet/apm/xgene/xgene_enet_main.c | 40 +++++++++++++--------
 drivers/net/ethernet/apm/xgene/xgene_enet_main.h | 19 ++++++++++
 4 files changed, 78 insertions(+), 41 deletions(-)

diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c
index 812d8d6..c8f3824 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c
@@ -402,7 +402,7 @@ static int xgene_mii_phy_read(struct xgene_enet_pdata *pdata,
 	return data;
 }
 
-void xgene_gmac_set_mac_addr(struct xgene_enet_pdata *pdata)
+static void xgene_gmac_set_mac_addr(struct xgene_enet_pdata *pdata)
 {
 	u32 addr0, addr1;
 	u8 *dev_addr = pdata->ndev->dev_addr;
@@ -436,13 +436,13 @@ static int xgene_enet_ecc_init(struct xgene_enet_pdata *pdata)
 	return 0;
 }
 
-void xgene_gmac_reset(struct xgene_enet_pdata *pdata)
+static void xgene_gmac_reset(struct xgene_enet_pdata *pdata)
 {
 	xgene_enet_wr_mcx_mac(pdata, MAC_CONFIG_1_ADDR, SOFT_RESET1);
 	xgene_enet_wr_mcx_mac(pdata, MAC_CONFIG_1_ADDR, 0);
 }
 
-void xgene_gmac_init(struct xgene_enet_pdata *pdata, int speed)
+static void xgene_gmac_init(struct xgene_enet_pdata *pdata)
 {
 	u32 value, mc2;
 	u32 intf_ctl, rgmii;
@@ -456,7 +456,7 @@ void xgene_gmac_init(struct xgene_enet_pdata *pdata, int speed)
 	xgene_enet_rd_mcx_mac(pdata, INTERFACE_CONTROL_ADDR, &intf_ctl);
 	xgene_enet_rd_csr(pdata, RGMII_REG_0_ADDR, &rgmii);
 
-	switch (speed) {
+	switch (pdata->phy_speed) {
 	case SPEED_10:
 		ENET_INTERFACE_MODE2_SET(&mc2, 1);
 		CFG_MACMODE_SET(&icm0, 0);
@@ -525,8 +525,8 @@ static void xgene_enet_config_ring_if_assoc(struct xgene_enet_pdata *pdata)
 	xgene_enet_wr_ring_if(pdata, ENET_CFGSSQMIQMLITEFPQASSOC_ADDR, val);
 }
 
-void xgene_enet_cle_bypass(struct xgene_enet_pdata *pdata,
-			   u32 dst_ring_num, u16 bufpool_id)
+static void xgene_enet_cle_bypass(struct xgene_enet_pdata *pdata,
+				  u32 dst_ring_num, u16 bufpool_id)
 {
 	u32 cb;
 	u32 fpsel;
@@ -544,7 +544,7 @@ void xgene_enet_cle_bypass(struct xgene_enet_pdata *pdata,
 	xgene_enet_wr_csr(pdata, CLE_BYPASS_REG1_0_ADDR, cb);
 }
 
-void xgene_gmac_rx_enable(struct xgene_enet_pdata *pdata)
+static void xgene_gmac_rx_enable(struct xgene_enet_pdata *pdata)
 {
 	u32 data;
 
@@ -552,7 +552,7 @@ void xgene_gmac_rx_enable(struct xgene_enet_pdata *pdata)
 	xgene_enet_wr_mcx_mac(pdata, MAC_CONFIG_1_ADDR, data | RX_EN);
 }
 
-void xgene_gmac_tx_enable(struct xgene_enet_pdata *pdata)
+static void xgene_gmac_tx_enable(struct xgene_enet_pdata *pdata)
 {
 	u32 data;
 
@@ -560,7 +560,7 @@ void xgene_gmac_tx_enable(struct xgene_enet_pdata *pdata)
 	xgene_enet_wr_mcx_mac(pdata, MAC_CONFIG_1_ADDR, data | TX_EN);
 }
 
-void xgene_gmac_rx_disable(struct xgene_enet_pdata *pdata)
+static void xgene_gmac_rx_disable(struct xgene_enet_pdata *pdata)
 {
 	u32 data;
 
@@ -568,7 +568,7 @@ void xgene_gmac_rx_disable(struct xgene_enet_pdata *pdata)
 	xgene_enet_wr_mcx_mac(pdata, MAC_CONFIG_1_ADDR, data & ~RX_EN);
 }
 
-void xgene_gmac_tx_disable(struct xgene_enet_pdata *pdata)
+static void xgene_gmac_tx_disable(struct xgene_enet_pdata *pdata)
 {
 	u32 data;
 
@@ -576,7 +576,7 @@ void xgene_gmac_tx_disable(struct xgene_enet_pdata *pdata)
 	xgene_enet_wr_mcx_mac(pdata, MAC_CONFIG_1_ADDR, data & ~TX_EN);
 }
 
-void xgene_enet_reset(struct xgene_enet_pdata *pdata)
+static void xgene_enet_reset(struct xgene_enet_pdata *pdata)
 {
 	u32 val;
 
@@ -593,7 +593,7 @@ void xgene_enet_reset(struct xgene_enet_pdata *pdata)
 	xgene_enet_wr_mcx_mac(pdata, MII_MGMT_CONFIG_ADDR, val);
 }
 
-void xgene_gport_shutdown(struct xgene_enet_pdata *pdata)
+static void xgene_gport_shutdown(struct xgene_enet_pdata *pdata)
 {
 	clk_disable_unprepare(pdata->clk);
 }
@@ -627,10 +627,10 @@ static void xgene_enet_adjust_link(struct net_device *ndev)
 
 	if (phydev->link) {
 		if (pdata->phy_speed != phydev->speed) {
-			xgene_gmac_init(pdata, phydev->speed);
+			pdata->phy_speed = phydev->speed;
+			xgene_gmac_init(pdata);
 			xgene_gmac_rx_enable(pdata);
 			xgene_gmac_tx_enable(pdata);
-			pdata->phy_speed = phydev->speed;
 			phy_print_status(phydev);
 		}
 	} else {
@@ -726,3 +726,19 @@ void xgene_enet_mdio_remove(struct xgene_enet_pdata *pdata)
 	mdiobus_free(pdata->mdio_bus);
 	pdata->mdio_bus = NULL;
 }
+
+struct xgene_mac_ops xgene_gmac_ops = {
+	.init = xgene_gmac_init,
+	.reset = xgene_gmac_reset,
+	.rx_enable = xgene_gmac_rx_enable,
+	.tx_enable = xgene_gmac_tx_enable,
+	.rx_disable = xgene_gmac_rx_disable,
+	.tx_disable = xgene_gmac_tx_disable,
+	.set_mac_addr = xgene_gmac_set_mac_addr,
+};
+
+struct xgene_port_ops xgene_gport_ops = {
+	.reset = xgene_enet_reset,
+	.cle_bypass = xgene_enet_cle_bypass,
+	.shutdown = xgene_gport_shutdown,
+};
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h
index 371e7a5..084ac68 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h
@@ -318,20 +318,10 @@ void xgene_enet_parse_error(struct xgene_enet_desc_ring *ring,
 			    struct xgene_enet_pdata *pdata,
 			    enum xgene_enet_err_code status);
 
-void xgene_enet_reset(struct xgene_enet_pdata *priv);
-void xgene_gmac_reset(struct xgene_enet_pdata *priv);
-void xgene_gmac_init(struct xgene_enet_pdata *priv, int speed);
-void xgene_gmac_tx_enable(struct xgene_enet_pdata *priv);
-void xgene_gmac_rx_enable(struct xgene_enet_pdata *priv);
-void xgene_gmac_tx_disable(struct xgene_enet_pdata *priv);
-void xgene_gmac_rx_disable(struct xgene_enet_pdata *priv);
-void xgene_gmac_set_mac_addr(struct xgene_enet_pdata *pdata);
-void xgene_enet_cle_bypass(struct xgene_enet_pdata *pdata,
-			   u32 dst_ring_num, u16 bufpool_id);
-void xgene_gport_shutdown(struct xgene_enet_pdata *priv);
-void xgene_gmac_get_tx_stats(struct xgene_enet_pdata *pdata);
-
 int xgene_enet_mdio_config(struct xgene_enet_pdata *pdata);
 void xgene_enet_mdio_remove(struct xgene_enet_pdata *pdata);
 
+extern struct xgene_mac_ops xgene_gmac_ops;
+extern struct xgene_port_ops xgene_gport_ops;
+
 #endif /* __XGENE_ENET_HW_H__ */
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
index e4222af..c432644 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
@@ -413,7 +413,7 @@ static void xgene_enet_timeout(struct net_device *ndev)
 {
 	struct xgene_enet_pdata *pdata = netdev_priv(ndev);
 
-	xgene_gmac_reset(pdata);
+	pdata->mac_ops->reset(pdata);
 }
 
 static int xgene_enet_register_irq(struct net_device *ndev)
@@ -445,10 +445,11 @@ static void xgene_enet_free_irq(struct net_device *ndev)
 static int xgene_enet_open(struct net_device *ndev)
 {
 	struct xgene_enet_pdata *pdata = netdev_priv(ndev);
+	struct xgene_mac_ops *mac_ops = pdata->mac_ops;
 	int ret;
 
-	xgene_gmac_tx_enable(pdata);
-	xgene_gmac_rx_enable(pdata);
+	mac_ops->tx_enable(pdata);
+	mac_ops->rx_enable(pdata);
 
 	ret = xgene_enet_register_irq(ndev);
 	if (ret)
@@ -466,6 +467,7 @@ static int xgene_enet_open(struct net_device *ndev)
 static int xgene_enet_close(struct net_device *ndev)
 {
 	struct xgene_enet_pdata *pdata = netdev_priv(ndev);
+	struct xgene_mac_ops *mac_ops = pdata->mac_ops;
 
 	netif_stop_queue(ndev);
 
@@ -476,8 +478,8 @@ static int xgene_enet_close(struct net_device *ndev)
 	xgene_enet_free_irq(ndev);
 	xgene_enet_process_ring(pdata->rx_ring, -1);
 
-	xgene_gmac_tx_disable(pdata);
-	xgene_gmac_rx_disable(pdata);
+	mac_ops->tx_disable(pdata);
+	mac_ops->rx_disable(pdata);
 
 	return 0;
 }
@@ -724,7 +726,7 @@ static int xgene_enet_set_mac_address(struct net_device *ndev, void *addr)
 	ret = eth_mac_addr(ndev, addr);
 	if (ret)
 		return ret;
-	xgene_gmac_set_mac_addr(pdata);
+	pdata->mac_ops->set_mac_addr(pdata);
 
 	return ret;
 }
@@ -834,8 +836,8 @@ static int xgene_enet_init_hw(struct xgene_enet_pdata *pdata)
 	u16 dst_ring_num;
 	int ret;
 
-	xgene_gmac_tx_disable(pdata);
-	xgene_gmac_rx_disable(pdata);
+	pdata->mac_ops->tx_disable(pdata);
+	pdata->mac_ops->rx_disable(pdata);
 
 	ret = xgene_enet_create_desc_rings(ndev);
 	if (ret) {
@@ -853,11 +855,17 @@ static int xgene_enet_init_hw(struct xgene_enet_pdata *pdata)
 	}
 
 	dst_ring_num = xgene_enet_dst_ring_num(pdata->rx_ring);
-	xgene_enet_cle_bypass(pdata, dst_ring_num, buf_pool->id);
+	pdata->port_ops->cle_bypass(pdata, dst_ring_num, buf_pool->id);
 
 	return ret;
 }
 
+static void xgene_enet_setup_ops(struct xgene_enet_pdata *pdata)
+{
+	pdata->mac_ops = &xgene_gmac_ops;
+	pdata->port_ops = &xgene_gport_ops;
+}
+
 static int xgene_enet_probe(struct platform_device *pdev)
 {
 	struct net_device *ndev;
@@ -886,8 +894,9 @@ static int xgene_enet_probe(struct platform_device *pdev)
 	if (ret)
 		goto err;
 
-	xgene_enet_reset(pdata);
-	xgene_gmac_init(pdata, SPEED_1000);
+	xgene_enet_setup_ops(pdata);
+	pdata->port_ops->reset(pdata);
+	pdata->mac_ops->init(pdata);
 
 	ret = register_netdev(ndev);
 	if (ret) {
@@ -918,19 +927,21 @@ err:
 static int xgene_enet_remove(struct platform_device *pdev)
 {
 	struct xgene_enet_pdata *pdata;
+	struct xgene_mac_ops *mac_ops;
 	struct net_device *ndev;
 
 	pdata = platform_get_drvdata(pdev);
+	mac_ops = pdata->mac_ops;
 	ndev = pdata->ndev;
 
-	xgene_gmac_rx_disable(pdata);
-	xgene_gmac_tx_disable(pdata);
+	mac_ops->rx_disable(pdata);
+	mac_ops->tx_disable(pdata);
 
 	netif_napi_del(&pdata->rx_ring->napi);
 	xgene_enet_mdio_remove(pdata);
 	xgene_enet_delete_desc_rings(pdata);
 	unregister_netdev(ndev);
-	xgene_gport_shutdown(pdata);
+	pdata->port_ops->shutdown(pdata);
 	free_netdev(ndev);
 
 	return 0;
@@ -956,5 +967,6 @@ module_platform_driver(xgene_enet_driver);
 
 MODULE_DESCRIPTION("APM X-Gene SoC Ethernet driver");
 MODULE_VERSION(XGENE_DRV_VERSION);
+MODULE_AUTHOR("Iyappan Subramanian <isubramanian@apm.com>");
 MODULE_AUTHOR("Keyur Chudgar <kchudgar@apm.com>");
 MODULE_LICENSE("GPL");
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.h b/drivers/net/ethernet/apm/xgene/xgene_enet_main.h
index 0815866..ac180f9 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.h
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.h
@@ -68,6 +68,23 @@ struct xgene_enet_desc_ring {
 	};
 };
 
+struct xgene_mac_ops {
+	void (*init)(struct xgene_enet_pdata *pdata);
+	void (*reset)(struct xgene_enet_pdata *pdata);
+	void (*tx_enable)(struct xgene_enet_pdata *pdata);
+	void (*rx_enable)(struct xgene_enet_pdata *pdata);
+	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);
+};
+
+struct xgene_port_ops {
+	void (*reset)(struct xgene_enet_pdata *pdata);
+	void (*cle_bypass)(struct xgene_enet_pdata *pdata,
+			   u32 dst_ring_num, u16 bufpool_id);
+	void (*shutdown)(struct xgene_enet_pdata *pdata);
+};
+
 /* ethernet private data */
 struct xgene_enet_pdata {
 	struct net_device *ndev;
@@ -98,6 +115,8 @@ struct xgene_enet_pdata {
 	u32 speed;
 	u16 rm;
 	struct rtnl_link_stats64 stats;
+	struct xgene_mac_ops *mac_ops;
+	struct xgene_port_ops *port_ops;
 };
 
 /* Set the specified value into a bit-field defined by its starting position
-- 
1.9.1

^ permalink raw reply related

* [PATCH v4 3/6] dtb: Add 10GbE node to APM X-Gene SoC device tree
From: Iyappan Subramanian @ 2014-10-10  1:32 UTC (permalink / raw)
  To: davem, netdev, devicetree
  Cc: linux-arm-kernel, patches, kchudgar, Iyappan Subramanian
In-Reply-To: <1412904727-23485-1-git-send-email-isubramanian@apm.com>

Added 10GbE interface and clock nodes.

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  | 29 +++++++++++++++++++++++++++--
 2 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/apm-mustang.dts b/arch/arm64/boot/dts/apm-mustang.dts
index b2f5622..2ae782b 100644
--- a/arch/arm64/boot/dts/apm-mustang.dts
+++ b/arch/arm64/boot/dts/apm-mustang.dts
@@ -32,3 +32,7 @@
 &menet {
 	status = "ok";
 };
+
+&xgenet {
+	status = "ok";
+};
diff --git a/arch/arm64/boot/dts/apm-storm.dtsi b/arch/arm64/boot/dts/apm-storm.dtsi
index f391972..d16cc03 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";
 			};
 
+			xge0clk: xge0clk@1f61c000 {
+				compatible = "apm,xgene-device-clock";
+				#clock-cells = <1>;
+				clocks = <&socplldiv2 0>;
+				reg = <0x0 0x1f61c000 0x0 0x1000>;
+				reg-names = "csr-reg";
+				csr-mask = <0x3>;
+				clock-output-names = "xge0clk";
+			};
+
 			sataphy1clk: sataphy1clk@1f21c000 {
 				compatible = "apm,xgene-device-clock";
 				#clock-cells = <1>;
@@ -420,7 +430,8 @@
 			interrupts = <0x0 0x3c 0x4>;
 			dma-coherent;
 			clocks = <&menetclk 0>;
-			local-mac-address = [00 01 73 00 00 01];
+			/* mac address will be overwritten by the bootloader */
+			local-mac-address = [00 00 00 00 00 00];
 			phy-connection-type = "rgmii";
 			phy-handle = <&menetphy>;
 			mdio {
@@ -435,12 +446,26 @@
 			};
 		};
 
+		xgenet: ethernet@1f610000 {
+			compatible = "apm,xgene-enet";
+			status = "disabled";
+			reg = <0x0 0x1f610000 0x0 0xd100>,
+			      <0x0 0x1f600000 0x0 0X400>,
+			      <0x0 0x18000000 0x0 0X200>;
+			reg-names = "enet_csr", "ring_csr", "ring_cmd";
+			interrupts = <0x0 0x60 0x4>;
+			dma-coherent;
+			clocks = <&xge0clk 0>;
+			/* mac address will be overwritten by the bootloader */
+			local-mac-address = [00 00 00 00 00 00];
+			phy-connection-type = "xgmii";
+		};
+
 		rng: rng@10520000 {
 			compatible = "apm,xgene-rng";
 			reg = <0x0 0x10520000 0x0 0x100>;
 			interrupts = <0x0 0x41 0x4>;
 			clocks = <&rngpkaclk 0>;
 		};
-
 	};
 };
-- 
1.9.1

^ permalink raw reply related

* [PATCH v4 1/6] MAINTAINERS: Update APM X-Gene section
From: Iyappan Subramanian @ 2014-10-10  1:32 UTC (permalink / raw)
  To: davem-fT/PcQaiUtIeIZ0/mPfg9Q, netdev-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	patches-qTEPVZfXA3Y, kchudgar-qTEPVZfXA3Y, Iyappan Subramanian
In-Reply-To: <1412904727-23485-1-git-send-email-isubramanian-qTEPVZfXA3Y@public.gmane.org>

Updated APM X-Gene ethernet driver maintainers list.

Signed-off-by: Iyappan Subramanian <isubramanian-qTEPVZfXA3Y@public.gmane.org>
Signed-off-by: Keyur Chudgar <kchudgar-qTEPVZfXA3Y@public.gmane.org>
---
 MAINTAINERS | 1 -
 1 file changed, 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 9e315a4..1a85af8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -734,7 +734,6 @@ F:	net/appletalk/
 APPLIED MICRO (APM) X-GENE SOC ETHERNET DRIVER
 M:	Iyappan Subramanian <isubramanian-qTEPVZfXA3Y@public.gmane.org>
 M:	Keyur Chudgar <kchudgar-qTEPVZfXA3Y@public.gmane.org>
-M:	Ravi Patel <rapatel-qTEPVZfXA3Y@public.gmane.org>
 S:	Supported
 F:	drivers/net/ethernet/apm/xgene/
 F:	Documentation/devicetree/bindings/net/apm-xgene-enet.txt
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* [PATCH v4 2/6] Documentation: dts: Update section header for APM X-Gene
From: Iyappan Subramanian @ 2014-10-10  1:32 UTC (permalink / raw)
  To: davem, netdev, devicetree
  Cc: linux-arm-kernel, patches, kchudgar, Iyappan Subramanian
In-Reply-To: <1412904727-23485-1-git-send-email-isubramanian@apm.com>

Signed-off-by: Iyappan Subramanian <isubramanian@apm.com>
Signed-off-by: Keyur Chudgar <kchudgar@apm.com>
---
 Documentation/devicetree/bindings/net/apm-xgene-enet.txt | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/net/apm-xgene-enet.txt b/Documentation/devicetree/bindings/net/apm-xgene-enet.txt
index ebcad25..cfcc527 100644
--- a/Documentation/devicetree/bindings/net/apm-xgene-enet.txt
+++ b/Documentation/devicetree/bindings/net/apm-xgene-enet.txt
@@ -3,7 +3,7 @@ APM X-Gene SoC Ethernet nodes
 Ethernet nodes are defined to describe on-chip ethernet interfaces in
 APM X-Gene SoC.
 
-Required properties:
+Required properties for all the ethernet interfaces:
 - compatible: Should be "apm,xgene-enet"
 - reg: Address and length of the register set for the device. It contains the
   information of registers in the same order as described by reg-names
@@ -15,6 +15,8 @@ Required properties:
 - clocks: Reference to the clock entry.
 - local-mac-address: MAC address assigned to this device
 - phy-connection-type: Interface type between ethernet device and PHY device
+
+Required properties for ethernet interfaces that have external PHY:
 - phy-handle: Reference to a PHY node connected to this device
 
 - mdio: Device tree subnode with the following required properties:
-- 
1.9.1

^ permalink raw reply related

* [PATCH v4 0/6] Add 10GbE support to APM X-Gene SoC ethernet driver
From: Iyappan Subramanian @ 2014-10-10  1:32 UTC (permalink / raw)
  To: davem-fT/PcQaiUtIeIZ0/mPfg9Q, netdev-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	patches-qTEPVZfXA3Y, kchudgar-qTEPVZfXA3Y, Iyappan Subramanian

Adding 10GbE support to APM X-Gene SoC ethernet driver.

v4: Address comments from v3
* dtb: resolved merge conflict for the net tree

v3: Address comments from v2
* dtb: changed to use all-zeros for the mac address

v2: Address comments from v1
* created preparatory patch to review before adding new functionality
* dtb: updated to use tabs consistently

v1:
* Initial version
---

Iyappan Subramanian (6):
  MAINTAINERS: Update APM X-Gene section
  Documentation: dts: Update section header for APM X-Gene
  dtb: Add 10GbE node to APM X-Gene SoC device tree
  drivers: net: xgene: Preparing for adding 10GbE support
  drivers: net: xgene: Add 10GbE support
  drivers: net: xgene: Add 10GbE ethtool support

 .../devicetree/bindings/net/apm-xgene-enet.txt     |   4 +-
 MAINTAINERS                                        |   1 -
 arch/arm64/boot/dts/apm-mustang.dts                |   4 +
 arch/arm64/boot/dts/apm-storm.dtsi                 |  29 +-
 drivers/net/ethernet/apm/xgene/Makefile            |   3 +-
 .../net/ethernet/apm/xgene/xgene_enet_ethtool.c    |  28 +-
 drivers/net/ethernet/apm/xgene/xgene_enet_hw.c     |  44 ++-
 drivers/net/ethernet/apm/xgene/xgene_enet_hw.h     |  30 +-
 drivers/net/ethernet/apm/xgene/xgene_enet_main.c   |  86 ++++--
 drivers/net/ethernet/apm/xgene/xgene_enet_main.h   |  24 +-
 drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c  | 331 +++++++++++++++++++++
 drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.h  |  57 ++++
 12 files changed, 566 insertions(+), 75 deletions(-)
 create mode 100644 drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c
 create mode 100644 drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.h

-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH net-next 0/2] sunvnet: Packet processing in non-interrupt context.
From: Raghuram Kothakota @ 2014-10-10  1:10 UTC (permalink / raw)
  To: Sowmini Varadhan; +Cc: David Miller, netdev
In-Reply-To: <20141006193111.GE24721@oracle.com>

I would like to share my experience, on sparc we need more parallelism to
get the high performance that's just the nature of CMT processors(at least today).
Lock less Tx and Rx implementation is very nice, but requires to the code path to
single threaded to achieve it. This may limit the performance to the single thread
performance, that may be not very high for standard MTU packets. The large MTU packets
like 64K MTU may have some advantage due to less processing both in the stack
and the driver, but still  single thread would limit the max performance. I would suggest
explore both lock less and high parallelism methods to see which one gives the
best performance.

-Raghuram
On Oct 6, 2014, at 12:31 PM, Sowmini Varadhan <sowmini.varadhan@oracle.com> wrote:

> On (10/06/14 15:25), David Miller wrote:
>> 
>>> But we still need to hold the vio lock around the ldc_write 
>>> (and also around dring write) in vnet_start_xmit, right?
>> 
>> You might be able to avoid it, you're fully serialized by the TX queue
>> lock.
> 
> yes, I was just noticing that. The only place where I believe I need
> to hold the vio spin-lock is to sync with the dr->cons checks
> (the "should I send a start_cons LDC message?" check in vnet_start_xmit()
> vs the vnet_ack() updates).
> 
> But isn't it better in general to declare NETIF_F_LLTX and have finer lock
> granularity in the driver?
> 
> --Sowmini
> 
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* [PATCH net 3/3] net: systemport: avoid unbalanced enable_irq_wake calls
From: Florian Fainelli @ 2014-10-10  1:06 UTC (permalink / raw)
  To: netdev; +Cc: davem, pgynther, jaedon.shin, Florian Fainelli
In-Reply-To: <1412903197-19193-1-git-send-email-f.fainelli@gmail.com>

Multiple enable_irq_wake() calls will keep increasing the IRQ
wake_depth, which ultimately leads to the following types of
situation:

1) enable Wake-on-LAN interrupt w/o password
2) enable Wake-on-LAN interrupt w/ password
3) enable Wake-on-LAN interrupt w/o password
4) disable Wake-on-LAN interrupt

After step 4), SYSTEMPORT would always wake-up the system no matter what
wake-up device we use, which is not what we want. Fix this by making
sure there are no unbalanced enable_irq_wake() calls.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
 drivers/net/ethernet/broadcom/bcmsysport.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/broadcom/bcmsysport.c b/drivers/net/ethernet/broadcom/bcmsysport.c
index 075688188644..9ae36979bdee 100644
--- a/drivers/net/ethernet/broadcom/bcmsysport.c
+++ b/drivers/net/ethernet/broadcom/bcmsysport.c
@@ -436,7 +436,8 @@ static int bcm_sysport_set_wol(struct net_device *dev,
 	/* Flag the device and relevant IRQ as wakeup capable */
 	if (wol->wolopts) {
 		device_set_wakeup_enable(kdev, 1);
-		enable_irq_wake(priv->wol_irq);
+		if (priv->wol_irq_disabled)
+			enable_irq_wake(priv->wol_irq);
 		priv->wol_irq_disabled = 0;
 	} else {
 		device_set_wakeup_enable(kdev, 0);
-- 
1.9.1

^ permalink raw reply related

* [PATCH net 2/3] net: bcmgenet: avoid unbalanced enable_irq_wake calls
From: Florian Fainelli @ 2014-10-10  1:06 UTC (permalink / raw)
  To: netdev; +Cc: davem, pgynther, jaedon.shin, Florian Fainelli
In-Reply-To: <1412903197-19193-1-git-send-email-f.fainelli@gmail.com>

Multiple enable_irq_wake() calls will keep increasing the IRQ
wake_depth, which ultimately leads to the following types of
situation:

1) enable Wake-on-LAN interrupt w/o password
2) enable Wake-on-LAN interrupt w/ password
3) enable Wake-on-LAN interrupt w/o password
4) disable Wake-on-LAN interrupt

After step 4), GENET would always wake-up the system no matter what
wake-up device we use, which is not what we want. Fix this by making
sure there are no unbalanced enable_irq_wake() calls.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
 drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c b/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c
index b82b7e4e06b2..149a0d70c108 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c
@@ -86,7 +86,9 @@ int bcmgenet_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
 	/* Flag the device and relevant IRQ as wakeup capable */
 	if (wol->wolopts) {
 		device_set_wakeup_enable(kdev, 1);
-		enable_irq_wake(priv->wol_irq);
+		/* Avoid unbalanced enable_irq_wake calls */
+		if (priv->wol_irq_disabled)
+			enable_irq_wake(priv->wol_irq);
 		priv->wol_irq_disabled = false;
 	} else {
 		device_set_wakeup_enable(kdev, 0);
-- 
1.9.1

^ permalink raw reply related

* [PATCH net 1/3] net: bcmgenet: fix off-by-one in incrementing read pointer
From: Florian Fainelli @ 2014-10-10  1:06 UTC (permalink / raw)
  To: netdev; +Cc: davem, pgynther, jaedon.shin, Florian Fainelli
In-Reply-To: <1412903197-19193-1-git-send-email-f.fainelli@gmail.com>

Commit b629be5c8399d7c423b92135eb43a86c924d1cbc ("net: bcmgenet: check
harder for out of memory conditions") moved the increment of the local
read pointer *before* reading from the hardware descriptor using
dmadesc_get_length_status(), which creates an off-by-one situation.

Fix this by moving again the read_ptr increment after we have read the
hardware descriptor to get both the control block and the read pointer
back in sync.

Fixes: b629be5c8399 ("net: bcmgenet: check harder for out of memory conditions")
Reported-by: Jaedon Shin <jaedon.shin@gmail.com>
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
 drivers/net/ethernet/broadcom/genet/bcmgenet.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
index fff2634b6f34..f1bcebcbba80 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -1287,9 +1287,6 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_priv *priv,
 
 		rxpktprocessed++;
 
-		priv->rx_read_ptr++;
-		priv->rx_read_ptr &= (priv->num_rx_bds - 1);
-
 		/* We do not have a backing SKB, so we do not have a
 		 * corresponding DMA mapping for this incoming packet since
 		 * bcmgenet_rx_refill always either has both skb and mapping or
@@ -1332,6 +1329,9 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_priv *priv,
 			  __func__, p_index, priv->rx_c_index,
 			  priv->rx_read_ptr, dma_length_status);
 
+		priv->rx_read_ptr++;
+		priv->rx_read_ptr &= (priv->num_rx_bds - 1);
+
 		if (unlikely(!(dma_flag & DMA_EOP) || !(dma_flag & DMA_SOP))) {
 			netif_err(priv, rx_status, dev,
 				  "dropping fragmented packet!\n");
-- 
1.9.1

^ permalink raw reply related

* [PATCH net 0/3] net: bcmgenet & systemport fixes
From: Florian Fainelli @ 2014-10-10  1:06 UTC (permalink / raw)
  To: netdev; +Cc: davem, pgynther, jaedon.shin, Florian Fainelli

Hi David,

This patch series fixes an off-by-one error introduced during a previous
change, and the two other fixes fix a wake depth imbalance situation for
the Wake-on-LAN interrupt line.

Thanks!

Florian Fainelli (3):
  net: bcmgenet: fix off-by-one in incrementing read pointer
  net: bcmgenet: avoid unbalanced enable_irq_wake calls
  net: systemport: avoid unbalanced enable_irq_wake calls

 drivers/net/ethernet/broadcom/bcmsysport.c         | 3 ++-
 drivers/net/ethernet/broadcom/genet/bcmgenet.c     | 6 +++---
 drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c | 4 +++-
 3 files changed, 8 insertions(+), 5 deletions(-)

-- 
1.9.1

^ permalink raw reply

* eth_get_headlen() and unaligned accesses...
From: David Miller @ 2014-10-10  0:12 UTC (permalink / raw)
  To: netdev; +Cc: alexander.duyck


So, we have a bit of a problem, this is on sparc64:

[423475.740836] Kernel unaligned access at TPC[81d330] __skb_flow_get_ports+0x70/0xe0
[423475.755756] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 3.17.0+ #2
[423475.767854] Call Trace:
[423475.772877]  [0000000000433288] kernel_unaligned_trap+0x368/0x5c0
[423475.785203]  [000000000042a824] sun4v_do_mna+0x84/0xa0
[423475.795624]  [0000000000406cd0] sun4v_mna+0x5c/0x68
[423475.805521]  [000000000081d330] __skb_flow_get_ports+0x70/0xe0
[423475.817323]  [000000000081d6ac] __skb_flow_dissect+0x1ac/0x460
[423475.829128]  [0000000000843c98] eth_get_headlen+0x38/0xa0
[423475.840083]  [0000000010064d54] igb_poll+0x8d4/0xf60 [igb]
[423475.851184]  [00000000008243c8] net_rx_action+0xa8/0x1c0

The chip DMA's to the beginning of a frag page and (unless timestamps
are enabled) that's where the ethernet header begins.

So any larger than 16-bit access to the IP and later headers will be
unaligned.

We have various ways we can deal with this based upon the capabilities
of the chips involved.  Can we configure the IGB to put 2 "don't care"
bytes at the beginning of the packet?

^ permalink raw reply

* Re: [PATCH net] niu: remove unnecessary atomic operation
From: Eric Dumazet @ 2014-10-09 23:40 UTC (permalink / raw)
  To: David Miller; +Cc: netdev
In-Reply-To: <1412875428.18196.3.camel@edumazet-glaptop2.roam.corp.google.com>

On Thu, 2014-10-09 at 10:23 -0700, Eric Dumazet wrote:
> From: Eric Dumazet <edumazet@google.com>
> 
> We allocate single page, compound_head() is not needed.
> 
> We own the page, we can simply set page->_count to the
> needed value instead of doing a locked addition.
> 
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> ---
>  drivers/net/ethernet/sun/niu.c |    5 ++---
>  1 file changed, 2 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/net/ethernet/sun/niu.c b/drivers/net/ethernet/sun/niu.c
> index 904fd1ab5f6e..ec2cd8a6d5bc 100644
> --- a/drivers/net/ethernet/sun/niu.c
> +++ b/drivers/net/ethernet/sun/niu.c
> @@ -3340,9 +3340,8 @@ static int niu_rbr_add_page(struct niu *np, struct rx_ring_info *rp,
>  	}
>  
>  	niu_hash_page(rp, page, addr);
> -	if (rp->rbr_blocks_per_page > 1)
> -		atomic_add(rp->rbr_blocks_per_page - 1,
> -			   &compound_head(page)->_count);
> +
> +	atomic_set(&page->_count, rp->rbr_blocks_per_page);
>  
>  	for (i = 0; i < rp->rbr_blocks_per_page; i++) {
>  		__le32 *rbr = &rp->rbr[start_index + i];
> 

Please disregard this patch.

We need to fix all usages of atomic_set() on page->_count as they are
racy.

I'll send fixes.

^ permalink raw reply

* Re: [PATCH] net_sched: restore qdisc quota fairness limits after bulk dequeue
From: David Miller @ 2014-10-09 23:12 UTC (permalink / raw)
  To: brouer; +Cc: netdev, eric.dumazet, hannes, dborkman, dave.taht
In-Reply-To: <20141009101640.26713.80729.stgit@dragon>

From: Jesper Dangaard Brouer <brouer@redhat.com>
Date: Thu, 09 Oct 2014 12:18:10 +0200

> Restore the quota fairness between qdisc's, that we broke with commit
> 5772e9a346 ("qdisc: bulk dequeue support for qdiscs with TCQ_F_ONETXQUEUE").
> 
> Before that commit, the quota in __qdisc_run() were in packets as
> dequeue_skb() would only dequeue a single packet, that assumption
> broke with bulk dequeue.
> 
> We choose not to account for the number of packets inside the TSO/GSO
> packets (accessable via "skb_gso_segs").  As the previous fairness
> also had this "defect". Thus, GSO/TSO packets counts as a single
> packet.
> 
> Further more, we choose to slack on accuracy, by allowing a bulk
> dequeue try_bulk_dequeue_skb() to exceed the "packets" limit, only
> limited by the BQL bytelimit.  This is done because BQL prefers to get
> its full budget for appropriate feedback from TX completion.
> 
> In future, we might consider reworking this further and, if it allows,
> switch to a time-based model, as suggested by Eric. Right now, we only
> restore old semantics.
> 
> Joint work with Eric, Hannes, Daniel and Jesper.  Hannes wrote the
> first patch in cooperation with Daniel and Jesper.  Eric rewrote the
> patch.
> 
> Fixes: 5772e9a346 ("qdisc: bulk dequeue support for qdiscs with TCQ_F_ONETXQUEUE")
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
> Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
> Signed-off-by: Daniel Borkmann <dborkman@redhat.com>

Looks fantastic, thanks everyone.

^ permalink raw reply

* Re: [PATCH net-next v2 0/3] r8152: use mutex for hw settings
From: David Miller @ 2014-10-09 23:06 UTC (permalink / raw)
  To: hayeswang; +Cc: netdev, nic_swsd, linux-kernel, linux-usb
In-Reply-To: <1394712342-15778-60-Taiwan-albertk@realtek.com>

From: Hayes Wang <hayeswang@realtek.com>
Date: Thu, 9 Oct 2014 18:00:23 +0800

> v2:
> Make sure the autoresume wouldn't occur inside the mutex, otherwise
> the dead lock would happen. For the purpose, adjust some code about
> autosuspend/autoresume.
> 
> v1:
> Use mutex to avoid that the serial hw settings would be interrupted
> by other settings. Although there is no problem now, it makes the
> driver more safe.

Series applied, thanks.

^ permalink raw reply

* Re: [PATCH net-next] r8152: use mutex for hw settings
From: David Miller @ 2014-10-09 23:05 UTC (permalink / raw)
  To: hayeswang-Rasf1IRRPZFBDgjK7y7TUQ
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA, nic_swsd-Rasf1IRRPZFBDgjK7y7TUQ,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-usb-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <0835B3720019904CB8F7AA43166CEEB2EC397B-DsoXZbr0xhNADej8IQs+YlSdAeM+KJnwp3nQiEPZk/A@public.gmane.org>

From: Hayes Wang <hayeswang-Rasf1IRRPZFBDgjK7y7TUQ@public.gmane.org>
Date: Thu, 9 Oct 2014 07:59:35 +0000

> If I use the rtnl_lock(), I get a dead lock when enabling autosuspend.
> 
> Case 1:
>    autosuspend before calling open.
>    rtnl_lock()
>    call open
>    try to autoresume and rtl8152_resume is called.
>    dead lock occurs.
> 
> Case 2:
>    autosuspend occurs.
>    rtnl_lock()
>    call close
>    try to autoresume and rtl8152_resume is called.
>    dead lock occurs.

That's really unfortunate that we can variably get into the resume
handlers from contexts holding the RTNL mutex.

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH] net: Missing @ before descriptions cause make xmldocs warning
From: David Miller @ 2014-10-09 22:57 UTC (permalink / raw)
  To: standby24x7; +Cc: linux-kernel, netdev, edumazet
In-Reply-To: <1412827088-30718-1-git-send-email-standby24x7@gmail.com>

From: Masanari Iida <standby24x7@gmail.com>
Date: Thu,  9 Oct 2014 12:58:08 +0900

> This patch fix following warning.
> Warning(.//net/core/skbuff.c:4142): No description found for parameter 'header_len'
> Warning(.//net/core/skbuff.c:4142): No description found for parameter 'data_len'
> Warning(.//net/core/skbuff.c:4142): No description found for parameter 'max_page_order'
> Warning(.//net/core/skbuff.c:4142): No description found for parameter 'errcode'
> Warning(.//net/core/skbuff.c:4142): No description found for parameter 'gfp_mask'
> 
> Acutually the descriptions exist, but missing "@" in front.
> 
> This problem start to happen when following commit was merged
> into Linus's tree during 3.18-rc1 merge period.
> commit 2e4e44107176d552f8bb1bb76053e850e3809841
> net: add alloc_skb_with_frags() helper
> 
> Signed-off-by: Masanari Iida <standby24x7@gmail.com>

Applied, thank you.

^ permalink raw reply

* Re: [PATCH v3 0/6] Add 10GbE support to APM X-Gene SoC ethernet driver
From: David Miller @ 2014-10-09 22:56 UTC (permalink / raw)
  To: isubramanian; +Cc: netdev, devicetree, linux-arm-kernel, patches, kchudgar
In-Reply-To: <1412826861-32208-1-git-send-email-isubramanian@apm.com>

From: Iyappan Subramanian <isubramanian@apm.com>
Date: Wed,  8 Oct 2014 20:54:15 -0700

> Adding 10GbE support to APM X-Gene SoC ethernet driver.
> 
> v3: Address comments from v2
> * dtb: changed to use all-zeros for the mac address
> 
> v2: Address comments from v1
> * created preparatory patch to review before adding new functionality
> * dtb: updated to use tabs consistently
> 
> v1:
> * Initial version

This does not apply to my current tree, in particular the DT files
get rejects.

^ permalink raw reply

* Re: [PATCH net-next 0/3] cxgb4/cxgb4vf: Misc fixes and 40G support for cxgb4vf
From: David Miller @ 2014-10-09 22:55 UTC (permalink / raw)
  To: hariprasad; +Cc: netdev, leedom, kumaras, nirranjan, santosh
In-Reply-To: <1412813927-24951-1-git-send-email-hariprasad@chelsio.com>

From: Hariprasad Shenai <hariprasad@chelsio.com>
Date: Thu,  9 Oct 2014 05:48:44 +0530

> This patch series adds 40G support for cxgb4vf driver. Update the LSO length for
> cxgb4vf, fix macro. Wait for device to get ready before reading PL_WHOAMI
> register.
> 
> The patches series is created against 'net-next' tree.
> And includes patches on cxgb4 and cxgb4vf driver.
> 
> We have included all the maintainers of respective drivers. Kindly review the
> change and let us know in case of any review comments.

Series applied, thanks.

^ permalink raw reply

* Re: [PATCH v3] Add support for GPIOs for SMSC LAN95xx chips.
From: David Miller @ 2014-10-09 22:45 UTC (permalink / raw)
  To: boger-hVk9LwgH4SrGCOCKMErq+g
  Cc: dforsi-Re5JQEeQqe8AvxtiuMwx3w,
	steve.glendinning-nksJyM/082jR7s880joybQ,
	netdev-u79uwXL29TY76Z2rM5mHXA, linux-usb-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1412806498-22556-1-git-send-email-boger-hVk9LwgH4SrGCOCKMErq+g@public.gmane.org>

From: Evgeny Boger <boger-hVk9LwgH4SrGCOCKMErq+g@public.gmane.org>
Date: Thu,  9 Oct 2014 02:14:58 +0400

> There might be 11 GPIOs in total.
> Last three GPIOs  (offsets 8-10, 0-based) are shared with FDX, LNKA, SPD
> LEDs respectively. The LEDs are driven by chip by default at startup time.
> Once the corresponding GPIO is requested, the chip LED drive logic is disabled.
> 
> The numbering scheme according to datasheets differs a bit between LAN9500
> and LAN951x.
> 
> For LAN951x:
> GPIOs with offsets 0-7 are named "GPIO3" - "GPIO7",
> offsets 8-10 are for "GPIO0" - "GPIO2" (these three are multiplexed with nFDX_LED,
> nLNKA_LED, nSPD_LED).
> 
> For LAN9500:
> The datasheet name is the same as the corresponding offset, i.e. offsets 0-10 are
> for "GPIO0"-"GPIO10".
> 
> Signed-off-by: Evgeny Boger <boger-hVk9LwgH4SrGCOCKMErq+g@public.gmane.org>

Please either "select GPIOLIB" from USB_NET_SMSC95XX, or add a new
config option "UBS_NET_SMSC95XX_GPIO" which does it.  I would prefer
the former, and then you can get rid of all of the ifdefs in your
patch.

Thanks.
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH net] ixgbe: check adapter->vfinfo before dereference
From: Jeff Kirsher @ 2014-10-09 22:35 UTC (permalink / raw)
  To: Thierry Herbelot; +Cc: netdev
In-Reply-To: <1412769913-22306-1-git-send-email-thierry.herbelot@6wind.com>

[-- Attachment #1: Type: text/plain, Size: 9955 bytes --]

On Wed, 2014-10-08 at 14:05 +0200, Thierry Herbelot wrote:
> this protects against the following panic:
> (before a VF was actually created on p96p1 PF Ethernet port)
> ip link set p96p1 vf 0 spoofchk off
> BUG: unable to handle kernel NULL pointer dereference at 0000000000000052
> IP: [<ffffffffa044a1c1>] ixgbe_ndo_set_vf_spoofchk+0x51/0x150 [ixgbe]
> 
> Signed-off-by: Thierry Herbelot <thierry.herbelot@6wind.com>
> ---
>  drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c |   73 +++++++++++++++++++++++-
>  1 file changed, 70 insertions(+), 3 deletions(-)

Dropping this patch because the driver generates compile warnings with
this patch applied.

n0324:[0]/usr/src/net-community-queue> make -j 18
SUBDIRS=drivers/net/ethernet/intel/ixgbe modules
  CC [M]  drivers/net/ethernet/intel/ixgbe/ixgbe_main.o
...
drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c: In function
âixgbe_ping_all_vfsâ:
drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c:1102: warning: âreturnâ
with a value, in function returning void
drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c: In function
âixgbe_ndo_set_vf_spoofchkâ:
drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c:1326: warning: âreturnâ
with no value, in function returning non-void
  LD [M]  drivers/net/ethernet/intel/ixgbe/ixgbe.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      drivers/net/ethernet/intel/ixgbe/ixgbe.mod.o
  LD [M]  drivers/net/ethernet/intel/ixgbe/ixgbe.ko

> 
> diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
> index c14d4d8..c6c9c0a 100644
> --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
> +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
> @@ -314,7 +314,7 @@ static int ixgbe_set_vf_multicasts(struct ixgbe_adapter *adapter,
>  	int entries = (msgbuf[0] & IXGBE_VT_MSGINFO_MASK)
>  		       >> IXGBE_VT_MSGINFO_SHIFT;
>  	u16 *hash_list = (u16 *)&msgbuf[1];
> -	struct vf_data_storage *vfinfo = &adapter->vfinfo[vf];
> +	struct vf_data_storage *vfinfo;
>  	struct ixgbe_hw *hw = &adapter->hw;
>  	int i;
>  	u32 vector_bit;
> @@ -322,6 +322,11 @@ static int ixgbe_set_vf_multicasts(struct ixgbe_adapter *adapter,
>  	u32 mta_reg;
>  	u32 vmolr = IXGBE_READ_REG(hw, IXGBE_VMOLR(vf));
>  
> +	if (!adapter->vfinfo)
> +		return -1;
> +
> +	vfinfo = &adapter->vfinfo[vf];
> +
>  	/* only so many hash values supported */
>  	entries = min(entries, IXGBE_MAX_VF_MC_ENTRIES);
>  
> @@ -363,6 +368,9 @@ void ixgbe_restore_vf_multicasts(struct ixgbe_adapter *adapter)
>  	u32 vector_reg;
>  	u32 mta_reg;
>  
> +	if (!adapter->vfinfo)
> +		return;
> +
>  	for (i = 0; i < adapter->num_vfs; i++) {
>  		u32 vmolr = IXGBE_READ_REG(hw, IXGBE_VMOLR(i));
>  		vfinfo = &adapter->vfinfo[i];
> @@ -416,6 +424,9 @@ static s32 ixgbe_set_vf_lpe(struct ixgbe_adapter *adapter, u32 *msgbuf, u32 vf)
>  		u32 reg_offset, vf_shift, vfre;
>  		s32 err = 0;
>  
> +		if (!adapter->vfinfo)
> +			return -1;
> +
>  #ifdef CONFIG_FCOE
>  		if (dev->features & NETIF_F_FCOE_MTU)
>  			pf_max_frame = max_t(int, pf_max_frame,
> @@ -505,6 +516,9 @@ static inline void ixgbe_vf_reset_event(struct ixgbe_adapter *adapter, u32 vf)
>  	struct vf_data_storage *vfinfo = &adapter->vfinfo[vf];
>  	u8 num_tcs = netdev_get_num_tc(adapter->netdev);
>  
> +	if (!adapter->vfinfo)
> +		return;
> +
>  	/* add PF assigned VLAN or VLAN 0 */
>  	ixgbe_set_vf_vlan(adapter, true, vfinfo->pf_vlan, vf);
>  
> @@ -541,6 +555,8 @@ static inline void ixgbe_vf_reset_event(struct ixgbe_adapter *adapter, u32 vf)
>  static int ixgbe_set_vf_mac(struct ixgbe_adapter *adapter,
>  			    int vf, unsigned char *mac_addr)
>  {
> +	if (!adapter->vfinfo)
> +		return -1;
>  	ixgbe_del_mac_filter(adapter, adapter->vfinfo[vf].vf_mac_addresses, vf);
>  	memcpy(adapter->vfinfo[vf].vf_mac_addresses, mac_addr, ETH_ALEN);
>  	ixgbe_add_mac_filter(adapter, adapter->vfinfo[vf].vf_mac_addresses, vf);
> @@ -610,6 +626,9 @@ int ixgbe_vf_configuration(struct pci_dev *pdev, unsigned int event_mask)
>  
>  	bool enable = ((event_mask & 0x10000000U) != 0);
>  
> +	if (!adapter->vfinfo)
> +		return -1;
> +
>  	if (enable)
>  		eth_zero_addr(adapter->vfinfo[vfn].vf_mac_addresses);
>  
> @@ -620,13 +639,18 @@ static int ixgbe_vf_reset_msg(struct ixgbe_adapter *adapter, u32 vf)
>  {
>  	struct ixgbe_ring_feature *vmdq = &adapter->ring_feature[RING_F_VMDQ];
>  	struct ixgbe_hw *hw = &adapter->hw;
> -	unsigned char *vf_mac = adapter->vfinfo[vf].vf_mac_addresses;
> +	unsigned char *vf_mac;
>  	u32 reg, reg_offset, vf_shift;
>  	u32 msgbuf[4] = {0, 0, 0, 0};
>  	u8 *addr = (u8 *)(&msgbuf[1]);
>  	u32 q_per_pool = __ALIGN_MASK(1, ~vmdq->mask);
>  	int i;
>  
> +	if (!adapter->vfinfo)
> +		return -1;
> +
> +	vf_mac = adapter->vfinfo[vf].vf_mac_addresses;
> +
>  	e_info(probe, "VF Reset msg received from vf %d\n", vf);
>  
>  	/* reset the filters for the device */
> @@ -721,6 +745,9 @@ static int ixgbe_set_vf_mac_addr(struct ixgbe_adapter *adapter,
>  {
>  	u8 *new_mac = ((u8 *)(&msgbuf[1]));
>  
> +	if (!adapter->vfinfo)
> +		return -1;
> +
>  	if (!is_valid_ether_addr(new_mac)) {
>  		e_warn(drv, "VF %d attempted to set invalid mac\n", vf);
>  		return -1;
> @@ -773,6 +800,9 @@ static int ixgbe_set_vf_vlan_msg(struct ixgbe_adapter *adapter,
>  	u32 bits;
>  	u8 tcs = netdev_get_num_tc(adapter->netdev);
>  
> +	if (!adapter->vfinfo)
> +		return -1;
> +
>  	if (adapter->vfinfo[vf].pf_vlan || tcs) {
>  		e_warn(drv,
>  		       "VF %d attempted to override administratively set VLAN configuration\n"
> @@ -839,6 +869,9 @@ static int ixgbe_set_vf_macvlan_msg(struct ixgbe_adapter *adapter,
>  		    IXGBE_VT_MSGINFO_SHIFT;
>  	int err;
>  
> +	if (!adapter->vfinfo)
> +		return -1;
> +
>  	if (adapter->vfinfo[vf].pf_set_mac && index > 0) {
>  		e_warn(drv,
>  		       "VF %d requested MACVLAN filter but is administratively denied\n",
> @@ -875,6 +908,9 @@ static int ixgbe_negotiate_vf_api(struct ixgbe_adapter *adapter,
>  {
>  	int api = msgbuf[1];
>  
> +	if (!adapter->vfinfo)
> +		return -1;
> +
>  	switch (api) {
>  	case ixgbe_mbox_api_10:
>  	case ixgbe_mbox_api_11:
> @@ -897,6 +933,9 @@ static int ixgbe_get_vf_queues(struct ixgbe_adapter *adapter,
>  	unsigned int default_tc = 0;
>  	u8 num_tcs = netdev_get_num_tc(dev);
>  
> +	if (!adapter->vfinfo)
> +		return -1;
> +
>  	/* verify the PF is supporting the correct APIs */
>  	switch (adapter->vfinfo[vf].vf_api) {
>  	case ixgbe_mbox_api_20:
> @@ -935,6 +974,9 @@ static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf)
>  	struct ixgbe_hw *hw = &adapter->hw;
>  	s32 retval;
>  
> +	if (!adapter->vfinfo)
> +		return -1;
> +
>  	retval = ixgbe_read_mbx(hw, msgbuf, mbx_size, vf);
>  
>  	if (retval) {
> @@ -1008,6 +1050,9 @@ static void ixgbe_rcv_ack_from_vf(struct ixgbe_adapter *adapter, u32 vf)
>  	struct ixgbe_hw *hw = &adapter->hw;
>  	u32 msg = IXGBE_VT_MSGTYPE_NACK;
>  
> +	if (!adapter->vfinfo)
> +		return;
> +
>  	/* if device isn't clear to send it shouldn't be reading either */
>  	if (!adapter->vfinfo[vf].clear_to_send)
>  		ixgbe_write_mbx(hw, &msg, 1, vf);
> @@ -1051,6 +1096,9 @@ void ixgbe_ping_all_vfs(struct ixgbe_adapter *adapter)
>  	u32 ping;
>  	int i;
>  
> +	if (!adapter->vfinfo)
> +		return -1;
> +

This should be simply "return;" since this is a void function.

>  	for (i = 0 ; i < adapter->num_vfs; i++) {
>  		ping = IXGBE_PF_CONTROL_MSG;
>  		if (adapter->vfinfo[i].clear_to_send)
> @@ -1064,6 +1112,9 @@ int ixgbe_ndo_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
>  	struct ixgbe_adapter *adapter = netdev_priv(netdev);
>  	if (!is_valid_ether_addr(mac) || (vf >= adapter->num_vfs))
>  		return -EINVAL;
> +	if (!adapter->vfinfo)
> +		return -1;
> +
>  	adapter->vfinfo[vf].pf_set_mac = true;
>  	dev_info(&adapter->pdev->dev, "setting MAC %pM on VF %d\n", mac, vf);
>  	dev_info(&adapter->pdev->dev, "Reload the VF driver to make this"
> @@ -1083,6 +1134,9 @@ int ixgbe_ndo_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos)
>  	struct ixgbe_adapter *adapter = netdev_priv(netdev);
>  	struct ixgbe_hw *hw = &adapter->hw;
>  
> +	if (!adapter->vfinfo)
> +		return -1;
> +
>  	if ((vf >= adapter->num_vfs) || (vlan > 4095) || (qos > 7))
>  		return -EINVAL;
>  	if (vlan || qos) {
> @@ -1147,8 +1201,12 @@ static void ixgbe_set_vf_rate_limit(struct ixgbe_adapter *adapter, int vf)
>  	struct ixgbe_hw *hw = &adapter->hw;
>  	u32 bcnrc_val = 0;
>  	u16 queue, queues_per_pool;
> -	u16 tx_rate = adapter->vfinfo[vf].tx_rate;
> +	u16 tx_rate;
>  
> +	if (!adapter->vfinfo)
> +		return;
> +
> +	tx_rate = adapter->vfinfo[vf].tx_rate;
>  	if (tx_rate) {
>  		/* start with base link speed value */
>  		bcnrc_val = adapter->vf_rate_link_speed;
> @@ -1197,6 +1255,9 @@ void ixgbe_check_vf_rate_limit(struct ixgbe_adapter *adapter)
>  {
>  	int i;
>  
> +	if (!adapter->vfinfo)
> +		return;
> +
>  	/* VF Tx rate limit was not set */
>  	if (!adapter->vf_rate_link_speed)
>  		return;
> @@ -1259,6 +1320,9 @@ int ixgbe_ndo_set_vf_spoofchk(struct net_device *netdev, int vf, bool setting)
>  	struct ixgbe_hw *hw = &adapter->hw;
>  	u32 regval;
>  
> +	if (!adapter->vfinfo)
> +		return;
> +

The return needs to return an integer.

>  	adapter->vfinfo[vf].spoofchk_enabled = setting;
>  
>  	regval = IXGBE_READ_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg));
> @@ -1283,6 +1347,9 @@ int ixgbe_ndo_get_vf_config(struct net_device *netdev,
>  	struct ixgbe_adapter *adapter = netdev_priv(netdev);
>  	if (vf >= adapter->num_vfs)
>  		return -EINVAL;
> +	if (!adapter->vfinfo)
> +		return -EINVAL;
> +
>  	ivi->vf = vf;
>  	memcpy(&ivi->mac, adapter->vfinfo[vf].vf_mac_addresses, ETH_ALEN);
>  	ivi->max_tx_rate = adapter->vfinfo[vf].tx_rate;



[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply

* [PATCH net] net: bpf: fix bpf syscall dependence on anon_inodes
From: Alexei Starovoitov @ 2014-10-09 22:16 UTC (permalink / raw)
  To: David S. Miller; +Cc: Michal Sojka, netdev, linux-kernel

minimal configurations where EPOLL, PERF_EVENTS, etc are disabled,
but NET is enabled, are failing to build with link error:
kernel/built-in.o: In function `bpf_prog_load':
syscall.c:(.text+0x3b728): undefined reference to `anon_inode_getfd'

fix it by selecting ANON_INODES when NET is enabled

Reported-by: Michal Sojka <sojkam1@fel.cvut.cz>
Signed-off-by: Alexei Starovoitov <ast@plumgrid.com>
---

I understand that 'select' is highly non-recommended for all good reasons,
but here 'depends on' is very user unfriendly, since ANON_INODES is
a hidden config that users cannot select directly.

 net/Kconfig |    1 +
 1 file changed, 1 insertion(+)

diff --git a/net/Kconfig b/net/Kconfig
index d6b138e..6272420 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -6,6 +6,7 @@ menuconfig NET
 	bool "Networking support"
 	select NLATTR
 	select GENERIC_NET_UTILS
+	select ANON_INODES
 	---help---
 	  Unless you really know what you are doing, you should say Y here.
 	  The reason is that some programs need kernel networking support even
-- 
1.7.9.5

^ permalink raw reply related

* Re: r8168 is needed to enter P-state: Package State 6 (pc6)onHaswell hardware: does the patch below against current kernel make a difference?
From: Francois Romieu @ 2014-10-09 22:14 UTC (permalink / raw)
  To: Ceriel Jacobs; +Cc: Hayes Wang, nic_swsd, netdev@vger.kernel.org
In-Reply-To: <54367965.7010301@crashplan.pro>

Ceriel Jacobs <linux-ide@crashplan.pro> :
> Francois Romieu schreef op 07-10-14 om 00:13:
> > Ceriel, does the patch below against current kernel make a difference?
[...]
> New r8169 "powertop" result (even without --auto-tune):
> C2 (pc2)    0.0%    |                     |
> C3 (pc3)    9.9%    | C3 (cc3)    0.7%    | C3-HSW      0.7%   16.4 ms
> C6 (pc6)   89.9%    | C6 (cc6)   99.2%    | C6-HSW     99.2%  223.2 ms
> ---

Fine (almost: I hope that ASPM was enabled from bios or during boot
behind your back).

Remember your "lspci -nnkvv -s 03:00.0" ?

03:00.0 Ethernet controller [0200]: Realtek Semiconductor Co., Ltd. RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller [10ec:8168] (rev 11)
[...]
        Capabilities: [70] Express (v2) Endpoint, MSI 01
                DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s <512ns, L1 <64us
                        ExtTag- AttnBtn- AttnInd- PwrInd- RBE+ FLReset-
                DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported-
                        RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop-
                        MaxPayload 128 bytes, MaxReadReq 4096 bytes
                DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr+ TransPend-
                LnkCap: Port #0, Speed 2.5GT/s, Width x1, ASPM L0s L1, Exit Latency L0s unlimited, L1 <64us
                   	ClockPM+ Surprise- LLActRep- BwNot-
                LnkCtl: ASPM Disabled; RCB 64 bytes Disabled- CommClk+
                        ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-

It should now look like:
[...]
                LnkCtl: ASPM L1 Enabled; RCB 64 bytes Disabled- CommClk+

Let's temporarily disable it and see if powertop notices a difference.

<full disclosure>

"Capabilities: [70]" above gives you the offset of the relevant registers:
# lspci -xxx -s 03:00.0
[...]
70: .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
^^ -> "[70]"

You are interested in the Link Control register, aka PCI_EXP_LNKCTL in
/usr/include/pci/header.h (devel part of pciutils) or kernel's
include/uapi/linux/pci_regs.h. It's 16 bytes further, thus
[...]
70: .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
80: 42 .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
    ^^

0x42 matches "LnkCtl: ASPM L1 Enabled; RCB 64 bytes Disabled- CommClk+
ExtSynch-" built from above. There may be differences but the 3 lower
weight binary digits in 0x42 encode ASPM control (0=nada, 1=L0, 2=L1,
see PCI_EXP_LNKCTL_ASPxyz in include/uapi/linux/pci_regs.h). Mask these
out (0x42 & ~0x03) and feed the resulting value back into the Link
Control register:

# setpci -s 03:00.0 CAP_EXP+10.b=0x40

(CAP_EXP is pciutils's alias for the PCI Express capability block, see
PCI_CAP_ID_EXP in kernel's include/uapi/linux/pci_regs.h)

If you are not too sure about the 0x40 value, you can retrieve it with
lspci and an unpatched r8169 driver.

</full disclosure>

If I have understood Hayes correctly and he got my question right, lspci
should now tell that ASPM is disabled. C6 should not be reached anymore.

ASPM could thus be enabled unconditionally at the driver level, then
controled through the PCI config registers. Kernel r8169 driver would
thus protect polar bears as Realtek's own r8168 driver already does.

I can't exclude that it will fail miserably in a firework of smelly
smoke though.

-- 
Ueimor

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox