Netdev List
 help / color / mirror / Atom feed
* [PATCH NEXT 6/8] qlcnic: fix link diag test
From: Amit Kumar Salecha @ 2010-08-11 12:05 UTC (permalink / raw)
  To: davem; +Cc: netdev, ameen.rahman, Sony Chacko
In-Reply-To: <1281528329-8812-1-git-send-email-amit.salecha@qlogic.com>

From: Sony Chacko <sony.chacko@qlogic.com>

o Give sufficient time for all makes of PHY modules
  to establish the link after loopback test.
o Perform online test before offline test.

Signed-off-by: Sony Chacko <sony.chacko@qlogic.com>
Signed-off-by: Amit Kumar Salecha <amit.salecha@qlogic.com>
---
 drivers/net/qlcnic/qlcnic_ethtool.c |   17 ++++++++---------
 drivers/net/qlcnic/qlcnic_hw.c      |    1 +
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c
index 9328d59..3d4655d 100644
--- a/drivers/net/qlcnic/qlcnic_ethtool.c
+++ b/drivers/net/qlcnic/qlcnic_ethtool.c
@@ -747,6 +747,14 @@ qlcnic_diag_test(struct net_device *dev, struct ethtool_test *eth_test,
 {
 	memset(data, 0, sizeof(u64) * QLCNIC_TEST_LEN);
 
+	data[0] = qlcnic_reg_test(dev);
+	if (data[0])
+		eth_test->flags |= ETH_TEST_FL_FAILED;
+
+	data[1] = (u64) qlcnic_test_link(dev);
+	if (data[1])
+		eth_test->flags |= ETH_TEST_FL_FAILED;
+
 	if (eth_test->flags == ETH_TEST_FL_OFFLINE) {
 		data[2] = qlcnic_irq_test(dev);
 		if (data[2])
@@ -757,15 +765,6 @@ qlcnic_diag_test(struct net_device *dev, struct ethtool_test *eth_test,
 			eth_test->flags |= ETH_TEST_FL_FAILED;
 
 	}
-
-	data[0] = qlcnic_reg_test(dev);
-	if (data[0])
-		eth_test->flags |= ETH_TEST_FL_FAILED;
-
-	/* link test */
-	data[1] = (u64) qlcnic_test_link(dev);
-	if (data[1])
-		eth_test->flags |= ETH_TEST_FL_FAILED;
 }
 
 static void
diff --git a/drivers/net/qlcnic/qlcnic_hw.c b/drivers/net/qlcnic/qlcnic_hw.c
index e08c8b0..9d40ce0 100644
--- a/drivers/net/qlcnic/qlcnic_hw.c
+++ b/drivers/net/qlcnic/qlcnic_hw.c
@@ -1245,4 +1245,5 @@ void qlcnic_clear_ilb_mode(struct qlcnic_adapter *adapter)
 		mode = VPORT_MISS_MODE_ACCEPT_MULTI;
 
 	qlcnic_nic_set_promisc(adapter, mode);
+	msleep(1000);
 }
-- 
1.6.0.2


^ permalink raw reply related

* [PATCH NEXT 5/8] qlcnic: fix link status message
From: Amit Kumar Salecha @ 2010-08-11 12:05 UTC (permalink / raw)
  To: davem; +Cc: netdev, ameen.rahman, Sony Chacko
In-Reply-To: <1281528329-8812-1-git-send-email-amit.salecha@qlogic.com>

From: Sony Chacko <sony.chacko@qlogic.com>

Display interface name for link status message.
With dev_info pci number get printed.

Signed-off-by: Sony Chacko <sony.chacko@qlogic.com>
Signed-off-by: Amit Kumar Salecha <amit.salecha@qlogic.com>
---
 drivers/net/qlcnic/qlcnic_main.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c
index 96e8e75..7c9072d 100644
--- a/drivers/net/qlcnic/qlcnic_main.c
+++ b/drivers/net/qlcnic/qlcnic_main.c
@@ -1934,14 +1934,16 @@ void qlcnic_advert_link_change(struct qlcnic_adapter *adapter, int linkup)
 	struct net_device *netdev = adapter->netdev;
 
 	if (adapter->ahw.linkup && !linkup) {
-		dev_info(&netdev->dev, "NIC Link is down\n");
+		printk(KERN_INFO "%s: %s NIC Link is down\n",
+		       qlcnic_driver_name, netdev->name);
 		adapter->ahw.linkup = 0;
 		if (netif_running(netdev)) {
 			netif_carrier_off(netdev);
 			netif_stop_queue(netdev);
 		}
 	} else if (!adapter->ahw.linkup && linkup) {
-		dev_info(&netdev->dev, "NIC Link is up\n");
+		printk(KERN_INFO "%s: %s NIC Link is up\n",
+		       qlcnic_driver_name, netdev->name);
 		adapter->ahw.linkup = 1;
 		if (netif_running(netdev)) {
 			netif_carrier_on(netdev);
-- 
1.6.0.2


^ permalink raw reply related

* [PATCH NEXT 8/8] qlcnic: update version 5.0.8.0
From: Amit Kumar Salecha @ 2010-08-11 12:05 UTC (permalink / raw)
  To: davem; +Cc: netdev, ameen.rahman
In-Reply-To: <1281528329-8812-1-git-send-email-amit.salecha@qlogic.com>

New field added to version number "_UPDATE",
to distinguish fixes and enhancement.

Signed-off-by: Amit Kumar Salecha <amit.salecha@qlogic.com>
---
 drivers/net/qlcnic/qlcnic.h |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h
index 1d680a5..8e711f1 100644
--- a/drivers/net/qlcnic/qlcnic.h
+++ b/drivers/net/qlcnic/qlcnic.h
@@ -51,8 +51,9 @@
 
 #define _QLCNIC_LINUX_MAJOR 5
 #define _QLCNIC_LINUX_MINOR 0
-#define _QLCNIC_LINUX_SUBVERSION 7
-#define QLCNIC_LINUX_VERSIONID  "5.0.7"
+#define _QLCNIC_LINUX_SUBVERSION 8
+#define _QLCNIC_LINUX_UPDATE 0
+#define QLCNIC_LINUX_VERSIONID  "5.0.8.0"
 #define QLCNIC_DRV_IDC_VER  0x01
 
 #define QLCNIC_VERSION_CODE(a, b, c)	(((a) << 24) + ((b) << 16) + (c))
-- 
1.6.0.2


^ permalink raw reply related

* [PATCH NEXT 7/8] qlcnic: turn off lro when rxcsum is disabled.
From: Amit Kumar Salecha @ 2010-08-11 12:05 UTC (permalink / raw)
  To: davem; +Cc: netdev, ameen.rahman, Sucheta Chakraborty
In-Reply-To: <1281528329-8812-1-git-send-email-amit.salecha@qlogic.com>

From: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com>

Signed-off-by: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com>
Signed-off-by: Amit Kumar Salecha <amit.salecha@qlogic.com>
---
 drivers/net/qlcnic/qlcnic.h         |    1 +
 drivers/net/qlcnic/qlcnic_ethtool.c |    8 ++++++++
 2 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h
index ae02b53..1d680a5 100644
--- a/drivers/net/qlcnic/qlcnic.h
+++ b/drivers/net/qlcnic/qlcnic.h
@@ -894,6 +894,7 @@ struct qlcnic_mac_req {
 #define QLCNIC_MSI_ENABLED		0x02
 #define QLCNIC_MSIX_ENABLED		0x04
 #define QLCNIC_LRO_ENABLED		0x08
+#define QLCNIC_LRO_DISABLED		0x00
 #define QLCNIC_BRIDGE_ENABLED       	0X10
 #define QLCNIC_DIAG_ENABLED		0x20
 #define QLCNIC_ESWITCH_ENABLED		0x40
diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c
index 3d4655d..706eb80 100644
--- a/drivers/net/qlcnic/qlcnic_ethtool.c
+++ b/drivers/net/qlcnic/qlcnic_ethtool.c
@@ -819,6 +819,14 @@ static int qlcnic_set_rx_csum(struct net_device *dev, u32 data)
 {
 	struct qlcnic_adapter *adapter = netdev_priv(dev);
 	adapter->rx_csum = !!data;
+
+	if (!(adapter->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO))
+		return 0;
+
+	if (!adapter->rx_csum && !(dev->features & NETIF_F_LRO)) {
+		dev->features &= ~NETIF_F_LRO;
+		qlcnic_config_hw_lro(adapter, QLCNIC_LRO_DISABLED);
+	}
 	return 0;
 }
 
-- 
1.6.0.2


^ permalink raw reply related

* [PATCH NEXT 1/8] qlcnic: fix aer for virtual func
From: Amit Kumar Salecha @ 2010-08-11 12:05 UTC (permalink / raw)
  To: davem; +Cc: netdev, ameen.rahman
In-Reply-To: <1281528329-8812-1-git-send-email-amit.salecha@qlogic.com>

Virtual function are not privilge to initialize firmware.

Signed-off-by: Amit Kumar Salecha <amit.salecha@qlogic.com>
---
 drivers/net/qlcnic/qlcnic_main.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c
index b9615bd..9cc8732 100644
--- a/drivers/net/qlcnic/qlcnic_main.c
+++ b/drivers/net/qlcnic/qlcnic_main.c
@@ -2723,7 +2723,7 @@ static int qlcnic_attach_func(struct pci_dev *pdev)
 	if (qlcnic_api_lock(adapter))
 		return -EINVAL;
 
-	if (first_func) {
+	if (adapter->op_mode != QLCNIC_NON_PRIV_FUNC && first_func) {
 		adapter->need_fw_reset = 1;
 		set_bit(__QLCNIC_START_FW, &adapter->state);
 		QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_INITIALIZING);
-- 
1.6.0.2


^ permalink raw reply related

* [PATCH NEXT 2/8] qlcnic: device state management fixes for virtual func
From: Amit Kumar Salecha @ 2010-08-11 12:05 UTC (permalink / raw)
  To: davem; +Cc: netdev, ameen.rahman
In-Reply-To: <1281528329-8812-1-git-send-email-amit.salecha@qlogic.com>

o NPAR state should be set to operationl by Mangement function only.
o NPAR state should be set to non operational before device reset.
o VF function should wait for NPAR state to be operational.

Signed-off-by: Amit Kumar Salecha <amit.salecha@qlogic.com>
---
 drivers/net/qlcnic/qlcnic_hdr.h  |    5 +-
 drivers/net/qlcnic/qlcnic_main.c |   80 +++++++++++++++++++++++---------------
 2 files changed, 51 insertions(+), 34 deletions(-)

diff --git a/drivers/net/qlcnic/qlcnic_hdr.h b/drivers/net/qlcnic/qlcnic_hdr.h
index 15fc320..bd346d9 100644
--- a/drivers/net/qlcnic/qlcnic_hdr.h
+++ b/drivers/net/qlcnic/qlcnic_hdr.h
@@ -718,8 +718,9 @@ enum {
 #define QLCNIC_DEV_FAILED		0x6
 #define QLCNIC_DEV_QUISCENT		0x7
 
-#define QLCNIC_DEV_NPAR_NOT_RDY	0
-#define QLCNIC_DEV_NPAR_RDY		1
+#define QLCNIC_DEV_NPAR_NON_OPER	0 /* NON Operational */
+#define QLCNIC_DEV_NPAR_OPER		1 /* NPAR Operational */
+#define QLCNIC_DEV_NPAR_OPER_TIMEO	30 /* Operational time out */
 
 #define QLC_DEV_CHECK_ACTIVE(VAL, FN)		((VAL) &= (1 << (FN * 4)))
 #define QLC_DEV_SET_REF_CNT(VAL, FN)		((VAL) |= (1 << (FN * 4)))
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c
index 9cc8732..bac2371 100644
--- a/drivers/net/qlcnic/qlcnic_main.c
+++ b/drivers/net/qlcnic/qlcnic_main.c
@@ -2388,7 +2388,7 @@ qlcnic_fwinit_work(struct work_struct *work)
 {
 	struct qlcnic_adapter *adapter = container_of(work,
 			struct qlcnic_adapter, fw_work.work);
-	u32 dev_state = 0xf, npar_state;
+	u32 dev_state = 0xf;
 
 	if (qlcnic_api_lock(adapter))
 		goto err_ret;
@@ -2402,16 +2402,8 @@ qlcnic_fwinit_work(struct work_struct *work)
 	}
 
 	if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC) {
-		npar_state = QLCRD32(adapter, QLCNIC_CRB_DEV_NPAR_STATE);
-		if (npar_state == QLCNIC_DEV_NPAR_RDY) {
-			qlcnic_api_unlock(adapter);
-			goto wait_npar;
-		} else {
-			qlcnic_schedule_work(adapter, qlcnic_fwinit_work,
-				FW_POLL_DELAY);
-			qlcnic_api_unlock(adapter);
-			return;
-		}
+		qlcnic_api_unlock(adapter);
+		goto wait_npar;
 	}
 
 	if (adapter->fw_wait_cnt++ > adapter->reset_ack_timeo) {
@@ -2460,20 +2452,17 @@ wait_npar:
 	QLCDB(adapter, HW, "Func waiting: Device state=%u\n", dev_state);
 
 	switch (dev_state) {
-	case QLCNIC_DEV_QUISCENT:
-	case QLCNIC_DEV_NEED_QUISCENT:
-	case QLCNIC_DEV_NEED_RESET:
-		qlcnic_schedule_work(adapter,
-			qlcnic_fwinit_work, FW_POLL_DELAY);
-		return;
-	case QLCNIC_DEV_FAILED:
-		break;
-
-	default:
+	case QLCNIC_DEV_READY:
 		if (!adapter->nic_ops->start_firmware(adapter)) {
 			qlcnic_schedule_work(adapter, qlcnic_attach_work, 0);
 			return;
 		}
+	case QLCNIC_DEV_FAILED:
+		break;
+	default:
+		qlcnic_schedule_work(adapter,
+			qlcnic_fwinit_work, FW_POLL_DELAY);
+		return;
 	}
 
 err_ret:
@@ -2520,6 +2509,22 @@ err_ret:
 
 }
 
+/*Transit NPAR state to NON Operational */
+static void
+qlcnic_set_npar_non_operational(struct qlcnic_adapter *adapter)
+{
+	u32 state;
+
+	state = QLCRD32(adapter, QLCNIC_CRB_DEV_NPAR_STATE);
+	if (state == QLCNIC_DEV_NPAR_NON_OPER)
+		return;
+
+	if (qlcnic_api_lock(adapter))
+		return;
+	QLCWR32(adapter, QLCNIC_CRB_DEV_NPAR_STATE, QLCNIC_DEV_NPAR_NON_OPER);
+	qlcnic_api_unlock(adapter);
+}
+
 /*Transit to RESET state from READY state only */
 static void
 qlcnic_dev_request_reset(struct qlcnic_adapter *adapter)
@@ -2538,6 +2543,7 @@ qlcnic_dev_request_reset(struct qlcnic_adapter *adapter)
 		qlcnic_idc_debug_info(adapter, 0);
 	}
 
+	QLCWR32(adapter, QLCNIC_CRB_DEV_NPAR_STATE, QLCNIC_DEV_NPAR_NON_OPER);
 	qlcnic_api_unlock(adapter);
 }
 
@@ -2545,21 +2551,14 @@ qlcnic_dev_request_reset(struct qlcnic_adapter *adapter)
 static void
 qlcnic_dev_set_npar_ready(struct qlcnic_adapter *adapter)
 {
-	u32 state;
-
 	if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED) ||
-		adapter->op_mode == QLCNIC_NON_PRIV_FUNC)
+		adapter->op_mode != QLCNIC_MGMT_FUNC)
 		return;
 	if (qlcnic_api_lock(adapter))
 		return;
 
-	state = QLCRD32(adapter, QLCNIC_CRB_DEV_NPAR_STATE);
-
-	if (state != QLCNIC_DEV_NPAR_RDY) {
-		QLCWR32(adapter, QLCNIC_CRB_DEV_NPAR_STATE,
-			QLCNIC_DEV_NPAR_RDY);
-		QLCDB(adapter, DRV, "NPAR READY state set\n");
-	}
+	QLCWR32(adapter, QLCNIC_CRB_DEV_NPAR_STATE, QLCNIC_DEV_NPAR_OPER);
+	QLCDB(adapter, DRV, "NPAR operational state set\n");
 
 	qlcnic_api_unlock(adapter);
 }
@@ -2621,8 +2620,11 @@ qlcnic_check_health(struct qlcnic_adapter *adapter)
 		qlcnic_dev_request_reset(adapter);
 
 	state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE);
-	if (state == QLCNIC_DEV_NEED_RESET || state == QLCNIC_DEV_NEED_QUISCENT)
+	if (state == QLCNIC_DEV_NEED_RESET ||
+	    state == QLCNIC_DEV_NEED_QUISCENT) {
+		qlcnic_set_npar_non_operational(adapter);
 		adapter->need_fw_reset = 1;
+	}
 
 	heartbit = QLCRD32(adapter, QLCNIC_PEG_ALIVE_COUNTER);
 	if (heartbit != adapter->heartbit) {
@@ -2812,11 +2814,25 @@ static int
 qlcnicvf_start_firmware(struct qlcnic_adapter *adapter)
 {
 	int err;
+	u8 npar_opt_timeo = QLCNIC_DEV_NPAR_OPER_TIMEO;
+	u32 npar_state;
 
 	err = qlcnic_can_start_firmware(adapter);
 	if (err)
 		return err;
 
+	npar_state = QLCRD32(adapter, QLCNIC_CRB_DEV_NPAR_STATE);
+	while (npar_state != QLCNIC_DEV_NPAR_OPER && --npar_opt_timeo) {
+		msleep(1000);
+		npar_state = QLCRD32(adapter, QLCNIC_CRB_DEV_NPAR_STATE);
+	}
+
+	if (!npar_opt_timeo) {
+		dev_err(&adapter->pdev->dev,
+			"Waiting for NPAR state to opertional timeout\n");
+		return -EIO;
+	}
+
 	qlcnic_check_options(adapter);
 
 	adapter->need_fw_reset = 0;
-- 
1.6.0.2


^ permalink raw reply related

* [PATCH NEXT 4/8] qlcnic: add eswitch statistics support
From: Amit Kumar Salecha @ 2010-08-11 12:05 UTC (permalink / raw)
  To: davem; +Cc: netdev, ameen.rahman
In-Reply-To: <1281528329-8812-1-git-send-email-amit.salecha@qlogic.com>

Adding eswitch statistics support. User can get
whole eswitch stats or stats of func belong to that eswitch.

Added:
o command to get statistics of eswitch and function.
o sysfs support to export eswitch and func statatistics.

Signed-off-by: Amit Kumar Salecha <amit.salecha@qlogic.com>
---
 drivers/net/qlcnic/qlcnic.h      |   33 ++++++++++
 drivers/net/qlcnic/qlcnic_ctx.c  |  125 ++++++++++++++++++++++++++++++++++++
 drivers/net/qlcnic/qlcnic_main.c |  132 +++++++++++++++++++++++++++++++++++++-
 3 files changed, 289 insertions(+), 1 deletions(-)

diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h
index 9703893..ae02b53 100644
--- a/drivers/net/qlcnic/qlcnic.h
+++ b/drivers/net/qlcnic/qlcnic.h
@@ -555,6 +555,7 @@ struct qlcnic_recv_context {
 #define QLCNIC_CDRP_CMD_GET_ESWITCH_STATUS	0x00000026
 #define QLCNIC_CDRP_CMD_SET_PORTMIRRORING	0x00000027
 #define QLCNIC_CDRP_CMD_CONFIGURE_ESWITCH	0x00000028
+#define QLCNIC_CDRP_CMD_GET_ESWITCH_STATS	0x0000002a
 
 #define QLCNIC_RCODE_SUCCESS		0
 #define QLCNIC_RCODE_TIMEOUT		17
@@ -1126,6 +1127,33 @@ struct qlcnic_esw_func_cfg {
 	u8	reserved;
 };
 
+#define QLCNIC_STATS_VERSION		1
+#define QLCNIC_STATS_PORT		1
+#define QLCNIC_STATS_ESWITCH		2
+#define QLCNIC_QUERY_RX_COUNTER		0
+#define QLCNIC_QUERY_TX_COUNTER		1
+struct __qlcnic_esw_statistics {
+
+	__le16 context_id;
+	__le16 version;
+	__le16 size;
+	__le16 unused;
+
+	__le64 unicast_frames;
+	__le64 multicast_frames;
+	__le64 broadcast_frames;
+	__le64 dropped_frames;
+	__le64 errors;
+	__le64 local_frames;
+	__le64 numbytes;
+	__le64 rsvd[3];
+};
+
+struct qlcnic_esw_statistics {
+	struct __qlcnic_esw_statistics rx;
+	struct __qlcnic_esw_statistics tx;
+};
+
 int qlcnic_fw_cmd_query_phy(struct qlcnic_adapter *adapter, u32 reg, u32 *val);
 int qlcnic_fw_cmd_set_phy(struct qlcnic_adapter *adapter, u32 reg, u32 val);
 
@@ -1252,6 +1280,11 @@ int qlcnic_toggle_eswitch(struct qlcnic_adapter *, u8, u8);
 int qlcnic_config_switch_port(struct qlcnic_adapter *, u8, int, u8, u8,
 			u8, u8, u16);
 int qlcnic_config_port_mirroring(struct qlcnic_adapter *, u8, u8, u8);
+int qlcnic_get_port_stats(struct qlcnic_adapter *, const u8, const u8,
+					struct __qlcnic_esw_statistics *);
+int qlcnic_get_eswitch_stats(struct qlcnic_adapter *, const u8, u8,
+					struct __qlcnic_esw_statistics *);
+int qlcnic_clear_esw_stats(struct qlcnic_adapter *adapter, u8, u8, u8);
 extern int qlcnic_config_tso;
 
 /*
diff --git a/drivers/net/qlcnic/qlcnic_ctx.c b/drivers/net/qlcnic/qlcnic_ctx.c
index cc5d861..57c9b09 100644
--- a/drivers/net/qlcnic/qlcnic_ctx.c
+++ b/drivers/net/qlcnic/qlcnic_ctx.c
@@ -983,3 +983,128 @@ int qlcnic_config_switch_port(struct qlcnic_adapter *adapter, u8 id,
 
 	return err;
 }
+
+int qlcnic_get_port_stats(struct qlcnic_adapter *adapter, const u8 func,
+		const u8 rx_tx, struct __qlcnic_esw_statistics *esw_stats) {
+
+	size_t stats_size = sizeof(struct __qlcnic_esw_statistics);
+	dma_addr_t stats_dma_t;
+	void *stats_addr;
+	u32 arg1;
+	int err;
+
+	if (esw_stats == NULL)
+		return -ENOMEM;
+
+	if (adapter->op_mode != QLCNIC_MGMT_FUNC &&
+	    func != adapter->ahw.pci_func) {
+		dev_err(&adapter->pdev->dev,
+			"Not privilege to query stats for func=%d", func);
+		return -EIO;
+	}
+
+	stats_addr = pci_alloc_consistent(adapter->pdev, stats_size,
+			&stats_dma_t);
+	if (!stats_addr) {
+		dev_err(&adapter->pdev->dev, "Unable to allocate memory\n");
+		return -ENOMEM;
+	}
+	memset(stats_addr, 0, stats_size);
+
+	arg1 = func | QLCNIC_STATS_VERSION << 8 | QLCNIC_STATS_PORT << 12;
+	arg1 |= rx_tx << 15 | stats_size << 16;
+
+	err = qlcnic_issue_cmd(adapter,
+			adapter->ahw.pci_func,
+			adapter->fw_hal_version,
+			arg1,
+			MSD(stats_dma_t),
+			LSD(stats_dma_t),
+			QLCNIC_CDRP_CMD_GET_ESWITCH_STATS);
+
+	if (!err)
+		memcpy(esw_stats, stats_addr, stats_size);
+
+	pci_free_consistent(adapter->pdev, stats_size, stats_addr,
+		stats_dma_t);
+	return err;
+}
+
+int qlcnic_get_eswitch_stats(struct qlcnic_adapter *adapter, const u8 eswitch,
+		const u8 rx_tx, struct __qlcnic_esw_statistics *esw_stats) {
+
+	struct __qlcnic_esw_statistics port_stats;
+	u8 i;
+	int ret = -EIO;
+
+	if (esw_stats == NULL)
+		return -ENOMEM;
+	if (adapter->op_mode != QLCNIC_MGMT_FUNC)
+		return -EIO;
+	if (adapter->npars == NULL)
+		return -EIO;
+
+	memset(esw_stats, 0, sizeof(struct __qlcnic_esw_statistics));
+	esw_stats->context_id = eswitch;
+
+	for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) {
+		if (adapter->npars[i].phy_port != eswitch)
+			continue;
+
+		memset(&port_stats, 0, sizeof(struct __qlcnic_esw_statistics));
+		if (qlcnic_get_port_stats(adapter, i, rx_tx, &port_stats))
+			continue;
+
+		esw_stats->size = port_stats.size;
+		esw_stats->version = port_stats.version;
+		esw_stats->unicast_frames += port_stats.unicast_frames;
+		esw_stats->multicast_frames += port_stats.multicast_frames;
+		esw_stats->broadcast_frames += port_stats.broadcast_frames;
+		esw_stats->dropped_frames += port_stats.dropped_frames;
+		esw_stats->errors += port_stats.errors;
+		esw_stats->local_frames += port_stats.local_frames;
+		esw_stats->numbytes += port_stats.numbytes;
+
+		ret = 0;
+	}
+	return ret;
+}
+
+int qlcnic_clear_esw_stats(struct qlcnic_adapter *adapter, const u8 func_esw,
+		const u8 port, const u8 rx_tx)
+{
+
+	u32 arg1;
+
+	if (adapter->op_mode != QLCNIC_MGMT_FUNC)
+		return -EIO;
+
+	if (func_esw == QLCNIC_STATS_PORT) {
+		if (port >= QLCNIC_MAX_PCI_FUNC)
+			goto err_ret;
+	} else if (func_esw == QLCNIC_STATS_ESWITCH) {
+		if (port >= QLCNIC_NIU_MAX_XG_PORTS)
+			goto err_ret;
+	} else {
+		goto err_ret;
+	}
+
+	if (rx_tx > QLCNIC_QUERY_TX_COUNTER)
+		goto err_ret;
+
+	arg1 = port | QLCNIC_STATS_VERSION << 8 | func_esw << 12;
+	arg1 |= BIT_14 | rx_tx << 15;
+
+	return qlcnic_issue_cmd(adapter,
+			adapter->ahw.pci_func,
+			adapter->fw_hal_version,
+			arg1,
+			0,
+			0,
+			QLCNIC_CDRP_CMD_GET_ESWITCH_STATS);
+
+err_ret:
+	dev_err(&adapter->pdev->dev, "Invalid argument func_esw=%d port=%d"
+		"rx_ctx=%d\n", func_esw, port, rx_tx);
+	return -EIO;
+}
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c
index 49c8110..96e8e75 100644
--- a/drivers/net/qlcnic/qlcnic_main.c
+++ b/drivers/net/qlcnic/qlcnic_main.c
@@ -3368,6 +3368,115 @@ qlcnic_sysfs_read_npar_config(struct file *file, struct kobject *kobj,
 }
 
 static ssize_t
+qlcnic_sysfs_get_port_stats(struct file *file, struct kobject *kobj,
+	struct bin_attribute *attr, char *buf, loff_t offset, size_t size)
+{
+	struct device *dev = container_of(kobj, struct device, kobj);
+	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
+	struct qlcnic_esw_statistics port_stats;
+	int ret;
+
+	if (size != sizeof(struct qlcnic_esw_statistics))
+		return QL_STATUS_INVALID_PARAM;
+
+	if (offset >= QLCNIC_MAX_PCI_FUNC)
+		return QL_STATUS_INVALID_PARAM;
+
+	memset(&port_stats, 0, size);
+	ret = qlcnic_get_port_stats(adapter, offset, QLCNIC_QUERY_RX_COUNTER,
+								&port_stats.rx);
+	if (ret)
+		return ret;
+
+	ret = qlcnic_get_port_stats(adapter, offset, QLCNIC_QUERY_TX_COUNTER,
+								&port_stats.tx);
+	if (ret)
+		return ret;
+
+	memcpy(buf, &port_stats, size);
+	return size;
+}
+
+static ssize_t
+qlcnic_sysfs_get_esw_stats(struct file *file, struct kobject *kobj,
+	struct bin_attribute *attr, char *buf, loff_t offset, size_t size)
+{
+	struct device *dev = container_of(kobj, struct device, kobj);
+	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
+	struct qlcnic_esw_statistics esw_stats;
+	int ret;
+
+	if (size != sizeof(struct qlcnic_esw_statistics))
+		return QL_STATUS_INVALID_PARAM;
+
+	if (offset >= QLCNIC_NIU_MAX_XG_PORTS)
+		return QL_STATUS_INVALID_PARAM;
+
+	memset(&esw_stats, 0, size);
+	ret = qlcnic_get_eswitch_stats(adapter, offset, QLCNIC_QUERY_RX_COUNTER,
+								&esw_stats.rx);
+	if (ret)
+		return ret;
+
+	ret = qlcnic_get_eswitch_stats(adapter, offset, QLCNIC_QUERY_TX_COUNTER,
+								&esw_stats.tx);
+	if (ret)
+		return ret;
+
+	memcpy(buf, &esw_stats, size);
+	return size;
+}
+
+static ssize_t
+qlcnic_sysfs_clear_esw_stats(struct file *file, struct kobject *kobj,
+	struct bin_attribute *attr, char *buf, loff_t offset, size_t size)
+{
+	struct device *dev = container_of(kobj, struct device, kobj);
+	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
+	int ret;
+
+	if (offset >= QLCNIC_NIU_MAX_XG_PORTS)
+		return QL_STATUS_INVALID_PARAM;
+
+	ret = qlcnic_clear_esw_stats(adapter, QLCNIC_STATS_ESWITCH, offset,
+						QLCNIC_QUERY_RX_COUNTER);
+	if (ret)
+		return ret;
+
+	ret = qlcnic_clear_esw_stats(adapter, QLCNIC_STATS_ESWITCH, offset,
+						QLCNIC_QUERY_TX_COUNTER);
+	if (ret)
+		return ret;
+
+	return size;
+}
+
+static ssize_t
+qlcnic_sysfs_clear_port_stats(struct file *file, struct kobject *kobj,
+	struct bin_attribute *attr, char *buf, loff_t offset, size_t size)
+{
+
+	struct device *dev = container_of(kobj, struct device, kobj);
+	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
+	int ret;
+
+	if (offset >= QLCNIC_MAX_PCI_FUNC)
+		return QL_STATUS_INVALID_PARAM;
+
+	ret = qlcnic_clear_esw_stats(adapter, QLCNIC_STATS_PORT, offset,
+						QLCNIC_QUERY_RX_COUNTER);
+	if (ret)
+		return ret;
+
+	ret = qlcnic_clear_esw_stats(adapter, QLCNIC_STATS_PORT, offset,
+						QLCNIC_QUERY_TX_COUNTER);
+	if (ret)
+		return ret;
+
+	return size;
+}
+
+static ssize_t
 qlcnic_sysfs_read_pci_config(struct file *file, struct kobject *kobj,
 	struct bin_attribute *attr, char *buf, loff_t offset, size_t size)
 {
@@ -3410,6 +3519,20 @@ static struct bin_attribute bin_attr_pci_config = {
 	.write = NULL,
 };
 
+static struct bin_attribute bin_attr_port_stats = {
+	.attr = {.name = "port_stats", .mode = (S_IRUGO | S_IWUSR)},
+	.size = 0,
+	.read = qlcnic_sysfs_get_port_stats,
+	.write = qlcnic_sysfs_clear_port_stats,
+};
+
+static struct bin_attribute bin_attr_esw_stats = {
+	.attr = {.name = "esw_stats", .mode = (S_IRUGO | S_IWUSR)},
+	.size = 0,
+	.read = qlcnic_sysfs_get_esw_stats,
+	.write = qlcnic_sysfs_clear_esw_stats,
+};
+
 static struct bin_attribute bin_attr_esw_config = {
 	.attr = {.name = "esw_config", .mode = (S_IRUGO | S_IWUSR)},
 	.size = 0,
@@ -3449,6 +3572,9 @@ qlcnic_create_diag_entries(struct qlcnic_adapter *adapter)
 {
 	struct device *dev = &adapter->pdev->dev;
 
+	if (device_create_bin_file(dev, &bin_attr_port_stats))
+		dev_info(dev, "failed to create port stats sysfs entry");
+
 	if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC)
 		return;
 	if (device_create_file(dev, &dev_attr_diag_mode))
@@ -3468,7 +3594,8 @@ qlcnic_create_diag_entries(struct qlcnic_adapter *adapter)
 		dev_info(dev, "failed to create esw config sysfs entry");
 	if (device_create_bin_file(dev, &bin_attr_pm_config))
 		dev_info(dev, "failed to create pm config sysfs entry");
-
+	if (device_create_bin_file(dev, &bin_attr_esw_stats))
+		dev_info(dev, "failed to create eswitch stats sysfs entry");
 }
 
 static void
@@ -3476,6 +3603,8 @@ qlcnic_remove_diag_entries(struct qlcnic_adapter *adapter)
 {
 	struct device *dev = &adapter->pdev->dev;
 
+	device_remove_bin_file(dev, &bin_attr_port_stats);
+
 	if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC)
 		return;
 	device_remove_file(dev, &dev_attr_diag_mode);
@@ -3488,6 +3617,7 @@ qlcnic_remove_diag_entries(struct qlcnic_adapter *adapter)
 	device_remove_bin_file(dev, &bin_attr_npar_config);
 	device_remove_bin_file(dev, &bin_attr_esw_config);
 	device_remove_bin_file(dev, &bin_attr_pm_config);
+	device_remove_bin_file(dev, &bin_attr_esw_stats);
 }
 
 #ifdef CONFIG_INET
-- 
1.6.0.2


^ permalink raw reply related

* [PATCH NEXT 0/8]qlcnic: enhancement and fixes
From: Amit Kumar Salecha @ 2010-08-11 12:05 UTC (permalink / raw)
  To: davem; +Cc: netdev, ameen.rahman

Hi
   Series of 8 patches to fix minor bugs and to add statistics
   support. Please apply them on net-next branch.
-Amit

^ permalink raw reply

* [PATCH NEXT 3/8] qlcnic: fix for setting function modes
From: Amit Kumar Salecha @ 2010-08-11 12:05 UTC (permalink / raw)
  To: davem; +Cc: netdev, ameen.rahman, Rajesh Borundia
In-Reply-To: <1281528329-8812-1-git-send-email-amit.salecha@qlogic.com>

From: Rajesh Borundia <rajesh.borundia@qlogic.com>

function modes was not working with CNA device, in CNA mode
other function(FCOE) can be enabled before nic.

Signed-off-by: Rajesh Borundia <rajesh.borundia@qlogic.com>
Signed-off-by: Amit Kumar Salecha <amit.salecha@qlogic.com>
---
 drivers/net/qlcnic/qlcnic_main.c |    3 ---
 1 files changed, 0 insertions(+), 3 deletions(-)

diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c
index bac2371..49c8110 100644
--- a/drivers/net/qlcnic/qlcnic_main.c
+++ b/drivers/net/qlcnic/qlcnic_main.c
@@ -533,8 +533,6 @@ qlcnic_set_function_modes(struct qlcnic_adapter *adapter)
 	ret = qlcnic_api_lock(adapter);
 	if (ret)
 		goto err_lock;
-	if (QLC_DEV_CLR_REF_CNT(ref_count, adapter->ahw.pci_func))
-		goto err_npar;
 
 	if (qlcnic_config_npars) {
 		for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) {
@@ -552,7 +550,6 @@ qlcnic_set_function_modes(struct qlcnic_adapter *adapter)
 			adapter->ahw.pci_func));
 	}
 	writel(data, priv_op);
-err_npar:
 	qlcnic_api_unlock(adapter);
 err_lock:
 	return ret;
-- 
1.6.0.2


^ permalink raw reply related

* [PATCH] net: Fix a memmove bug in dev_gro_receive()
From: Jarek Poplawski @ 2010-08-11 12:02 UTC (permalink / raw)
  To: Xin, Xiaohui
  Cc: netdev@vger.kernel.org, herbert@gondor.apana.org.au,
	davem@davemloft.net
In-Reply-To: <20100810083426.GA11509@ff.dom.local>

[was: Re: Is it a possible bug in dev_gro_receive()?]
On Tue, Aug 10, 2010 at 08:34:26AM +0000, Jarek Poplawski wrote:
> On Tue, Aug 10, 2010 at 04:11:54PM +0800, Xin, Xiaohui wrote:
> > Jarek,
> > Seems community agree with your patch more.
> > So may you send out your patch then? Thanks!
> > Some of my related patches still need this fix.
> 
> Hmm... But there was no my patch. Only a tiny, cosmetical suggestion
> to your patch. I'd be glad if you add some credit or my "Acked-by",
> of course. But if you really have a big problem, e.g. you don't like
> my suggestion, please confirm.

Hmm#2... OK, it's probably something with my English, but since it
seems to take too long, here it is. Xiaohui, I hope you'll send your
"Signed-off-by" at least.

Thanks,
Jarek P.

PS: I know, there is a bit too long line...
--------------------------->

>Xin Xiaohui wrote:
> I looked into the code dev_gro_receive(), found the code here:
> if the frags[0] is pulled to 0, then the page will be released,
> and memmove() frags left.
> Is that right? I'm not sure if memmove do right or not, but
> frags[0].size is never set after memove at least. what I think
> a simple way is not to do anything if we found frags[0].size == 0.
> The patch is as followed.
...

This version of the patch fixes the bug directly in memmove.

Reported-by: "Xin, Xiaohui" <xiaohui.xin@intel.com>
Signed-off-by: Jarek Poplawski <jarkao2@gmail.com>

---

diff --git a/net/core/dev.c b/net/core/dev.c
index 1ae6543..3721fbb 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -3143,7 +3143,7 @@ pull:
 			put_page(skb_shinfo(skb)->frags[0].page);
 			memmove(skb_shinfo(skb)->frags,
 				skb_shinfo(skb)->frags + 1,
-				--skb_shinfo(skb)->nr_frags);
+				--skb_shinfo(skb)->nr_frags * sizeof(skb_frag_t));
 		}
 	}
 

^ permalink raw reply related

* Re: Problem with non aligned DMA in usbnet on ARM
From: Martin Fuzzey @ 2010-08-11 11:38 UTC (permalink / raw)
  To: Matthieu CASTET
  Cc: linux-usb, netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
In-Reply-To: <4C627479.4060400-ITF29qwbsa/QT0dZR+AlfA@public.gmane.org>

On Wed, Aug 11, 2010 at 11:59 AM, Matthieu CASTET
<matthieu.castet-ITF29qwbsa/QT0dZR+AlfA@public.gmane.org> wrote:
> It is best to solve in usb driver, because for example in Asix case the
> driver already do copy (see asix_rx_fixup/asix_tx_fixup).
>
Yes, however those functions are only called for devices which register them.
Looking at the driver_info and product id tables shows that it's only
a subset of the devices that asix supports (88772 and 88178 chips)

In fact my hardware _is_ included
	// DLink DUB-E100 H/W Ver B1 Alternate
	USB_DEVICE (0x2001, 0x3c05),
	.driver_info = (unsigned long) &ax88772_info,

but fixing this in asix_rx_fixup wouldn't solve it for the other
supported devices.

It seems to me these fixup functions are not intended to solve
alignment issues but rather implement device specific framing (such as
when the hardware packs multiple ethernet frames into a single urb)

> PS : what hcd driver do you use ?
imx21_hcd

Martin
--
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] netpoll: use non-BH variant of RCU
From: Herbert Xu @ 2010-08-11 11:27 UTC (permalink / raw)
  To: David Miller; +Cc: paulmck, linville, netdev
In-Reply-To: <20100811110330.GA6440@gondor.apana.org.au>

On Wed, Aug 11, 2010 at 07:03:30AM -0400, Herbert Xu wrote:
>
> To use rcu_read_lock safely we'd also need to add do synchronize_rcu
> in addition of synchronize_rcu_bh, right Paul?
> 
> Of course as we were doing this unsafely prior to my patch anyway
> I'm also fine with just reverting it.

Actually, we could just disable IRQs for stable.  How about this
patch (untested)?

netpoll: Disable IRQ around RCU dereference in netpoll_rx

We cannot use rcu_dereference_bh safely in netpoll_rx as we may
be called with IRQs disabled.  We could however simply disable
IRQs as that too causes BH to be disabled and is safe in either
case.

Thanks to John Linville for discovering this bug and providing
a patch.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

diff --git a/include/linux/netpoll.h b/include/linux/netpoll.h
index 413742c..54f286b 100644
--- a/include/linux/netpoll.h
+++ b/include/linux/netpoll.h
@@ -63,20 +63,20 @@ static inline bool netpoll_rx(struct sk_buff *skb)
 	unsigned long flags;
 	bool ret = false;
 
-	rcu_read_lock_bh();
+	local_irq_save(flags);
 	npinfo = rcu_dereference_bh(skb->dev->npinfo);
 
 	if (!npinfo || (list_empty(&npinfo->rx_np) && !npinfo->rx_flags))
 		goto out;
 
-	spin_lock_irqsave(&npinfo->rx_lock, flags);
+	spin_lock(&npinfo->rx_lock);
 	/* check rx_flags again with the lock held */
 	if (npinfo->rx_flags && __netpoll_rx(skb))
 		ret = true;
-	spin_unlock_irqrestore(&npinfo->rx_lock, flags);
+	spin_unlock(&npinfo->rx_lock);
 
 out:
-	rcu_read_unlock_bh();
+	local_irq_restore(flags);
 	return ret;
 }
 
Cheers,
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply related

* Re: [PATCH] netpoll: use non-BH variant of RCU
From: Herbert Xu @ 2010-08-11 11:03 UTC (permalink / raw)
  To: David Miller; +Cc: paulmck, linville, netdev
In-Reply-To: <20100810.163117.241919476.davem@davemloft.net>

On Tue, Aug 10, 2010 at 04:31:17PM -0700, David Miller wrote:
>
> Linus's tree is fine for this.
> 
> But we need this fix for 2.6.35-stable too.  Herbert would
> you object to putting John's more simple fix there?

To use rcu_read_lock safely we'd also need to add do synchronize_rcu
in addition of synchronize_rcu_bh, right Paul?

Of course as we were doing this unsafely prior to my patch anyway
I'm also fine with just reverting it.

Thanks,
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply

* Re: [MeeGo-Dev][PATCH] Topcliff: Update PCH_CAN driver to 2.6.35
From: Daniel Baluta @ 2010-08-11 10:37 UTC (permalink / raw)
  To: Masayuki Ohtak
  Cc: andrew.chih.howe.khor-ral2JQCrhuEAvxtiuMwx3w,
	qi.wang-ral2JQCrhuEAvxtiuMwx3w, netdev-u79uwXL29TY76Z2rM5mHXA,
	gregkh-l3A5Bk7waGM, yong.y.wang-ral2JQCrhuEAvxtiuMwx3w,
	socketcan-core-0fE9KPoRgkgATYTw5x5z8w,
	meego-dev-WXzIur8shnEAvxtiuMwx3w, arjan-VuQAYsv1563Yd54FQh9/CA,
	Wolfgang Grandegger
In-Reply-To: <4C61EDE5.4030505-ECg8zkTtlr0C6LszWs/t0g@public.gmane.org>

Hi,

2010/8/11 Masayuki Ohtak <masa-korg-ECg8zkTtlr0C6LszWs/t0g@public.gmane.org>:
> CAN driver of Topcliff PCH
>
> Topcliff PCH is the platform controller hub that is going to be used in
> Intel's upcoming general embedded platform. All IO peripherals in
> Topcliff PCH are actually devices sitting on AMBA bus.
> Topcliff PCH has CAN I/F. This driver enables CAN function.
>
> Signed-off-by: Masayuki Ohtake <masa-korg-ECg8zkTtlr0C6LszWs/t0g@public.gmane.org>

I have a few questions:

1. Is your code based on Intel's CAN EP80579 ([1]) ?
2. Why don't you use kernel existing kfifo infrastructure? ([2]).
3. Can you provide a pointer to Topcliff PCH CAN I/F datasheet ?

thanks,
Daniel.

[1] http://www.intel.com/design/intarch/ep80579/sw_tools.htm
[2] http://lxr.linux.no/#linux+v2.6.35/kernel/kfifo.c

^ permalink raw reply

* Re: Problem with non aligned DMA in usbnet on ARM
From: Martin Fuzzey @ 2010-08-11 10:11 UTC (permalink / raw)
  To: Russell King - ARM Linux; +Cc: linux-usb, netdev, linux-arm-kernel
In-Reply-To: <20100811095454.GA22543@n2100.arm.linux.org.uk>

> You haven't said what HCD you're using.
>
imx21_hcd  (submitted by me and mainlined in 2.6.34)

> In that case, I'd say the HCD must handle misaligned URBs itself so
> behaviour is consistent between all implementations on different
> platforms.
>
Here is a pointer to the thread where it was stated that HCD's don't
have to handle this.

http://kerneltrap.org/mailarchive/linux-usb/2009/4/20/5528164

^ permalink raw reply

* Re: Problem with non aligned DMA in usbnet on ARM
From: Matthieu CASTET @ 2010-08-11  9:59 UTC (permalink / raw)
  To: Martin Fuzzey
  Cc: linux-usb, netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
In-Reply-To: <AANLkTi=ycg=adcizNWKMCb7EdfDANM=6Es7r_gF1LbhV-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>

Hi,

Martin Fuzzey a écrit :
> Hi all,

> So what is the correct fix for this problem?
> The options seem to be:
> 1) Remove skb_reserve() from usbnet
> But this will cause the ip header to be non aligned on platforms that
> don't have the DMA alignment requirement.
And cause lot's of unaligned access for the IP stack. This will slow 
down arm platform...

> 
> 2) Define NET_IP_ALIGN to 0 for ARM
> Seems a bit intrusive to me.
Again this will generate lot's of unaligned access.
> 
> 3) Change the HCD to copy if not aligned
> I'd like to avoid that.
> 
> 4) Change usbnet to use seperate buffers for the usb side and skb.
> Copy between them so both remain aligned
> Seems unlikely that the gain further up the stack from ensuring the ip
> header is aligned will offset the cost of the copy.
> 
> Any ideas?
I got the same problem on the gadget side : 
http://article.gmane.org/gmane.linux.usb.general/28700

A solution could be the hcd driver to tell it doesn't support unaligned 
transfert and in this case the usb stack/usb driver align it.

It is best to solve in usb driver, because for example in Asix case the 
driver already do copy (see asix_rx_fixup/asix_tx_fixup).


Matthieu

PS : what hcd driver do you use ?
--
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: Problem with non aligned DMA in usbnet on ARM
From: Russell King - ARM Linux @ 2010-08-11  9:54 UTC (permalink / raw)
  To: Martin Fuzzey
  Cc: linux-usb, netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <AANLkTi=ycg=adcizNWKMCb7EdfDANM=6Es7r_gF1LbhV-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>

On Wed, Aug 11, 2010 at 11:41:41AM +0200, Martin Fuzzey wrote:
> Digging a bit showed that the driver was submitting a non aligned data
> pointer in the URB.
> This is due to:
> skb_reserve (skb, NET_IP_ALIGN);
> 
> in net/usb/usbnet.c rx_submit()
> 
> NET_IP_ALIGN is defined as 2 in skbuff.h (default value as not defined
> by ARM) hence the data buffer address was offset by 2 whereas the hcd
> requires 4 byte alignment to work at all and cache line (32 byte here)
> alignment to work reliably.

x86 also has NET_IP_ALIGN as 2, so it will also be IP-header aligned there
too, so the restriction won't be from the USB stack.

> Removing this call to skb_reserve() fixes the problem for me.

However, that makes parsing and creating IP headers really inefficient,
especially as we take a trap each time a misaligned access is performed.

> 3) Change the HCD to copy if not aligned
> I'd like to avoid that.

You haven't said what HCD you're using.

> On a related note, this is the second time I've run into this type of
> problem.It would be much easier to debug if the HCD warned (or
> refused) misaligned URBs.

If HCD can't cope with misaligned URBs, it should fail across the board -
or be made to warn across the board - but I suspect it's a specific HCD
that you're using which is only applicable to ARM.

In that case, I'd say the HCD must handle misaligned URBs itself so
behaviour is consistent between all implementations on different
platforms.
--
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

* [PATCH] can: add limit for nframes and clean up signed/unsigned variables
From: Oliver Hartkopp @ 2010-08-11  9:44 UTC (permalink / raw)
  To: David Miller; +Cc: Ben Hawkes, Urs Thuermann, Linux Netdev List

This patch adds a limit for nframes as the number of frames in TX_SETUP and
RX_SETUP are derived from a single byte multiplex value by default.
Use-cases that would require to send/filter more than 256 CAN frames should
be implemented in userspace for complexity reasons anyway.

Additionally the assignments of unsigned values from userspace to signed
values in kernelspace and vice versa are fixed by using unsigned values in
kernelspace consistently.

Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
Reported-by: Ben Hawkes <hawkes@google.com>
Acked-by: Urs Thuermann <urs.thuermann@volkswagen.de>

---

diff --git a/net/can/bcm.c b/net/can/bcm.c
index 9c65e9d..a917fac 100644
--- a/net/can/bcm.c
+++ b/net/can/bcm.c
@@ -60,6 +60,13 @@
 #include <net/sock.h>
 #include <net/net_namespace.h>
 
+/*
+ * To send multiple CAN frame content within TX_SETUP or to filter
+ * CAN messages with multiplex index within RX_SETUP, the number of
+ * different filters is limited to 256 due to the one byte index value. 
+ */
+#define MAX_NFRAMES 256
+
 /* use of last_frames[index].can_dlc */
 #define RX_RECV    0x40 /* received data for this element */
 #define RX_THR     0x80 /* element not been sent due to throttle feature */
@@ -89,16 +96,16 @@ struct bcm_op {
 	struct list_head list;
 	int ifindex;
 	canid_t can_id;
-	int flags;
+	u32 flags;
 	unsigned long frames_abs, frames_filtered;
 	struct timeval ival1, ival2;
 	struct hrtimer timer, thrtimer;
 	struct tasklet_struct tsklet, thrtsklet;
 	ktime_t rx_stamp, kt_ival1, kt_ival2, kt_lastmsg;
 	int rx_ifindex;
-	int count;
-	int nframes;
-	int currframe;
+	u32 count;
+	u32 nframes;
+	u32 currframe;
 	struct can_frame *frames;
 	struct can_frame *last_frames;
 	struct can_frame sframe;
@@ -175,7 +182,7 @@ static int bcm_proc_show(struct seq_file *m, void *v)
 
 		seq_printf(m, "rx_op: %03X %-5s ",
 				op->can_id, bcm_proc_getifname(ifname, op->ifindex));
-		seq_printf(m, "[%d]%c ", op->nframes,
+		seq_printf(m, "[%u]%c ", op->nframes,
 				(op->flags & RX_CHECK_DLC)?'d':' ');
 		if (op->kt_ival1.tv64)
 			seq_printf(m, "timeo=%lld ",
@@ -198,7 +205,7 @@ static int bcm_proc_show(struct seq_file *m, void *v)
 
 	list_for_each_entry(op, &bo->tx_ops, list) {
 
-		seq_printf(m, "tx_op: %03X %s [%d] ",
+		seq_printf(m, "tx_op: %03X %s [%u] ",
 				op->can_id,
 				bcm_proc_getifname(ifname, op->ifindex),
 				op->nframes);
@@ -283,7 +290,7 @@ static void bcm_send_to_user(struct bcm_op *op, struct bcm_msg_head *head,
 	struct can_frame *firstframe;
 	struct sockaddr_can *addr;
 	struct sock *sk = op->sk;
-	int datalen = head->nframes * CFSIZ;
+	unsigned int datalen = head->nframes * CFSIZ;
 	int err;
 
 	skb = alloc_skb(sizeof(*head) + datalen, gfp_any());
@@ -468,7 +475,7 @@ rx_changed_settime:
  * bcm_rx_cmp_to_index - (bit)compares the currently received data to formerly
  *                       received data stored in op->last_frames[]
  */
-static void bcm_rx_cmp_to_index(struct bcm_op *op, int index,
+static void bcm_rx_cmp_to_index(struct bcm_op *op, unsigned int index,
 				const struct can_frame *rxdata)
 {
 	/*
@@ -554,7 +561,8 @@ static enum hrtimer_restart bcm_rx_timeout_handler(struct hrtimer *hrtimer)
 /*
  * bcm_rx_do_flush - helper for bcm_rx_thr_flush
  */
-static inline int bcm_rx_do_flush(struct bcm_op *op, int update, int index)
+static inline int bcm_rx_do_flush(struct bcm_op *op, int update,
+				  unsigned int index)
 {
 	if ((op->last_frames) && (op->last_frames[index].can_dlc & RX_THR)) {
 		if (update)
@@ -575,7 +583,7 @@ static int bcm_rx_thr_flush(struct bcm_op *op, int update)
 	int updated = 0;
 
 	if (op->nframes > 1) {
-		int i;
+		unsigned int i;
 
 		/* for MUX filter we start at index 1 */
 		for (i = 1; i < op->nframes; i++)
@@ -624,7 +632,7 @@ static void bcm_rx_handler(struct sk_buff *skb, void *data)
 {
 	struct bcm_op *op = (struct bcm_op *)data;
 	const struct can_frame *rxframe = (struct can_frame *)skb->data;
-	int i;
+	unsigned int i;
 
 	/* disable timeout */
 	hrtimer_cancel(&op->timer);
@@ -822,14 +830,15 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
 {
 	struct bcm_sock *bo = bcm_sk(sk);
 	struct bcm_op *op;
-	int i, err;
+	unsigned int i;
+	int err;
 
 	/* we need a real device to send frames */
 	if (!ifindex)
 		return -ENODEV;
 
-	/* we need at least one can_frame */
-	if (msg_head->nframes < 1)
+	/* check nframes boundaries - we need at least one can_frame */
+	if (msg_head->nframes < 1 || msg_head->nframes > MAX_NFRAMES)
 		return -EINVAL;
 
 	/* check the given can_id */
@@ -993,6 +1002,10 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
 		msg_head->nframes = 0;
 	}
 
+	/* the first element contains the mux-mask => MAX_NFRAMES + 1  */
+	if (msg_head->nframes > MAX_NFRAMES + 1)
+		return -EINVAL;
+
 	if ((msg_head->flags & RX_RTR_FRAME) &&
 	    ((msg_head->nframes != 1) ||
 	     (!(msg_head->can_id & CAN_RTR_FLAG))))



^ permalink raw reply related

* Problem with non aligned DMA in usbnet on ARM
From: Martin Fuzzey @ 2010-08-11  9:41 UTC (permalink / raw)
  To: linux-usb, netdev-u79uwXL29TY76Z2rM5mHXA
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

Hi all,

I have a DLINK DUB-E100 USB / Ethernet adapter with using the Asix
AX88772 chipset.
This device works fine on linux x86 using the usbnet based asix driver
however on ARM (iMX21 SoC, kernel 2.6.35) transmit works but receive
fails with:
"asix_rx_fixup() Bad Header Length"

Digging a bit showed that the driver was submitting a non aligned data
pointer in the URB.
This is due to:
skb_reserve (skb, NET_IP_ALIGN);

in net/usb/usbnet.c rx_submit()

NET_IP_ALIGN is defined as 2 in skbuff.h (default value as not defined
by ARM) hence the data buffer address was offset by 2 whereas the hcd
requires 4 byte alignment to work at all and cache line (32 byte here)
alignment to work reliably.
Note that usbnet uses skb->data as the buffer submitted to USB in the URB.

Removing this call to skb_reserve() fixes the problem for me.

However the comments in skbuff.h make it clear that this is done
deliberately knowing that it will cause non aligned DMA but seem to
suggest that this should work anyway (even if less efficiently).

My understanding, based on previous discussions on -usb a year back
while I was working on the usb hcd is that the hcd does _not_ have to
support unaligned DMA.

So what is the correct fix for this problem?
The options seem to be:
1) Remove skb_reserve() from usbnet
But this will cause the ip header to be non aligned on platforms that
don't have the DMA alignment requirement.

2) Define NET_IP_ALIGN to 0 for ARM
Seems a bit intrusive to me.

3) Change the HCD to copy if not aligned
I'd like to avoid that.

4) Change usbnet to use seperate buffers for the usb side and skb.
Copy between them so both remain aligned
Seems unlikely that the gain further up the stack from ensuring the ip
header is aligned will offset the cost of the copy.

Any ideas?

On a related note, this is the second time I've run into this type of
problem.It would be much easier to debug if the HCD warned (or
refused) misaligned URBs. If HCDs provided information on their
alignment requirements then the USB core could do this in a uniform
way. For example adding an alignment field to struct hc_driver or
struct usb_hcd?

Cheers,

Martin
--
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 1/2] pkt_sched: Fix sch_sfq vs tc_modify_qdisc oops
From: David Miller @ 2010-08-11  8:37 UTC (permalink / raw)
  To: jarkao2; +Cc: netdev, shemminger, kaber, franchoze
In-Reply-To: <20100811083101.GA10126@ff.dom.local>

From: Jarek Poplawski <jarkao2@gmail.com>
Date: Wed, 11 Aug 2010 08:31:02 +0000

> After more investigation I've found sch_sfq is still vulnerable
> because off its missing class handlers. Here is an oops as
> proof of the concept, and a patch below. This patch should be
> considered for stable (without following 2/2 patch).

Thanks Jarek, both applied to net-2.6 and the first queued up
for -stable.

^ permalink raw reply

* [PATCH 2/2] pkt_sched: Check .walk and .leaf class handlers
From: Jarek Poplawski @ 2010-08-11  8:31 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, Stephen Hemminger, Patrick McHardy, Franchoze Eric

Require qdisc class ops .walk and .leaf for classful qdisc in
register_qdisc(). The checks could be done later insted, but these
ops are really needed and used by most of classful qdiscs.

Signed-off-by: Jarek Poplawski <jarkao2@gmail.com>
---

diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index 8ed2f56..408eea7 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -161,7 +161,7 @@ int register_qdisc(struct Qdisc_ops *qops)
 	if (qops->cl_ops) {
 		const struct Qdisc_class_ops *cops = qops->cl_ops;
 
-		if (!(cops->get && cops->put))
+		if (!(cops->get && cops->put && cops->walk && cops->leaf))
 			goto out_einval;
 
 		if (cops->tcf_chain && !(cops->bind_tcf && cops->unbind_tcf))

^ permalink raw reply related

* [PATCH 1/2] pkt_sched: Fix sch_sfq vs tc_modify_qdisc oops
From: Jarek Poplawski @ 2010-08-11  8:31 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, Stephen Hemminger, Patrick McHardy, Franchoze Eric

Hi,
After more investigation I've found sch_sfq is still vulnerable
because off its missing class handlers. Here is an oops as
proof of the concept, and a patch below. This patch should be
considered for stable (without following 2/2 patch).

Jarek P.

This oops can happen while doing tc qdisc replace on sfq
leaf qdiscs under some traffic.

BUG: unable to handle kernel NULL pointer dereference at (null)
IP: [<(null)>] (null)
*pde = 00000000 
Oops: 0000 [#1] SMP 
last sysfs file: /sys/module/sch_htb/refcnt
Modules linked in: sch_htb sch_sfq sch_prio snd_seq_dummy snd_seq_oss snd_seq_midi_event snd_seq snd_seq_device snd_pcm_oss snd_mixer_oss ipv6 ext3 jbd mbcache lp fuse ppdev snd_intel8x0 snd_ac97_codec ac97_bus rtc_cmos parport_pc uhci_hcd intel_agp snd_pcm e100 psmouse rtc_core mii i2c_i801 parport agpgart processor snd_timer thermal dcdbas serio_raw ehci_hcd rtc_lib shpchp thermal_sys button i2c_core evdev hwmon snd soundcore snd_page_alloc reiserfs [last unloaded: sch_htb]

Pid: 2925, comm: tc Not tainted (2.6.32-smp #1) OptiPlex 170L                
EIP: 0060:[<00000000>] EFLAGS: 00010286 CPU: 0
EIP is at 0x0
EAX: cdb52000 EBX: c44dbc98 ECX: d041fe20 EDX: 00000028
ESI: c44dbc98 EDI: cdb52080 EBP: cdb52000 ESP: c44dbc14
 DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068
Process tc (pid: 2925, ti=c44da000 task=ce819500 task.ti=c44da000)
Stack:
 c12dfbe6 00000000 c44dbc98 00000028 cdb52080 cdb52000 c1353949 c44dbc98
<0> 00000028 d041f37a d041fdbd cdb52000 cf151410 cd8b7000 cf065800 c12e1dc1
<0> 00000000 00000000 cd9fd700 cf045000 cf151424 cf151400 cd9fd700 00010002
Call Trace:
 [<c12dfbe6>] ? check_loop_fn+0x16/0xa0
 [<c1353949>] ? printk+0x17/0x1e
 [<d041f37a>] ? sfq_walk+0x8a/0xb0 [sch_sfq]
 [<c12e1dc1>] ? tc_modify_qdisc+0x451/0x4f0
 [<c12dfbd0>] ? check_loop_fn+0x0/0xa0
 [<c12e1970>] ? tc_modify_qdisc+0x0/0x4f0
 [<c12d635d>] ? rtnetlink_rcv_msg+0x16d/0x210
 [<c12bf2d5>] ? sock_rmalloc+0x35/0x90
 [<c12d61f0>] ? rtnetlink_rcv_msg+0x0/0x210
 [<c12e7d26>] ? netlink_rcv_skb+0x66/0x90
 [<c12d61e9>] ? rtnetlink_rcv+0x19/0x20
 [<c12e79fe>] ? netlink_unicast+0x26e/0x280
 [<c12e81d5>] ? netlink_sendmsg+0x1d5/0x2f0
 [<c12bc401>] ? sock_sendmsg+0x111/0x130
 [<c104b560>] ? autoremove_wake_function+0x0/0x50
 [<c104b560>] ? autoremove_wake_function+0x0/0x50
 [<c12bc594>] ? sys_sendmsg+0x174/0x280
 [<c12bd4a6>] ? sys_recvmsg+0x1a6/0x240
 [<c10804f4>] ? find_get_page+0x24/0xb0
 [<c1080e34>] ? filemap_fault+0x74/0x3a0
 [<c1097371>] ? __do_fault+0x361/0x450
 [<c12bed30>] ? lock_sock_nested+0x90/0xb0
 [<c1098f94>] ? handle_mm_fault+0x144/0x800
 [<c12bdc0d>] ? sys_socketcall+0xbd/0x290
 [<c101d22a>] ? do_page_fault+0x13a/0x2a0
 [<c101d0f0>] ? do_page_fault+0x0/0x2a0
 [<c1002eb5>] ? syscall_call+0x7/0xb
Code:  Bad EIP value.
EIP: [<00000000>] 0x0 SS:ESP 0068:c44dbc14
CR2: 0000000000000000

------------>

sch_sfq as a classful qdisc needs the .leaf handler. Otherwise, there
is an oops possible in tc_modify_qdisc()/check_loop().

Fixes commit 7d2681a6ff4f9ab5e48d02550b4c6338f1638998

Signed-off-by: Jarek Poplawski <jarkao2@gmail.com>
---

diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c
index b8bcb20..201cbac 100644
--- a/net/sched/sch_sfq.c
+++ b/net/sched/sch_sfq.c
@@ -508,6 +508,11 @@ nla_put_failure:
 	return -1;
 }
 
+static struct Qdisc *sfq_leaf(struct Qdisc *sch, unsigned long arg)
+{
+	return NULL;
+}
+
 static unsigned long sfq_get(struct Qdisc *sch, u32 classid)
 {
 	return 0;
@@ -575,6 +580,7 @@ static void sfq_walk(struct Qdisc *sch, struct qdisc_walker *arg)
 }
 
 static const struct Qdisc_class_ops sfq_class_ops = {
+	.leaf		=	sfq_leaf,
 	.get		=	sfq_get,
 	.put		=	sfq_put,
 	.tcf_chain	=	sfq_find_tcf,

^ permalink raw reply related

* Re: [RFC PATCH v9 00/16] Provide a zero-copy method on KVM virtio-net.
From: Shirley Ma @ 2010-08-11  6:55 UTC (permalink / raw)
  To: xiaohui.xin; +Cc: netdev, kvm, linux-kernel, mst, mingo, davem, herbert, jdike
In-Reply-To: <1281506460.3391.42.camel@localhost.localdomain>

On Tue, 2010-08-10 at 23:01 -0700, Shirley Ma wrote:
> On Tue, 2010-08-10 at 18:43 -0700, Shirley Ma wrote:
> > > Also I found some vhost performance regression on the new
> > > kernel with tuning. I used to get 9.4Gb/s, now I couldn't get it. 
> > 
> > I forgot to mention the kernel I used 2.6.36 one. And I found the
> > native
> > host BW is limited to 8.0Gb/s, so the regression might come from the
> > device driver not vhost.
> 
> Something is very interesting, when binding ixgbe interrupts to cpu1,
> and running netperf/netserver on cpu0, the native host to host
> performance is still around 8.0Gb/s, however, the macvtap zero copy
> result is 9.0Gb/s.
> 
> root@localhost ~]# netperf -H 192.168.10.74 -c -C -l60 -T0,0 -- -m 64K
> TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 192.168.10.74 (192.168..
> 10.74) port 0 AF_INET : cpu bind
> Recv   Send    Send                          Utilization       Service Demand
> Socket Socket  Message  Elapsed              Send     Recv     Send    Recv
> Size   Size    Size     Time     Throughput  local    remote   local   remote
> bytes  bytes   bytes    secs.    10^6bits/s  % S      % S      us/KB   us/KB
> 
>  87380  16384  65536    60.00      9013.59   53.01    8.21     0.963   0.597
> 
> Below is perf top output:
> 
>               578.00  6.5% copy_user_generic_string   
>               381.00  4.3% vmx_vcpu_run                
>               250.00  2.8% schedule                    
>               207.00  2.3% vhost_get_vq_desc           
>               204.00  2.3% _raw_spin_lock_irqsave      
>               197.00  2.2% translate_desc              
>               193.00  2.2% memcpy_fromiovec            
>               162.00  1.8% gup_pte_range   
> 
> We can compare your results with mine to see any difference.

When binding vhost thread to cpu3, qemu I/O thread to cpu2, macvtap zero
copy patch can get 9.4Gb/s. 

TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 192.168.10.74 (192.168.10.74) port 0 AF_INET : cpu bind
Recv   Send    Send                          Utilization       Service Demand
Socket Socket  Message  Elapsed              Send     Recv     Send    Recv
Size   Size    Size     Time     Throughput  local    remote   local   remote
bytes  bytes   bytes    secs.    10^6bits/s  % S      % S      us/KB   us/KB

 87380  16384  65536    60.00      9408.19   55.69    8.45     0.970   0.589

Shirley


^ permalink raw reply

* Re: [RFC PATCH v9 00/16] Provide a zero-copy method on KVM virtio-net.
From: Shirley Ma @ 2010-08-11  6:01 UTC (permalink / raw)
  To: xiaohui.xin; +Cc: netdev, kvm, linux-kernel, mst, mingo, davem, herbert, jdike
In-Reply-To: <1281490993.3391.25.camel@localhost.localdomain>

On Tue, 2010-08-10 at 18:43 -0700, Shirley Ma wrote:
> > Also I found some vhost performance regression on the new
> > kernel with tuning. I used to get 9.4Gb/s, now I couldn't get it. 
> 
> I forgot to mention the kernel I used 2.6.36 one. And I found the
> native
> host BW is limited to 8.0Gb/s, so the regression might come from the
> device driver not vhost.

Something is very interesting, when binding ixgbe interrupts to cpu1,
and running netperf/netserver on cpu0, the native host to host
performance is still around 8.0Gb/s, however, the macvtap zero copy
result is 9.0Gb/s.

root@localhost ~]# netperf -H 192.168.10.74 -c -C -l60 -T0,0 -- -m 64K
TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 192.168.10.74 (192.168..
10.74) port 0 AF_INET : cpu bind
Recv   Send    Send                          Utilization       Service Demand
Socket Socket  Message  Elapsed              Send     Recv     Send    Recv
Size   Size    Size     Time     Throughput  local    remote   local   remote
bytes  bytes   bytes    secs.    10^6bits/s  % S      % S      us/KB   us/KB

 87380  16384  65536    60.00      9013.59   53.01    8.21     0.963   0.597

Below is perf top output:

              578.00  6.5% copy_user_generic_string   
              381.00  4.3% vmx_vcpu_run                
              250.00  2.8% schedule                    
              207.00  2.3% vhost_get_vq_desc           
              204.00  2.3% _raw_spin_lock_irqsave      
              197.00  2.2% translate_desc              
              193.00  2.2% memcpy_fromiovec            
              162.00  1.8% gup_pte_range   

We can compare your results with mine to see any difference.

Thanks
Shirley

^ permalink raw reply

* [net-next-2.6 PATCH 7/7] enic: Mark intr_timer in vnic_enet_config as deprecated
From: Roopa Prabhu @ 2010-08-11  4:55 UTC (permalink / raw)
  To: davem; +Cc: netdev
In-Reply-To: <20100811045436.3877.51650.stgit@savbu-pc100.cisco.com>

From: Roopa Prabhu <roprabhu@cisco.com>



Signed-off-by: Scott Feldman <scofeldm@cisco.com>
Signed-off-by: Roopa Prabhu <roprabhu@cisco.com>
Signed-off-by: Vasanthy Kolluri <vkolluri@cisco.com>
---
 drivers/net/enic/vnic_enet.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)


diff --git a/drivers/net/enic/vnic_enet.h b/drivers/net/enic/vnic_enet.h
index 3b32912..e8740e3 100644
--- a/drivers/net/enic/vnic_enet.h
+++ b/drivers/net/enic/vnic_enet.h
@@ -30,7 +30,7 @@ struct vnic_enet_config {
 	u32 wq_desc_count;
 	u32 rq_desc_count;
 	u16 mtu;
-	u16 intr_timer;
+	u16 intr_timer_deprecated;
 	u8 intr_timer_type;
 	u8 intr_mode;
 	char devname[16];


^ permalink raw reply related


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