[PATCH] net: netcp: fix unused interface rx buffer size configuration

2015-08-04 Thread WingMan Kwok
Prior to this patch, rx buffer size for each rx queue
of an interface is configurable through dts bindings.
But for an interface, the first rx queue's rx buffer
size is always the usual MTU size (plus usual overhead)
and page size for the remaining rx queues (if they are
enabled by specifying a non-zero rx queue depth dts
binding of the corresponding interface).  This patch
removes the rx buffer size configuration capability.

Signed-off-by: WingMan Kwok w-kw...@ti.com
---
 drivers/net/ethernet/ti/netcp.h  |1 -
 drivers/net/ethernet/ti/netcp_core.c |   35 +-
 2 files changed, 13 insertions(+), 23 deletions(-)

diff --git a/drivers/net/ethernet/ti/netcp.h b/drivers/net/ethernet/ti/netcp.h
index a8a7306..bb1bb72 100644
--- a/drivers/net/ethernet/ti/netcp.h
+++ b/drivers/net/ethernet/ti/netcp.h
@@ -85,7 +85,6 @@ struct netcp_intf {
struct list_headrxhook_list_head;
unsigned intrx_queue_id;
void*rx_fdq[KNAV_DMA_FDQ_PER_CHAN];
-   u32 rx_buffer_sizes[KNAV_DMA_FDQ_PER_CHAN];
struct napi_struct  rx_napi;
struct napi_struct  tx_napi;
 
diff --git a/drivers/net/ethernet/ti/netcp_core.c 
b/drivers/net/ethernet/ti/netcp_core.c
index 9749dfd..4755838 100644
--- a/drivers/net/ethernet/ti/netcp_core.c
+++ b/drivers/net/ethernet/ti/netcp_core.c
@@ -34,6 +34,7 @@
 #define NETCP_SOP_OFFSET   (NET_IP_ALIGN + NET_SKB_PAD)
 #define NETCP_NAPI_WEIGHT  64
 #define NETCP_TX_TIMEOUT   (5 * HZ)
+#define NETCP_PACKET_SIZE  (ETH_FRAME_LEN + ETH_FCS_LEN)
 #define NETCP_MIN_PACKET_SIZE  ETH_ZLEN
 #define NETCP_MAX_MCAST_ADDR   16
 
@@ -804,30 +805,28 @@ static void netcp_allocate_rx_buf(struct netcp_intf 
*netcp, int fdq)
if (likely(fdq == 0)) {
unsigned int primary_buf_len;
/* Allocate a primary receive queue entry */
-   buf_len = netcp-rx_buffer_sizes[0] + NETCP_SOP_OFFSET;
+   buf_len = NETCP_PACKET_SIZE + NETCP_SOP_OFFSET;
primary_buf_len = SKB_DATA_ALIGN(buf_len) +
SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
 
-   if (primary_buf_len = PAGE_SIZE) {
-   bufptr = netdev_alloc_frag(primary_buf_len);
-   pad[1] = primary_buf_len;
-   } else {
-   bufptr = kmalloc(primary_buf_len, GFP_ATOMIC |
-GFP_DMA32 | __GFP_COLD);
-   pad[1] = 0;
-   }
+   bufptr = netdev_alloc_frag(primary_buf_len);
+   pad[1] = primary_buf_len;
 
if (unlikely(!bufptr)) {
-   dev_warn_ratelimited(netcp-ndev_dev, Primary RX 
buffer alloc failed\n);
+   dev_warn_ratelimited(netcp-ndev_dev,
+Primary RX buffer alloc 
failed\n);
goto fail;
}
dma = dma_map_single(netcp-dev, bufptr, buf_len,
 DMA_TO_DEVICE);
+   if (unlikely(dma_mapping_error(netcp-dev, dma)))
+   goto fail;
+
pad[0] = (u32)bufptr;
 
} else {
/* Allocate a secondary receive queue entry */
-   page = alloc_page(GFP_ATOMIC | GFP_DMA32 | __GFP_COLD);
+   page = alloc_page(GFP_ATOMIC | GFP_DMA | __GFP_COLD);
if (unlikely(!page)) {
dev_warn_ratelimited(netcp-ndev_dev, Secondary page 
alloc failed\n);
goto fail;
@@ -1010,7 +1009,7 @@ netcp_tx_map_skb(struct sk_buff *skb, struct netcp_intf 
*netcp)
 
/* Map the linear buffer */
dma_addr = dma_map_single(dev, skb-data, pkt_len, DMA_TO_DEVICE);
-   if (unlikely(!dma_addr)) {
+   if (unlikely(dma_mapping_error(dev, dma_addr))) {
dev_err(netcp-ndev_dev, Failed to map skb buffer\n);
return NULL;
}
@@ -1546,8 +1545,8 @@ static int netcp_setup_navigator_resources(struct 
net_device *ndev)
knav_queue_disable_notify(netcp-rx_queue);
 
/* open Rx FDQs */
-   for (i = 0; i  KNAV_DMA_FDQ_PER_CHAN 
-netcp-rx_queue_depths[i]  netcp-rx_buffer_sizes[i]; ++i) {
+   for (i = 0; i  KNAV_DMA_FDQ_PER_CHAN  netcp-rx_queue_depths[i];
+++i) {
snprintf(name, sizeof(name), rx-fdq-%s-%d, ndev-name, i);
netcp-rx_fdq[i] = knav_queue_open(name, KNAV_QUEUE_GP, 0);
if (IS_ERR_OR_NULL(netcp-rx_fdq[i])) {
@@ -1941,14 +1940,6 @@ static int netcp_create_interface(struct netcp_device 
*netcp_device,
netcp-rx_queue_depths[0] = 128;
}
 
-   ret = of_property_read_u32_array(node_interface, rx-buffer-size,
-netcp-rx_buffer_sizes

[PATCH 2/2] net: netcp: Allocate RX packet buffers using __GFP_DMA

2015-07-29 Thread WingMan Kwok
The Keystone II DMA hardware can only access addresses in the
lower 2 GiB of SDRAM. This patch makes sure the RX buffers are
allocated using the __GFP_DMA flag so they meet this requirement.

Signed-off-by: WingMan Kwok w-kw...@ti.com
Signed-off-by: Reece R. Pollack x0183...@ti.com
---
 drivers/net/ethernet/ti/netcp_core.c |   11 +++
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/ti/netcp_core.c 
b/drivers/net/ethernet/ti/netcp_core.c
index 2d07701..39c68df 100644
--- a/drivers/net/ethernet/ti/netcp_core.c
+++ b/drivers/net/ethernet/ti/netcp_core.c
@@ -820,11 +820,13 @@ static void netcp_allocate_rx_buf(struct netcp_intf 
*netcp, int fdq)
SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
 
if (primary_buf_len = PAGE_SIZE) {
-   bufptr = netdev_alloc_frag(primary_buf_len);
+   bufptr = __netdev_alloc_frag(primary_buf_len,
+GFP_ATOMIC | __GFP_COLD |
+__GFP_DMA);
pad[1] = primary_buf_len;
} else {
bufptr = kmalloc(primary_buf_len, GFP_ATOMIC |
-GFP_DMA32 | __GFP_COLD);
+__GFP_COLD | __GFP_DMA);
pad[1] = 0;
}
 
@@ -838,9 +840,10 @@ static void netcp_allocate_rx_buf(struct netcp_intf 
*netcp, int fdq)
 
} else {
/* Allocate a secondary receive queue entry */
-   page = alloc_page(GFP_ATOMIC | GFP_DMA32 | __GFP_COLD);
+   page = alloc_page(GFP_ATOMIC | __GFP_COLD | __GFP_DMA);
if (unlikely(!page)) {
-   dev_warn_ratelimited(netcp-ndev_dev, Secondary page 
alloc failed\n);
+   dev_warn_ratelimited(netcp-ndev_dev,
+Secondary page alloc failed\n);
goto fail;
}
buf_len = PAGE_SIZE;
-- 
1.7.9.5

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


[PATCH 1/2] net: Export __netdev_alloc_frag() to allow gfp_mask flags

2015-07-29 Thread WingMan Kwok
This patch makes the function __netdev_alloc_frag() non-static and
exports it so that drivers that need to specify additional flags,
such as __GFP_DMA, can use it. The currently exported function,
netdev_alloc_frag() doesn't allow passing in gfp_mask flags.

Signed-off-by: WingMan Kwok w-kw...@ti.com
Signed-off-by: Reece R. Pollack x0183...@ti.com
---
 include/linux/skbuff.h |1 +
 net/core/skbuff.c  |3 ++-
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index d6cdd6e..596deb3 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -2139,6 +2139,7 @@ static inline void __skb_queue_purge(struct sk_buff_head 
*list)
kfree_skb(skb);
 }
 
+void *__netdev_alloc_frag(unsigned int fragsz, gfp_t gfp_mask);
 void *netdev_alloc_frag(unsigned int fragsz);
 
 struct sk_buff *__netdev_alloc_skb(struct net_device *dev, unsigned int length,
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index b6a19ca..6f3451f 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -350,7 +350,7 @@ EXPORT_SYMBOL(build_skb);
 static DEFINE_PER_CPU(struct page_frag_cache, netdev_alloc_cache);
 static DEFINE_PER_CPU(struct page_frag_cache, napi_alloc_cache);
 
-static void *__netdev_alloc_frag(unsigned int fragsz, gfp_t gfp_mask)
+void *__netdev_alloc_frag(unsigned int fragsz, gfp_t gfp_mask)
 {
struct page_frag_cache *nc;
unsigned long flags;
@@ -362,6 +362,7 @@ static void *__netdev_alloc_frag(unsigned int fragsz, gfp_t 
gfp_mask)
local_irq_restore(flags);
return data;
 }
+EXPORT_SYMBOL(__netdev_alloc_frag);
 
 /**
  * netdev_alloc_frag - allocate a page fragment
-- 
1.7.9.5

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


[net-next PATCH] net: netcp: Fixes efuse mac addr swap on k2e and k2l

2015-07-28 Thread WingMan Kwok
On some of the K2E and K2L platforms, the two DWORDs in
efuse occupied by the pre-programmed mac address for
slave port 1 are swapped.  To workaround this issue,
this patch adds a new define NETCP_EFUSE_ADDR_SWAP (2)
which signifies the occurrence of such swapping so that
the driver can take proper action.  The flag can be
enabled in the corresponding netcp interface dts binding
as efuse-mac = 2  under the corresponding netcp
interface node.

Signed-off-by: WingMan Kwok w-kw...@ti.com
---
 .../devicetree/bindings/net/keystone-netcp.txt |6 +-
 drivers/net/ethernet/ti/netcp_core.c   |   15 +--
 2 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/net/keystone-netcp.txt 
b/Documentation/devicetree/bindings/net/keystone-netcp.txt
index d0e6fa3..b30ab6b 100644
--- a/Documentation/devicetree/bindings/net/keystone-netcp.txt
+++ b/Documentation/devicetree/bindings/net/keystone-netcp.txt
@@ -130,7 +130,11 @@ Required properties:
 
 Optional properties:
 - efuse-mac:   If this is 1, then the MAC address for the interface is
-   obtained from the device efuse mac address register
+   obtained from the device efuse mac address register.
+   If this is 2, the two DWORDs occupied by the MAC address
+   are swapped.  The netcp driver will swap the two DWORDs
+   back to the proper order when this property is set to 2
+   when it obtains the mac address from efuse.
 - local-mac-address:   the driver is designed to use the of_get_mac_address api
only if efuse-mac is 0. When efuse-mac is 0, the MAC
address is obtained from local-mac-address. If this
diff --git a/drivers/net/ethernet/ti/netcp_core.c 
b/drivers/net/ethernet/ti/netcp_core.c
index 3ca87f2..6f2e151 100644
--- a/drivers/net/ethernet/ti/netcp_core.c
+++ b/drivers/net/ethernet/ti/netcp_core.c
@@ -51,6 +51,8 @@
NETIF_MSG_PKTDATA   | NETIF_MSG_TX_QUEUED   |   \
NETIF_MSG_RX_STATUS)
 
+#define NETCP_EFUSE_ADDR_SWAP  2
+
 #define knav_queue_get_id(q)   knav_queue_device_control(q, \
KNAV_QUEUE_GET_ID, (unsigned long)NULL)
 
@@ -172,13 +174,22 @@ static void set_words(u32 *words, int num_words, u32 
*desc)
 }
 
 /* Read the e-fuse value as 32 bit values to be endian independent */
-static int emac_arch_get_mac_addr(char *x, void __iomem *efuse_mac)
+static int emac_arch_get_mac_addr(char *x, void __iomem *efuse_mac, u32 swap)
 {
unsigned int addr0, addr1;
 
addr1 = readl(efuse_mac + 4);
addr0 = readl(efuse_mac);
 
+   switch (swap) {
+   case NETCP_EFUSE_ADDR_SWAP:
+   addr0 = addr1;
+   addr1 = readl(efuse_mac);
+   break;
+   default:
+   break;
+   }
+
x[0] = (addr1  0xff00)  8;
x[1] = addr1  0x00ff;
x[2] = (addr0  0xff00)  24;
@@ -1902,7 +1913,7 @@ static int netcp_create_interface(struct netcp_device 
*netcp_device,
goto quit;
}
 
-   emac_arch_get_mac_addr(efuse_mac_addr, efuse);
+   emac_arch_get_mac_addr(efuse_mac_addr, efuse, efuse_mac);
if (is_valid_ether_addr(efuse_mac_addr))
ether_addr_copy(ndev-dev_addr, efuse_mac_addr);
else
-- 
1.7.9.5

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


[PATCH] net: netcp: Fixes SGMII reset on network interface shutdown

2015-07-24 Thread WingMan Kwok
This patch asserts SGMII RTRESET, i.e. resetting the SGMII Tx/Rx
logic,  during network interface shutdown to avoid having the
hardware wedge when shutting down with high incoming traffic rates.
This is cleared (brought out of RTRESET) when the interface is
brought back up.


Signed-off-by: WingMan Kwok w-kw...@ti.com
---
This patch depends on the patch set 

Subject: [net-next PATCH v1 0/6] net: netcp: Bug fixes of CPSW statistics
 collection

submitted earlier.

 drivers/net/ethernet/ti/netcp.h   |1 +
 drivers/net/ethernet/ti/netcp_ethss.c |   18 ++
 drivers/net/ethernet/ti/netcp_sgmii.c |   30 --
 3 files changed, 47 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/ti/netcp.h b/drivers/net/ethernet/ti/netcp.h
index bbacf5c..a8a7306 100644
--- a/drivers/net/ethernet/ti/netcp.h
+++ b/drivers/net/ethernet/ti/netcp.h
@@ -223,6 +223,7 @@ void *netcp_device_find_module(struct netcp_device 
*netcp_device,
 
 /* SGMII functions */
 int netcp_sgmii_reset(void __iomem *sgmii_ofs, int port);
+bool netcp_sgmii_rtreset(void __iomem *sgmii_ofs, int port, bool set);
 int netcp_sgmii_get_port_link(void __iomem *sgmii_ofs, int port);
 int netcp_sgmii_config(void __iomem *sgmii_ofs, int port, u32 interface);
 
diff --git a/drivers/net/ethernet/ti/netcp_ethss.c 
b/drivers/net/ethernet/ti/netcp_ethss.c
index 7782120..571cf7a 100644
--- a/drivers/net/ethernet/ti/netcp_ethss.c
+++ b/drivers/net/ethernet/ti/netcp_ethss.c
@@ -2101,11 +2101,28 @@ static void gbe_port_config(struct gbe_priv *gbe_dev, 
struct gbe_slave *slave,
writel(slave-mac_control, GBE_REG_ADDR(slave, emac_regs, mac_control));
 }
 
+static void gbe_sgmii_rtreset(struct gbe_priv *priv,
+ struct gbe_slave *slave, bool set)
+{
+   void __iomem *sgmii_port_regs;
+
+   if (SLAVE_LINK_IS_XGMII(slave))
+   return;
+
+   if ((priv-ss_version == GBE_SS_VERSION_14)  (slave-slave_num = 2))
+   sgmii_port_regs = priv-sgmii_port34_regs;
+   else
+   sgmii_port_regs = priv-sgmii_port_regs;
+
+   netcp_sgmii_rtreset(sgmii_port_regs, slave-slave_num, set);
+}
+
 static void gbe_slave_stop(struct gbe_intf *intf)
 {
struct gbe_priv *gbe_dev = intf-gbe_dev;
struct gbe_slave *slave = intf-slave;
 
+   gbe_sgmii_rtreset(gbe_dev, slave, true);
gbe_port_reset(slave);
/* Disable forwarding */
cpsw_ale_control_set(gbe_dev-ale, slave-port_num,
@@ -2147,6 +2164,7 @@ static int gbe_slave_open(struct gbe_intf *gbe_intf)
 
gbe_sgmii_config(priv, slave);
gbe_port_reset(slave);
+   gbe_sgmii_rtreset(priv, slave, false);
gbe_port_config(priv, slave, priv-rx_packet_max);
gbe_set_slave_mac(slave, gbe_intf);
/* enable forwarding */
diff --git a/drivers/net/ethernet/ti/netcp_sgmii.c 
b/drivers/net/ethernet/ti/netcp_sgmii.c
index dbeb142..5d8419f 100644
--- a/drivers/net/ethernet/ti/netcp_sgmii.c
+++ b/drivers/net/ethernet/ti/netcp_sgmii.c
@@ -18,6 +18,9 @@
 
 #include netcp.h
 
+#define SGMII_SRESET_RESET BIT(0)
+#define SGMII_SRESET_RTRESET   BIT(1)
+
 #define SGMII_REG_STATUS_LOCK  BIT(4)
 #defineSGMII_REG_STATUS_LINK   BIT(0)
 #define SGMII_REG_STATUS_AUTONEG   BIT(2)
@@ -51,12 +54,35 @@ static void sgmii_write_reg_bit(void __iomem *base, int 
reg, u32 val)
 int netcp_sgmii_reset(void __iomem *sgmii_ofs, int port)
 {
/* Soft reset */
-   sgmii_write_reg_bit(sgmii_ofs, SGMII_SRESET_REG(port), 0x1);
-   while (sgmii_read_reg(sgmii_ofs, SGMII_SRESET_REG(port)) != 0x0)
+   sgmii_write_reg_bit(sgmii_ofs, SGMII_SRESET_REG(port),
+   SGMII_SRESET_RESET);
+
+   while ((sgmii_read_reg(sgmii_ofs, SGMII_SRESET_REG(port)) 
+   SGMII_SRESET_RESET) != 0x0)
;
+
return 0;
 }
 
+/* port is 0 based */
+bool netcp_sgmii_rtreset(void __iomem *sgmii_ofs, int port, bool set)
+{
+   u32 reg;
+   bool oldval;
+
+   /* Initiate a soft reset */
+   reg = sgmii_read_reg(sgmii_ofs, SGMII_SRESET_REG(port));
+   oldval = (reg  SGMII_SRESET_RTRESET) != 0x0;
+   if (set)
+   reg |= SGMII_SRESET_RTRESET;
+   else
+   reg = ~SGMII_SRESET_RTRESET;
+   sgmii_write_reg(sgmii_ofs, SGMII_SRESET_REG(port), reg);
+   wmb();
+
+   return oldval;
+}
+
 int netcp_sgmii_get_port_link(void __iomem *sgmii_ofs, int port)
 {
u32 status = 0, link = 0;
-- 
1.7.9.5

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


[net-next PATCH v0 0/6] net: netcp: Bug fixes of CPSW statistics collection

2015-07-23 Thread WingMan Kwok
This patch set contains bug fixes and enhencements of hw ethernet
statistics processing on TI's Keystone2 CPSW ethernet switches.

WingMan Kwok (6):
  net: netcp: Fixes the use of spin_lock_bh in timer function
  net: netcp: Fixes hw statistics module base setting error
  net: netcp: Fixes error in oversized memory allocation for statistics
storage
  net: netcp: Consolidates statistics collection code
  net: netcp: Fixes to CPSW statistics collection
  net: netcp: Adds missing statistics for K2L and K2E

 drivers/net/ethernet/ti/netcp_ethss.c |  399 ++---
 1 file changed, 324 insertions(+), 75 deletions(-)

-- 
1.7.9.5

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


[net-next PATCH v0 5/6] net: netcp: Fixes to CPSW statistics collection

2015-07-23 Thread WingMan Kwok
In certain applications it's beneficial to allow the CPSW h/w
stats counters to continue to increment even while the kernel
polls them. This patch implements this behavior for both 1G
and 10G ethernet subsystem modules.

Signed-off-by: WingMan Kwok w-kw...@ti.com
---
 drivers/net/ethernet/ti/netcp_ethss.c |   86 -
 1 file changed, 75 insertions(+), 11 deletions(-)

diff --git a/drivers/net/ethernet/ti/netcp_ethss.c 
b/drivers/net/ethernet/ti/netcp_ethss.c
index aadca02..e2ef7ba 100644
--- a/drivers/net/ethernet/ti/netcp_ethss.c
+++ b/drivers/net/ethernet/ti/netcp_ethss.c
@@ -646,6 +646,7 @@ struct gbe_priv {
boolenable_ale;
u8  max_num_slaves;
u8  max_num_ports; /* max_num_slaves + 1 */
+   u8  num_stats_mods;
struct netcp_tx_pipetx_pipe;
 
int host_port;
@@ -675,6 +676,7 @@ struct gbe_priv {
struct net_device   *dummy_ndev;
 
u64 *hw_stats;
+   u32 *hw_stats_prev;
const struct netcp_ethtool_stat *et_stats;
int num_et_stats;
/*  Lock for updating the hwstats */
@@ -1554,25 +1556,37 @@ static int keystone_get_sset_count(struct net_device 
*ndev, int stringset)
}
 }
 
+static void gbe_reset_mod_stats(struct gbe_priv *gbe_dev, int stats_mod)
+{
+   void __iomem *base = gbe_dev-hw_stats_regs[stats_mod];
+   u32  __iomem *p_stats_entry;
+   int i;
+
+   for (i = 0; i  gbe_dev-num_et_stats; i++) {
+   if (gbe_dev-et_stats[i].type == stats_mod) {
+   p_stats_entry = base + gbe_dev-et_stats[i].offset;
+   gbe_dev-hw_stats[i] = 0;
+   gbe_dev-hw_stats_prev[i] = readl(p_stats_entry);
+   }
+   }
+}
+
 static inline void gbe_update_hw_stats_entry(struct gbe_priv *gbe_dev,
 int et_stats_entry)
 {
void __iomem *base = NULL;
-   u32  __iomem *p;
-   u32 tmp = 0;
+   u32  __iomem *p_stats_entry;
+   u32 curr, delta;
 
/* The hw_stats_regs pointers are already
 * properly set to point to the right base:
 */
base = gbe_dev-hw_stats_regs[gbe_dev-et_stats[et_stats_entry].type];
-   p = base + gbe_dev-et_stats[et_stats_entry].offset;
-   tmp = readl(p);
-   gbe_dev-hw_stats[et_stats_entry] += tmp;
-
-   /* write-to-decrement:
-* new register value = old register value - write value
-*/
-   writel(tmp, p);
+   p_stats_entry = base + gbe_dev-et_stats[et_stats_entry].offset;
+   curr = readl(p_stats_entry);
+   delta = curr - gbe_dev-hw_stats_prev[et_stats_entry];
+   gbe_dev-hw_stats_prev[et_stats_entry] = curr;
+   gbe_dev-hw_stats[et_stats_entry] += delta;
 }
 
 static void gbe_update_stats(struct gbe_priv *gbe_dev, uint64_t *data)
@@ -1611,6 +1625,12 @@ static inline void gbe_stats_mod_visible_ver14(struct 
gbe_priv *gbe_dev,
writel(val, GBE_REG_ADDR(gbe_dev, switch_regs, stat_port_en));
 }
 
+static void gbe_reset_mod_stats_ver14(struct gbe_priv *gbe_dev, int stats_mod)
+{
+   gbe_stats_mod_visible_ver14(gbe_dev, stats_mod);
+   gbe_reset_mod_stats(gbe_dev, stats_mod);
+}
+
 static void gbe_update_stats_ver14(struct gbe_priv *gbe_dev, uint64_t *data)
 {
u32 half_num_et_stats = (gbe_dev-num_et_stats / 2);
@@ -2564,6 +2584,7 @@ static int set_xgbe_ethss10_priv(struct gbe_priv *gbe_dev,
}
gbe_dev-xgbe_serdes_regs = regs;
 
+   gbe_dev-num_stats_mods = gbe_dev-max_num_ports;
gbe_dev-et_stats = xgbe10_et_stats;
gbe_dev-num_et_stats = ARRAY_SIZE(xgbe10_et_stats);
 
@@ -2575,6 +2596,16 @@ static int set_xgbe_ethss10_priv(struct gbe_priv 
*gbe_dev,
return -ENOMEM;
}
 
+   gbe_dev-hw_stats_prev =
+   devm_kzalloc(gbe_dev-dev,
+gbe_dev-num_et_stats * sizeof(u32),
+GFP_KERNEL);
+   if (!gbe_dev-hw_stats_prev) {
+   dev_err(gbe_dev-dev,
+   hw_stats_prev memory allocation failed\n);
+   return -ENOMEM;
+   }
+
gbe_dev-ss_version = XGBE_SS_VERSION_10;
gbe_dev-sgmii_port_regs = gbe_dev-ss_regs +
XGBE10_SGMII_MODULE_OFFSET;
@@ -2672,6 +2703,7 @@ static int set_gbe_ethss14_priv(struct gbe_priv *gbe_dev,
}
gbe_dev-switch_regs = regs;
 
+   gbe_dev-num_stats_mods = gbe_dev-max_num_slaves;
gbe_dev-et_stats = gbe13_et_stats;
gbe_dev-num_et_stats = ARRAY_SIZE(gbe13_et_stats);
 
@@ -2683,6 +2715,16 @@ static int set_gbe_ethss14_priv(struct gbe_priv *gbe_dev,
return -ENOMEM;
}
 
+   gbe_dev

[net-next PATCH v0 4/6] net: netcp: Consolidates statistics collection code

2015-07-23 Thread WingMan Kwok
Different Keystone2 platforms have different number and
layouts of hw statistics modules.  This patch consolidates
the statistics processing of different Keystone2 platforms
for easy maintenance.

Signed-off-by: WingMan Kwok w-kw...@ti.com
---
 drivers/net/ethernet/ti/netcp_ethss.c |   99 ++---
 1 file changed, 54 insertions(+), 45 deletions(-)

diff --git a/drivers/net/ethernet/ti/netcp_ethss.c 
b/drivers/net/ethernet/ti/netcp_ethss.c
index a1f16e1..aadca02 100644
--- a/drivers/net/ethernet/ti/netcp_ethss.c
+++ b/drivers/net/ethernet/ti/netcp_ethss.c
@@ -1554,70 +1554,79 @@ static int keystone_get_sset_count(struct net_device 
*ndev, int stringset)
}
 }
 
-static void gbe_update_stats(struct gbe_priv *gbe_dev, uint64_t *data)
+static inline void gbe_update_hw_stats_entry(struct gbe_priv *gbe_dev,
+int et_stats_entry)
 {
void __iomem *base = NULL;
u32  __iomem *p;
u32 tmp = 0;
+
+   /* The hw_stats_regs pointers are already
+* properly set to point to the right base:
+*/
+   base = gbe_dev-hw_stats_regs[gbe_dev-et_stats[et_stats_entry].type];
+   p = base + gbe_dev-et_stats[et_stats_entry].offset;
+   tmp = readl(p);
+   gbe_dev-hw_stats[et_stats_entry] += tmp;
+
+   /* write-to-decrement:
+* new register value = old register value - write value
+*/
+   writel(tmp, p);
+}
+
+static void gbe_update_stats(struct gbe_priv *gbe_dev, uint64_t *data)
+{
int i;
 
for (i = 0; i  gbe_dev-num_et_stats; i++) {
-   base = gbe_dev-hw_stats_regs[gbe_dev-et_stats[i].type];
-   p = base + gbe_dev-et_stats[i].offset;
-   tmp = readl(p);
-   gbe_dev-hw_stats[i] = gbe_dev-hw_stats[i] + tmp;
+   gbe_update_hw_stats_entry(gbe_dev, i);
+
if (data)
data[i] = gbe_dev-hw_stats[i];
-   /* write-to-decrement:
-* new register value = old register value - write value
-*/
-   writel(tmp, p);
}
 }
 
-static void gbe_update_stats_ver14(struct gbe_priv *gbe_dev, uint64_t *data)
+static inline void gbe_stats_mod_visible_ver14(struct gbe_priv *gbe_dev,
+  int stats_mod)
 {
-   void __iomem *gbe_statsa = gbe_dev-hw_stats_regs[0];
-   void __iomem *gbe_statsb = gbe_dev-hw_stats_regs[1];
-   u64 *hw_stats = gbe_dev-hw_stats[0];
-   void __iomem *base = NULL;
-   u32  __iomem *p;
-   u32 tmp = 0, val, pair_size = (gbe_dev-num_et_stats / 2);
-   int i, j, pair;
+   u32 val;
 
-   for (pair = 0; pair  2; pair++) {
-   val = readl(GBE_REG_ADDR(gbe_dev, switch_regs, stat_port_en));
+   val = readl(GBE_REG_ADDR(gbe_dev, switch_regs, stat_port_en));
 
-   if (pair == 0)
-   val = ~GBE_STATS_CD_SEL;
-   else
-   val |= GBE_STATS_CD_SEL;
+   switch (stats_mod) {
+   case GBE_STATSA_MODULE:
+   case GBE_STATSB_MODULE:
+   val = ~GBE_STATS_CD_SEL;
+   break;
+   case GBE_STATSC_MODULE:
+   case GBE_STATSD_MODULE:
+   val |= GBE_STATS_CD_SEL;
+   break;
+   default:
+   return;
+   }
+
+   /* make the stat module visible */
+   writel(val, GBE_REG_ADDR(gbe_dev, switch_regs, stat_port_en));
+}
 
-   /* make the stat modules visible */
-   writel(val, GBE_REG_ADDR(gbe_dev, switch_regs, stat_port_en));
+static void gbe_update_stats_ver14(struct gbe_priv *gbe_dev, uint64_t *data)
+{
+   u32 half_num_et_stats = (gbe_dev-num_et_stats / 2);
+   int et_entry, j, pair;
 
-   for (i = 0; i  pair_size; i++) {
-   j = pair * pair_size + i;
-   switch (gbe_dev-et_stats[j].type) {
-   case GBE_STATSA_MODULE:
-   case GBE_STATSC_MODULE:
-   base = gbe_statsa;
-   break;
-   case GBE_STATSB_MODULE:
-   case GBE_STATSD_MODULE:
-   base  = gbe_statsb;
-   break;
-   }
+   for (pair = 0; pair  2; pair++) {
+   gbe_stats_mod_visible_ver14(gbe_dev, (pair ?
+ GBE_STATSC_MODULE :
+ GBE_STATSA_MODULE));
+
+   for (j = 0; j  half_num_et_stats; j++) {
+   et_entry = pair * half_num_et_stats + j;
+   gbe_update_hw_stats_entry(gbe_dev, et_entry);
 
-   p = base + gbe_dev-et_stats[j].offset;
-   tmp = readl(p);
-   hw_stats[j] += tmp;
if (data

[net-next PATCH v0 3/6] net: netcp: Fixes error in oversized memory allocation for statistics storage

2015-07-23 Thread WingMan Kwok
The CPSW driver keeps internally some, but not all, of
the statistics available in the hw statistics modules.  Furthermore,
some of the locations in the hw statistics modules are reserved and
contain no useful information.  Prior to this patch, the driver
allocates memory of the size of the the whole hw statistics modules,
instead of the size of statistics-entries-interested-in (i.e. et_stats),
for internal storage.  This patch fixes that.

Signed-off-by: WingMan Kwok w-kw...@ti.com
---
 drivers/net/ethernet/ti/netcp_ethss.c |   42 -
 1 file changed, 21 insertions(+), 21 deletions(-)

diff --git a/drivers/net/ethernet/ti/netcp_ethss.c 
b/drivers/net/ethernet/ti/netcp_ethss.c
index b954856..a1f16e1 100644
--- a/drivers/net/ethernet/ti/netcp_ethss.c
+++ b/drivers/net/ethernet/ti/netcp_ethss.c
@@ -2555,10 +2555,12 @@ static int set_xgbe_ethss10_priv(struct gbe_priv 
*gbe_dev,
}
gbe_dev-xgbe_serdes_regs = regs;
 
+   gbe_dev-et_stats = xgbe10_et_stats;
+   gbe_dev-num_et_stats = ARRAY_SIZE(xgbe10_et_stats);
+
gbe_dev-hw_stats = devm_kzalloc(gbe_dev-dev,
- XGBE10_NUM_STAT_ENTRIES *
- (gbe_dev-max_num_ports) * sizeof(u64),
- GFP_KERNEL);
+gbe_dev-num_et_stats * sizeof(u64),
+GFP_KERNEL);
if (!gbe_dev-hw_stats) {
dev_err(gbe_dev-dev, hw_stats memory allocation failed\n);
return -ENOMEM;
@@ -2577,8 +2579,6 @@ static int set_xgbe_ethss10_priv(struct gbe_priv *gbe_dev,
gbe_dev-ale_ports = gbe_dev-max_num_ports;
gbe_dev-host_port = XGBE10_HOST_PORT_NUM;
gbe_dev-ale_entries = XGBE10_NUM_ALE_ENTRIES;
-   gbe_dev-et_stats = xgbe10_et_stats;
-   gbe_dev-num_et_stats = ARRAY_SIZE(xgbe10_et_stats);
gbe_dev-stats_en_mask = (1  (gbe_dev-max_num_ports)) - 1;
 
/* Subsystem registers */
@@ -2663,10 +2663,12 @@ static int set_gbe_ethss14_priv(struct gbe_priv 
*gbe_dev,
}
gbe_dev-switch_regs = regs;
 
+   gbe_dev-et_stats = gbe13_et_stats;
+   gbe_dev-num_et_stats = ARRAY_SIZE(gbe13_et_stats);
+
gbe_dev-hw_stats = devm_kzalloc(gbe_dev-dev,
- GBE13_NUM_HW_STAT_ENTRIES *
- gbe_dev-max_num_slaves * sizeof(u64),
- GFP_KERNEL);
+gbe_dev-num_et_stats * sizeof(u64),
+GFP_KERNEL);
if (!gbe_dev-hw_stats) {
dev_err(gbe_dev-dev, hw_stats memory allocation failed\n);
return -ENOMEM;
@@ -2689,8 +2691,6 @@ static int set_gbe_ethss14_priv(struct gbe_priv *gbe_dev,
gbe_dev-ale_ports = gbe_dev-max_num_ports;
gbe_dev-host_port = GBE13_HOST_PORT_NUM;
gbe_dev-ale_entries = GBE13_NUM_ALE_ENTRIES;
-   gbe_dev-et_stats = gbe13_et_stats;
-   gbe_dev-num_et_stats = ARRAY_SIZE(gbe13_et_stats);
gbe_dev-stats_en_mask = GBE13_REG_VAL_STAT_ENABLE_ALL;
 
/* Subsystem registers */
@@ -2717,10 +2717,18 @@ static int set_gbenu_ethss_priv(struct gbe_priv 
*gbe_dev,
void __iomem *regs;
int i, ret;
 
+   gbe_dev-et_stats = gbenu_et_stats;
+
+   if (IS_SS_ID_NU(gbe_dev))
+   gbe_dev-num_et_stats = GBENU_ET_STATS_HOST_SIZE +
+   (gbe_dev-max_num_slaves * GBENU_ET_STATS_PORT_SIZE);
+   else
+   gbe_dev-num_et_stats = GBENU_ET_STATS_HOST_SIZE +
+   GBENU_ET_STATS_PORT_SIZE;
+
gbe_dev-hw_stats = devm_kzalloc(gbe_dev-dev,
- GBENU_NUM_HW_STAT_ENTRIES *
- (gbe_dev-max_num_ports) * sizeof(u64),
- GFP_KERNEL);
+gbe_dev-num_et_stats * sizeof(u64),
+GFP_KERNEL);
if (!gbe_dev-hw_stats) {
dev_err(gbe_dev-dev, hw_stats memory allocation failed\n);
return -ENOMEM;
@@ -2753,16 +2761,8 @@ static int set_gbenu_ethss_priv(struct gbe_priv *gbe_dev,
gbe_dev-ale_ports = gbe_dev-max_num_ports;
gbe_dev-host_port = GBENU_HOST_PORT_NUM;
gbe_dev-ale_entries = GBE13_NUM_ALE_ENTRIES;
-   gbe_dev-et_stats = gbenu_et_stats;
gbe_dev-stats_en_mask = (1  (gbe_dev-max_num_ports)) - 1;
 
-   if (IS_SS_ID_NU(gbe_dev))
-   gbe_dev-num_et_stats = GBENU_ET_STATS_HOST_SIZE +
-   (gbe_dev-max_num_slaves * GBENU_ET_STATS_PORT_SIZE);
-   else
-   gbe_dev-num_et_stats = GBENU_ET_STATS_HOST_SIZE +
-   GBENU_ET_STATS_PORT_SIZE;
-
/* Subsystem registers */
GBENU_SET_REG_OFS(gbe_dev, ss_regs, id_ver);
 
-- 
1.7.9.5

[net-next PATCH v0 6/6] net: netcp: Adds missing statistics for K2L and K2E

2015-07-23 Thread WingMan Kwok
This patch adds the missing statistics for the host
and slave ports of the CPSW on K2L and K2E platforms.

Signed-off-by: WingMan Kwok w-kw...@ti.com
---
 drivers/net/ethernet/ti/netcp_ethss.c |  177 -
 1 file changed, 174 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/ti/netcp_ethss.c 
b/drivers/net/ethernet/ti/netcp_ethss.c
index e2ef7ba..7782120 100644
--- a/drivers/net/ethernet/ti/netcp_ethss.c
+++ b/drivers/net/ethernet/ti/netcp_ethss.c
@@ -876,7 +876,7 @@ static const struct netcp_ethtool_stat gbe13_et_stats[] = {
 };
 
 /* This is the size of entries in GBENU_STATS_HOST */
-#define GBENU_ET_STATS_HOST_SIZE   33
+#define GBENU_ET_STATS_HOST_SIZE   52
 
 #define GBENU_STATS_HOST(field)\
 {  \
@@ -885,8 +885,8 @@ static const struct netcp_ethtool_stat gbe13_et_stats[] = {
offsetof(struct gbenu_hw_stats, field)  \
 }
 
-/* This is the size of entries in GBENU_STATS_HOST */
-#define GBENU_ET_STATS_PORT_SIZE   46
+/* This is the size of entries in GBENU_STATS_PORT */
+#define GBENU_ET_STATS_PORT_SIZE   65
 
 #define GBENU_STATS_P1(field)  \
 {  \
@@ -978,7 +978,26 @@ static const struct netcp_ethtool_stat gbenu_et_stats[] = {
GBENU_STATS_HOST(ale_unknown_mcast_bytes),
GBENU_STATS_HOST(ale_unknown_bcast),
GBENU_STATS_HOST(ale_unknown_bcast_bytes),
+   GBENU_STATS_HOST(ale_pol_match),
+   GBENU_STATS_HOST(ale_pol_match_red),
+   GBENU_STATS_HOST(ale_pol_match_yellow),
GBENU_STATS_HOST(tx_mem_protect_err),
+   GBENU_STATS_HOST(tx_pri0_drop),
+   GBENU_STATS_HOST(tx_pri1_drop),
+   GBENU_STATS_HOST(tx_pri2_drop),
+   GBENU_STATS_HOST(tx_pri3_drop),
+   GBENU_STATS_HOST(tx_pri4_drop),
+   GBENU_STATS_HOST(tx_pri5_drop),
+   GBENU_STATS_HOST(tx_pri6_drop),
+   GBENU_STATS_HOST(tx_pri7_drop),
+   GBENU_STATS_HOST(tx_pri0_drop_bcnt),
+   GBENU_STATS_HOST(tx_pri1_drop_bcnt),
+   GBENU_STATS_HOST(tx_pri2_drop_bcnt),
+   GBENU_STATS_HOST(tx_pri3_drop_bcnt),
+   GBENU_STATS_HOST(tx_pri4_drop_bcnt),
+   GBENU_STATS_HOST(tx_pri5_drop_bcnt),
+   GBENU_STATS_HOST(tx_pri6_drop_bcnt),
+   GBENU_STATS_HOST(tx_pri7_drop_bcnt),
/* GBENU Module 1 */
GBENU_STATS_P1(rx_good_frames),
GBENU_STATS_P1(rx_broadcast_frames),
@@ -1025,7 +1044,26 @@ static const struct netcp_ethtool_stat gbenu_et_stats[] 
= {
GBENU_STATS_P1(ale_unknown_mcast_bytes),
GBENU_STATS_P1(ale_unknown_bcast),
GBENU_STATS_P1(ale_unknown_bcast_bytes),
+   GBENU_STATS_P1(ale_pol_match),
+   GBENU_STATS_P1(ale_pol_match_red),
+   GBENU_STATS_P1(ale_pol_match_yellow),
GBENU_STATS_P1(tx_mem_protect_err),
+   GBENU_STATS_P1(tx_pri0_drop),
+   GBENU_STATS_P1(tx_pri1_drop),
+   GBENU_STATS_P1(tx_pri2_drop),
+   GBENU_STATS_P1(tx_pri3_drop),
+   GBENU_STATS_P1(tx_pri4_drop),
+   GBENU_STATS_P1(tx_pri5_drop),
+   GBENU_STATS_P1(tx_pri6_drop),
+   GBENU_STATS_P1(tx_pri7_drop),
+   GBENU_STATS_P1(tx_pri0_drop_bcnt),
+   GBENU_STATS_P1(tx_pri1_drop_bcnt),
+   GBENU_STATS_P1(tx_pri2_drop_bcnt),
+   GBENU_STATS_P1(tx_pri3_drop_bcnt),
+   GBENU_STATS_P1(tx_pri4_drop_bcnt),
+   GBENU_STATS_P1(tx_pri5_drop_bcnt),
+   GBENU_STATS_P1(tx_pri6_drop_bcnt),
+   GBENU_STATS_P1(tx_pri7_drop_bcnt),
/* GBENU Module 2 */
GBENU_STATS_P2(rx_good_frames),
GBENU_STATS_P2(rx_broadcast_frames),
@@ -1072,7 +1110,26 @@ static const struct netcp_ethtool_stat gbenu_et_stats[] 
= {
GBENU_STATS_P2(ale_unknown_mcast_bytes),
GBENU_STATS_P2(ale_unknown_bcast),
GBENU_STATS_P2(ale_unknown_bcast_bytes),
+   GBENU_STATS_P2(ale_pol_match),
+   GBENU_STATS_P2(ale_pol_match_red),
+   GBENU_STATS_P2(ale_pol_match_yellow),
GBENU_STATS_P2(tx_mem_protect_err),
+   GBENU_STATS_P2(tx_pri0_drop),
+   GBENU_STATS_P2(tx_pri1_drop),
+   GBENU_STATS_P2(tx_pri2_drop),
+   GBENU_STATS_P2(tx_pri3_drop),
+   GBENU_STATS_P2(tx_pri4_drop),
+   GBENU_STATS_P2(tx_pri5_drop),
+   GBENU_STATS_P2(tx_pri6_drop),
+   GBENU_STATS_P2(tx_pri7_drop),
+   GBENU_STATS_P2(tx_pri0_drop_bcnt),
+   GBENU_STATS_P2(tx_pri1_drop_bcnt),
+   GBENU_STATS_P2(tx_pri2_drop_bcnt),
+   GBENU_STATS_P2(tx_pri3_drop_bcnt),
+   GBENU_STATS_P2(tx_pri4_drop_bcnt),
+   GBENU_STATS_P2(tx_pri5_drop_bcnt),
+   GBENU_STATS_P2(tx_pri6_drop_bcnt),
+   GBENU_STATS_P2(tx_pri7_drop_bcnt),
/* GBENU Module 3 */
GBENU_STATS_P3(rx_good_frames),
GBENU_STATS_P3(rx_broadcast_frames),
@@ -1119,7 +1176,26 @@ static const struct netcp_ethtool_stat gbenu_et_stats[] 
= {
GBENU_STATS_P3(ale_unknown_mcast_bytes

[net-next PATCH v0 1/6] net: netcp: Fixes the use of spin_lock_bh in timer function

2015-07-23 Thread WingMan Kwok
This patch fixes a bug in which the timer routine synchronized
against the ethtool-triggered statistics updates with spin_lock_bh().
A timer function is itself a bottom-half, so this should be
spin_lock().

Signed-off-by: WingMan Kwok w-kw...@ti.com
---
 drivers/net/ethernet/ti/netcp_ethss.c |5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/ti/netcp_ethss.c 
b/drivers/net/ethernet/ti/netcp_ethss.c
index 9b7e0a3..cabf977 100644
--- a/drivers/net/ethernet/ti/netcp_ethss.c
+++ b/drivers/net/ethernet/ti/netcp_ethss.c
@@ -2189,14 +2189,15 @@ static void netcp_ethss_timer(unsigned long arg)
netcp_ethss_update_link_state(gbe_dev, slave, NULL);
}
 
-   spin_lock_bh(gbe_dev-hw_stats_lock);
+   /* A timer runs as a BH, no need to block them */
+   spin_lock(gbe_dev-hw_stats_lock);
 
if (gbe_dev-ss_version == GBE_SS_VERSION_14)
gbe_update_stats_ver14(gbe_dev, NULL);
else
gbe_update_stats(gbe_dev, NULL);
 
-   spin_unlock_bh(gbe_dev-hw_stats_lock);
+   spin_unlock(gbe_dev-hw_stats_lock);
 
gbe_dev-timer.expires  = jiffies + GBE_TIMER_INTERVAL;
add_timer(gbe_dev-timer);
-- 
1.7.9.5

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


[net-next PATCH v0 2/6] net: netcp: Fixes hw statistics module base setting error

2015-07-23 Thread WingMan Kwok
This patch fixes error in the setting of the hw statistics
module base for K2HK platform.  In K2HK although there are
4 hw statistics modules, but only 2 are visible at a time.
Thus when setting up the pointers to the base of the
corresponding hw statistics modules, modules 0 and 2 should
point to one base, while modules 1 and 3 should point to the
other.

Signed-off-by: WingMan Kwok w-kw...@ti.com
---
 drivers/net/ethernet/ti/netcp_ethss.c |6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/ti/netcp_ethss.c 
b/drivers/net/ethernet/ti/netcp_ethss.c
index cabf977..b954856 100644
--- a/drivers/net/ethernet/ti/netcp_ethss.c
+++ b/drivers/net/ethernet/ti/netcp_ethss.c
@@ -2675,10 +2675,14 @@ static int set_gbe_ethss14_priv(struct gbe_priv 
*gbe_dev,
gbe_dev-sgmii_port_regs = gbe_dev-ss_regs + GBE13_SGMII_MODULE_OFFSET;
gbe_dev-host_port_regs = gbe_dev-switch_regs + GBE13_HOST_PORT_OFFSET;
 
+   /* K2HK has only 2 hw stats modules visible at a time, so
+* module 0  2 points to one base and
+* module 1  3 points to the other base
+*/
for (i = 0; i  gbe_dev-max_num_slaves; i++) {
gbe_dev-hw_stats_regs[i] =
gbe_dev-switch_regs + GBE13_HW_STATS_OFFSET +
-   (GBE_HW_STATS_REG_MAP_SZ * i);
+   (GBE_HW_STATS_REG_MAP_SZ * (i  0x1));
}
 
gbe_dev-ale_reg = gbe_dev-switch_regs + GBE13_ALE_OFFSET;
-- 
1.7.9.5

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


[net-next PATCH v1 5/6] net: netcp: Fixes to CPSW statistics collection

2015-07-23 Thread WingMan Kwok
In certain applications it's beneficial to allow the CPSW h/w
stats counters to continue to increment even while the kernel
polls them. This patch implements this behavior for both 1G
and 10G ethernet subsystem modules.

Signed-off-by: WingMan Kwok w-kw...@ti.com
---
 drivers/net/ethernet/ti/netcp_ethss.c |   86 -
 1 file changed, 75 insertions(+), 11 deletions(-)

diff --git a/drivers/net/ethernet/ti/netcp_ethss.c 
b/drivers/net/ethernet/ti/netcp_ethss.c
index b06f210..aa33066 100644
--- a/drivers/net/ethernet/ti/netcp_ethss.c
+++ b/drivers/net/ethernet/ti/netcp_ethss.c
@@ -642,6 +642,7 @@ struct gbe_priv {
boolenable_ale;
u8  max_num_slaves;
u8  max_num_ports; /* max_num_slaves + 1 */
+   u8  num_stats_mods;
struct netcp_tx_pipetx_pipe;
 
int host_port;
@@ -671,6 +672,7 @@ struct gbe_priv {
struct net_device   *dummy_ndev;
 
u64 *hw_stats;
+   u32 *hw_stats_prev;
const struct netcp_ethtool_stat *et_stats;
int num_et_stats;
/*  Lock for updating the hwstats */
@@ -1550,25 +1552,37 @@ static int keystone_get_sset_count(struct net_device 
*ndev, int stringset)
}
 }
 
+static void gbe_reset_mod_stats(struct gbe_priv *gbe_dev, int stats_mod)
+{
+   void __iomem *base = gbe_dev-hw_stats_regs[stats_mod];
+   u32  __iomem *p_stats_entry;
+   int i;
+
+   for (i = 0; i  gbe_dev-num_et_stats; i++) {
+   if (gbe_dev-et_stats[i].type == stats_mod) {
+   p_stats_entry = base + gbe_dev-et_stats[i].offset;
+   gbe_dev-hw_stats[i] = 0;
+   gbe_dev-hw_stats_prev[i] = readl(p_stats_entry);
+   }
+   }
+}
+
 static inline void gbe_update_hw_stats_entry(struct gbe_priv *gbe_dev,
 int et_stats_entry)
 {
void __iomem *base = NULL;
-   u32  __iomem *p;
-   u32 tmp = 0;
+   u32  __iomem *p_stats_entry;
+   u32 curr, delta;
 
/* The hw_stats_regs pointers are already
 * properly set to point to the right base:
 */
base = gbe_dev-hw_stats_regs[gbe_dev-et_stats[et_stats_entry].type];
-   p = base + gbe_dev-et_stats[et_stats_entry].offset;
-   tmp = readl(p);
-   gbe_dev-hw_stats[et_stats_entry] += tmp;
-
-   /* write-to-decrement:
-* new register value = old register value - write value
-*/
-   writel(tmp, p);
+   p_stats_entry = base + gbe_dev-et_stats[et_stats_entry].offset;
+   curr = readl(p_stats_entry);
+   delta = curr - gbe_dev-hw_stats_prev[et_stats_entry];
+   gbe_dev-hw_stats_prev[et_stats_entry] = curr;
+   gbe_dev-hw_stats[et_stats_entry] += delta;
 }
 
 static void gbe_update_stats(struct gbe_priv *gbe_dev, uint64_t *data)
@@ -1607,6 +1621,12 @@ static inline void gbe_stats_mod_visible_ver14(struct 
gbe_priv *gbe_dev,
writel(val, GBE_REG_ADDR(gbe_dev, switch_regs, stat_port_en));
 }
 
+static void gbe_reset_mod_stats_ver14(struct gbe_priv *gbe_dev, int stats_mod)
+{
+   gbe_stats_mod_visible_ver14(gbe_dev, stats_mod);
+   gbe_reset_mod_stats(gbe_dev, stats_mod);
+}
+
 static void gbe_update_stats_ver14(struct gbe_priv *gbe_dev, uint64_t *data)
 {
u32 half_num_et_stats = (gbe_dev-num_et_stats / 2);
@@ -2560,6 +2580,7 @@ static int set_xgbe_ethss10_priv(struct gbe_priv *gbe_dev,
}
gbe_dev-xgbe_serdes_regs = regs;
 
+   gbe_dev-num_stats_mods = gbe_dev-max_num_ports;
gbe_dev-et_stats = xgbe10_et_stats;
gbe_dev-num_et_stats = ARRAY_SIZE(xgbe10_et_stats);
 
@@ -2571,6 +2592,16 @@ static int set_xgbe_ethss10_priv(struct gbe_priv 
*gbe_dev,
return -ENOMEM;
}
 
+   gbe_dev-hw_stats_prev =
+   devm_kzalloc(gbe_dev-dev,
+gbe_dev-num_et_stats * sizeof(u32),
+GFP_KERNEL);
+   if (!gbe_dev-hw_stats_prev) {
+   dev_err(gbe_dev-dev,
+   hw_stats_prev memory allocation failed\n);
+   return -ENOMEM;
+   }
+
gbe_dev-ss_version = XGBE_SS_VERSION_10;
gbe_dev-sgmii_port_regs = gbe_dev-ss_regs +
XGBE10_SGMII_MODULE_OFFSET;
@@ -2668,6 +2699,7 @@ static int set_gbe_ethss14_priv(struct gbe_priv *gbe_dev,
}
gbe_dev-switch_regs = regs;
 
+   gbe_dev-num_stats_mods = gbe_dev-max_num_slaves;
gbe_dev-et_stats = gbe13_et_stats;
gbe_dev-num_et_stats = ARRAY_SIZE(gbe13_et_stats);
 
@@ -2679,6 +2711,16 @@ static int set_gbe_ethss14_priv(struct gbe_priv *gbe_dev,
return -ENOMEM;
}
 
+   gbe_dev

[net-next PATCH v1 4/6] net: netcp: Consolidates statistics collection code

2015-07-23 Thread WingMan Kwok
Different Keystone2 platforms have different number and
layouts of hw statistics modules.  This patch consolidates
the statistics processing of different Keystone2 platforms
for easy maintenance.

Signed-off-by: WingMan Kwok w-kw...@ti.com
---
 drivers/net/ethernet/ti/netcp_ethss.c |   99 ++---
 1 file changed, 54 insertions(+), 45 deletions(-)

diff --git a/drivers/net/ethernet/ti/netcp_ethss.c 
b/drivers/net/ethernet/ti/netcp_ethss.c
index 3976516..b06f210 100644
--- a/drivers/net/ethernet/ti/netcp_ethss.c
+++ b/drivers/net/ethernet/ti/netcp_ethss.c
@@ -1550,70 +1550,79 @@ static int keystone_get_sset_count(struct net_device 
*ndev, int stringset)
}
 }
 
-static void gbe_update_stats(struct gbe_priv *gbe_dev, uint64_t *data)
+static inline void gbe_update_hw_stats_entry(struct gbe_priv *gbe_dev,
+int et_stats_entry)
 {
void __iomem *base = NULL;
u32  __iomem *p;
u32 tmp = 0;
+
+   /* The hw_stats_regs pointers are already
+* properly set to point to the right base:
+*/
+   base = gbe_dev-hw_stats_regs[gbe_dev-et_stats[et_stats_entry].type];
+   p = base + gbe_dev-et_stats[et_stats_entry].offset;
+   tmp = readl(p);
+   gbe_dev-hw_stats[et_stats_entry] += tmp;
+
+   /* write-to-decrement:
+* new register value = old register value - write value
+*/
+   writel(tmp, p);
+}
+
+static void gbe_update_stats(struct gbe_priv *gbe_dev, uint64_t *data)
+{
int i;
 
for (i = 0; i  gbe_dev-num_et_stats; i++) {
-   base = gbe_dev-hw_stats_regs[gbe_dev-et_stats[i].type];
-   p = base + gbe_dev-et_stats[i].offset;
-   tmp = readl(p);
-   gbe_dev-hw_stats[i] = gbe_dev-hw_stats[i] + tmp;
+   gbe_update_hw_stats_entry(gbe_dev, i);
+
if (data)
data[i] = gbe_dev-hw_stats[i];
-   /* write-to-decrement:
-* new register value = old register value - write value
-*/
-   writel(tmp, p);
}
 }
 
-static void gbe_update_stats_ver14(struct gbe_priv *gbe_dev, uint64_t *data)
+static inline void gbe_stats_mod_visible_ver14(struct gbe_priv *gbe_dev,
+  int stats_mod)
 {
-   void __iomem *gbe_statsa = gbe_dev-hw_stats_regs[0];
-   void __iomem *gbe_statsb = gbe_dev-hw_stats_regs[1];
-   u64 *hw_stats = gbe_dev-hw_stats[0];
-   void __iomem *base = NULL;
-   u32  __iomem *p;
-   u32 tmp = 0, val, pair_size = (gbe_dev-num_et_stats / 2);
-   int i, j, pair;
+   u32 val;
 
-   for (pair = 0; pair  2; pair++) {
-   val = readl(GBE_REG_ADDR(gbe_dev, switch_regs, stat_port_en));
+   val = readl(GBE_REG_ADDR(gbe_dev, switch_regs, stat_port_en));
 
-   if (pair == 0)
-   val = ~GBE_STATS_CD_SEL;
-   else
-   val |= GBE_STATS_CD_SEL;
+   switch (stats_mod) {
+   case GBE_STATSA_MODULE:
+   case GBE_STATSB_MODULE:
+   val = ~GBE_STATS_CD_SEL;
+   break;
+   case GBE_STATSC_MODULE:
+   case GBE_STATSD_MODULE:
+   val |= GBE_STATS_CD_SEL;
+   break;
+   default:
+   return;
+   }
+
+   /* make the stat module visible */
+   writel(val, GBE_REG_ADDR(gbe_dev, switch_regs, stat_port_en));
+}
 
-   /* make the stat modules visible */
-   writel(val, GBE_REG_ADDR(gbe_dev, switch_regs, stat_port_en));
+static void gbe_update_stats_ver14(struct gbe_priv *gbe_dev, uint64_t *data)
+{
+   u32 half_num_et_stats = (gbe_dev-num_et_stats / 2);
+   int et_entry, j, pair;
 
-   for (i = 0; i  pair_size; i++) {
-   j = pair * pair_size + i;
-   switch (gbe_dev-et_stats[j].type) {
-   case GBE_STATSA_MODULE:
-   case GBE_STATSC_MODULE:
-   base = gbe_statsa;
-   break;
-   case GBE_STATSB_MODULE:
-   case GBE_STATSD_MODULE:
-   base  = gbe_statsb;
-   break;
-   }
+   for (pair = 0; pair  2; pair++) {
+   gbe_stats_mod_visible_ver14(gbe_dev, (pair ?
+ GBE_STATSC_MODULE :
+ GBE_STATSA_MODULE));
+
+   for (j = 0; j  half_num_et_stats; j++) {
+   et_entry = pair * half_num_et_stats + j;
+   gbe_update_hw_stats_entry(gbe_dev, et_entry);
 
-   p = base + gbe_dev-et_stats[j].offset;
-   tmp = readl(p);
-   hw_stats[j] += tmp;
if (data

[net-next PATCH v1 3/6] net: netcp: Fixes error in oversized memory allocation for statistics storage

2015-07-23 Thread WingMan Kwok
The CPSW driver keeps internally some, but not all, of
the statistics available in the hw statistics modules.  Furthermore,
some of the locations in the hw statistics modules are reserved and
contain no useful information.  Prior to this patch, the driver
allocates memory of the size of the the whole hw statistics modules,
instead of the size of statistics-entries-interested-in (i.e. et_stats),
for internal storage.  This patch fixes that.

Signed-off-by: WingMan Kwok w-kw...@ti.com
---
 drivers/net/ethernet/ti/netcp_ethss.c |   46 +++--
 1 file changed, 21 insertions(+), 25 deletions(-)

diff --git a/drivers/net/ethernet/ti/netcp_ethss.c 
b/drivers/net/ethernet/ti/netcp_ethss.c
index b954856..3976516 100644
--- a/drivers/net/ethernet/ti/netcp_ethss.c
+++ b/drivers/net/ethernet/ti/netcp_ethss.c
@@ -295,8 +295,6 @@ struct xgbe_hw_stats {
u32 rx_dma_overruns;
 };
 
-#define XGBE10_NUM_STAT_ENTRIES (sizeof(struct xgbe_hw_stats)/sizeof(u32))
-
 struct gbenu_ss_regs {
u32 id_ver;
u32 synce_count;/* NU */
@@ -480,7 +478,6 @@ struct gbenu_hw_stats {
u32 tx_pri7_drop_bcnt;
 };
 
-#define GBENU_NUM_HW_STAT_ENTRIES (sizeof(struct gbenu_hw_stats) / sizeof(u32))
 #define GBENU_HW_STATS_REG_MAP_SZ  0x200
 
 struct gbe_ss_regs {
@@ -615,7 +612,6 @@ struct gbe_hw_stats {
u32 rx_dma_overruns;
 };
 
-#define GBE13_NUM_HW_STAT_ENTRIES (sizeof(struct gbe_hw_stats)/sizeof(u32))
 #define GBE_MAX_HW_STAT_MODS   9
 #define GBE_HW_STATS_REG_MAP_SZ0x100
 
@@ -2555,10 +2551,12 @@ static int set_xgbe_ethss10_priv(struct gbe_priv 
*gbe_dev,
}
gbe_dev-xgbe_serdes_regs = regs;
 
+   gbe_dev-et_stats = xgbe10_et_stats;
+   gbe_dev-num_et_stats = ARRAY_SIZE(xgbe10_et_stats);
+
gbe_dev-hw_stats = devm_kzalloc(gbe_dev-dev,
- XGBE10_NUM_STAT_ENTRIES *
- (gbe_dev-max_num_ports) * sizeof(u64),
- GFP_KERNEL);
+gbe_dev-num_et_stats * sizeof(u64),
+GFP_KERNEL);
if (!gbe_dev-hw_stats) {
dev_err(gbe_dev-dev, hw_stats memory allocation failed\n);
return -ENOMEM;
@@ -2577,8 +2575,6 @@ static int set_xgbe_ethss10_priv(struct gbe_priv *gbe_dev,
gbe_dev-ale_ports = gbe_dev-max_num_ports;
gbe_dev-host_port = XGBE10_HOST_PORT_NUM;
gbe_dev-ale_entries = XGBE10_NUM_ALE_ENTRIES;
-   gbe_dev-et_stats = xgbe10_et_stats;
-   gbe_dev-num_et_stats = ARRAY_SIZE(xgbe10_et_stats);
gbe_dev-stats_en_mask = (1  (gbe_dev-max_num_ports)) - 1;
 
/* Subsystem registers */
@@ -2663,10 +2659,12 @@ static int set_gbe_ethss14_priv(struct gbe_priv 
*gbe_dev,
}
gbe_dev-switch_regs = regs;
 
+   gbe_dev-et_stats = gbe13_et_stats;
+   gbe_dev-num_et_stats = ARRAY_SIZE(gbe13_et_stats);
+
gbe_dev-hw_stats = devm_kzalloc(gbe_dev-dev,
- GBE13_NUM_HW_STAT_ENTRIES *
- gbe_dev-max_num_slaves * sizeof(u64),
- GFP_KERNEL);
+gbe_dev-num_et_stats * sizeof(u64),
+GFP_KERNEL);
if (!gbe_dev-hw_stats) {
dev_err(gbe_dev-dev, hw_stats memory allocation failed\n);
return -ENOMEM;
@@ -2689,8 +2687,6 @@ static int set_gbe_ethss14_priv(struct gbe_priv *gbe_dev,
gbe_dev-ale_ports = gbe_dev-max_num_ports;
gbe_dev-host_port = GBE13_HOST_PORT_NUM;
gbe_dev-ale_entries = GBE13_NUM_ALE_ENTRIES;
-   gbe_dev-et_stats = gbe13_et_stats;
-   gbe_dev-num_et_stats = ARRAY_SIZE(gbe13_et_stats);
gbe_dev-stats_en_mask = GBE13_REG_VAL_STAT_ENABLE_ALL;
 
/* Subsystem registers */
@@ -2717,10 +2713,18 @@ static int set_gbenu_ethss_priv(struct gbe_priv 
*gbe_dev,
void __iomem *regs;
int i, ret;
 
+   gbe_dev-et_stats = gbenu_et_stats;
+
+   if (IS_SS_ID_NU(gbe_dev))
+   gbe_dev-num_et_stats = GBENU_ET_STATS_HOST_SIZE +
+   (gbe_dev-max_num_slaves * GBENU_ET_STATS_PORT_SIZE);
+   else
+   gbe_dev-num_et_stats = GBENU_ET_STATS_HOST_SIZE +
+   GBENU_ET_STATS_PORT_SIZE;
+
gbe_dev-hw_stats = devm_kzalloc(gbe_dev-dev,
- GBENU_NUM_HW_STAT_ENTRIES *
- (gbe_dev-max_num_ports) * sizeof(u64),
- GFP_KERNEL);
+gbe_dev-num_et_stats * sizeof(u64),
+GFP_KERNEL);
if (!gbe_dev-hw_stats) {
dev_err(gbe_dev-dev, hw_stats memory allocation failed\n);
return -ENOMEM

[net-next PATCH v1 1/6] net: netcp: Fixes the use of spin_lock_bh in timer function

2015-07-23 Thread WingMan Kwok
This patch fixes a bug in which the timer routine synchronized
against the ethtool-triggered statistics updates with spin_lock_bh().
A timer function is itself a bottom-half, so this should be
spin_lock().

Signed-off-by: WingMan Kwok w-kw...@ti.com
---
 drivers/net/ethernet/ti/netcp_ethss.c |5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/ti/netcp_ethss.c 
b/drivers/net/ethernet/ti/netcp_ethss.c
index 9b7e0a3..cabf977 100644
--- a/drivers/net/ethernet/ti/netcp_ethss.c
+++ b/drivers/net/ethernet/ti/netcp_ethss.c
@@ -2189,14 +2189,15 @@ static void netcp_ethss_timer(unsigned long arg)
netcp_ethss_update_link_state(gbe_dev, slave, NULL);
}
 
-   spin_lock_bh(gbe_dev-hw_stats_lock);
+   /* A timer runs as a BH, no need to block them */
+   spin_lock(gbe_dev-hw_stats_lock);
 
if (gbe_dev-ss_version == GBE_SS_VERSION_14)
gbe_update_stats_ver14(gbe_dev, NULL);
else
gbe_update_stats(gbe_dev, NULL);
 
-   spin_unlock_bh(gbe_dev-hw_stats_lock);
+   spin_unlock(gbe_dev-hw_stats_lock);
 
gbe_dev-timer.expires  = jiffies + GBE_TIMER_INTERVAL;
add_timer(gbe_dev-timer);
-- 
1.7.9.5

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


[net-next PATCH v1 2/6] net: netcp: Fixes hw statistics module base setting error

2015-07-23 Thread WingMan Kwok
This patch fixes error in the setting of the hw statistics
module base for K2HK platform.  In K2HK although there are
4 hw statistics modules, but only 2 are visible at a time.
Thus when setting up the pointers to the base of the
corresponding hw statistics modules, modules 0 and 2 should
point to one base, while modules 1 and 3 should point to the
other.

Signed-off-by: WingMan Kwok w-kw...@ti.com
---
 drivers/net/ethernet/ti/netcp_ethss.c |6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/ti/netcp_ethss.c 
b/drivers/net/ethernet/ti/netcp_ethss.c
index cabf977..b954856 100644
--- a/drivers/net/ethernet/ti/netcp_ethss.c
+++ b/drivers/net/ethernet/ti/netcp_ethss.c
@@ -2675,10 +2675,14 @@ static int set_gbe_ethss14_priv(struct gbe_priv 
*gbe_dev,
gbe_dev-sgmii_port_regs = gbe_dev-ss_regs + GBE13_SGMII_MODULE_OFFSET;
gbe_dev-host_port_regs = gbe_dev-switch_regs + GBE13_HOST_PORT_OFFSET;
 
+   /* K2HK has only 2 hw stats modules visible at a time, so
+* module 0  2 points to one base and
+* module 1  3 points to the other base
+*/
for (i = 0; i  gbe_dev-max_num_slaves; i++) {
gbe_dev-hw_stats_regs[i] =
gbe_dev-switch_regs + GBE13_HW_STATS_OFFSET +
-   (GBE_HW_STATS_REG_MAP_SZ * i);
+   (GBE_HW_STATS_REG_MAP_SZ * (i  0x1));
}
 
gbe_dev-ale_reg = gbe_dev-switch_regs + GBE13_ALE_OFFSET;
-- 
1.7.9.5

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


[net-next PATCH v1 6/6] net: netcp: Adds missing statistics for K2L and K2E

2015-07-23 Thread WingMan Kwok
This patch adds the missing statistics for the host
and slave ports of the CPSW on K2L and K2E platforms.

Signed-off-by: WingMan Kwok w-kw...@ti.com
---
 drivers/net/ethernet/ti/netcp_ethss.c |  177 -
 1 file changed, 174 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/ti/netcp_ethss.c 
b/drivers/net/ethernet/ti/netcp_ethss.c
index aa33066..01a955c 100644
--- a/drivers/net/ethernet/ti/netcp_ethss.c
+++ b/drivers/net/ethernet/ti/netcp_ethss.c
@@ -872,7 +872,7 @@ static const struct netcp_ethtool_stat gbe13_et_stats[] = {
 };
 
 /* This is the size of entries in GBENU_STATS_HOST */
-#define GBENU_ET_STATS_HOST_SIZE   33
+#define GBENU_ET_STATS_HOST_SIZE   52
 
 #define GBENU_STATS_HOST(field)\
 {  \
@@ -881,8 +881,8 @@ static const struct netcp_ethtool_stat gbe13_et_stats[] = {
offsetof(struct gbenu_hw_stats, field)  \
 }
 
-/* This is the size of entries in GBENU_STATS_HOST */
-#define GBENU_ET_STATS_PORT_SIZE   46
+/* This is the size of entries in GBENU_STATS_PORT */
+#define GBENU_ET_STATS_PORT_SIZE   65
 
 #define GBENU_STATS_P1(field)  \
 {  \
@@ -974,7 +974,26 @@ static const struct netcp_ethtool_stat gbenu_et_stats[] = {
GBENU_STATS_HOST(ale_unknown_mcast_bytes),
GBENU_STATS_HOST(ale_unknown_bcast),
GBENU_STATS_HOST(ale_unknown_bcast_bytes),
+   GBENU_STATS_HOST(ale_pol_match),
+   GBENU_STATS_HOST(ale_pol_match_red),
+   GBENU_STATS_HOST(ale_pol_match_yellow),
GBENU_STATS_HOST(tx_mem_protect_err),
+   GBENU_STATS_HOST(tx_pri0_drop),
+   GBENU_STATS_HOST(tx_pri1_drop),
+   GBENU_STATS_HOST(tx_pri2_drop),
+   GBENU_STATS_HOST(tx_pri3_drop),
+   GBENU_STATS_HOST(tx_pri4_drop),
+   GBENU_STATS_HOST(tx_pri5_drop),
+   GBENU_STATS_HOST(tx_pri6_drop),
+   GBENU_STATS_HOST(tx_pri7_drop),
+   GBENU_STATS_HOST(tx_pri0_drop_bcnt),
+   GBENU_STATS_HOST(tx_pri1_drop_bcnt),
+   GBENU_STATS_HOST(tx_pri2_drop_bcnt),
+   GBENU_STATS_HOST(tx_pri3_drop_bcnt),
+   GBENU_STATS_HOST(tx_pri4_drop_bcnt),
+   GBENU_STATS_HOST(tx_pri5_drop_bcnt),
+   GBENU_STATS_HOST(tx_pri6_drop_bcnt),
+   GBENU_STATS_HOST(tx_pri7_drop_bcnt),
/* GBENU Module 1 */
GBENU_STATS_P1(rx_good_frames),
GBENU_STATS_P1(rx_broadcast_frames),
@@ -1021,7 +1040,26 @@ static const struct netcp_ethtool_stat gbenu_et_stats[] 
= {
GBENU_STATS_P1(ale_unknown_mcast_bytes),
GBENU_STATS_P1(ale_unknown_bcast),
GBENU_STATS_P1(ale_unknown_bcast_bytes),
+   GBENU_STATS_P1(ale_pol_match),
+   GBENU_STATS_P1(ale_pol_match_red),
+   GBENU_STATS_P1(ale_pol_match_yellow),
GBENU_STATS_P1(tx_mem_protect_err),
+   GBENU_STATS_P1(tx_pri0_drop),
+   GBENU_STATS_P1(tx_pri1_drop),
+   GBENU_STATS_P1(tx_pri2_drop),
+   GBENU_STATS_P1(tx_pri3_drop),
+   GBENU_STATS_P1(tx_pri4_drop),
+   GBENU_STATS_P1(tx_pri5_drop),
+   GBENU_STATS_P1(tx_pri6_drop),
+   GBENU_STATS_P1(tx_pri7_drop),
+   GBENU_STATS_P1(tx_pri0_drop_bcnt),
+   GBENU_STATS_P1(tx_pri1_drop_bcnt),
+   GBENU_STATS_P1(tx_pri2_drop_bcnt),
+   GBENU_STATS_P1(tx_pri3_drop_bcnt),
+   GBENU_STATS_P1(tx_pri4_drop_bcnt),
+   GBENU_STATS_P1(tx_pri5_drop_bcnt),
+   GBENU_STATS_P1(tx_pri6_drop_bcnt),
+   GBENU_STATS_P1(tx_pri7_drop_bcnt),
/* GBENU Module 2 */
GBENU_STATS_P2(rx_good_frames),
GBENU_STATS_P2(rx_broadcast_frames),
@@ -1068,7 +1106,26 @@ static const struct netcp_ethtool_stat gbenu_et_stats[] 
= {
GBENU_STATS_P2(ale_unknown_mcast_bytes),
GBENU_STATS_P2(ale_unknown_bcast),
GBENU_STATS_P2(ale_unknown_bcast_bytes),
+   GBENU_STATS_P2(ale_pol_match),
+   GBENU_STATS_P2(ale_pol_match_red),
+   GBENU_STATS_P2(ale_pol_match_yellow),
GBENU_STATS_P2(tx_mem_protect_err),
+   GBENU_STATS_P2(tx_pri0_drop),
+   GBENU_STATS_P2(tx_pri1_drop),
+   GBENU_STATS_P2(tx_pri2_drop),
+   GBENU_STATS_P2(tx_pri3_drop),
+   GBENU_STATS_P2(tx_pri4_drop),
+   GBENU_STATS_P2(tx_pri5_drop),
+   GBENU_STATS_P2(tx_pri6_drop),
+   GBENU_STATS_P2(tx_pri7_drop),
+   GBENU_STATS_P2(tx_pri0_drop_bcnt),
+   GBENU_STATS_P2(tx_pri1_drop_bcnt),
+   GBENU_STATS_P2(tx_pri2_drop_bcnt),
+   GBENU_STATS_P2(tx_pri3_drop_bcnt),
+   GBENU_STATS_P2(tx_pri4_drop_bcnt),
+   GBENU_STATS_P2(tx_pri5_drop_bcnt),
+   GBENU_STATS_P2(tx_pri6_drop_bcnt),
+   GBENU_STATS_P2(tx_pri7_drop_bcnt),
/* GBENU Module 3 */
GBENU_STATS_P3(rx_good_frames),
GBENU_STATS_P3(rx_broadcast_frames),
@@ -1115,7 +1172,26 @@ static const struct netcp_ethtool_stat gbenu_et_stats[] 
= {
GBENU_STATS_P3(ale_unknown_mcast_bytes

[net-next PATCH v1 0/6] net: netcp: Bug fixes of CPSW statistics collection

2015-07-23 Thread WingMan Kwok
This patch set contains bug fixes and enhencements of hw ethernet
statistics processing on TI's Keystone2 CPSW ethernet switches.

v1: Removes unused defines in PATCH 3/6 based on reviewer's comment

WingMan Kwok (6):
  net: netcp: Fixes the use of spin_lock_bh in timer function
  net: netcp: Fixes hw statistics module base setting error
  net: netcp: Fixes error in oversized memory allocation for statistics
storage
  net: netcp: Consolidates statistics collection code
  net: netcp: Fixes to CPSW statistics collection
  net: netcp: Adds missing statistics for K2L and K2E

 drivers/net/ethernet/ti/netcp_ethss.c |  403 ++---
 1 file changed, 324 insertions(+), 79 deletions(-)

-- 
1.7.9.5

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