Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH] netback: Fix alert message.
From: David Miller @ 2011-12-06  5:33 UTC (permalink / raw)
  To: Ian.Campbell; +Cc: wei.liu2, xen-devel, netdev
In-Reply-To: <1323104325.23681.22.camel@zakaz.uk.xensource.com>

From: Ian Campbell <Ian.Campbell@citrix.com>
Date: Mon, 5 Dec 2011 16:58:45 +0000

> On Mon, 2011-12-05 at 16:57 +0000, Wei Liu wrote:
>> The original message in netback_init was 'kthread_run() fails', which should be
>> 'kthread_create() fails'.
>> 
>> Signed-off-by: Wei Liu <wei.liu2@citrix.com>
> Acked-by: Ian Campbell <ian.campbell@citrix.com>

Applied, thanks.

^ permalink raw reply

* Re: [PATCH net-next] ipv4: arp: Cleanup in arp.c
From: David Miller @ 2011-12-06  5:35 UTC (permalink / raw)
  To: igorm; +Cc: netdev
In-Reply-To: <1323087957-26429-1-git-send-email-igorm@etf.rs>

From: igorm@etf.rs
Date: Mon,  5 Dec 2011 13:25:57 +0100

> From: Igor Maravic <igorm@etf.rs>
> 
> Use "IS_ENABLED(CONFIG_FOO)" macro instead of
> "defined(CONFIG_FOO) || defined(CONFIG_FOO_MODULE)"
> 
> Signed-off-by: Igor Maravic <igorm@etf.rs>

Applied.

^ permalink raw reply

* Re: [PATCH] fsl_pq_mdio: Clean up tbi address configuration
From: Kumar Gala @ 2011-12-06  5:38 UTC (permalink / raw)
  To: David Miller; +Cc: afleming, netdev
In-Reply-To: <D789ECCE-08DE-4E6D-BCA7-2C54EC5758B7@kernel.crashing.org>


On Dec 1, 2011, at 10:38 PM, Kumar Gala wrote:

> 
> On Nov 13, 2011, at 11:26 PM, David Miller wrote:
> 
>> From: Andy Fleming <afleming@freescale.com>
>> Date: Fri, 11 Nov 2011 09:10:39 -0600
>> 
>>> The code for setting the address of the internal TBI PHY was
>>> convoluted enough without a maze of ifdefs. Clean it up a bit
>>> so we allow the logic to fail down to -ENODEV at the end of
>>> the if/else ladder, rather than using ifdefs to repeat the same
>>> failure code over and over.
>>> 
>>> Also, remove the support for the auto-configuration. I'm not aware of
>>> anyone using it, and it ends up using the bus mutex before it's been
>>> initialized.
>>> 
>>> Signed-off-by: Andy Fleming <afleming@freescale.com>
>> 
>> Applied, thanks.
> 
> I believe we need this on mainline otherwise we get something like:
> 
> Fixed MDIO Bus: probed
> Unable to handle kernel paging request for data at address 0x00000000
> Faulting instruction address: 0xc0451630
> Oops: Kernel access of bad area, sig: 11 [#1]
> SMP NR_CPUS=2 P1022 DS
> Modules linked in:
> NIP: c0451630 LR: c0451618 CTR: 00000007
> REGS: ef03fce0 TRAP: 0300   Not tainted  (3.2.0-rc3-00099-g883381d)
> MSR: 00029000 <EE,ME,CE>  CR: 24042022  XER: 00000000
> DEAR: 00000000, ESR: 00800000
> TASK = ef040000[1] 'swapper' THREAD: ef03e000 CPU: 0
> GPR00: ef03fd98 ef03fd90 ef040000 ef1ab22c 00000000 00000002 ffeb0000 0000fffe
> GPR08: b0541215 00000000 00000000 00000000 24042028 23c406c2 00000000 00000000
> GPR16: c0000a00 00000014 3fffffff 03ff9000 00000015 7ff3a760 f1044030 fffffff4
> GPR24: c053e128 ef1ab230 c056a3a8 ef03e000 ef040000 ef1ab22c 00000000 ef1ab228
> NIP [c0451630] __mutex_lock_slowpath+0xb4/0x190
> LR [c0451618] __mutex_lock_slowpath+0x9c/0x190
> Call Trace:
> [ef03fdd0] [c0451758] mutex_lock+0x4c/0x50
> [ef03fde0] [c02b5124] mdiobus_read+0x38/0x74
> [ef03fe00] [c02b41f4] get_phy_id+0x24/0x80
> [ef03fe20] [c02b9de4] fsl_pq_mdio_probe+0x3b4/0x580
> [ef03feb0] [c0266120] platform_drv_probe+0x20/0x30
> [ef03fec0] [c0264bbc] driver_probe_device+0xa4/0x1d4
> [ef03fee0] [c0264da8] __driver_attach+0xbc/0xc0
> [ef03ff00] [c0263ac0] bus_for_each_dev+0x60/0x9c
> [ef03ff30] [c02647f4] driver_attach+0x24/0x34
> [ef03ff40] [c0264444] bus_add_driver+0x1ac/0x274
> [ef03ff70] [c02651b0] driver_register+0x88/0x154
> [ef03ff90] [c0266450] platform_driver_register+0x68/0x78
> [ef03ffa0] [c05d93b8] fsl_pq_mdio_init+0x18/0x28
> [ef03ffb0] [c0001eb8] do_one_initcall+0x34/0x1a8
> [ef03ffe0] [c05bb82c] kernel_init+0xa0/0x13c
> [ef03fff0] [c000d878] kernel_thread+0x4c/0x68
> Instruction dump:
> 801c0020 2f800063 419dffe8 3bbf0004 7fa3eb78 48001aad 813f000c 38010008
> 3b3f0008 901f000c 93210008 9121000c
> 3800ffff 93810010 7c0004ac
> ---[ end trace 1643a9a9c5097f8f ]---
> Kernel panic - not syncing: Attempted to kill init!
> Call Trace:
> [ef03fbc0] [c0008044] show_stack+0x44/0x154 (unreliable)
> [ef03fc00] [c04532c8] panic+0xa4/0x1d8
> [ef03fc50] [c0049a00] do_exit+0x5dc/0x684
> [ef03fca0] [c000a6f0] die+0xdc/0x1b4
> [ef03fcc0] [c00128d0] bad_page_fault+0xb4/0xfc
> [ef03fcd0] [c000ebe4] handle_page_fault+0x7c/0x80
> --- Exception: 300 at __mutex_lock_slowpath+0xb4/0x190
>   LR = __mutex_lock_slowpath+0x9c/0x190
> [ef03fd90] [00000000]   (null) (unreliable)
> [ef03fdd0] [c0451758] mutex_lock+0x4c/0x50
> [ef03fde0] [c02b5124] mdiobus_read+0x38/0x74
> [ef03fe00] [c02b41f4] get_phy_id+0x24/0x80
> [ef03fe20] [c02b9de4] fsl_pq_mdio_probe+0x3b4/0x580
> [ef03feb0] [c0266120] platform_drv_probe+0x20/0x30
> [ef03fec0] [c0264bbc] driver_probe_device+0xa4/0x1d4
> [ef03fee0] [c0264da8] __driver_attach+0xbc/0xc0
> [ef03ff00] [c0263ac0] bus_for_each_dev+0x60/0x9c
> [ef03ff30] [c02647f4] driver_attach+0x24/0x34
> [ef03ff40] [c0264444] bus_add_driver+0x1ac/0x274
> [ef03ff70] [c02651b0] driver_register+0x88/0x154
> [ef03ff90] [c0266450] platform_driver_register+0x68/0x78
> [ef03ffa0] [c05d93b8] fsl_pq_mdio_init+0x18/0x28
> [ef03ffb0] [c0001eb8] do_one_initcall+0x34/0x1a8
> [ef03ffe0] [c05bb82c] kernel_init+0xa0/0x13c
> [ef03fff0] [c000d878] kernel_thread+0x4c/0x68
> Rebooting in 180 seconds..

David,

Any comment on getting this patch pulled into net.git?

- k

^ permalink raw reply

* [PATCH net-next 3/4] bnx2x: support classification config query
From: Michael Chan @ 2011-12-06  5:44 UTC (permalink / raw)
  To: davem; +Cc: netdev, barak, eilong
In-Reply-To: <1323150288-28153-2-git-send-email-mchan@broadcom.com>

From: Ariel Elior <ariele@broadcom.com>

To support copying MAC addresses to firmware info structure in the proper
format.

Signed-off-by: Ariel Elior <ariele@broadcom.com>
Signed-off-by: Barak Witkowski <barak@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
Signed-off-by: Michael Chan <mchan@broadcom.com>
---
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c |   39 ++++++++++++++++++++++++
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h |   17 ++++++++++
 2 files changed, 56 insertions(+), 0 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c
index a34362e..da377d1 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c
@@ -30,6 +30,8 @@
 
 #define BNX2X_MAX_EMUL_MULTI		16
 
+#define MAC_LEADING_ZERO_CNT (ALIGN(ETH_ALEN, sizeof(u32)) - ETH_ALEN)
+
 /**** Exe Queue interfaces ****/
 
 /**
@@ -441,6 +443,42 @@ static bool bnx2x_put_credit_vlan_mac(struct bnx2x_vlan_mac_obj *o)
 	return true;
 }
 
+static int bnx2x_get_n_elements(struct bnx2x *bp,
+			 struct bnx2x_vlan_mac_obj *o,
+			 int n,
+			 u8 *buf)
+{
+	struct bnx2x_vlan_mac_registry_elem *pos;
+	u8 *next = buf;
+	int counter = 0;
+
+	/* traverse list */
+	list_for_each_entry(pos, &o->head, link)
+	{
+		if ((counter < n)) {
+
+			/* place leading zeroes in buffer */
+			memset(next, 0, MAC_LEADING_ZERO_CNT);
+
+			/* place mac after leading zeroes*/
+			memcpy(next + MAC_LEADING_ZERO_CNT,
+				  pos->u.mac.mac, ETH_ALEN);
+
+			/* calculate address of next element and
+			 * advance counter
+			 */
+			counter++;
+			next = buf + counter * ALIGN(ETH_ALEN,
+							   sizeof(u32));
+
+			DP(BNX2X_MSG_SP, "copied element number "
+				   "%d to address %p element was "
+				   "%pM\n", counter, next, pos->u.mac.mac);
+		}
+	}
+	return counter * ETH_ALEN;
+}
+
 /* check_add() callbacks */
 static int bnx2x_check_mac_add(struct bnx2x_vlan_mac_obj *o,
 			       union bnx2x_classification_ramrod_data *data)
@@ -1886,6 +1924,7 @@ void bnx2x_init_mac_obj(struct bnx2x *bp,
 		mac_obj->check_move        = bnx2x_check_move;
 		mac_obj->ramrod_cmd        =
 			RAMROD_CMD_ID_ETH_CLASSIFICATION_RULES;
+		mac_obj->get_n_elements    = bnx2x_get_n_elements;
 
 		/* Exe Queue */
 		bnx2x_exe_queue_init(bp,
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h
index 9a517c2..bf898fb 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h
@@ -286,6 +286,23 @@ struct bnx2x_vlan_mac_obj {
 	int				ramrod_cmd;
 
 	/**
+	 * copy first n elements onto preallocated buffer
+	 *
+	 * @param n number of elements to get
+	 * @param buf buffer preallocated by caller into which elements
+	 *            will be copied. Note elements are 4-byte aligned
+	 *            so buffer size must be able to accomodate the
+	 *            aligned elements.
+	 *
+	 * @return number of copied bytes
+	 *  */
+
+	int (*get_n_elements)(struct bnx2x *bp,
+			 struct bnx2x_vlan_mac_obj *o,
+			 int n,
+			 u8 *buf);
+
+	/**
 	 * Checks if ADD-ramrod with the given params may be performed.
 	 *
 	 * @return zero if the element may be added
-- 
1.7.1

^ permalink raw reply related

* [PATCH net-next 4/4] bnx2x, cnic: support DRV_INFO upon FW request
From: Michael Chan @ 2011-12-06  5:44 UTC (permalink / raw)
  To: davem; +Cc: netdev, barak, eilong
In-Reply-To: <1323150288-28153-3-git-send-email-mchan@broadcom.com>

From: Barak Witkowski <barak@broadcom.com>

Add support to send driver capabilities, settings and statistics to
management firmware.

Signed-off-by: Barak Witkowski <barak@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
Signed-off-by: Eddie Wai <eddie.wai@broadcom.com>
Signed-off-by: Michael Chan <mchan@broadcom.com>
---
 drivers/net/ethernet/broadcom/bnx2x/bnx2x.h       |    4 +
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h   |  151 ++++++++++++-
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c  |  251 ++++++++++++++++++++-
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c |   20 ++-
 drivers/net/ethernet/broadcom/cnic.c              |   47 ++++
 drivers/net/ethernet/broadcom/cnic_if.h           |    9 +
 6 files changed, 474 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
index 40cfce0..8c73d34 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
@@ -887,6 +887,8 @@ struct bnx2x_common {
 #define CHIP_PORT_MODE_NONE			0x2
 #define CHIP_MODE(bp)			(bp->common.chip_port_mode)
 #define CHIP_MODE_IS_4_PORT(bp) (CHIP_MODE(bp) == CHIP_4_PORT_MODE)
+
+	u32			boot_mode;
 };
 
 /* IGU MSIX STATISTICS on 57712: 64 for VFs; 4 for PFs; 4 for Attentions */
@@ -1048,6 +1050,8 @@ struct bnx2x_slowpath {
 
 	u32				wb_comp;
 	u32				wb_data[4];
+
+	union drv_info_to_mcp		drv_info_to_mcp;
 };
 
 #define bnx2x_sp(bp, var)		(&bp->slowpath->var)
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h
index d9f07cb..996b57c 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h
@@ -1253,6 +1253,8 @@ struct drv_func_mb {
 	#define DRV_MSG_CODE_DCBX_PMF_DRV_OK            0xb2000000
 
 	#define DRV_MSG_CODE_VF_DISABLED_DONE           0xc0000000
+	#define DRV_MSG_CODE_DRV_INFO_ACK               0xd8000000
+	#define DRV_MSG_CODE_DRV_INFO_NACK              0xd9000000
 
 	#define DRV_MSG_CODE_SET_MF_BW                  0xe0000000
 	#define REQ_BC_VER_4_SET_MF_BW                  0x00060202
@@ -1305,6 +1307,8 @@ struct drv_func_mb {
 	#define FW_MSG_CODE_VRFY_OPT_MDL_INVLD_IMG      0xa0200000
 	#define FW_MSG_CODE_VRFY_OPT_MDL_UNAPPROVED     0xa0300000
 	#define FW_MSG_CODE_VF_DISABLED_DONE            0xb0000000
+	#define FW_MSG_CODE_DRV_INFO_ACK                0xd8100000
+	#define FW_MSG_CODE_DRV_INFO_NACK               0xd9100000
 
 	#define FW_MSG_CODE_SET_MF_BW_SENT              0xe0000000
 	#define FW_MSG_CODE_SET_MF_BW_DONE              0xe1000000
@@ -1361,6 +1365,7 @@ struct drv_func_mb {
 
 	#define DRV_STATUS_DCBX_EVENT_MASK              0x000f0000
 	#define DRV_STATUS_DCBX_NEGOTIATION_RESULTS     0x00010000
+	#define DRV_STATUS_DRV_INFO_REQ                 0x04000000
 
 	u32 virt_mac_upper;
 	#define VIRT_MAC_SIGN_MASK                      0xffff0000
@@ -1965,9 +1970,38 @@ struct shmem2_region {
 	u32 extended_dev_info_shared_addr;
 	u32 ncsi_oem_data_addr;
 
-	u32 ocsd_host_addr;
-	u32 ocbb_host_addr;
-	u32 ocsd_req_update_interval;
+	u32 ocsd_host_addr; /* initialized by option ROM */
+	u32 ocbb_host_addr; /* initialized by option ROM */
+	u32 ocsd_req_update_interval; /* initialized by option ROM */
+	u32 temperature_in_half_celsius;
+	u32 glob_struct_in_host;
+
+	u32 dcbx_neg_res_ext_offset;
+	#define SHMEM_DCBX_NEG_RES_EXT_NONE			0x00000000
+
+	u32 drv_capabilities_flag[E2_FUNC_MAX];
+	#define DRV_FLAGS_CAPABALITIES_LOADED_SUPPORTED 0x00000001
+	#define DRV_FLAGS_CAPABILITIES_LOADED_L2        0x00000002
+	#define DRV_FLAGS_CAPABILITIES_LOADED_FCOE      0x00000004
+	#define DRV_FLAGS_CAPABILITIES_LOADED_ISCSI     0x00000008
+
+	u32 extended_dev_info_shared_cfg_size;
+
+	u32 dcbx_en[PORT_MAX];
+
+	/* The offset points to the multi threaded meta structure */
+	u32 multi_thread_data_offset;
+
+	/* address of DMAable host address holding values from the drivers */
+	u32 drv_info_host_addr_lo;
+	u32 drv_info_host_addr_hi;
+
+	/* general values written by the MFW (such as current version) */
+	u32 drv_info_control;
+	#define DRV_INFO_CONTROL_VER_MASK          0x000000ff
+	#define DRV_INFO_CONTROL_VER_SHIFT         0
+	#define DRV_INFO_CONTROL_OP_CODE_MASK      0x0000ff00
+	#define DRV_INFO_CONTROL_OP_CODE_SHIFT     8
 };
 
 
@@ -2553,6 +2587,117 @@ struct host_func_stats {
 /* VIC definitions */
 #define VICSTATST_UIF_INDEX 2
 
+/* current drv_info version */
+#define DRV_INFO_CUR_VER 1
+
+/* drv_info op codes supported */
+enum drv_info_opcode {
+	ETH_STATS_OPCODE,
+	FCOE_STATS_OPCODE,
+	ISCSI_STATS_OPCODE
+};
+
+#define ETH_STAT_INFO_VERSION_LEN	12
+/*  Per PCI Function Ethernet Statistics required from the driver */
+struct eth_stats_info {
+	/* Function's Driver Version. padded to 12 */
+	u8 version[ETH_STAT_INFO_VERSION_LEN];
+	/* Locally Admin Addr. BigEndian EIU48. Actual size is 6 bytes */
+	u8 mac_local[8];
+	u8 mac_add1[8];		/* Additional Programmed MAC Addr 1. */
+	u8 mac_add2[8];		/* Additional Programmed MAC Addr 2. */
+	u32 mtu_size;		/* MTU Size. Note   : Negotiated MTU */
+	u32 feature_flags;	/* Feature_Flags. */
+	#define FEATURE_ETH_CHKSUM_OFFLOAD_MASK		0x01
+	#define FEATURE_ETH_LSO_MASK			0x02
+	#define FEATURE_ETH_BOOTMODE_MASK		0x1C
+	#define FEATURE_ETH_BOOTMODE_SHIFT		2
+	#define FEATURE_ETH_BOOTMODE_NONE		(0x0 << 2)
+	#define FEATURE_ETH_BOOTMODE_PXE		(0x1 << 2)
+	#define FEATURE_ETH_BOOTMODE_ISCSI		(0x2 << 2)
+	#define FEATURE_ETH_BOOTMODE_FCOE		(0x3 << 2)
+	#define FEATURE_ETH_TOE_MASK			0x20
+	u32 lso_max_size;	/* LSO MaxOffloadSize. */
+	u32 lso_min_seg_cnt;	/* LSO MinSegmentCount. */
+	/* Num Offloaded Connections TCP_IPv4. */
+	u32 ipv4_ofld_cnt;
+	/* Num Offloaded Connections TCP_IPv6. */
+	u32 ipv6_ofld_cnt;
+	u32 promiscuous_mode;	/* Promiscuous Mode. non-zero true */
+	u32 txq_size;		/* TX Descriptors Queue Size */
+	u32 rxq_size;		/* RX Descriptors Queue Size */
+	/* TX Descriptor Queue Avg Depth. % Avg Queue Depth since last poll */
+	u32 txq_avg_depth;
+	/* RX Descriptors Queue Avg Depth. % Avg Queue Depth since last poll */
+	u32 rxq_avg_depth;
+	/* IOV_Offload. 0=none; 1=MultiQueue, 2=VEB 3= VEPA*/
+	u32 iov_offload;
+	/* Number of NetQueue/VMQ Config'd. */
+	u32 netq_cnt;
+	u32 vf_cnt;		/* Num VF assigned to this PF. */
+};
+
+/*  Per PCI Function FCOE Statistics required from the driver */
+struct fcoe_stats_info {
+	u8 version[12];		/* Function's Driver Version. */
+	u8 mac_local[8];	/* Locally Admin Addr. */
+	u8 mac_add1[8];		/* Additional Programmed MAC Addr 1. */
+	u8 mac_add2[8];		/* Additional Programmed MAC Addr 2. */
+	/* QoS Priority (per 802.1p). 0-7255 */
+	u32 qos_priority;
+	u32 txq_size;		/* FCoE TX Descriptors Queue Size. */
+	u32 rxq_size;		/* FCoE RX Descriptors Queue Size. */
+	/* FCoE TX Descriptor Queue Avg Depth. */
+	u32 txq_avg_depth;
+	/* FCoE RX Descriptors Queue Avg Depth. */
+	u32 rxq_avg_depth;
+	u32 rx_frames_lo;	/* FCoE RX Frames received. */
+	u32 rx_frames_hi;	/* FCoE RX Frames received. */
+	u32 rx_bytes_lo;	/* FCoE RX Bytes received. */
+	u32 rx_bytes_hi;	/* FCoE RX Bytes received. */
+	u32 tx_frames_lo;	/* FCoE TX Frames sent. */
+	u32 tx_frames_hi;	/* FCoE TX Frames sent. */
+	u32 tx_bytes_lo;	/* FCoE TX Bytes sent. */
+	u32 tx_bytes_hi;	/* FCoE TX Bytes sent. */
+};
+
+/* Per PCI  Function iSCSI Statistics required from the driver*/
+struct iscsi_stats_info {
+	u8 version[12];		/* Function's Driver Version. */
+	u8 mac_local[8];	/* Locally Admin iSCSI MAC Addr. */
+	u8 mac_add1[8];		/* Additional Programmed MAC Addr 1. */
+	/* QoS Priority (per 802.1p). 0-7255 */
+	u32 qos_priority;
+	u8 initiator_name[64];	/* iSCSI Boot Initiator Node name. */
+	u8 ww_port_name[64];	/* iSCSI World wide port name */
+	u8 boot_target_name[64];/* iSCSI Boot Target Name. */
+	u8 boot_target_ip[16];	/* iSCSI Boot Target IP. */
+	u32 boot_target_portal;	/* iSCSI Boot Target Portal. */
+	u8 boot_init_ip[16];	/* iSCSI Boot Initiator IP Address. */
+	u32 max_frame_size;	/* Max Frame Size. bytes */
+	u32 txq_size;		/* PDU TX Descriptors Queue Size. */
+	u32 rxq_size;		/* PDU RX Descriptors Queue Size. */
+	u32 txq_avg_depth;	/*PDU TX Descriptor Queue Avg Depth. */
+	u32 rxq_avg_depth;	/*PDU RX Descriptors Queue Avg Depth. */
+	u32 rx_pdus_lo;		/* iSCSI PDUs received. */
+	u32 rx_pdus_hi;		/* iSCSI PDUs received. */
+	u32 rx_bytes_lo;	/* iSCSI RX Bytes received. */
+	u32 rx_bytes_hi;	/* iSCSI RX Bytes received. */
+	u32 tx_pdus_lo;		/* iSCSI PDUs sent. */
+	u32 tx_pdus_hi;		/* iSCSI PDUs sent. */
+	u32 tx_bytes_lo;	/* iSCSI PDU TX Bytes sent. */
+	u32 tx_bytes_hi;	/* iSCSI PDU TX Bytes sent. */
+	u32 pcp_prior_map_tbl;	/*C-PCP to S-PCP Priority MapTable.
+				9 nibbles, the position of each nibble
+				represents the C-PCP value, the value
+				of the nibble = S-PCP value.*/
+};
+
+union drv_info_to_mcp {
+	struct eth_stats_info	ether_stat;
+	struct fcoe_stats_info	fcoe_stat;
+	struct iscsi_stats_info	iscsi_stat;
+};
 #define BCM_5710_FW_MAJOR_VERSION			7
 #define BCM_5710_FW_MINOR_VERSION			0
 #define BCM_5710_FW_REVISION_VERSION		29
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index 552c564..35d2256 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -2912,6 +2912,159 @@ static void bnx2x_e1h_enable(struct bnx2x *bp)
 	 */
 }
 
+#define DRV_INFO_ETH_STAT_NUM_MACS_REQUIRED 3
+
+static inline void bnx2x_drv_info_ether_stat(struct bnx2x *bp)
+{
+	/* leave last char as NULL */
+	memcpy(bp->slowpath->drv_info_to_mcp.ether_stat.version,
+		DRV_MODULE_VERSION, ETH_STAT_INFO_VERSION_LEN - 1);
+
+	bp->fp[0].mac_obj.get_n_elements(bp, &bp->fp[0].mac_obj,
+					 DRV_INFO_ETH_STAT_NUM_MACS_REQUIRED,
+			bp->slowpath->drv_info_to_mcp.ether_stat.mac_local);
+
+	bp->slowpath->drv_info_to_mcp.ether_stat.mtu_size = bp->dev->mtu;
+
+	if (bp->dev->features & NETIF_F_RXCSUM)
+		bp->slowpath->drv_info_to_mcp.ether_stat.feature_flags |=
+		FEATURE_ETH_CHKSUM_OFFLOAD_MASK;
+	if (bp->dev->features & NETIF_F_TSO)
+		bp->slowpath->drv_info_to_mcp.ether_stat.feature_flags |=
+		FEATURE_ETH_LSO_MASK;
+	bp->slowpath->drv_info_to_mcp.ether_stat.feature_flags |=
+		bp->common.boot_mode;
+
+	bp->slowpath->drv_info_to_mcp.ether_stat.promiscuous_mode =
+		((bp->dev->flags & IFF_PROMISC) ? 1 : 0);
+
+	bp->slowpath->drv_info_to_mcp.ether_stat.txq_size = bp->tx_ring_size;
+	bp->slowpath->drv_info_to_mcp.ether_stat.rxq_size = bp->rx_ring_size;
+}
+
+static inline void bnx2x_drv_info_fcoe_stat(struct bnx2x *bp)
+{
+	struct bnx2x_dcbx_app_params *app = &bp->dcbx_port_params.app;
+
+	memcpy(bp->slowpath->drv_info_to_mcp.fcoe_stat.mac_local,
+		bp->fip_mac, ETH_ALEN);
+
+	bp->slowpath->drv_info_to_mcp.fcoe_stat.qos_priority =
+		app->traffic_type_priority[LLFC_TRAFFIC_TYPE_FCOE];
+
+	/* insert FCoE stats from ramrod response */
+	if (!NO_FCOE(bp)) {
+		struct tstorm_per_queue_stats *fcoe_q_tstorm_stats =
+			&bp->fw_stats_data->queue_stats[FCOE_IDX].
+			tstorm_queue_statistics;
+
+		struct xstorm_per_queue_stats *fcoe_q_xstorm_stats =
+			&bp->fw_stats_data->queue_stats[FCOE_IDX].
+			xstorm_queue_statistics;
+
+		ADD_64(bp->slowpath->drv_info_to_mcp.fcoe_stat.rx_bytes_hi,
+			0,
+			bp->slowpath->drv_info_to_mcp.fcoe_stat.rx_bytes_lo,
+			bp->fw_stats_data->fcoe.rx_stat0.fcoe_rx_byte_cnt);
+
+		ADD_64(bp->slowpath->drv_info_to_mcp.fcoe_stat.rx_bytes_hi,
+			fcoe_q_tstorm_stats->rcv_ucast_bytes.hi,
+			bp->slowpath->drv_info_to_mcp.fcoe_stat.rx_bytes_lo,
+			fcoe_q_tstorm_stats->rcv_ucast_bytes.lo);
+
+		ADD_64(bp->slowpath->drv_info_to_mcp.fcoe_stat.rx_bytes_hi,
+			fcoe_q_tstorm_stats->rcv_bcast_bytes.hi,
+			bp->slowpath->drv_info_to_mcp.fcoe_stat.rx_bytes_lo,
+			fcoe_q_tstorm_stats->rcv_bcast_bytes.lo);
+
+		ADD_64(bp->slowpath->drv_info_to_mcp.fcoe_stat.rx_bytes_hi,
+			fcoe_q_tstorm_stats->rcv_mcast_bytes.hi,
+			bp->slowpath->drv_info_to_mcp.fcoe_stat.rx_bytes_lo,
+			fcoe_q_tstorm_stats->rcv_mcast_bytes.lo);
+
+		ADD_64(bp->slowpath->drv_info_to_mcp.fcoe_stat.rx_frames_hi,
+			0,
+			bp->slowpath->drv_info_to_mcp.fcoe_stat.rx_frames_lo,
+			bp->fw_stats_data->fcoe.rx_stat0.fcoe_rx_pkt_cnt);
+
+		ADD_64(bp->slowpath->drv_info_to_mcp.fcoe_stat.rx_frames_hi,
+			0,
+			bp->slowpath->drv_info_to_mcp.fcoe_stat.rx_frames_lo,
+			fcoe_q_tstorm_stats->rcv_ucast_pkts);
+
+		ADD_64(bp->slowpath->drv_info_to_mcp.fcoe_stat.rx_frames_hi,
+			0,
+			bp->slowpath->drv_info_to_mcp.fcoe_stat.rx_frames_lo,
+			fcoe_q_tstorm_stats->rcv_bcast_pkts);
+
+		ADD_64(bp->slowpath->drv_info_to_mcp.fcoe_stat.rx_frames_hi,
+			0,
+			bp->slowpath->drv_info_to_mcp.fcoe_stat.rx_frames_lo,
+			fcoe_q_tstorm_stats->rcv_ucast_pkts);
+
+		ADD_64(bp->slowpath->drv_info_to_mcp.fcoe_stat.tx_bytes_hi,
+			0,
+			bp->slowpath->drv_info_to_mcp.fcoe_stat.tx_bytes_lo,
+			bp->fw_stats_data->fcoe.tx_stat.fcoe_tx_byte_cnt);
+
+		ADD_64(bp->slowpath->drv_info_to_mcp.fcoe_stat.tx_bytes_hi,
+			fcoe_q_xstorm_stats->ucast_bytes_sent.hi,
+			bp->slowpath->drv_info_to_mcp.fcoe_stat.tx_bytes_lo,
+			fcoe_q_xstorm_stats->ucast_bytes_sent.lo);
+
+		ADD_64(bp->slowpath->drv_info_to_mcp.fcoe_stat.tx_bytes_hi,
+			fcoe_q_xstorm_stats->bcast_bytes_sent.hi,
+			bp->slowpath->drv_info_to_mcp.fcoe_stat.tx_bytes_lo,
+			fcoe_q_xstorm_stats->bcast_bytes_sent.lo);
+
+		ADD_64(bp->slowpath->drv_info_to_mcp.fcoe_stat.tx_bytes_hi,
+			fcoe_q_xstorm_stats->mcast_bytes_sent.hi,
+			bp->slowpath->drv_info_to_mcp.fcoe_stat.tx_bytes_lo,
+			fcoe_q_xstorm_stats->mcast_bytes_sent.lo);
+
+		ADD_64(bp->slowpath->drv_info_to_mcp.fcoe_stat.tx_frames_hi,
+			0,
+			bp->slowpath->drv_info_to_mcp.fcoe_stat.tx_frames_lo,
+			bp->fw_stats_data->fcoe.tx_stat.fcoe_tx_pkt_cnt);
+
+		ADD_64(bp->slowpath->drv_info_to_mcp.fcoe_stat.tx_frames_hi,
+			0,
+			bp->slowpath->drv_info_to_mcp.fcoe_stat.tx_frames_lo,
+			fcoe_q_xstorm_stats->ucast_pkts_sent);
+
+		ADD_64(bp->slowpath->drv_info_to_mcp.fcoe_stat.tx_frames_hi,
+			0,
+			bp->slowpath->drv_info_to_mcp.fcoe_stat.tx_frames_lo,
+			fcoe_q_xstorm_stats->bcast_pkts_sent);
+
+		ADD_64(bp->slowpath->drv_info_to_mcp.fcoe_stat.tx_frames_hi,
+			0,
+			bp->slowpath->drv_info_to_mcp.fcoe_stat.tx_frames_lo,
+			fcoe_q_xstorm_stats->mcast_pkts_sent);
+	}
+
+#ifdef BCM_CNIC
+	/* ask L5 driver to add data to the struct */
+	bnx2x_cnic_notify(bp, CNIC_CTL_FCOE_STATS_GET_CMD);
+#endif
+}
+
+static inline void bnx2x_drv_info_iscsi_stat(struct bnx2x *bp)
+{
+	struct bnx2x_dcbx_app_params *app = &bp->dcbx_port_params.app;
+
+	memcpy(bp->slowpath->drv_info_to_mcp.iscsi_stat.mac_local,
+		bp->cnic_eth_dev.iscsi_mac, ETH_ALEN);
+
+	bp->slowpath->drv_info_to_mcp.fcoe_stat.qos_priority =
+		app->traffic_type_priority[LLFC_TRAFFIC_TYPE_ISCSI];
+
+#ifdef BCM_CNIC
+	/* ask L5 driver to add data to the struct */
+	bnx2x_cnic_notify(bp, CNIC_CTL_ISCSI_STATS_GET_CMD);
+#endif
+}
+
 /* called due to MCP event (on pmf):
  *	reread new bandwidth configuration
  *	configure FW
@@ -2932,6 +3085,50 @@ static inline void bnx2x_set_mf_bw(struct bnx2x *bp)
 	bnx2x_fw_command(bp, DRV_MSG_CODE_SET_MF_BW_ACK, 0);
 }
 
+static inline void bnx2x_handle_drv_info_req(struct bnx2x *bp)
+{
+	enum drv_info_opcode op_code;
+	u32 drv_info_ctl = SHMEM2_RD(bp, drv_info_control);
+
+	/* if drv_info version supported by MFW doesn't match - send NACK */
+	if ((drv_info_ctl & DRV_INFO_CONTROL_VER_MASK) != DRV_INFO_CUR_VER) {
+		bnx2x_fw_command(bp, DRV_MSG_CODE_DRV_INFO_NACK, 0);
+		return;
+	}
+
+	op_code = (drv_info_ctl & DRV_INFO_CONTROL_OP_CODE_MASK) >>
+		DRV_INFO_CONTROL_OP_CODE_SHIFT;
+
+	memset(&bp->slowpath->drv_info_to_mcp, 0,
+		sizeof(union drv_info_to_mcp));
+
+	switch (op_code) {
+	case ETH_STATS_OPCODE:
+		bnx2x_drv_info_ether_stat(bp);
+		break;
+	case FCOE_STATS_OPCODE:
+		bnx2x_drv_info_fcoe_stat(bp);
+		break;
+	case ISCSI_STATS_OPCODE:
+		bnx2x_drv_info_iscsi_stat(bp);
+		break;
+	default:
+		/* if op code isn't supported - send NACK */
+		bnx2x_fw_command(bp, DRV_MSG_CODE_DRV_INFO_NACK, 0);
+		return;
+	}
+
+	/* if we got drv_info attn from MFW then these fields are defined in
+	 * shmem2 for sure
+	 */
+	SHMEM2_WR(bp, drv_info_host_addr_lo,
+		U64_LO(bnx2x_sp_mapping(bp, drv_info_to_mcp)));
+	SHMEM2_WR(bp, drv_info_host_addr_hi,
+		U64_HI(bnx2x_sp_mapping(bp, drv_info_to_mcp)));
+
+	bnx2x_fw_command(bp, DRV_MSG_CODE_DRV_INFO_ACK, 0);
+}
+
 static void bnx2x_dcc_event(struct bnx2x *bp, u32 dcc_event)
 {
 	DP(BNX2X_MSG_MCP, "dcc_event 0x%x\n", dcc_event);
@@ -3439,6 +3636,8 @@ static inline void bnx2x_attn_int_deasserted3(struct bnx2x *bp, u32 attn)
 			if (val & DRV_STATUS_SET_MF_BW)
 				bnx2x_set_mf_bw(bp);
 
+			if (val & DRV_STATUS_DRV_INFO_REQ)
+				bnx2x_handle_drv_info_req(bp);
 			if ((bp->port.pmf == 0) && (val & DRV_STATUS_PMF))
 				bnx2x_pmf_update(bp);
 
@@ -8716,7 +8915,7 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp)
 
 static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp)
 {
-	u32 val, val2, val3, val4, id;
+	u32 val, val2, val3, val4, id, boot_mode;
 	u16 pmc;
 
 	/* Get the chip revision id and number. */
@@ -8828,6 +9027,24 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp)
 	bp->flags |= (val >= REQ_BC_VER_4_PFC_STATS_SUPPORTED) ?
 			BC_SUPPORTS_PFC_STATS : 0;
 
+	boot_mode = SHMEM_RD(bp,
+			dev_info.port_feature_config[BP_PORT(bp)].mba_config) &
+			PORT_FEATURE_MBA_BOOT_AGENT_TYPE_MASK;
+	switch (boot_mode) {
+	case PORT_FEATURE_MBA_BOOT_AGENT_TYPE_PXE:
+		bp->common.boot_mode = FEATURE_ETH_BOOTMODE_PXE;
+		break;
+	case PORT_FEATURE_MBA_BOOT_AGENT_TYPE_ISCSIB:
+		bp->common.boot_mode = FEATURE_ETH_BOOTMODE_ISCSI;
+		break;
+	case PORT_FEATURE_MBA_BOOT_AGENT_TYPE_FCOE_BOOT:
+		bp->common.boot_mode = FEATURE_ETH_BOOTMODE_FCOE;
+		break;
+	case PORT_FEATURE_MBA_BOOT_AGENT_TYPE_NONE:
+		bp->common.boot_mode = FEATURE_ETH_BOOTMODE_NONE;
+		break;
+	}
+
 	pci_read_config_word(bp->pdev, bp->pm_cap + PCI_PM_PMC, &pmc);
 	bp->flags |= (pmc & PCI_PM_CAP_PME_D3cold) ? 0 : NO_WOL_FLAG;
 
@@ -11550,6 +11767,38 @@ static int bnx2x_drv_ctl(struct net_device *dev, struct drv_ctl_info *ctl)
 		smp_mb__after_atomic_inc();
 		break;
 	}
+	case DRV_CTL_ULP_REGISTER_CMD: {
+		int ulp_type = ctl->data.ulp_type;
+
+		if (CHIP_IS_E3(bp)) {
+			int idx = BP_FW_MB_IDX(bp);
+			u32 cap;
+
+			cap = SHMEM2_RD(bp, drv_capabilities_flag[idx]);
+			if (ulp_type == CNIC_ULP_ISCSI)
+				cap |= DRV_FLAGS_CAPABILITIES_LOADED_ISCSI;
+			else if (ulp_type == CNIC_ULP_FCOE)
+				cap |= DRV_FLAGS_CAPABILITIES_LOADED_FCOE;
+			SHMEM2_WR(bp, drv_capabilities_flag[idx], cap);
+		}
+		break;
+	}
+	case DRV_CTL_ULP_UNREGISTER_CMD: {
+		int ulp_type = ctl->data.ulp_type;
+
+		if (CHIP_IS_E3(bp)) {
+			int idx = BP_FW_MB_IDX(bp);
+			u32 cap;
+
+			cap = SHMEM2_RD(bp, drv_capabilities_flag[idx]);
+			if (ulp_type == CNIC_ULP_ISCSI)
+				cap &= ~DRV_FLAGS_CAPABILITIES_LOADED_ISCSI;
+			else if (ulp_type == CNIC_ULP_FCOE)
+				cap &= ~DRV_FLAGS_CAPABILITIES_LOADED_FCOE;
+			SHMEM2_WR(bp, drv_capabilities_flag[idx], cap);
+		}
+		break;
+	}
 
 	default:
 		BNX2X_ERR("unknown command %x\n", ctl->cmd);
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c
index 41a33ce..c40e6b3 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c
@@ -39,6 +39,17 @@ static inline long bnx2x_hilo(u32 *hiref)
 #endif
 }
 
+static inline u16 bnx2x_get_port_stats_dma_len(struct bnx2x *bp)
+{
+	u16 res = sizeof(struct host_port_stats) >> 2;
+
+	/* if PFC stats are not supported by the MFW, don't DMA them */
+	if (!(bp->flags &  BC_SUPPORTS_PFC_STATS))
+		res -= (sizeof(u32)*4) >> 2;
+
+	return res;
+}
+
 /*
  * Init service functions
  */
@@ -178,7 +189,8 @@ static void bnx2x_stats_pmf_update(struct bnx2x *bp)
 				   DMAE_LEN32_RD_MAX * 4);
 	dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, port_stats) +
 				   DMAE_LEN32_RD_MAX * 4);
-	dmae->len = (sizeof(struct host_port_stats) >> 2) - DMAE_LEN32_RD_MAX;
+	dmae->len = bnx2x_get_port_stats_dma_len(bp) - DMAE_LEN32_RD_MAX;
+
 	dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, stats_comp));
 	dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, stats_comp));
 	dmae->comp_val = DMAE_COMP_VAL;
@@ -217,7 +229,7 @@ static void bnx2x_port_stats_init(struct bnx2x *bp)
 		dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, port_stats));
 		dmae->dst_addr_lo = bp->port.port_stx >> 2;
 		dmae->dst_addr_hi = 0;
-		dmae->len = sizeof(struct host_port_stats) >> 2;
+		dmae->len = bnx2x_get_port_stats_dma_len(bp);
 		dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
 		dmae->comp_addr_hi = 0;
 		dmae->comp_val = 1;
@@ -1307,7 +1319,7 @@ static void bnx2x_port_stats_stop(struct bnx2x *bp)
 		dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, port_stats));
 		dmae->dst_addr_lo = bp->port.port_stx >> 2;
 		dmae->dst_addr_hi = 0;
-		dmae->len = sizeof(struct host_port_stats) >> 2;
+		dmae->len = bnx2x_get_port_stats_dma_len(bp);
 		if (bp->func_stx) {
 			dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
 			dmae->comp_addr_hi = 0;
@@ -1424,7 +1436,7 @@ static void bnx2x_port_stats_base_init(struct bnx2x *bp)
 	dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, port_stats));
 	dmae->dst_addr_lo = bp->port.port_stx >> 2;
 	dmae->dst_addr_hi = 0;
-	dmae->len = sizeof(struct host_port_stats) >> 2;
+	dmae->len = bnx2x_get_port_stats_dma_len(bp);
 	dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, stats_comp));
 	dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, stats_comp));
 	dmae->comp_val = DMAE_COMP_VAL;
diff --git a/drivers/net/ethernet/broadcom/cnic.c b/drivers/net/ethernet/broadcom/cnic.c
index b336e55..ea96420 100644
--- a/drivers/net/ethernet/broadcom/cnic.c
+++ b/drivers/net/ethernet/broadcom/cnic.c
@@ -250,6 +250,21 @@ static u32 cnic_reg_rd_ind(struct cnic_dev *dev, u32 off)
 	return io->data;
 }
 
+static void cnic_ulp_ctl(struct cnic_dev *dev, int ulp_type, bool reg)
+{
+	struct cnic_local *cp = dev->cnic_priv;
+	struct cnic_eth_dev *ethdev = cp->ethdev;
+	struct drv_ctl_info info;
+
+	if (reg)
+		info.cmd = DRV_CTL_ULP_REGISTER_CMD;
+	else
+		info.cmd = DRV_CTL_ULP_UNREGISTER_CMD;
+
+	info.data.ulp_type = ulp_type;
+	ethdev->drv_ctl(dev->netdev, &info);
+}
+
 static int cnic_in_use(struct cnic_sock *csk)
 {
 	return test_bit(SK_F_INUSE, &csk->flags);
@@ -563,6 +578,8 @@ static int cnic_register_device(struct cnic_dev *dev, int ulp_type,
 
 	mutex_unlock(&cnic_lock);
 
+	cnic_ulp_ctl(dev, ulp_type, true);
+
 	return 0;
 
 }
@@ -602,6 +619,8 @@ static int cnic_unregister_device(struct cnic_dev *dev, int ulp_type)
 	if (test_bit(ULP_F_CALL_PENDING, &cp->ulp_flags[ulp_type]))
 		netdev_warn(dev->netdev, "Failed waiting for ULP up call to complete\n");
 
+	cnic_ulp_ctl(dev, ulp_type, false);
+
 	return 0;
 }
 EXPORT_SYMBOL(cnic_unregister_driver);
@@ -3052,9 +3071,26 @@ static void cnic_ulp_start(struct cnic_dev *dev)
 	}
 }
 
+static int cnic_copy_ulp_stats(struct cnic_dev *dev, int ulp_type)
+{
+	struct cnic_local *cp = dev->cnic_priv;
+	struct cnic_ulp_ops *ulp_ops;
+	int rc;
+
+	mutex_lock(&cnic_lock);
+	ulp_ops = cnic_ulp_tbl_prot(ulp_type);
+	if (ulp_ops && ulp_ops->cnic_get_stats)
+		rc = ulp_ops->cnic_get_stats(cp->ulp_handle[ulp_type]);
+	else
+		rc = -ENODEV;
+	mutex_unlock(&cnic_lock);
+	return rc;
+}
+
 static int cnic_ctl(void *data, struct cnic_ctl_info *info)
 {
 	struct cnic_dev *dev = data;
+	int ulp_type = CNIC_ULP_ISCSI;
 
 	switch (info->cmd) {
 	case CNIC_CTL_STOP_CMD:
@@ -3100,6 +3136,15 @@ static int cnic_ctl(void *data, struct cnic_ctl_info *info)
 		}
 		break;
 	}
+	case CNIC_CTL_FCOE_STATS_GET_CMD:
+		ulp_type = CNIC_ULP_FCOE;
+		/* fall through */
+	case CNIC_CTL_ISCSI_STATS_GET_CMD:
+		cnic_hold(dev);
+		cnic_copy_ulp_stats(dev, ulp_type);
+		cnic_put(dev);
+		break;
+
 	default:
 		return -EINVAL;
 	}
@@ -5288,6 +5333,8 @@ static struct cnic_dev *init_bnx2x_cnic(struct net_device *dev)
 	cdev->pcidev = pdev;
 	cp->chip_id = ethdev->chip_id;
 
+	cdev->stats_addr = ethdev->addr_drv_info_to_mcp;
+
 	if (!(ethdev->drv_state & CNIC_DRV_STATE_NO_ISCSI))
 		cdev->max_iscsi_conn = ethdev->max_iscsi_conn;
 	if (BNX2X_CHIP_IS_E2_PLUS(cp->chip_id) &&
diff --git a/drivers/net/ethernet/broadcom/cnic_if.h b/drivers/net/ethernet/broadcom/cnic_if.h
index 79443e0..d1f6456 100644
--- a/drivers/net/ethernet/broadcom/cnic_if.h
+++ b/drivers/net/ethernet/broadcom/cnic_if.h
@@ -86,6 +86,8 @@ struct kcqe {
 #define CNIC_CTL_START_CMD		2
 #define CNIC_CTL_COMPLETION_CMD		3
 #define CNIC_CTL_STOP_ISCSI_CMD		4
+#define CNIC_CTL_FCOE_STATS_GET_CMD	5
+#define CNIC_CTL_ISCSI_STATS_GET_CMD	6
 
 #define DRV_CTL_IO_WR_CMD		0x101
 #define DRV_CTL_IO_RD_CMD		0x102
@@ -96,6 +98,8 @@ struct kcqe {
 #define DRV_CTL_STOP_L2_CMD		0x107
 #define DRV_CTL_RET_L2_SPQ_CREDIT_CMD	0x10c
 #define DRV_CTL_ISCSI_STOPPED_CMD	0x10d
+#define DRV_CTL_ULP_REGISTER_CMD	0x10e
+#define DRV_CTL_ULP_UNREGISTER_CMD	0x10f
 
 struct cnic_ctl_completion {
 	u32	cid;
@@ -133,6 +137,7 @@ struct drv_ctl_info {
 		struct drv_ctl_spq_credit credit;
 		struct drv_ctl_io io;
 		struct drv_ctl_l2_ring ring;
+		int ulp_type;
 		char bytes[MAX_DRV_CTL_DATA];
 	} data;
 };
@@ -201,6 +206,7 @@ struct cnic_eth_dev {
 					       struct kwqe_16 *[], u32);
 	int		(*drv_ctl)(struct net_device *, struct drv_ctl_info *);
 	unsigned long	reserved1[2];
+	union drv_info_to_mcp	*addr_drv_info_to_mcp;
 };
 
 struct cnic_sockaddr {
@@ -297,6 +303,8 @@ struct cnic_dev {
 	int		max_fcoe_conn;
 	int		max_rdma_conn;
 
+	union drv_info_to_mcp	*stats_addr;
+
 	void		*cnic_priv;
 };
 
@@ -326,6 +334,7 @@ struct cnic_ulp_ops {
 	void (*cm_remote_abort)(struct cnic_sock *);
 	int (*iscsi_nl_send_msg)(void *ulp_ctx, u32 msg_type,
 				  char *data, u16 data_size);
+	int (*cnic_get_stats)(void *ulp_ctx);
 	struct module *owner;
 	atomic_t ref_count;
 };
-- 
1.7.1

^ permalink raw reply related

* [PATCH net-next 2/4] bnx2x: add fcoe statistics
From: Michael Chan @ 2011-12-06  5:44 UTC (permalink / raw)
  To: davem; +Cc: netdev, barak, eilong
In-Reply-To: <1323150288-28153-1-git-send-email-mchan@broadcom.com>

From: Barak Witkowski <barak@broadcom.com>

Add FCoE statistics support for FCoE capable devices.

Signed-off-by: Barak Witkowski <barak@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
Signed-off-by: Michael Chan <mchan@broadcom.com>
---
 drivers/net/ethernet/broadcom/bnx2x/bnx2x.h       |    5 ++-
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h   |   56 ++++++++++++++++++++-
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c  |   38 +++++++-------
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c |   44 ++++++++++++++++-
 4 files changed, 120 insertions(+), 23 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
index 32af052..40cfce0 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
@@ -1128,18 +1128,21 @@ enum {
 enum {
 	BNX2X_PORT_QUERY_IDX,
 	BNX2X_PF_QUERY_IDX,
+	BNX2X_FCOE_QUERY_IDX,
 	BNX2X_FIRST_QUEUE_QUERY_IDX,
 };
 
 struct bnx2x_fw_stats_req {
 	struct stats_query_header hdr;
-	struct stats_query_entry query[STATS_QUERY_CMD_COUNT];
+	struct stats_query_entry query[FP_SB_MAX_E1x+
+		BNX2X_FIRST_QUEUE_QUERY_IDX];
 };
 
 struct bnx2x_fw_stats_data {
 	struct stats_counter	storm_counters;
 	struct per_port_stats	port;
 	struct per_pf_stats	pf;
+	struct fcoe_statistics_params	fcoe;
 	struct per_queue_stats  queue_stats[1];
 };
 
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h
index 79b6e43..d9f07cb 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h
@@ -4166,8 +4166,62 @@ struct ustorm_eth_rx_producers {
 
 
 /*
- * cfc delete event data
+ * FCoE RX statistics parameters section#0
+ */
+struct fcoe_rx_stat_params_section0 {
+	__le32 fcoe_rx_pkt_cnt;
+	__le32 fcoe_rx_byte_cnt;
+};
+
+
+/*
+ * FCoE RX statistics parameters section#1
+ */
+struct fcoe_rx_stat_params_section1 {
+	__le32 fcoe_ver_cnt;
+	__le32 fcoe_rx_drop_pkt_cnt;
+};
+
+
+/*
+ * FCoE RX statistics parameters section#2
  */
+struct fcoe_rx_stat_params_section2 {
+	__le32 fc_crc_cnt;
+	__le32 eofa_del_cnt;
+	__le32 miss_frame_cnt;
+	__le32 seq_timeout_cnt;
+	__le32 drop_seq_cnt;
+	__le32 fcoe_rx_drop_pkt_cnt;
+	__le32 fcp_rx_pkt_cnt;
+	__le32 reserved0;
+};
+
+
+/*
+ * FCoE TX statistics parameters
+ */
+struct fcoe_tx_stat_params {
+	__le32 fcoe_tx_pkt_cnt;
+	__le32 fcoe_tx_byte_cnt;
+	__le32 fcp_tx_pkt_cnt;
+	__le32 reserved0;
+};
+
+/*
+ * FCoE statistics parameters
+ */
+struct fcoe_statistics_params {
+	struct fcoe_tx_stat_params tx_stat;
+	struct fcoe_rx_stat_params_section0 rx_stat0;
+	struct fcoe_rx_stat_params_section1 rx_stat1;
+	struct fcoe_rx_stat_params_section2 rx_stat2;
+};
+
+
+/*
+ * cfc delete event data
+*/
 struct cfc_del_event_data {
 	u32 cid;
 	u32 reserved0;
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index 052ab99..552c564 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -2624,15 +2624,6 @@ u32 bnx2x_fw_command(struct bnx2x *bp, u32 command, u32 param)
 	return rc;
 }
 
-static u8 stat_counter_valid(struct bnx2x *bp, struct bnx2x_fastpath *fp)
-{
-#ifdef BCM_CNIC
-	/* Statistics are not supported for CNIC Clients at the moment */
-	if (IS_FCOE_FP(fp))
-		return false;
-#endif
-	return true;
-}
 
 void bnx2x_func_init(struct bnx2x *bp, struct bnx2x_func_init_params *p)
 {
@@ -2676,11 +2667,11 @@ static inline unsigned long bnx2x_get_common_flags(struct bnx2x *bp,
 	 *  parent connection). The statistics are zeroed when the parent
 	 *  connection is initialized.
 	 */
-	if (stat_counter_valid(bp, fp)) {
-		__set_bit(BNX2X_Q_FLG_STATS, &flags);
-		if (zero_stats)
-			__set_bit(BNX2X_Q_FLG_ZERO_STATS, &flags);
-	}
+
+	__set_bit(BNX2X_Q_FLG_STATS, &flags);
+	if (zero_stats)
+		__set_bit(BNX2X_Q_FLG_ZERO_STATS, &flags);
+
 
 	return flags;
 }
@@ -6848,13 +6839,16 @@ void bnx2x_free_mem(struct bnx2x *bp)
 static inline int bnx2x_alloc_fw_stats_mem(struct bnx2x *bp)
 {
 	int num_groups;
+	int is_fcoe_stats = NO_FCOE(bp) ? 0 : 1;
 
-	/* number of eth_queues */
-	u8 num_queue_stats = BNX2X_NUM_ETH_QUEUES(bp);
+	/* number of queues for statistics is number of eth queues + FCoE */
+	u8 num_queue_stats = BNX2X_NUM_ETH_QUEUES(bp) + is_fcoe_stats;
 
 	/* Total number of FW statistics requests =
-	 * 1 for port stats + 1 for PF stats + num_eth_queues */
-	bp->fw_stats_num = 2 + num_queue_stats;
+	 * 1 for port stats + 1 for PF stats + potential 1 for FCoE stats +
+	 * num of queues
+	 */
+	bp->fw_stats_num = 2 + is_fcoe_stats + num_queue_stats;
 
 
 	/* Request is built from stats_query_header and an array of
@@ -6862,8 +6856,8 @@ static inline int bnx2x_alloc_fw_stats_mem(struct bnx2x *bp)
 	 * STATS_QUERY_CMD_COUNT rules. The real number or requests is
 	 * configured in the stats_query_header.
 	 */
-	num_groups = (2 + num_queue_stats) / STATS_QUERY_CMD_COUNT +
-		(((2 + num_queue_stats) % STATS_QUERY_CMD_COUNT) ? 1 : 0);
+	num_groups = ((bp->fw_stats_num) / STATS_QUERY_CMD_COUNT) +
+		     (((bp->fw_stats_num) % STATS_QUERY_CMD_COUNT) ? 1 : 0);
 
 	bp->fw_stats_req_sz = sizeof(struct stats_query_header) +
 			num_groups * sizeof(struct stats_query_cmd_group);
@@ -6872,9 +6866,13 @@ static inline int bnx2x_alloc_fw_stats_mem(struct bnx2x *bp)
 	 *
 	 * stats_counter holds per-STORM counters that are incremented
 	 * when STORM has finished with the current request.
+	 *
+	 * memory for FCoE offloaded statistics are counted anyway,
+	 * even if they will not be sent.
 	 */
 	bp->fw_stats_data_sz = sizeof(struct per_port_stats) +
 		sizeof(struct per_pf_stats) +
+		sizeof(struct fcoe_statistics_params) +
 		sizeof(struct per_queue_stats) * num_queue_stats +
 		sizeof(struct stats_counter);
 
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c
index c943545..41a33ce 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c
@@ -1501,6 +1501,7 @@ static void bnx2x_func_stats_base_update(struct bnx2x *bp)
 static inline void bnx2x_prep_fw_stats_req(struct bnx2x *bp)
 {
 	int i;
+	int first_queue_query_index;
 	struct stats_query_header *stats_hdr = &bp->fw_stats_req->hdr;
 
 	dma_addr_t cur_data_offset;
@@ -1556,14 +1557,40 @@ static inline void bnx2x_prep_fw_stats_req(struct bnx2x *bp)
 	cur_query_entry->address.hi = cpu_to_le32(U64_HI(cur_data_offset));
 	cur_query_entry->address.lo = cpu_to_le32(U64_LO(cur_data_offset));
 
+	/**** FCoE FW statistics data ****/
+	if (!NO_FCOE(bp)) {
+		cur_data_offset = bp->fw_stats_data_mapping +
+			offsetof(struct bnx2x_fw_stats_data, fcoe);
+
+		cur_query_entry =
+			&bp->fw_stats_req->query[BNX2X_FCOE_QUERY_IDX];
+
+		cur_query_entry->kind = STATS_TYPE_FCOE;
+		/* For FCoE query index is a DONT CARE */
+		cur_query_entry->index = BP_PORT(bp);
+		cur_query_entry->funcID = cpu_to_le16(BP_FUNC(bp));
+		cur_query_entry->address.hi =
+			cpu_to_le32(U64_HI(cur_data_offset));
+		cur_query_entry->address.lo =
+			cpu_to_le32(U64_LO(cur_data_offset));
+	}
+
 	/**** Clients' queries ****/
 	cur_data_offset = bp->fw_stats_data_mapping +
 		offsetof(struct bnx2x_fw_stats_data, queue_stats);
 
+	/* first queue query index depends whether FCoE offloaded request will
+	 * be included in the ramrod
+	 */
+	if (!NO_FCOE(bp))
+		first_queue_query_index = BNX2X_FIRST_QUEUE_QUERY_IDX;
+	else
+		first_queue_query_index = BNX2X_FIRST_QUEUE_QUERY_IDX - 1;
+
 	for_each_eth_queue(bp, i) {
 		cur_query_entry =
 			&bp->fw_stats_req->
-					query[BNX2X_FIRST_QUEUE_QUERY_IDX + i];
+					query[first_queue_query_index + i];
 
 		cur_query_entry->kind = STATS_TYPE_QUEUE;
 		cur_query_entry->index = bnx2x_stats_id(&bp->fp[i]);
@@ -1575,6 +1602,21 @@ static inline void bnx2x_prep_fw_stats_req(struct bnx2x *bp)
 
 		cur_data_offset += sizeof(struct per_queue_stats);
 	}
+
+	/* add FCoE queue query if needed */
+	if (!NO_FCOE(bp)) {
+		cur_query_entry =
+			&bp->fw_stats_req->
+					query[first_queue_query_index + i];
+
+		cur_query_entry->kind = STATS_TYPE_QUEUE;
+		cur_query_entry->index = bnx2x_stats_id(&bp->fp[FCOE_IDX]);
+		cur_query_entry->funcID = cpu_to_le16(BP_FUNC(bp));
+		cur_query_entry->address.hi =
+			cpu_to_le32(U64_HI(cur_data_offset));
+		cur_query_entry->address.lo =
+			cpu_to_le32(U64_LO(cur_data_offset));
+	}
 }
 
 void bnx2x_stats_init(struct bnx2x *bp)
-- 
1.7.1

^ permalink raw reply related

* [PATCH net-next 1/4] bnx2x: add PFC statistics
From: Michael Chan @ 2011-12-06  5:44 UTC (permalink / raw)
  To: davem; +Cc: netdev, barak, eilong

From: Barak Witkowski <barak@broadcom.com>

Add Priority flow control counters for ethtool -S.

Signed-off-by: Barak Witkowski <barak@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
Signed-off-by: Michael Chan <mchan@broadcom.com>
---
 drivers/net/ethernet/broadcom/bnx2x/bnx2x.h        |    1 +
 .../net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c    |    4 ++
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h    |    9 +++-
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c   |    2 +
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c  |   44 +++++++++++++++++++-
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h  |    6 +++
 6 files changed, 63 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
index 6c7bd63..32af052 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
@@ -1266,6 +1266,7 @@ struct bnx2x {
 #define NO_ISCSI_OOO_FLAG		(1 << 13)
 #define NO_ISCSI_FLAG			(1 << 14)
 #define NO_FCOE_FLAG			(1 << 15)
+#define BC_SUPPORTS_PFC_STATS		(1 << 17)
 
 #define NO_ISCSI(bp)		((bp)->flags & NO_ISCSI_FLAG)
 #define NO_ISCSI_OOO(bp)	((bp)->flags & NO_ISCSI_OOO_FLAG)
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
index c679ed9..e64bdf6 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
@@ -107,6 +107,10 @@ static const struct {
 				4, STATS_FLAGS_PORT, "rx_filtered_packets" },
 	{ STATS_OFFSET32(mf_tag_discard),
 				4, STATS_FLAGS_PORT, "rx_mf_tag_discard" },
+	{ STATS_OFFSET32(pfc_frames_received_hi),
+				8, STATS_FLAGS_PORT, "pfc_frames_received" },
+	{ STATS_OFFSET32(pfc_frames_sent_hi),
+				8, STATS_FLAGS_PORT, "pfc_frames_sent" },
 	{ STATS_OFFSET32(brb_drop_hi),
 				8, STATS_FLAGS_PORT, "rx_brb_discard" },
 	{ STATS_OFFSET32(brb_truncate_hi),
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h
index fc754cb..79b6e43 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h
@@ -1247,6 +1247,7 @@ struct drv_func_mb {
 	#define DRV_MSG_CODE_VRFY_SPECIFIC_PHY_OPT_MDL  0xa1000000
 	#define REQ_BC_VER_4_VRFY_SPECIFIC_PHY_OPT_MDL  0x00050234
 	#define REQ_BC_VER_4_SFP_TX_DISABLE_SUPPORTED   0x00070014
+	#define REQ_BC_VER_4_PFC_STATS_SUPPORTED        0x00070201
 
 	#define DRV_MSG_CODE_DCBX_ADMIN_PMF_MSG         0xb0000000
 	#define DRV_MSG_CODE_DCBX_PMF_DRV_OK            0xb2000000
@@ -2501,14 +2502,18 @@ struct mac_stx {
 #define MAC_STX_IDX_MAX                     2
 
 struct host_port_stats {
-	u32            host_port_stats_start;
+	u32            host_port_stats_counter;
 
 	struct mac_stx mac_stx[MAC_STX_IDX_MAX];
 
 	u32            brb_drop_hi;
 	u32            brb_drop_lo;
 
-	u32            host_port_stats_end;
+	u32            not_used; /* obsolete */
+	u32            pfc_frames_tx_hi;
+	u32            pfc_frames_tx_lo;
+	u32            pfc_frames_rx_hi;
+	u32            pfc_frames_rx_lo;
 };
 
 
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index 2213e0b..052ab99 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -8827,6 +8827,8 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp)
 	bp->link_params.feature_config_flags |=
 		(val >= REQ_BC_VER_4_SFP_TX_DISABLE_SUPPORTED) ?
 		FEATURE_CONFIG_BC_SUPPORTS_SFP_TX_DISABLED : 0;
+	bp->flags |= (val >= REQ_BC_VER_4_PFC_STATS_SUPPORTED) ?
+			BC_SUPPORTS_PFC_STATS : 0;
 
 	pci_read_config_word(bp->pdev, bp->pm_cap + PCI_PM_PMC, &pmc);
 	bp->flags |= (pmc & PCI_PM_CAP_PME_D3cold) ? 0 : NO_WOL_FLAG;
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c
index 3034f0e..c943545 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c
@@ -540,6 +540,25 @@ static void bnx2x_bmac_stats_update(struct bnx2x *bp)
 		UPDATE_STAT64(tx_stat_gterr,
 				tx_stat_dot3statsinternalmactransmiterrors);
 		UPDATE_STAT64(tx_stat_gtufl, tx_stat_mac_ufl);
+
+		/* collect PFC stats */
+		DIFF_64(diff.hi, new->tx_stat_gtpp_hi,
+			pstats->pfc_frames_tx_hi,
+			diff.lo, new->tx_stat_gtpp_lo,
+			pstats->pfc_frames_tx_lo);
+		pstats->pfc_frames_tx_hi = new->tx_stat_gtpp_hi;
+		pstats->pfc_frames_tx_lo = new->tx_stat_gtpp_lo;
+		ADD_64(pstats->pfc_frames_tx_hi, diff.hi,
+			pstats->pfc_frames_tx_lo, diff.lo);
+
+		DIFF_64(diff.hi, new->rx_stat_grpp_hi,
+			pstats->pfc_frames_rx_hi,
+			diff.lo, new->rx_stat_grpp_lo,
+			pstats->pfc_frames_rx_lo);
+		pstats->pfc_frames_rx_hi = new->rx_stat_grpp_hi;
+		pstats->pfc_frames_rx_lo = new->rx_stat_grpp_lo;
+		ADD_64(pstats->pfc_frames_rx_hi, diff.hi,
+			pstats->pfc_frames_rx_lo, diff.lo);
 	}
 
 	estats->pause_frames_received_hi =
@@ -551,6 +570,15 @@ static void bnx2x_bmac_stats_update(struct bnx2x *bp)
 				pstats->mac_stx[1].tx_stat_outxoffsent_hi;
 	estats->pause_frames_sent_lo =
 				pstats->mac_stx[1].tx_stat_outxoffsent_lo;
+
+	estats->pfc_frames_received_hi =
+				pstats->pfc_frames_rx_hi;
+	estats->pfc_frames_received_lo =
+				pstats->pfc_frames_rx_lo;
+	estats->pfc_frames_sent_hi =
+				pstats->pfc_frames_tx_hi;
+	estats->pfc_frames_sent_lo =
+				pstats->pfc_frames_tx_lo;
 }
 
 static void bnx2x_mstat_stats_update(struct bnx2x *bp)
@@ -571,6 +599,11 @@ static void bnx2x_mstat_stats_update(struct bnx2x *bp)
 	ADD_STAT64(stats_tx.tx_gtxpf, tx_stat_outxoffsent);
 	ADD_STAT64(stats_tx.tx_gtxpf, tx_stat_flowcontroldone);
 
+	/* collect pfc stats */
+	ADD_64(pstats->pfc_frames_tx_hi, new->stats_tx.tx_gtxpp_hi,
+		pstats->pfc_frames_tx_lo, new->stats_tx.tx_gtxpp_lo);
+	ADD_64(pstats->pfc_frames_rx_hi, new->stats_rx.rx_grxpp_hi,
+		pstats->pfc_frames_rx_lo, new->stats_rx.rx_grxpp_lo);
 
 	ADD_STAT64(stats_tx.tx_gt64, tx_stat_etherstatspkts64octets);
 	ADD_STAT64(stats_tx.tx_gt127,
@@ -628,6 +661,15 @@ static void bnx2x_mstat_stats_update(struct bnx2x *bp)
 				pstats->mac_stx[1].tx_stat_outxoffsent_hi;
 	estats->pause_frames_sent_lo =
 				pstats->mac_stx[1].tx_stat_outxoffsent_lo;
+
+	estats->pfc_frames_received_hi =
+				pstats->pfc_frames_rx_hi;
+	estats->pfc_frames_received_lo =
+				pstats->pfc_frames_rx_lo;
+	estats->pfc_frames_sent_hi =
+				pstats->pfc_frames_tx_hi;
+	estats->pfc_frames_sent_lo =
+				pstats->pfc_frames_tx_lo;
 }
 
 static void bnx2x_emac_stats_update(struct bnx2x *bp)
@@ -740,7 +782,7 @@ static int bnx2x_hw_stats_update(struct bnx2x *bp)
 	estats->brb_drop_hi = pstats->brb_drop_hi;
 	estats->brb_drop_lo = pstats->brb_drop_lo;
 
-	pstats->host_port_stats_start = ++pstats->host_port_stats_end;
+	pstats->host_port_stats_counter++;
 
 	if (!BP_NOMCP(bp)) {
 		u32 nig_timer_max =
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h
index 5d8ce2f..683deb0 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h
@@ -193,6 +193,12 @@ struct bnx2x_eth_stats {
 	u32 total_tpa_aggregated_frames_lo;
 	u32 total_tpa_bytes_hi;
 	u32 total_tpa_bytes_lo;
+
+	/* PFC */
+	u32 pfc_frames_received_hi;
+	u32 pfc_frames_received_lo;
+	u32 pfc_frames_sent_hi;
+	u32 pfc_frames_sent_lo;
 };
 
 
-- 
1.7.1

^ permalink raw reply related

* Re: [PATCH] fsl_pq_mdio: Clean up tbi address configuration
From: David Miller @ 2011-12-06  5:41 UTC (permalink / raw)
  To: galak; +Cc: afleming, netdev
In-Reply-To: <436A94C3-8F5B-4A8F-A46B-B66B503B98A0@kernel.crashing.org>

From: Kumar Gala <galak@kernel.crashing.org>
Date: Mon, 5 Dec 2011 23:38:14 -0600

> Any comment on getting this patch pulled into net.git?

It requires a DT patch or related set of changes which have need
to be done differently as per feedback.

My understanding is there are two patches required, this revert plus
the changes to add the tbi property to the DT which are missing it.

That's why these tbi changes went in to begin with, to handle DT
which lack the property, or something like that.  So you can't
just revert this thing without also fixing the DT that lack the
tbi property, or else you break those systems.

^ permalink raw reply

* [PATCH net] pasemi_mac: Fix building as module
From: Ben Hutchings @ 2011-12-06  5:44 UTC (permalink / raw)
  To: David Miller; +Cc: Jeff Kirsher, Olof Johansson, netdev

Commit ded19addf9c937d83b9bfb4d73a836732569041b ('pasemic_mac*: Move
the PA Semi driver') inadvertently split pasemi_mac into two separate
modules with unresolved symbols.  Change it back into a single module.

Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
The build failure can currently be seen at
<https://buildd.debian.org/status/package.php?p=linux-2.6&suite=experimental>.

Ben.

 drivers/net/ethernet/pasemi/Makefile |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/net/ethernet/pasemi/Makefile b/drivers/net/ethernet/pasemi/Makefile
index 05db543..90497ff 100644
--- a/drivers/net/ethernet/pasemi/Makefile
+++ b/drivers/net/ethernet/pasemi/Makefile
@@ -2,4 +2,5 @@
 # Makefile for the A Semi network device drivers.
 #
 
-obj-$(CONFIG_PASEMI_MAC) += pasemi_mac.o pasemi_mac_ethtool.o
+obj-$(CONFIG_PASEMI_MAC) += pasemi_mac_driver.o
+pasemi_mac_driver-objs := pasemi_mac.o pasemi_mac_ethtool.o
-- 
1.7.7.3

^ permalink raw reply related

* Re: [PATCH net-next 3/4] bnx2x: support classification config query
From: David Miller @ 2011-12-06  5:46 UTC (permalink / raw)
  To: mchan; +Cc: netdev, barak, eilong
In-Reply-To: <1323150288-28153-3-git-send-email-mchan@broadcom.com>

From: "Michael Chan" <mchan@broadcom.com>
Date: Mon, 5 Dec 2011 21:44:47 -0800

> +	/* traverse list */
> +	list_for_each_entry(pos, &o->head, link)
> +	{

Put openning "{" at end of list_for_each_entry(), rather than
on a new line.

> +		if ((counter < n)) {

Excessive parenthesis, remove.

> +			memcpy(next + MAC_LEADING_ZERO_CNT,
> +				  pos->u.mac.mac, ETH_ALEN);

Paremeters on subsequent lines don't line up properly.

> +			next = buf + counter * ALIGN(ETH_ALEN,
> +							   sizeof(u32));

Likewise.

> +			DP(BNX2X_MSG_SP, "copied element number "
> +				   "%d to address %p element was "
> +				   "%pM\n", counter, next, pos->u.mac.mac);

Likewise.

> +	int (*get_n_elements)(struct bnx2x *bp,
> +			 struct bnx2x_vlan_mac_obj *o,
> +			 int n,
> +			 u8 *buf);
> +

Likewise.

Sigh.

Definitely a new-comer wrote this code, but I know more experienced hands
reviewed it, therefore I am disappointed.

^ permalink raw reply

* Re: [PATCH net] pasemi_mac: Fix building as module
From: David Miller @ 2011-12-06  5:49 UTC (permalink / raw)
  To: ben; +Cc: jeffrey.t.kirsher, olof, netdev
In-Reply-To: <1323150262.7454.247.camel@deadeye>

From: Ben Hutchings <ben@decadent.org.uk>
Date: Tue, 06 Dec 2011 05:44:22 +0000

> Commit ded19addf9c937d83b9bfb4d73a836732569041b ('pasemic_mac*: Move
> the PA Semi driver') inadvertently split pasemi_mac into two separate
> modules with unresolved symbols.  Change it back into a single module.
> 
> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
> ---
> The build failure can currently be seen at
> <https://buildd.debian.org/status/package.php?p=linux-2.6&suite=experimental>.

Applied, thanks Ben.

^ permalink raw reply

* Re: [PATCH net-next 4/4] bnx2x, cnic: support DRV_INFO upon FW request
From: Joe Perches @ 2011-12-06  5:56 UTC (permalink / raw)
  To: Michael Chan; +Cc: davem, netdev, barak, eilong
In-Reply-To: <1323150288-28153-4-git-send-email-mchan@broadcom.com>

On Mon, 2011-12-05 at 21:44 -0800, Michael Chan wrote:
> From: Barak Witkowski <barak@broadcom.com>
> Add support to send driver capabilities, settings and statistics to
> management firmware.
[]
> diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
[]
> @@ -2912,6 +2912,159 @@ static void bnx2x_e1h_enable(struct bnx2x *bp)
>  	 */
>  }
>  
> +#define DRV_INFO_ETH_STAT_NUM_MACS_REQUIRED 3
> +
> +static inline void bnx2x_drv_info_ether_stat(struct bnx2x *bp)

Most likely this should not be inline

> +{
> +	/* leave last char as NULL */
> +	memcpy(bp->slowpath->drv_info_to_mcp.ether_stat.version,
> +		DRV_MODULE_VERSION, ETH_STAT_INFO_VERSION_LEN - 1);

This would read and perform a lot better with temporaries.
Many (all?) gcc versions don't optimize out the repeated indirections.

	whatever_type *dev = bp->dev;
	whatever_type *ether_stats = &bp->slowpath->drv_info_to_mp.etherstat;

> +
> +	bp->fp[0].mac_obj.get_n_elements(bp, &bp->fp[0].mac_obj,
> +					 DRV_INFO_ETH_STAT_NUM_MACS_REQUIRED,
> +			bp->slowpath->drv_info_to_mcp.ether_stat.mac_local);
> +
> +	bp->slowpath->drv_info_to_mcp.ether_stat.mtu_size = bp->dev->mtu;

	ether_stats->mtu_size = dev->mtu;
> +
> +	if (bp->dev->features & NETIF_F_RXCSUM)
> +		bp->slowpath->drv_info_to_mcp.ether_stat.feature_flags |=
> +		FEATURE_ETH_CHKSUM_OFFLOAD_MASK;

	if (dev->features & NETIF_F_RXCSUM)
		ether_stats->feature_flags |= FEATURE_ETH_CHKSUM_OFFLOAD_MASK;

> +	if (bp->dev->features & NETIF_F_TSO)
> +		bp->slowpath->drv_info_to_mcp.ether_stat.feature_flags |=
> +		FEATURE_ETH_LSO_MASK;

	if (dev->features & NETIF_F_TSO)
		ether_stats->feature_flags |= FEATURE_ETH_LSO_MASK;

> +	bp->slowpath->drv_info_to_mcp.ether_stat.feature_flags |=
> +		bp->common.boot_mode;

etc.,

> +static inline void bnx2x_drv_info_fcoe_stat(struct bnx2x *bp)
> +{
> +	struct bnx2x_dcbx_app_params *app = &bp->dcbx_port_params.app;
> +
> +	memcpy(bp->slowpath->drv_info_to_mcp.fcoe_stat.mac_local,
> +		bp->fip_mac, ETH_ALEN);

Same temporary use.

> +
> +	bp->slowpath->drv_info_to_mcp.fcoe_stat.qos_priority =
> +		app->traffic_type_priority[LLFC_TRAFFIC_TYPE_FCOE];
> +
> +	/* insert FCoE stats from ramrod response */
> +	if (!NO_FCOE(bp)) {
> +		struct tstorm_per_queue_stats *fcoe_q_tstorm_stats =
> +			&bp->fw_stats_data->queue_stats[FCOE_IDX].
> +			tstorm_queue_statistics;
> +
> +		struct xstorm_per_queue_stats *fcoe_q_xstorm_stats =
> +			&bp->fw_stats_data->queue_stats[FCOE_IDX].
> +			xstorm_queue_statistics;
> +
> +		ADD_64(bp->slowpath->drv_info_to_mcp.fcoe_stat.rx_bytes_hi,
> +			0,
> +			bp->slowpath->drv_info_to_mcp.fcoe_stat.rx_bytes_lo,
> +			bp->fw_stats_data->fcoe.rx_stat0.fcoe_rx_byte_cnt);

temporaries for bp->slowpath->drv_info_to_mcp.fcoe_stat
and bp->fw_stats_data->fcoe.rx_stat0 too.

> +
> +		ADD_64(bp->slowpath->drv_info_to_mcp.fcoe_stat.rx_bytes_hi,
> +			fcoe_q_tstorm_stats->rcv_ucast_bytes.hi,
> +			bp->slowpath->drv_info_to_mcp.fcoe_stat.rx_bytes_lo,
> +			fcoe_q_tstorm_stats->rcv_ucast_bytes.lo);
> +
> +		ADD_64(bp->slowpath->drv_info_to_mcp.fcoe_stat.rx_bytes_hi,
> +			fcoe_q_tstorm_stats->rcv_bcast_bytes.hi,
> +			bp->slowpath->drv_info_to_mcp.fcoe_stat.rx_bytes_lo,
> +			fcoe_q_tstorm_stats->rcv_bcast_bytes.lo);
> +
> +		ADD_64(bp->slowpath->drv_info_to_mcp.fcoe_stat.rx_bytes_hi,
> +			fcoe_q_tstorm_stats->rcv_mcast_bytes.hi,
> +			bp->slowpath->drv_info_to_mcp.fcoe_stat.rx_bytes_lo,
> +			fcoe_q_tstorm_stats->rcv_mcast_bytes.lo);
> +
> +		ADD_64(bp->slowpath->drv_info_to_mcp.fcoe_stat.rx_frames_hi,
> +			0,
> +			bp->slowpath->drv_info_to_mcp.fcoe_stat.rx_frames_lo,
> +			bp->fw_stats_data->fcoe.rx_stat0.fcoe_rx_pkt_cnt);
> +
> +		ADD_64(bp->slowpath->drv_info_to_mcp.fcoe_stat.rx_frames_hi,
> +			0,
> +			bp->slowpath->drv_info_to_mcp.fcoe_stat.rx_frames_lo,
> +			fcoe_q_tstorm_stats->rcv_ucast_pkts);
> +
> +		ADD_64(bp->slowpath->drv_info_to_mcp.fcoe_stat.rx_frames_hi,
> +			0,
> +			bp->slowpath->drv_info_to_mcp.fcoe_stat.rx_frames_lo,
> +			fcoe_q_tstorm_stats->rcv_bcast_pkts);
> +
> +		ADD_64(bp->slowpath->drv_info_to_mcp.fcoe_stat.rx_frames_hi,
> +			0,
> +			bp->slowpath->drv_info_to_mcp.fcoe_stat.rx_frames_lo,
> +			fcoe_q_tstorm_stats->rcv_ucast_pkts);
> +
> +		ADD_64(bp->slowpath->drv_info_to_mcp.fcoe_stat.tx_bytes_hi,
> +			0,
> +			bp->slowpath->drv_info_to_mcp.fcoe_stat.tx_bytes_lo,
> +			bp->fw_stats_data->fcoe.tx_stat.fcoe_tx_byte_cnt);
> +
> +		ADD_64(bp->slowpath->drv_info_to_mcp.fcoe_stat.tx_bytes_hi,
> +			fcoe_q_xstorm_stats->ucast_bytes_sent.hi,
> +			bp->slowpath->drv_info_to_mcp.fcoe_stat.tx_bytes_lo,
> +			fcoe_q_xstorm_stats->ucast_bytes_sent.lo);
> +
> +		ADD_64(bp->slowpath->drv_info_to_mcp.fcoe_stat.tx_bytes_hi,
> +			fcoe_q_xstorm_stats->bcast_bytes_sent.hi,
> +			bp->slowpath->drv_info_to_mcp.fcoe_stat.tx_bytes_lo,
> +			fcoe_q_xstorm_stats->bcast_bytes_sent.lo);
> +
> +		ADD_64(bp->slowpath->drv_info_to_mcp.fcoe_stat.tx_bytes_hi,
> +			fcoe_q_xstorm_stats->mcast_bytes_sent.hi,
> +			bp->slowpath->drv_info_to_mcp.fcoe_stat.tx_bytes_lo,
> +			fcoe_q_xstorm_stats->mcast_bytes_sent.lo);
> +
> +		ADD_64(bp->slowpath->drv_info_to_mcp.fcoe_stat.tx_frames_hi,
> +			0,
> +			bp->slowpath->drv_info_to_mcp.fcoe_stat.tx_frames_lo,
> +			bp->fw_stats_data->fcoe.tx_stat.fcoe_tx_pkt_cnt);
> +
> +		ADD_64(bp->slowpath->drv_info_to_mcp.fcoe_stat.tx_frames_hi,
> +			0,
> +			bp->slowpath->drv_info_to_mcp.fcoe_stat.tx_frames_lo,
> +			fcoe_q_xstorm_stats->ucast_pkts_sent);
> +
> +		ADD_64(bp->slowpath->drv_info_to_mcp.fcoe_stat.tx_frames_hi,
> +			0,
> +			bp->slowpath->drv_info_to_mcp.fcoe_stat.tx_frames_lo,
> +			fcoe_q_xstorm_stats->bcast_pkts_sent);
> +
> +		ADD_64(bp->slowpath->drv_info_to_mcp.fcoe_stat.tx_frames_hi,
> +			0,
> +			bp->slowpath->drv_info_to_mcp.fcoe_stat.tx_frames_lo,
> +			fcoe_q_xstorm_stats->mcast_pkts_sent);
> +	}
> +

cheers, Joe

^ permalink raw reply

* Re: [PATCH net-next 3/4] bnx2x: support classification config query
From: Michael Chan @ 2011-12-06  5:57 UTC (permalink / raw)
  To: 'David Miller'
  Cc: 'netdev@vger.kernel.org', Barak Witkowski,
	Eilon Greenstein
In-Reply-To: <20111206.004629.1477080329086805790.davem@davemloft.net>

David Miller wrote:

> 
> Sigh.
> 
> Definitely a new-comer wrote this code, but I know more experienced
> hands
> reviewed it, therefore I am disappointed.

Sorry, I'll fix everything up and re-send.

^ permalink raw reply

* Re: [PATCH net-next 3/4] bnx2x: support classification config query
From: Joe Perches @ 2011-12-06  5:59 UTC (permalink / raw)
  To: David Miller; +Cc: mchan, netdev, barak, eilong
In-Reply-To: <20111206.004629.1477080329086805790.davem@davemloft.net>

On Tue, 2011-12-06 at 00:46 -0500, David Miller wrote:
> > +			DP(BNX2X_MSG_SP, "copied element number "
> > +				   "%d to address %p element was "
> > +				   "%pM\n", counter, next, pos->u.mac.mac);
> 
> Likewise.

Ideally, the format should be coalesced as well.

			DP(BNX2X_MSG_SP, "copied element number %d to address %p - element was %pM\n",
			   counter, next, pos->u.mac.mac);

^ permalink raw reply

* Re: Shaping TCP ACK packets
From: Eric Dumazet @ 2011-12-06  5:59 UTC (permalink / raw)
  To: John A. Sullivan III; +Cc: netdev
In-Reply-To: <7cf7b0f6-b30f-465a-9e50-20bd2c31bbe9@jasiiieee>

Le lundi 05 décembre 2011 à 23:18 -0500, John A. Sullivan III a écrit :
> Hello, all.  I've seen several sites recommend prioritizing TCP ACK
> packets using tc.  Is that a good idea? I have two reservations:
> 
> 1) If my line is congested, isn't delaying ACKs a good way to slow
> down the conversation? Accelerating ACKs under congestion sounds a bit
> like stuffing more food in my mouth when I'm already choking.
> 
It depends which way is congested. Sites recommends prioritizing ACKS on
the up way, because most of the time ADSL links are assymetric. an
uplink is congested.


> 2) By messing with normal coordination of TCP, do I risk making a
> mess.  Specifically, can I create problems with out of order packet
> delivery - send an ACK before the packet which should have preceded
> it? I suppose in a well behaved protocol that wouldn't happen but I'm
> not sure.  Thanks - John
> --

Well, if you prioritize true acks (packets with no payload), there is no
reorder problem per se.

^ permalink raw reply

* Re: Latency difference between fifo and pfifo_fast
From: Eric Dumazet @ 2011-12-06  6:02 UTC (permalink / raw)
  To: John A. Sullivan III; +Cc: netdev
In-Reply-To: <30c2e9e0-4208-4c19-9e43-31f95e13575d@jasiiieee>

Le lundi 05 décembre 2011 à 23:10 -0500, John A. Sullivan III a écrit :
> Hello, all.  We are trying to minimize latency on our iSCSI SAN.  The
> network is entirely dedicated to the iSCSI traffic.  Since all the
> traffic is the same, would it make sense to change the qdisc for that
> interface to fifo from the default pfifo_fast or is the latency
> difference between the two completely negligible? Thanks - John

A very small difference indeed. How many packets per second are
expected ? What kind of NIC are you using ?

^ permalink raw reply

* [patch] openvswitch: small potential memory leak in ovs_vport_alloc()
From: Dan Carpenter @ 2011-12-06  6:27 UTC (permalink / raw)
  To: Jesse Gross
  Cc: dev-yBygre7rU0TnMu66kgdUjQ, netdev-u79uwXL29TY76Z2rM5mHXA,
	kernel-janitors-u79uwXL29TY76Z2rM5mHXA, David S. Miller

We're unlikely to hit this leak, but the static checkers complain if we
don't take care of it.

Signed-off-by: Dan Carpenter <dan.carpenter-QHcLZuEGTsvQT0dZR+AlfA@public.gmane.org>

diff --git a/net/openvswitch/vport.c b/net/openvswitch/vport.c
index 6cd7601..7f0ef37 100644
--- a/net/openvswitch/vport.c
+++ b/net/openvswitch/vport.c
@@ -127,8 +127,10 @@ struct vport *ovs_vport_alloc(int priv_size, const struct vport_ops *ops,
 	vport->ops = ops;
 
 	vport->percpu_stats = alloc_percpu(struct vport_percpu_stats);
-	if (!vport->percpu_stats)
+	if (!vport->percpu_stats) {
+		kfree(vport);
 		return ERR_PTR(-ENOMEM);
+	}
 
 	spin_lock_init(&vport->stats_lock);
 

^ permalink raw reply related

* Re: Latency difference between fifo and pfifo_fast
From: Eric Dumazet @ 2011-12-06  6:29 UTC (permalink / raw)
  To: John A. Sullivan III; +Cc: netdev
In-Reply-To: <1323151377.2467.13.camel@edumazet-laptop>

Le mardi 06 décembre 2011 à 07:02 +0100, Eric Dumazet a écrit :
> Le lundi 05 décembre 2011 à 23:10 -0500, John A. Sullivan III a écrit :
> > Hello, all.  We are trying to minimize latency on our iSCSI SAN.  The
> > network is entirely dedicated to the iSCSI traffic.  Since all the
> > traffic is the same, would it make sense to change the qdisc for that
> > interface to fifo from the default pfifo_fast or is the latency
> > difference between the two completely negligible? Thanks - John
> 
> A very small difference indeed. How many packets per second are
> expected ? What kind of NIC are you using ?
> 

To really remove a possible source of latency, you could remove qdisc
layer...

ifconfig eth2 txqueuelen 0
tc qdisc add dev eth2 root pfifo
tc qdisc del dev eth2 root

^ permalink raw reply

* Re: [net-next RFC PATCH 5/5] virtio-net: flow director support
From: Jason Wang @ 2011-12-06  6:33 UTC (permalink / raw)
  To: Stefan Hajnoczi
  Cc: krkumar2, kvm, mst, netdev, virtualization, levinsasha928,
	bhutchings
In-Reply-To: <CAJSP0QXfHC8j2Kk9x6wyBMubo2=YvpaLAShJtwMWA2mtro6UhA@mail.gmail.com>

On 12/05/2011 06:55 PM, Stefan Hajnoczi wrote:
> On Mon, Dec 5, 2011 at 8:59 AM, Jason Wang<jasowang@redhat.com>  wrote:
>> +static int virtnet_set_fd(struct net_device *dev, u32 pfn)
>> +{
>> +       struct virtnet_info *vi = netdev_priv(dev);
>> +       struct virtio_device *vdev = vi->vdev;
>> +
>> +       if (virtio_has_feature(vdev, VIRTIO_NET_F_HOST_FD)) {
>> +               vdev->config->set(vdev,
>> +                                 offsetof(struct virtio_net_config_fd, addr),
>> +&pfn, sizeof(u32));
> Please use the virtio model (i.e. virtqueues) instead of shared
> memory.  Mapping a page breaks the virtio abstraction.

Using control virtqueue is more suitable but there's are also some problems:

One problem is the interface,  if we use control virtqueue, we need a 
interface between the backend and tap/macvtap to change the flow 
mapping. But qemu and vhost_net only know about the file descriptor, 
more informations or interfaces need to be exposed in order to let 
ethtool or ioctl work.

Another problem is the delay introduced by ctrl vq, as the ctrl vq would 
be used in the critical path in guest and it use busy wait to get the 
response, the delay is not neglectable.

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

^ permalink raw reply

* [PATCH net] ipv6:export nd_tbl
From: Weiping Pan @ 2011-12-06  6:52 UTC (permalink / raw)
  Cc: Weiping Pan, David S. Miller, Alexey Kuznetsov, James Morris,
	Hideaki YOSHIFUJI, Patrick McHardy,
	open list:NETWORKING [IPv4/..., open list

A customer wants to use nd_tbl in his kernel module,
the easiest way is to export nd_tbl, just as arp_tbl.

There were some requests to export nd_tbl, like:
http://marc.info/?l=netfilter-devel&m=111416950824614&w=2
http://marc.info/?l=linux-netdev&m=110715893206991&w=2

But they were all rejected.
I want to know the reason why can't nd_tbl be exported just as arp_tbl,
and how can we look up nd_tbl without exporting it.

thanks
Weiping Pan

Signed-off-by: Weiping Pan <panweiping3@gmail.com>
---
 net/ipv6/ndisc.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 0cb78d7..1ab98b5 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -153,6 +153,7 @@ struct neigh_table nd_tbl = {
 	.gc_thresh2 =	 512,
 	.gc_thresh3 =	1024,
 };
+EXPORT_SYMBOL(nd_tbl);
 
 /* ND options */
 struct ndisc_options {
-- 
1.7.4.4

^ permalink raw reply related

* [RFC] socket sk_sndmsg_page waste
From: Eric Dumazet @ 2011-12-06  6:53 UTC (permalink / raw)
  To: David Miller; +Cc: netdev

TCP can steer one page of memory per socket to cook outgoing frames.

This means a machine handling long living sockets can consume a lot of
ram.

1.000.000 tcp sockets : up to 4GB of allocated memory, if some writes
had been done on these sockets.

It would make sense to use a per thread page as a pool, instead of a per
socket pool, and remove sk_sndmsg_page/off fields.

Problem with this strategy is impact outside of net tree, and a cost at
thread creation/destruction.

[ But this could be used in fs/pipe.c or fs/splice.c code..., so that
small writes() dont allocate a full page but try to reuse the "per
task_struct" page ]

^ permalink raw reply

* Re: [net-next RFC PATCH 2/5] tuntap: simple flow director support
From: Jason Wang @ 2011-12-06  7:21 UTC (permalink / raw)
  To: Ben Hutchings; +Cc: krkumar2, kvm, mst, netdev, virtualization, levinsasha928
In-Reply-To: <1323115763.2887.12.camel@bwh-desktop>

On 12/06/2011 04:09 AM, Ben Hutchings wrote:
> On Mon, 2011-12-05 at 16:58 +0800, Jason Wang wrote:
>> This patch adds a simple flow director to tun/tap device. It is just a
>> page that contains the hash to queue mapping which could be changed by
>> user-space. The backend (tap/macvtap) would query this table to get
>> the desired queue of a packets when it send packets to userspace.
> This is just flow hashing (RSS), not flow steering.
>
>> The page address were set through a new kind of ioctl - TUNSETFD and
>> were pinned until device exit or another new page were specified.
> [...]
>
> You should implement ethtool ETHTOOL_{G,S}RXFHINDIR instead.
>
> Ben.
>

I'm not fully understanding this. The page belongs to guest, and the 
idea is to let guest driver can easily change any entry. Looks like if 
ethtool_set_rxfh_indir() is used, this kind of change is not easy as it 
needs one copy and can only accept the whole table as its parameters.

^ permalink raw reply

* Re: [net-next RFC PATCH 5/5] virtio-net: flow director support
From: Jason Wang @ 2011-12-06  7:25 UTC (permalink / raw)
  To: Ben Hutchings; +Cc: krkumar2, kvm, mst, netdev, virtualization, levinsasha928
In-Reply-To: <1323117745.2887.31.camel@bwh-desktop>

On 12/06/2011 04:42 AM, Ben Hutchings wrote:
> On Mon, 2011-12-05 at 16:59 +0800, Jason Wang wrote:
>> In order to let the packets of a flow to be passed to the desired
>> guest cpu, we can co-operate with devices through programming the flow
>> director which was just a hash to queue table.
>>
>> This kinds of co-operation is done through the accelerate RFS support,
>> a device specific flow sterring method virtnet_fd() is used to modify
>> the flow director based on rfs mapping. The desired queue were
>> calculated through reverse mapping of the irq affinity table. In order
>> to parallelize the ingress path, irq affinity of rx queue were also
>> provides by the driver.
>>
>> In addition to accelerate RFS, we can also use the guest scheduler to
>> balance the load of TX and reduce the lock contention on egress path,
>> so the processor_id() were used to tx queue selection.
> [...]
>> +#ifdef CONFIG_RFS_ACCEL
>> +
>> +int virtnet_fd(struct net_device *net_dev, const struct sk_buff *skb,
>> +	       u16 rxq_index, u32 flow_id)
>> +{
>> +	struct virtnet_info *vi = netdev_priv(net_dev);
>> +	u16 *table = NULL;
>> +
>> +	if (skb->protocol != htons(ETH_P_IP) || !skb->rxhash)
>> +		return -EPROTONOSUPPORT;
> Why only IPv4?

Oops, IPv6 should work also.
>> +	table = kmap_atomic(vi->fd_page);
>> +	table[skb->rxhash&  TAP_HASH_MASK] = rxq_index;
>> +	kunmap_atomic(table);
>> +
>> +	return 0;
>> +}
>> +#endif
> This is not a proper implementation of ndo_rx_flow_steer.  If you steer
> a flow by changing the RSS table this can easily cause packet reordering
> in other flows.  The filtering should be more precise, ideally matching
> exactly a single flow by e.g. VID and IP 5-tuple.
>
> I think you need to add a second hash table which records exactly which
> flow is supposed to be steered.  Also, you must call
> rps_may_expire_flow() to check whether an entry in this table may be
> replaced; otherwise you can cause packet reordering in the flow that was
> previously being steered.
>
> Finally, this function must return the table index it assigned, so that
> rps_may_expire_flow() works.

Thanks for the explanation, how about document this briefly in scaling.txt?
>> +static u16 virtnet_select_queue(struct net_device *dev, struct sk_buff *skb)
>> +{
>> +	int txq = skb_rx_queue_recorded(skb) ? skb_get_rx_queue(skb) :
>> +					       smp_processor_id();
>> +
>> +	/* As we make use of the accelerate rfs which let the scheduler to
>> +	 * balance the load, it make sense to choose the tx queue also based on
>> +	 * theprocessor id?
>> +	 */
>> +	while (unlikely(txq>= dev->real_num_tx_queues))
>> +		txq -= dev->real_num_tx_queues;
>> +	return txq;
>> +}
> [...]
>
> Don't do this, let XPS handle it.
>
> Ben.
>

^ permalink raw reply

* Re: Latency difference between fifo and pfifo_fast
From: John A. Sullivan III @ 2011-12-06  8:39 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: netdev
In-Reply-To: <1323152942.2467.16.camel@edumazet-laptop>



----- Original Message -----
> From: "Eric Dumazet" <eric.dumazet@gmail.com>
> To: "John A. Sullivan III" <jsullivan@opensourcedevel.com>
> Cc: netdev@vger.kernel.org
> Sent: Tuesday, December 6, 2011 1:29:02 AM
> Subject: Re: Latency difference between fifo and pfifo_fast
> 
> Le mardi 06 décembre 2011 à 07:02 +0100, Eric Dumazet a écrit :
> > Le lundi 05 décembre 2011 à 23:10 -0500, John A. Sullivan III a
> > écrit :
> > > Hello, all.  We are trying to minimize latency on our iSCSI SAN.
> > >  The
> > > network is entirely dedicated to the iSCSI traffic.  Since all
> > > the
> > > traffic is the same, would it make sense to change the qdisc for
> > > that
> > > interface to fifo from the default pfifo_fast or is the latency
> > > difference between the two completely negligible? Thanks - John
> > 
> > A very small difference indeed. How many packets per second are
> > expected ? What kind of NIC are you using ?
> > 
> 
> To really remove a possible source of latency, you could remove qdisc
> layer...
> 
> ifconfig eth2 txqueuelen 0
> tc qdisc add dev eth2 root pfifo
> tc qdisc del dev eth2 root
> 
> 
> 
> 
Really? I didn't know one could do that.  Thanks.  However, with no queue length, do I have a significant risk of dropping packets? To answer your other response's question, these are Intel quad port e1000 cards.  We are frequently pushing them to near line speed so 1,000,000,000 / 1534 / 8 = 81,486 pps - John

^ permalink raw reply

* [PATCH V2 net] ipv4:correct description for tcp_max_syn_backlog
From: Weiping Pan @ 2011-12-06  7:39 UTC (permalink / raw)
  To: shanwei88
  Cc: Weiping Pan, Randy Dunlap, David S. Miller, Eric Dumazet,
	Shan Wei, Neil Horman, Max Matveev, open list:DOCUMENTATION,
	open list, open list:NETWORKING [GENERAL]
In-Reply-To: <4EDDC1D6.6000708@gmail.com>

Since commit c5ed63d66f24(tcp: fix three tcp sysctls tuning),
sysctl_max_syn_backlog is determined by tcp_hashinfo->ehash_mask,
and the minimal value is 128, and it will increase in proportion to the
memory of machine.
The original description for tcp_max_syn_backlog and sysctl_max_syn_backlog
are out of date.

Changelog:
V2: update description for sysctl_max_syn_backlog

Signed-off-by: Weiping Pan <panweiping3@gmail.com>
---
 Documentation/networking/ip-sysctl.txt |   10 +++++-----
 net/core/request_sock.c                |    7 ++++---
 2 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
index f049a1c..589f2da 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -282,11 +282,11 @@ tcp_max_ssthresh - INTEGER
 	Default: 0 (off)
 
 tcp_max_syn_backlog - INTEGER
-	Maximal number of remembered connection requests, which are
-	still did not receive an acknowledgment from connecting client.
-	Default value is 1024 for systems with more than 128Mb of memory,
-	and 128 for low memory machines. If server suffers of overload,
-	try to increase this number.
+	Maximal number of remembered connection requests, which have not
+	received an acknowledgment from connecting client.
+	The minimal value is 128 for low memory machines, and it will
+	increase in proportion to the memory of machine.
+	If server suffers from overload, try increasing this number.
 
 tcp_max_tw_buckets - INTEGER
 	Maximal number of timewait sockets held by system simultaneously.
diff --git a/net/core/request_sock.c b/net/core/request_sock.c
index 182236b..9b570a6 100644
--- a/net/core/request_sock.c
+++ b/net/core/request_sock.c
@@ -26,10 +26,11 @@
  * but then some measure against one socket starving all other sockets
  * would be needed.
  *
- * It was 128 by default. Experiments with real servers show, that
+ * The minimum value of it is 128. Experiments with real servers show that
  * it is absolutely not enough even at 100conn/sec. 256 cures most
- * of problems. This value is adjusted to 128 for very small machines
- * (<=32Mb of memory) and to 1024 on normal or better ones (>=256Mb).
+ * of problems.
+ * This value is adjusted to 128 for low memory machines,
+ * and it will increase in proportion to the memory of machine.
  * Note : Dont forget somaxconn that may limit backlog too.
  */
 int sysctl_max_syn_backlog = 256;
-- 
1.7.4.4


^ 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