[kernel] r19037 - in dists/sid/linux-2.6/debian: . patches/bugfix/all patches/features/all/be2net patches/series
Ben Hutchings
benh at alioth.debian.org
Sun May 27 00:21:24 UTC 2012
Author: benh
Date: Sun May 27 00:21:22 2012
New Revision: 19037
Log:
be2net: Backport most changes up to Linux 3.5-rc1 (Closes: #673391)
Added:
dists/sid/linux-2.6/debian/patches/bugfix/all/ethtool-null-terminate-filename-passed-to.patch
dists/sid/linux-2.6/debian/patches/features/all/be2net/
dists/sid/linux-2.6/debian/patches/features/all/be2net/0001-sweep-the-floors-and-convert-some-.get_drvinfo-routi.patch
dists/sid/linux-2.6/debian/patches/features/all/be2net/0002-be2net-init-vf-_if_handle-vf_pmac_id-to-handle-failu.patch
dists/sid/linux-2.6/debian/patches/features/all/be2net/0003-be2net-stop-checking-the-UE-registers-after-an-EEH-e.patch
dists/sid/linux-2.6/debian/patches/features/all/be2net/0004-be2net-don-t-log-more-than-one-error-on-detecting-EE.patch
dists/sid/linux-2.6/debian/patches/features/all/be2net/0005-be2net-stop-issuing-FW-cmds-if-any-cmd-times-out.patch
dists/sid/linux-2.6/debian/patches/features/all/be2net/0006-be2net-Fix-TX-queue-create-for-Lancer.patch
dists/sid/linux-2.6/debian/patches/features/all/be2net/0007-be2net-add-register-dump-feature-for-Lancer.patch
dists/sid/linux-2.6/debian/patches/features/all/be2net/0008-be2net-Add-EEPROM-dump-feature-for-Lancer.patch
dists/sid/linux-2.6/debian/patches/features/all/be2net/0009-be2net-Fix-VLAN-promiscous-mode-for-Lancer.patch
dists/sid/linux-2.6/debian/patches/features/all/be2net/0010-be2net-Use-V1-query-link-status-command-for-lancer.patch
dists/sid/linux-2.6/debian/patches/features/all/be2net/0011-be2net-Move-to-new-SR-IOV-implementation-in-Lancer.patch
dists/sid/linux-2.6/debian/patches/features/all/be2net/0012-be2net-Fix-error-recovery-paths.patch
dists/sid/linux-2.6/debian/patches/features/all/be2net/0013-be2net-Add-error-handling-for-Lancer.patch
dists/sid/linux-2.6/debian/patches/features/all/be2net/0014-be2net-Use-new-hash-key.patch
dists/sid/linux-2.6/debian/patches/features/all/be2net/0015-be2net-Fix-non-utilization-of-RX-queues.patch
dists/sid/linux-2.6/debian/patches/features/all/be2net/0016-be2net-netpoll-support.patch
dists/sid/linux-2.6/debian/patches/features/all/be2net/0017-be2net-update-some-counters-to-display-via-ethtool.patch
dists/sid/linux-2.6/debian/patches/features/all/be2net/0018-be2net-workaround-to-fix-a-bug-in-BE.patch
dists/sid/linux-2.6/debian/patches/features/all/be2net/0019-be2net-fix-ethtool-ringparam-reporting.patch
dists/sid/linux-2.6/debian/patches/features/all/be2net/0020-be2net-refactor-cleanup-vf-configuration-code.patch
dists/sid/linux-2.6/debian/patches/features/all/be2net/0021-be2net-Add-support-for-Skyhawk-cards.patch
dists/sid/linux-2.6/debian/patches/features/all/be2net/0022-be2net-Fix-INTx-processing-for-Lancer.patch
dists/sid/linux-2.6/debian/patches/features/all/be2net/0023-be2net-fix-be_vlan_add-rem_vid.patch
dists/sid/linux-2.6/debian/patches/features/all/be2net/0024-be2net-fix-range-check-for-set_qos-for-a-VF.patch
dists/sid/linux-2.6/debian/patches/features/all/be2net/0025-be2net-query-link-status-in-be_open.patch
dists/sid/linux-2.6/debian/patches/features/all/be2net/0026-netdev-make-net_device_ops-const.patch
dists/sid/linux-2.6/debian/patches/features/all/be2net/0027-be2net-create-RSS-rings-even-in-multi-channel-config.patch
dists/sid/linux-2.6/debian/patches/features/all/be2net/0028-be2net-allocate-more-headroom-in-incoming-skbs.patch
dists/sid/linux-2.6/debian/patches/features/all/be2net/0029-be2net-add-descriptions-for-stat-counters-reported-v.patch
dists/sid/linux-2.6/debian/patches/features/all/be2net/0030-be2net-Fix-link-status-query-command.patch
dists/sid/linux-2.6/debian/patches/features/all/be2net/0031-be2net-Use-new-implementation-of-get-mac-list-comman.patch
dists/sid/linux-2.6/debian/patches/features/all/be2net/0032-be2net-event-queue-re-design.patch
dists/sid/linux-2.6/debian/patches/features/all/be2net/0033-be2net-cancel-be_worker-during-EEH-recovery.patch
dists/sid/linux-2.6/debian/patches/features/all/be2net/0034-be2net-fix-tx-completion-cleanup.patch
dists/sid/linux-2.6/debian/patches/features/all/be2net/0035-be2net-reset-queue-address-after-freeing.patch
dists/sid/linux-2.6/debian/patches/features/all/be2net/0036-be2net-enable-RSS-for-ipv6-pkts.patch
dists/sid/linux-2.6/debian/patches/features/all/be2net/0037-be2net-update-driver-version.patch
dists/sid/linux-2.6/debian/patches/features/all/be2net/0038-be2net-Remove-unused-OFFSET_IN_PAGE-macro.patch
dists/sid/linux-2.6/debian/patches/features/all/be2net/0039-be2net-enable-WOL-by-default-if-h-w-supports-it.patch
dists/sid/linux-2.6/debian/patches/features/all/be2net/0040-be2net-Program-secondary-UC-MAC-address-into-MAC-fil.patch
dists/sid/linux-2.6/debian/patches/features/all/be2net/0041-be2net-Fix-number-of-vlan-slots-in-flex-mode.patch
dists/sid/linux-2.6/debian/patches/features/all/be2net/0042-be2net-fix-programming-of-VLAN-tags-for-VF.patch
dists/sid/linux-2.6/debian/patches/features/all/be2net/0043-be2net-fix-ethtool-get-settings.patch
dists/sid/linux-2.6/debian/patches/features/all/be2net/0044-be2net-Fix-VLAN-multicast-packet-reception.patch
dists/sid/linux-2.6/debian/patches/features/all/be2net/0045-be2net-Fix-FW-download-in-Lancer.patch
dists/sid/linux-2.6/debian/patches/features/all/be2net/0046-be2net-Fix-ethtool-self-test-for-Lancer.patch
dists/sid/linux-2.6/debian/patches/features/all/be2net/0047-be2net-Fix-traffic-stall-INTx-mode.patch
dists/sid/linux-2.6/debian/patches/features/all/be2net/0048-be2net-Fix-Lancer-statistics.patch
dists/sid/linux-2.6/debian/patches/features/all/be2net/0049-be2net-Fix-wrong-status-getting-returned-for-MCC-com.patch
dists/sid/linux-2.6/debian/patches/features/all/be2net/0050-be2net-Fix-FW-download-for-BE.patch
dists/sid/linux-2.6/debian/patches/features/all/be2net/0051-be2net-Ignore-status-of-some-ioctls-during-driver-lo.patch
dists/sid/linux-2.6/debian/patches/features/all/be2net/0052-be2net-fix-speed-displayed-by-ethtool-on-certain-SKU.patch
dists/sid/linux-2.6/debian/patches/features/all/be2net/0053-be2net-update-the-driver-version.patch
dists/sid/linux-2.6/debian/patches/features/all/be2net/0054-be2net-Fix-to-not-set-link-speed-for-disabled-functi.patch
dists/sid/linux-2.6/debian/patches/features/all/be2net/0055-be2net-Fix-to-apply-duplex-value-as-unknown-when-lin.patch
dists/sid/linux-2.6/debian/patches/features/all/be2net/0056-be2net-Record-receive-queue-index-in-skb-to-aid-RPS.patch
dists/sid/linux-2.6/debian/patches/features/all/be2net/0057-be2net-Fix-EEH-error-reset-before-a-flash-dump-compl.patch
dists/sid/linux-2.6/debian/patches/features/all/be2net/0058-be2net-avoid-disabling-sriov-while-VFs-are-assigned.patch
Modified:
dists/sid/linux-2.6/debian/changelog
dists/sid/linux-2.6/debian/patches/series/base
Modified: dists/sid/linux-2.6/debian/changelog
==============================================================================
--- dists/sid/linux-2.6/debian/changelog Fri May 25 14:02:43 2012 (r19036)
+++ dists/sid/linux-2.6/debian/changelog Sun May 27 00:21:22 2012 (r19037)
@@ -1,3 +1,11 @@
+linux-2.6 (3.2.18-2) UNRELEASED; urgency=low
+
+ [ Ben Hutchings ]
+ * be2net: Backport most changes up to Linux 3.5-rc1 (Closes: #673391)
+ - Add support for Skyhawk cards
+
+ -- Ben Hutchings <ben at decadent.org.uk> Sun, 27 May 2012 01:12:44 +0100
+
linux-2.6 (3.2.18-1) unstable; urgency=low
* New upstream stable update:
Added: dists/sid/linux-2.6/debian/patches/bugfix/all/ethtool-null-terminate-filename-passed-to.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/all/ethtool-null-terminate-filename-passed-to.patch Sun May 27 00:21:22 2012 (r19037)
@@ -0,0 +1,53 @@
+From: Ben Hutchings <bhutchings at solarflare.com>
+Date: Wed, 1 Feb 2012 09:32:25 +0000
+Subject: [PATCH] ethtool: Null-terminate filename passed to
+ ethtool_ops::flash_device
+
+commit 786f528119722f564a22ad953411374e06116333 upstream.
+
+The parameters for ETHTOOL_FLASHDEV include a filename, which ought to
+be null-terminated. Currently the only driver that implements
+ethtool_ops::flash_device attempts to add a null terminator if
+necessary, but does it wrongly. Do it in the ethtool core instead.
+
+Signed-off-by: Ben Hutchings <bhutchings at solarflare.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/emulex/benet/be_ethtool.c | 6 +-----
+ net/core/ethtool.c | 2 ++
+ 2 files changed, 3 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be_ethtool.c b/drivers/net/ethernet/emulex/benet/be_ethtool.c
+index 6db6b6a..802e5dd 100644
+--- a/drivers/net/ethernet/emulex/benet/be_ethtool.c
++++ b/drivers/net/ethernet/emulex/benet/be_ethtool.c
+@@ -716,12 +716,8 @@ static int
+ be_do_flash(struct net_device *netdev, struct ethtool_flash *efl)
+ {
+ struct be_adapter *adapter = netdev_priv(netdev);
+- char file_name[ETHTOOL_FLASH_MAX_FILENAME];
+
+- file_name[ETHTOOL_FLASH_MAX_FILENAME - 1] = 0;
+- strcpy(file_name, efl->data);
+-
+- return be_load_fw(adapter, file_name);
++ return be_load_fw(adapter, efl->data);
+ }
+
+ static int
+diff --git a/net/core/ethtool.c b/net/core/ethtool.c
+index 369b418..3f79db1 100644
+--- a/net/core/ethtool.c
++++ b/net/core/ethtool.c
+@@ -1190,6 +1190,8 @@ static noinline_for_stack int ethtool_flash_device(struct net_device *dev,
+ if (!dev->ethtool_ops->flash_device)
+ return -EOPNOTSUPP;
+
++ efl.data[ETHTOOL_FLASH_MAX_FILENAME - 1] = 0;
++
+ return dev->ethtool_ops->flash_device(dev, &efl);
+ }
+
+--
+1.7.10
+
Added: dists/sid/linux-2.6/debian/patches/features/all/be2net/0001-sweep-the-floors-and-convert-some-.get_drvinfo-routi.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/be2net/0001-sweep-the-floors-and-convert-some-.get_drvinfo-routi.patch Sun May 27 00:21:22 2012 (r19037)
@@ -0,0 +1,47 @@
+From: Rick Jones <rick.jones2 at hp.com>
+Date: Mon, 7 Nov 2011 13:29:27 +0000
+Subject: [PATCH 01/58] sweep the floors and convert some .get_drvinfo
+ routines to strlcpy
+
+commit 68aad78c5023b8aa82da99b47f9d8cf40e8ca453 upstream.
+
+Per the mention made by Ben Hutchings that strlcpy is now the preferred
+string copy routine for a .get_drvinfo routine, do a bit of floor
+sweeping and convert some of the as-yet unconverted ethernet drivers to
+it.
+
+Signed-off-by: Rick Jones <rick.jones2 at hp.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+[bwh: Restrict to drivers/net/ethernet/emulex/benet/]
+---
+ drivers/net/ethernet/emulex/benet/be_ethtool.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be_ethtool.c b/drivers/net/ethernet/emulex/benet/be_ethtool.c
+index bf8153e..1ad7a28 100644
+--- a/drivers/net/ethernet/emulex/benet/be_ethtool.c
++++ b/drivers/net/ethernet/emulex/benet/be_ethtool.c
+@@ -127,8 +127,8 @@ static void be_get_drvinfo(struct net_device *netdev,
+ memset(fw_on_flash, 0 , sizeof(fw_on_flash));
+ be_cmd_get_fw_ver(adapter, adapter->fw_ver, fw_on_flash);
+
+- strcpy(drvinfo->driver, DRV_NAME);
+- strcpy(drvinfo->version, DRV_VER);
++ strlcpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver));
++ strlcpy(drvinfo->version, DRV_VER, sizeof(drvinfo->version));
+ strncpy(drvinfo->fw_version, adapter->fw_ver, FW_VER_LEN);
+ if (memcmp(adapter->fw_ver, fw_on_flash, FW_VER_LEN) != 0) {
+ strcat(drvinfo->fw_version, " [");
+@@ -136,7 +136,8 @@ static void be_get_drvinfo(struct net_device *netdev,
+ strcat(drvinfo->fw_version, "]");
+ }
+
+- strcpy(drvinfo->bus_info, pci_name(adapter->pdev));
++ strlcpy(drvinfo->bus_info, pci_name(adapter->pdev),
++ sizeof(drvinfo->bus_info));
+ drvinfo->testinfo_len = 0;
+ drvinfo->regdump_len = 0;
+ drvinfo->eedump_len = 0;
+--
+1.7.10
+
Added: dists/sid/linux-2.6/debian/patches/features/all/be2net/0002-be2net-init-vf-_if_handle-vf_pmac_id-to-handle-failu.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/be2net/0002-be2net-init-vf-_if_handle-vf_pmac_id-to-handle-failu.patch Sun May 27 00:21:22 2012 (r19037)
@@ -0,0 +1,227 @@
+From: Sathya Perla <sathya.perla at emulex.com>
+Date: Thu, 10 Nov 2011 19:17:57 +0000
+Subject: [PATCH 02/58] be2net: init (vf)_if_handle/vf_pmac_id to handle
+ failure scenarios
+
+commit 30128031d71741ef7d0e32c345e3bf02aa8a0704 upstream.
+
+Initialize if_handle, vf_if_handle and vf_pmac_id with "-1" so that in
+failure cases when be_clear() is called, we can skip over
+if_destroy/pmac_del cmds if they have not been created.
+
+Signed-off-by: Sathya Perla <sathya.perla at emulex.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/emulex/benet/be.h | 8 ++--
+ drivers/net/ethernet/emulex/benet/be_cmds.c | 9 +++--
+ drivers/net/ethernet/emulex/benet/be_cmds.h | 4 +-
+ drivers/net/ethernet/emulex/benet/be_main.c | 55 +++++++++++++++------------
+ 4 files changed, 42 insertions(+), 34 deletions(-)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h
+index 644e8fe..4163980 100644
+--- a/drivers/net/ethernet/emulex/benet/be.h
++++ b/drivers/net/ethernet/emulex/benet/be.h
+@@ -289,14 +289,12 @@ struct be_drv_stats {
+
+ struct be_vf_cfg {
+ unsigned char vf_mac_addr[ETH_ALEN];
+- u32 vf_if_handle;
+- u32 vf_pmac_id;
++ int vf_if_handle;
++ int vf_pmac_id;
+ u16 vf_vlan_tag;
+ u32 vf_tx_rate;
+ };
+
+-#define BE_INVALID_PMAC_ID 0xffffffff
+-
+ struct be_adapter {
+ struct pci_dev *pdev;
+ struct net_device *netdev;
+@@ -347,7 +345,7 @@ struct be_adapter {
+
+ /* Ethtool knobs and info */
+ char fw_ver[FW_VER_LEN];
+- u32 if_handle; /* Used to configure filtering */
++ int if_handle; /* Used to configure filtering */
+ u32 pmac_id; /* MAC addr handle used by BE card */
+ u32 beacon_state; /* for set_phys_id */
+
+diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
+index 2c7b366..c5912c4 100644
+--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
++++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
+@@ -695,12 +695,15 @@ err:
+ }
+
+ /* Uses synchronous MCCQ */
+-int be_cmd_pmac_del(struct be_adapter *adapter, u32 if_id, u32 pmac_id, u32 dom)
++int be_cmd_pmac_del(struct be_adapter *adapter, u32 if_id, int pmac_id, u32 dom)
+ {
+ struct be_mcc_wrb *wrb;
+ struct be_cmd_req_pmac_del *req;
+ int status;
+
++ if (pmac_id == -1)
++ return 0;
++
+ spin_lock_bh(&adapter->mcc_lock);
+
+ wrb = wrb_from_mccq(adapter);
+@@ -1136,7 +1139,7 @@ err:
+ }
+
+ /* Uses MCCQ */
+-int be_cmd_if_destroy(struct be_adapter *adapter, u32 interface_id, u32 domain)
++int be_cmd_if_destroy(struct be_adapter *adapter, int interface_id, u32 domain)
+ {
+ struct be_mcc_wrb *wrb;
+ struct be_cmd_req_if_destroy *req;
+@@ -1145,7 +1148,7 @@ int be_cmd_if_destroy(struct be_adapter *adapter, u32 interface_id, u32 domain)
+ if (adapter->eeh_err)
+ return -EIO;
+
+- if (!interface_id)
++ if (interface_id == -1)
+ return 0;
+
+ spin_lock_bh(&adapter->mcc_lock);
+diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h
+index a35cd03..0818039 100644
+--- a/drivers/net/ethernet/emulex/benet/be_cmds.h
++++ b/drivers/net/ethernet/emulex/benet/be_cmds.h
+@@ -1417,11 +1417,11 @@ extern int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr,
+ extern int be_cmd_pmac_add(struct be_adapter *adapter, u8 *mac_addr,
+ u32 if_id, u32 *pmac_id, u32 domain);
+ extern int be_cmd_pmac_del(struct be_adapter *adapter, u32 if_id,
+- u32 pmac_id, u32 domain);
++ int pmac_id, u32 domain);
+ extern int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags,
+ u32 en_flags, u8 *mac, u32 *if_handle, u32 *pmac_id,
+ u32 domain);
+-extern int be_cmd_if_destroy(struct be_adapter *adapter, u32 if_handle,
++extern int be_cmd_if_destroy(struct be_adapter *adapter, int if_handle,
+ u32 domain);
+ extern int be_cmd_eq_create(struct be_adapter *adapter,
+ struct be_queue_info *eq, int eq_delay);
+diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
+index bf266a0..83d971d 100644
+--- a/drivers/net/ethernet/emulex/benet/be_main.c
++++ b/drivers/net/ethernet/emulex/benet/be_main.c
+@@ -848,15 +848,11 @@ static int be_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
+ if (!is_valid_ether_addr(mac) || (vf >= num_vfs))
+ return -EINVAL;
+
+- if (adapter->vf_cfg[vf].vf_pmac_id != BE_INVALID_PMAC_ID)
+- status = be_cmd_pmac_del(adapter,
+- adapter->vf_cfg[vf].vf_if_handle,
+- adapter->vf_cfg[vf].vf_pmac_id, vf + 1);
++ status = be_cmd_pmac_del(adapter, adapter->vf_cfg[vf].vf_if_handle,
++ adapter->vf_cfg[vf].vf_pmac_id, vf + 1);
+
+- status = be_cmd_pmac_add(adapter, mac,
+- adapter->vf_cfg[vf].vf_if_handle,
++ status = be_cmd_pmac_add(adapter, mac, adapter->vf_cfg[vf].vf_if_handle,
+ &adapter->vf_cfg[vf].vf_pmac_id, vf + 1);
+-
+ if (status)
+ dev_err(&adapter->pdev->dev, "MAC %pM set on VF %d Failed\n",
+ mac, vf);
+@@ -2488,17 +2484,13 @@ static void be_vf_clear(struct be_adapter *adapter)
+ {
+ u32 vf;
+
+- for (vf = 0; vf < num_vfs; vf++) {
+- if (adapter->vf_cfg[vf].vf_pmac_id != BE_INVALID_PMAC_ID)
+- be_cmd_pmac_del(adapter,
+- adapter->vf_cfg[vf].vf_if_handle,
+- adapter->vf_cfg[vf].vf_pmac_id, vf + 1);
+- }
++ for (vf = 0; vf < num_vfs; vf++)
++ be_cmd_pmac_del(adapter, adapter->vf_cfg[vf].vf_if_handle,
++ adapter->vf_cfg[vf].vf_pmac_id, vf + 1);
+
+ for (vf = 0; vf < num_vfs; vf++)
+- if (adapter->vf_cfg[vf].vf_if_handle)
+- be_cmd_if_destroy(adapter,
+- adapter->vf_cfg[vf].vf_if_handle, vf + 1);
++ be_cmd_if_destroy(adapter, adapter->vf_cfg[vf].vf_if_handle,
++ vf + 1);
+ }
+
+ static int be_clear(struct be_adapter *adapter)
+@@ -2511,22 +2503,30 @@ static int be_clear(struct be_adapter *adapter)
+ be_mcc_queues_destroy(adapter);
+ be_rx_queues_destroy(adapter);
+ be_tx_queues_destroy(adapter);
+- adapter->eq_next_idx = 0;
+-
+- adapter->be3_native = false;
+- adapter->promiscuous = false;
+
+ /* tell fw we're done with firing cmds */
+ be_cmd_fw_clean(adapter);
+ return 0;
+ }
+
++static void be_vf_setup_init(struct be_adapter *adapter)
++{
++ int vf;
++
++ for (vf = 0; vf < num_vfs; vf++) {
++ adapter->vf_cfg[vf].vf_if_handle = -1;
++ adapter->vf_cfg[vf].vf_pmac_id = -1;
++ }
++}
++
+ static int be_vf_setup(struct be_adapter *adapter)
+ {
+ u32 cap_flags, en_flags, vf;
+ u16 lnk_speed;
+ int status;
+
++ be_vf_setup_init(adapter);
++
+ cap_flags = en_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST;
+ for (vf = 0; vf < num_vfs; vf++) {
+ status = be_cmd_if_create(adapter, cap_flags, en_flags, NULL,
+@@ -2534,7 +2534,6 @@ static int be_vf_setup(struct be_adapter *adapter)
+ NULL, vf+1);
+ if (status)
+ goto err;
+- adapter->vf_cfg[vf].vf_pmac_id = BE_INVALID_PMAC_ID;
+ }
+
+ if (!lancer_chip(adapter)) {
+@@ -2555,6 +2554,16 @@ err:
+ return status;
+ }
+
++static void be_setup_init(struct be_adapter *adapter)
++{
++ adapter->vlan_prio_bmap = 0xff;
++ adapter->link_speed = -1;
++ adapter->if_handle = -1;
++ adapter->be3_native = false;
++ adapter->promiscuous = false;
++ adapter->eq_next_idx = 0;
++}
++
+ static int be_setup(struct be_adapter *adapter)
+ {
+ struct net_device *netdev = adapter->netdev;
+@@ -2563,9 +2572,7 @@ static int be_setup(struct be_adapter *adapter)
+ int status;
+ u8 mac[ETH_ALEN];
+
+- /* Allow all priorities by default. A GRP5 evt may modify this */
+- adapter->vlan_prio_bmap = 0xff;
+- adapter->link_speed = -1;
++ be_setup_init(adapter);
+
+ be_cmd_req_native_mode(adapter);
+
+--
+1.7.10
+
Added: dists/sid/linux-2.6/debian/patches/features/all/be2net/0003-be2net-stop-checking-the-UE-registers-after-an-EEH-e.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/be2net/0003-be2net-stop-checking-the-UE-registers-after-an-EEH-e.patch Sun May 27 00:21:22 2012 (r19037)
@@ -0,0 +1,40 @@
+From: Sathya Perla <sathya.perla at emulex.com>
+Date: Thu, 10 Nov 2011 19:17:58 +0000
+Subject: [PATCH 03/58] be2net: stop checking the UE registers after an EEH
+ error
+
+commit 72f02485626b3e71955e54d227ede1b54021d571 upstream.
+
+Signed-off-by: Sathya Perla <sathya.perla at emulex.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/emulex/benet/be_main.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
+index 83d971d..99da07f 100644
+--- a/drivers/net/ethernet/emulex/benet/be_main.c
++++ b/drivers/net/ethernet/emulex/benet/be_main.c
+@@ -1978,6 +1978,9 @@ void be_detect_dump_ue(struct be_adapter *adapter)
+ u32 sliport_status = 0, sliport_err1 = 0, sliport_err2 = 0;
+ u32 i;
+
++ if (adapter->eeh_err || adapter->ue_detected)
++ return;
++
+ if (lancer_chip(adapter)) {
+ sliport_status = ioread32(adapter->db + SLIPORT_STATUS_OFFSET);
+ if (sliport_status & SLIPORT_STATUS_ERR_MASK) {
+@@ -2039,8 +2042,7 @@ static void be_worker(struct work_struct *work)
+ struct be_rx_obj *rxo;
+ int i;
+
+- if (!adapter->ue_detected)
+- be_detect_dump_ue(adapter);
++ be_detect_dump_ue(adapter);
+
+ /* when interrupts are not yet enabled, just reap any pending
+ * mcc completions */
+--
+1.7.10
+
Added: dists/sid/linux-2.6/debian/patches/features/all/be2net/0004-be2net-don-t-log-more-than-one-error-on-detecting-EE.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/be2net/0004-be2net-don-t-log-more-than-one-error-on-detecting-EE.patch Sun May 27 00:21:22 2012 (r19037)
@@ -0,0 +1,73 @@
+From: Sathya Perla <sathya.perla at emulex.com>
+Date: Thu, 10 Nov 2011 19:17:59 +0000
+Subject: [PATCH 04/58] be2net: don't log more than one error on detecting
+ EEH/UE errors
+
+commit 434b3648e9a58600cea5f3a1a0a7a89048e4df61 upstream.
+
+Currently we're spamming error messages each time a FW cmd call is made
+while in EEH/UE error state. One log msg on error detection is enough.
+
+Signed-off-by: Sathya Perla <sathya.perla at emulex.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/emulex/benet/be_cmds.c | 15 +++------------
+ drivers/net/ethernet/emulex/benet/be_main.c | 3 ++-
+ 2 files changed, 5 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
+index c5912c4..94cd77c 100644
+--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
++++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
+@@ -31,11 +31,8 @@ static void be_mcc_notify(struct be_adapter *adapter)
+ struct be_queue_info *mccq = &adapter->mcc_obj.q;
+ u32 val = 0;
+
+- if (adapter->eeh_err) {
+- dev_info(&adapter->pdev->dev,
+- "Error in Card Detected! Cannot issue commands\n");
++ if (adapter->eeh_err)
+ return;
+- }
+
+ val |= mccq->id & DB_MCCQ_RING_ID_MASK;
+ val |= 1 << DB_MCCQ_NUM_POSTED_SHIFT;
+@@ -298,19 +295,13 @@ static int be_mbox_db_ready_wait(struct be_adapter *adapter, void __iomem *db)
+ int msecs = 0;
+ u32 ready;
+
+- if (adapter->eeh_err) {
+- dev_err(&adapter->pdev->dev,
+- "Error detected in card.Cannot issue commands\n");
++ if (adapter->eeh_err)
+ return -EIO;
+- }
+
+ do {
+ ready = ioread32(db);
+- if (ready == 0xffffffff) {
+- dev_err(&adapter->pdev->dev,
+- "pci slot disconnected\n");
++ if (ready == 0xffffffff)
+ return -1;
+- }
+
+ ready &= MPU_MAILBOX_DB_RDY_MASK;
+ if (ready)
+diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
+index 99da07f..0e97b6d 100644
+--- a/drivers/net/ethernet/emulex/benet/be_main.c
++++ b/drivers/net/ethernet/emulex/benet/be_main.c
+@@ -2007,7 +2007,8 @@ void be_detect_dump_ue(struct be_adapter *adapter)
+ sliport_status & SLIPORT_STATUS_ERR_MASK) {
+ adapter->ue_detected = true;
+ adapter->eeh_err = true;
+- dev_err(&adapter->pdev->dev, "UE Detected!!\n");
++ dev_err(&adapter->pdev->dev,
++ "Unrecoverable error in the card\n");
+ }
+
+ if (ue_lo) {
+--
+1.7.10
+
Added: dists/sid/linux-2.6/debian/patches/features/all/be2net/0005-be2net-stop-issuing-FW-cmds-if-any-cmd-times-out.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/be2net/0005-be2net-stop-issuing-FW-cmds-if-any-cmd-times-out.patch Sun May 27 00:21:22 2012 (r19037)
@@ -0,0 +1,158 @@
+From: Sathya Perla <sathya.perla at emulex.com>
+Date: Thu, 10 Nov 2011 19:18:00 +0000
+Subject: [PATCH 05/58] be2net: stop issuing FW cmds if any cmd times out
+
+commit 6589ade019dcab245d3bb847370f855b56cdf6ad upstream.
+
+A FW cmd timeout (with a sufficiently large timeout value in the
+order of tens of seconds) indicates an unresponsive FW. In this state
+issuing further cmds and waiting for a completion will only stall the process.
+
+Signed-off-by: Sathya Perla <sathya.perla at emulex.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/emulex/benet/be.h | 8 +++++++-
+ drivers/net/ethernet/emulex/benet/be_cmds.c | 29 ++++++++++-----------------
+ drivers/net/ethernet/emulex/benet/be_main.c | 2 ++
+ 3 files changed, 20 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h
+index 4163980..34f162d 100644
+--- a/drivers/net/ethernet/emulex/benet/be.h
++++ b/drivers/net/ethernet/emulex/benet/be.h
+@@ -350,6 +350,8 @@ struct be_adapter {
+ u32 beacon_state; /* for set_phys_id */
+
+ bool eeh_err;
++ bool ue_detected;
++ bool fw_timeout;
+ u32 port_num;
+ bool promiscuous;
+ bool wol;
+@@ -357,7 +359,6 @@ struct be_adapter {
+ u32 function_caps;
+ u32 rx_fc; /* Rx flow control */
+ u32 tx_fc; /* Tx flow control */
+- bool ue_detected;
+ bool stats_cmd_sent;
+ int link_speed;
+ u8 port_type;
+@@ -522,6 +523,11 @@ static inline bool be_multi_rxq(const struct be_adapter *adapter)
+ return adapter->num_rx_qs > 1;
+ }
+
++static inline bool be_error(struct be_adapter *adapter)
++{
++ return adapter->eeh_err || adapter->ue_detected || adapter->fw_timeout;
++}
++
+ extern void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm,
+ u16 num_popped);
+ extern void be_link_status_update(struct be_adapter *adapter, u32 link_status);
+diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
+index 94cd77c..ad3eef0 100644
+--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
++++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
+@@ -31,7 +31,7 @@ static void be_mcc_notify(struct be_adapter *adapter)
+ struct be_queue_info *mccq = &adapter->mcc_obj.q;
+ u32 val = 0;
+
+- if (adapter->eeh_err)
++ if (be_error(adapter))
+ return;
+
+ val |= mccq->id & DB_MCCQ_RING_ID_MASK;
+@@ -263,10 +263,10 @@ static int be_mcc_wait_compl(struct be_adapter *adapter)
+ int i, num, status = 0;
+ struct be_mcc_obj *mcc_obj = &adapter->mcc_obj;
+
+- if (adapter->eeh_err)
+- return -EIO;
+-
+ for (i = 0; i < mcc_timeout; i++) {
++ if (be_error(adapter))
++ return -EIO;
++
+ num = be_process_mcc(adapter, &status);
+ if (num)
+ be_cq_notify(adapter, mcc_obj->cq.id,
+@@ -277,7 +277,8 @@ static int be_mcc_wait_compl(struct be_adapter *adapter)
+ udelay(100);
+ }
+ if (i == mcc_timeout) {
+- dev_err(&adapter->pdev->dev, "mccq poll timed out\n");
++ dev_err(&adapter->pdev->dev, "FW not responding\n");
++ adapter->fw_timeout = true;
+ return -1;
+ }
+ return status;
+@@ -295,10 +296,10 @@ static int be_mbox_db_ready_wait(struct be_adapter *adapter, void __iomem *db)
+ int msecs = 0;
+ u32 ready;
+
+- if (adapter->eeh_err)
+- return -EIO;
+-
+ do {
++ if (be_error(adapter))
++ return -EIO;
++
+ ready = ioread32(db);
+ if (ready == 0xffffffff)
+ return -1;
+@@ -308,7 +309,8 @@ static int be_mbox_db_ready_wait(struct be_adapter *adapter, void __iomem *db)
+ break;
+
+ if (msecs > 4000) {
+- dev_err(&adapter->pdev->dev, "mbox poll timed out\n");
++ dev_err(&adapter->pdev->dev, "FW not responding\n");
++ adapter->fw_timeout = true;
+ be_detect_dump_ue(adapter);
+ return -1;
+ }
+@@ -546,9 +548,6 @@ int be_cmd_fw_clean(struct be_adapter *adapter)
+ u8 *wrb;
+ int status;
+
+- if (adapter->eeh_err)
+- return -EIO;
+-
+ if (mutex_lock_interruptible(&adapter->mbox_lock))
+ return -1;
+
+@@ -1012,9 +1011,6 @@ int be_cmd_q_destroy(struct be_adapter *adapter, struct be_queue_info *q,
+ u8 subsys = 0, opcode = 0;
+ int status;
+
+- if (adapter->eeh_err)
+- return -EIO;
+-
+ if (mutex_lock_interruptible(&adapter->mbox_lock))
+ return -1;
+
+@@ -1136,9 +1132,6 @@ int be_cmd_if_destroy(struct be_adapter *adapter, int interface_id, u32 domain)
+ struct be_cmd_req_if_destroy *req;
+ int status;
+
+- if (adapter->eeh_err)
+- return -EIO;
+-
+ if (interface_id == -1)
+ return 0;
+
+diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
+index 0e97b6d..ce20d64 100644
+--- a/drivers/net/ethernet/emulex/benet/be_main.c
++++ b/drivers/net/ethernet/emulex/benet/be_main.c
+@@ -3569,6 +3569,8 @@ static pci_ers_result_t be_eeh_reset(struct pci_dev *pdev)
+
+ dev_info(&adapter->pdev->dev, "EEH reset\n");
+ adapter->eeh_err = false;
++ adapter->ue_detected = false;
++ adapter->fw_timeout = false;
+
+ status = pci_enable_device(pdev);
+ if (status)
+--
+1.7.10
+
Added: dists/sid/linux-2.6/debian/patches/features/all/be2net/0006-be2net-Fix-TX-queue-create-for-Lancer.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/be2net/0006-be2net-Fix-TX-queue-create-for-Lancer.patch Sun May 27 00:21:22 2012 (r19037)
@@ -0,0 +1,99 @@
+From: Padmanabh Ratnakar <padmanabh.ratnakar at emulex.com>
+Date: Wed, 16 Nov 2011 02:02:23 +0000
+Subject: [PATCH 06/58] be2net: Fix TX queue create for Lancer
+
+commit 293c4a7d9b95d0beeb5df03c14bd35bc21f9e6f2 upstream.
+
+Lancer uses V1 version of TXQ create. This command needs interface
+id for TX queue creation. Rearrange code such that tx queue create
+is after interface create. As TXQ create is now called after MCC
+ring create use MCC instead of MBOX.
+
+Signed-off-by: Padmanabh Ratnakar <padmanabh.ratnakar at emulex.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/emulex/benet/be_cmds.c | 15 ++++++++++-----
+ drivers/net/ethernet/emulex/benet/be_main.c | 12 ++++++++----
+ 2 files changed, 18 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
+index ad3eef0..d35a214 100644
+--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
++++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
+@@ -916,10 +916,14 @@ int be_cmd_txq_create(struct be_adapter *adapter,
+ void *ctxt;
+ int status;
+
+- if (mutex_lock_interruptible(&adapter->mbox_lock))
+- return -1;
++ spin_lock_bh(&adapter->mcc_lock);
++
++ wrb = wrb_from_mccq(adapter);
++ if (!wrb) {
++ status = -EBUSY;
++ goto err;
++ }
+
+- wrb = wrb_from_mbox(adapter);
+ req = embedded_payload(wrb);
+ ctxt = &req->context;
+
+@@ -945,14 +949,15 @@ int be_cmd_txq_create(struct be_adapter *adapter,
+
+ be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
+
+- status = be_mbox_notify_wait(adapter);
++ status = be_mcc_notify_wait(adapter);
+ if (!status) {
+ struct be_cmd_resp_eth_tx_create *resp = embedded_payload(wrb);
+ txq->id = le16_to_cpu(resp->cid);
+ txq->created = true;
+ }
+
+- mutex_unlock(&adapter->mbox_lock);
++err:
++ spin_unlock_bh(&adapter->mcc_lock);
+
+ return status;
+ }
+diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
+index ce20d64..c982b51 100644
+--- a/drivers/net/ethernet/emulex/benet/be_main.c
++++ b/drivers/net/ethernet/emulex/benet/be_main.c
+@@ -1689,9 +1689,6 @@ static int be_tx_queues_create(struct be_adapter *adapter)
+ if (be_queue_alloc(adapter, q, TX_Q_LEN,
+ sizeof(struct be_eth_wrb)))
+ goto err;
+-
+- if (be_cmd_txq_create(adapter, q, cq))
+- goto err;
+ }
+ return 0;
+
+@@ -2572,8 +2569,9 @@ static int be_setup(struct be_adapter *adapter)
+ struct net_device *netdev = adapter->netdev;
+ u32 cap_flags, en_flags;
+ u32 tx_fc, rx_fc;
+- int status;
++ int status, i;
+ u8 mac[ETH_ALEN];
++ struct be_tx_obj *txo;
+
+ be_setup_init(adapter);
+
+@@ -2613,6 +2611,12 @@ static int be_setup(struct be_adapter *adapter)
+ if (status != 0)
+ goto err;
+
++ for_all_tx_queues(adapter, txo, i) {
++ status = be_cmd_txq_create(adapter, &txo->q, &txo->cq);
++ if (status)
++ goto err;
++ }
++
+ /* For BEx, the VF's permanent mac queried from card is incorrect.
+ * Query the mac configued by the PF using if_handle
+ */
+--
+1.7.10
+
Added: dists/sid/linux-2.6/debian/patches/features/all/be2net/0007-be2net-add-register-dump-feature-for-Lancer.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/be2net/0007-be2net-add-register-dump-feature-for-Lancer.patch Sun May 27 00:21:22 2012 (r19037)
@@ -0,0 +1,234 @@
+From: Padmanabh Ratnakar <padmanabh.ratnakar at emulex.com>
+Date: Wed, 16 Nov 2011 02:02:43 +0000
+Subject: [PATCH 07/58] be2net: add register dump feature for Lancer
+
+commit de49bd5a447887fa630c54bb2769102d50fbe40a upstream.
+
+Implement register dump using ethtool for Lancer.
+
+Signed-off-by: Padmanabh Ratnakar <padmanabh.ratnakar at emulex.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/emulex/benet/be_cmds.c | 47 +++++++++++++++
+ drivers/net/ethernet/emulex/benet/be_cmds.h | 34 +++++++++++
+ drivers/net/ethernet/emulex/benet/be_ethtool.c | 74 ++++++++++++++++++++++--
+ 3 files changed, 151 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
+index d35a214..1522065 100644
+--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
++++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
+@@ -1828,6 +1828,53 @@ err_unlock:
+ return status;
+ }
+
++int lancer_cmd_read_object(struct be_adapter *adapter, struct be_dma_mem *cmd,
++ u32 data_size, u32 data_offset, const char *obj_name,
++ u32 *data_read, u32 *eof, u8 *addn_status)
++{
++ struct be_mcc_wrb *wrb;
++ struct lancer_cmd_req_read_object *req;
++ struct lancer_cmd_resp_read_object *resp;
++ int status;
++
++ spin_lock_bh(&adapter->mcc_lock);
++
++ wrb = wrb_from_mccq(adapter);
++ if (!wrb) {
++ status = -EBUSY;
++ goto err_unlock;
++ }
++
++ req = embedded_payload(wrb);
++
++ be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
++ OPCODE_COMMON_READ_OBJECT,
++ sizeof(struct lancer_cmd_req_read_object), wrb,
++ NULL);
++
++ req->desired_read_len = cpu_to_le32(data_size);
++ req->read_offset = cpu_to_le32(data_offset);
++ strcpy(req->object_name, obj_name);
++ req->descriptor_count = cpu_to_le32(1);
++ req->buf_len = cpu_to_le32(data_size);
++ req->addr_low = cpu_to_le32((cmd->dma & 0xFFFFFFFF));
++ req->addr_high = cpu_to_le32(upper_32_bits(cmd->dma));
++
++ status = be_mcc_notify_wait(adapter);
++
++ resp = embedded_payload(wrb);
++ if (!status) {
++ *data_read = le32_to_cpu(resp->actual_read_len);
++ *eof = le32_to_cpu(resp->eof);
++ } else {
++ *addn_status = resp->additional_status;
++ }
++
++err_unlock:
++ spin_unlock_bh(&adapter->mcc_lock);
++ return status;
++}
++
+ int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd,
+ u32 flash_type, u32 flash_opcode, u32 buf_size)
+ {
+diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h
+index 0818039..2d3fe6a 100644
+--- a/drivers/net/ethernet/emulex/benet/be_cmds.h
++++ b/drivers/net/ethernet/emulex/benet/be_cmds.h
+@@ -189,6 +189,7 @@ struct be_mcc_mailbox {
+ #define OPCODE_COMMON_GET_PHY_DETAILS 102
+ #define OPCODE_COMMON_SET_DRIVER_FUNCTION_CAP 103
+ #define OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES 121
++#define OPCODE_COMMON_READ_OBJECT 171
+ #define OPCODE_COMMON_WRITE_OBJECT 172
+
+ #define OPCODE_ETH_RSS_CONFIG 1
+@@ -1161,6 +1162,36 @@ struct lancer_cmd_resp_write_object {
+ u32 actual_write_len;
+ };
+
++/************************ Lancer Read FW info **************/
++#define LANCER_READ_FILE_CHUNK (32*1024)
++#define LANCER_READ_FILE_EOF_MASK 0x80000000
++
++#define LANCER_FW_DUMP_FILE "/dbg/dump.bin"
++
++struct lancer_cmd_req_read_object {
++ struct be_cmd_req_hdr hdr;
++ u32 desired_read_len;
++ u32 read_offset;
++ u8 object_name[104];
++ u32 descriptor_count;
++ u32 buf_len;
++ u32 addr_low;
++ u32 addr_high;
++};
++
++struct lancer_cmd_resp_read_object {
++ u8 opcode;
++ u8 subsystem;
++ u8 rsvd1[2];
++ u8 status;
++ u8 additional_status;
++ u8 rsvd2[2];
++ u32 resp_len;
++ u32 actual_resp_len;
++ u32 actual_read_len;
++ u32 eof;
++};
++
+ /************************ WOL *******************************/
+ struct be_cmd_req_acpi_wol_magic_config{
+ struct be_cmd_req_hdr hdr;
+@@ -1480,6 +1511,9 @@ extern int lancer_cmd_write_object(struct be_adapter *adapter,
+ u32 data_size, u32 data_offset,
+ const char *obj_name,
+ u32 *data_written, u8 *addn_status);
++int lancer_cmd_read_object(struct be_adapter *adapter, struct be_dma_mem *cmd,
++ u32 data_size, u32 data_offset, const char *obj_name,
++ u32 *data_read, u32 *eof, u8 *addn_status);
+ int be_cmd_get_flash_crc(struct be_adapter *adapter, u8 *flashed_crc,
+ int offset);
+ extern int be_cmd_enable_magic_wol(struct be_adapter *adapter, u8 *mac,
+diff --git a/drivers/net/ethernet/emulex/benet/be_ethtool.c b/drivers/net/ethernet/emulex/benet/be_ethtool.c
+index 1ad7a28..1e7252e 100644
+--- a/drivers/net/ethernet/emulex/benet/be_ethtool.c
++++ b/drivers/net/ethernet/emulex/benet/be_ethtool.c
+@@ -143,15 +143,77 @@ static void be_get_drvinfo(struct net_device *netdev,
+ drvinfo->eedump_len = 0;
+ }
+
++static u32
++lancer_cmd_get_file_len(struct be_adapter *adapter, u8 *file_name)
++{
++ u32 data_read = 0, eof;
++ u8 addn_status;
++ struct be_dma_mem data_len_cmd;
++ int status;
++
++ memset(&data_len_cmd, 0, sizeof(data_len_cmd));
++ /* data_offset and data_size should be 0 to get reg len */
++ status = lancer_cmd_read_object(adapter, &data_len_cmd, 0, 0,
++ file_name, &data_read, &eof, &addn_status);
++
++ return data_read;
++}
++
++static int
++lancer_cmd_read_file(struct be_adapter *adapter, u8 *file_name,
++ u32 buf_len, void *buf)
++{
++ struct be_dma_mem read_cmd;
++ u32 read_len = 0, total_read_len = 0, chunk_size;
++ u32 eof = 0;
++ u8 addn_status;
++ int status = 0;
++
++ read_cmd.size = LANCER_READ_FILE_CHUNK;
++ read_cmd.va = pci_alloc_consistent(adapter->pdev, read_cmd.size,
++ &read_cmd.dma);
++
++ if (!read_cmd.va) {
++ dev_err(&adapter->pdev->dev,
++ "Memory allocation failure while reading dump\n");
++ return -ENOMEM;
++ }
++
++ while ((total_read_len < buf_len) && !eof) {
++ chunk_size = min_t(u32, (buf_len - total_read_len),
++ LANCER_READ_FILE_CHUNK);
++ chunk_size = ALIGN(chunk_size, 4);
++ status = lancer_cmd_read_object(adapter, &read_cmd, chunk_size,
++ total_read_len, file_name, &read_len,
++ &eof, &addn_status);
++ if (!status) {
++ memcpy(buf + total_read_len, read_cmd.va, read_len);
++ total_read_len += read_len;
++ eof &= LANCER_READ_FILE_EOF_MASK;
++ } else {
++ status = -EIO;
++ break;
++ }
++ }
++ pci_free_consistent(adapter->pdev, read_cmd.size, read_cmd.va,
++ read_cmd.dma);
++
++ return status;
++}
++
+ static int
+ be_get_reg_len(struct net_device *netdev)
+ {
+ struct be_adapter *adapter = netdev_priv(netdev);
+ u32 log_size = 0;
+
+- if (be_physfn(adapter))
+- be_cmd_get_reg_len(adapter, &log_size);
+-
++ if (be_physfn(adapter)) {
++ if (lancer_chip(adapter))
++ log_size = lancer_cmd_get_file_len(adapter,
++ LANCER_FW_DUMP_FILE);
++ else
++ be_cmd_get_reg_len(adapter, &log_size);
++ }
+ return log_size;
+ }
+
+@@ -162,7 +224,11 @@ be_get_regs(struct net_device *netdev, struct ethtool_regs *regs, void *buf)
+
+ if (be_physfn(adapter)) {
+ memset(buf, 0, regs->len);
+- be_cmd_get_regs(adapter, regs->len, buf);
++ if (lancer_chip(adapter))
++ lancer_cmd_read_file(adapter, LANCER_FW_DUMP_FILE,
++ regs->len, buf);
++ else
++ be_cmd_get_regs(adapter, regs->len, buf);
+ }
+ }
+
+--
+1.7.10
+
Added: dists/sid/linux-2.6/debian/patches/features/all/be2net/0008-be2net-Add-EEPROM-dump-feature-for-Lancer.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/be2net/0008-be2net-Add-EEPROM-dump-feature-for-Lancer.patch Sun May 27 00:21:22 2012 (r19037)
@@ -0,0 +1,70 @@
+From: Padmanabh Ratnakar <padmanabh.ratnakar at emulex.com>
+Date: Wed, 16 Nov 2011 02:03:07 +0000
+Subject: [PATCH 08/58] be2net: Add EEPROM dump feature for Lancer
+
+commit af5875bdfed02a10a0c76bbd547753fea7979244 upstream.
+
+Implemented eeprom dump using ethtool feature for Lancer.
+
+Signed-off-by: Padmanabh Ratnakar <padmanabh.ratnakar at emulex.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/emulex/benet/be_cmds.h | 2 ++
+ drivers/net/ethernet/emulex/benet/be_ethtool.c | 21 ++++++++++++++++++++-
+ 2 files changed, 22 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h
+index 2d3fe6a..ac11246 100644
+--- a/drivers/net/ethernet/emulex/benet/be_cmds.h
++++ b/drivers/net/ethernet/emulex/benet/be_cmds.h
+@@ -1167,6 +1167,8 @@ struct lancer_cmd_resp_write_object {
+ #define LANCER_READ_FILE_EOF_MASK 0x80000000
+
+ #define LANCER_FW_DUMP_FILE "/dbg/dump.bin"
++#define LANCER_VPD_PF_FILE "/vpd/ntr_pf.vpd"
++#define LANCER_VPD_VF_FILE "/vpd/ntr_vf.vpd"
+
+ struct lancer_cmd_req_read_object {
+ struct be_cmd_req_hdr hdr;
+diff --git a/drivers/net/ethernet/emulex/benet/be_ethtool.c b/drivers/net/ethernet/emulex/benet/be_ethtool.c
+index 1e7252e..575c783 100644
+--- a/drivers/net/ethernet/emulex/benet/be_ethtool.c
++++ b/drivers/net/ethernet/emulex/benet/be_ethtool.c
+@@ -727,7 +727,17 @@ be_do_flash(struct net_device *netdev, struct ethtool_flash *efl)
+ static int
+ be_get_eeprom_len(struct net_device *netdev)
+ {
+- return BE_READ_SEEPROM_LEN;
++ struct be_adapter *adapter = netdev_priv(netdev);
++ if (lancer_chip(adapter)) {
++ if (be_physfn(adapter))
++ return lancer_cmd_get_file_len(adapter,
++ LANCER_VPD_PF_FILE);
++ else
++ return lancer_cmd_get_file_len(adapter,
++ LANCER_VPD_VF_FILE);
++ } else {
++ return BE_READ_SEEPROM_LEN;
++ }
+ }
+
+ static int
+@@ -742,6 +752,15 @@ be_read_eeprom(struct net_device *netdev, struct ethtool_eeprom *eeprom,
+ if (!eeprom->len)
+ return -EINVAL;
+
++ if (lancer_chip(adapter)) {
++ if (be_physfn(adapter))
++ return lancer_cmd_read_file(adapter, LANCER_VPD_PF_FILE,
++ eeprom->len, data);
++ else
++ return lancer_cmd_read_file(adapter, LANCER_VPD_VF_FILE,
++ eeprom->len, data);
++ }
++
+ eeprom->magic = BE_VENDOR_ID | (adapter->pdev->device<<16);
+
+ memset(&eeprom_cmd, 0, sizeof(struct be_dma_mem));
+--
+1.7.10
+
Added: dists/sid/linux-2.6/debian/patches/features/all/be2net/0009-be2net-Fix-VLAN-promiscous-mode-for-Lancer.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/be2net/0009-be2net-Fix-VLAN-promiscous-mode-for-Lancer.patch Sun May 27 00:21:22 2012 (r19037)
@@ -0,0 +1,33 @@
+From: Padmanabh Ratnakar <padmanabh.ratnakar at emulex.com>
+Date: Wed, 16 Nov 2011 02:03:32 +0000
+Subject: [PATCH 09/58] be2net: Fix VLAN promiscous mode for Lancer
+
+commit 5d5adb93d0efca8b47cc3e649a41ba650ff3d270 upstream.
+
+To enable VLAN promiscous mode, the HW interface should be created
+with VLAN promiscous capability in Lancer. Add this capability during
+creation of the HW interface.
+
+Signed-off-by: Padmanabh Ratnakar <padmanabh.ratnakar at emulex.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/emulex/benet/be_main.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
+index c982b51..93869d4 100644
+--- a/drivers/net/ethernet/emulex/benet/be_main.c
++++ b/drivers/net/ethernet/emulex/benet/be_main.c
+@@ -2600,7 +2600,8 @@ static int be_setup(struct be_adapter *adapter)
+ en_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST |
+ BE_IF_FLAGS_MULTICAST | BE_IF_FLAGS_PASS_L3L4_ERRORS;
+ cap_flags = en_flags | BE_IF_FLAGS_MCAST_PROMISCUOUS |
+- BE_IF_FLAGS_PROMISCUOUS;
++ BE_IF_FLAGS_VLAN_PROMISCUOUS | BE_IF_FLAGS_PROMISCUOUS;
++
+ if (adapter->function_caps & BE_FUNCTION_CAPS_RSS) {
+ cap_flags |= BE_IF_FLAGS_RSS;
+ en_flags |= BE_IF_FLAGS_RSS;
+--
+1.7.10
+
Added: dists/sid/linux-2.6/debian/patches/features/all/be2net/0010-be2net-Use-V1-query-link-status-command-for-lancer.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/be2net/0010-be2net-Use-V1-query-link-status-command-for-lancer.patch Sun May 27 00:21:22 2012 (r19037)
@@ -0,0 +1,31 @@
+From: Padmanabh Ratnakar <padmanabh.ratnakar at emulex.com>
+Date: Wed, 16 Nov 2011 02:03:45 +0000
+Subject: [PATCH 10/58] be2net: Use V1 query link status command for lancer
+
+commit daad6167d97b43cfc448cfe698784730b53ed3d6 upstream.
+
+Use V1 version of query link status command for Lancer.
+
+Signed-off-by: Padmanabh Ratnakar <padmanabh.ratnakar at emulex.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/emulex/benet/be_cmds.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
+index 1522065..64f0c1a 100644
+--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
++++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
+@@ -1246,6 +1246,9 @@ int be_cmd_link_status_query(struct be_adapter *adapter, u8 *mac_speed,
+ }
+ req = embedded_payload(wrb);
+
++ if (lancer_chip(adapter))
++ req->hdr.version = 1;
++
+ be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+ OPCODE_COMMON_NTWK_LINK_STATUS_QUERY, sizeof(*req), wrb, NULL);
+
+--
+1.7.10
+
Added: dists/sid/linux-2.6/debian/patches/features/all/be2net/0011-be2net-Move-to-new-SR-IOV-implementation-in-Lancer.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/be2net/0011-be2net-Move-to-new-SR-IOV-implementation-in-Lancer.patch Sun May 27 00:21:22 2012 (r19037)
@@ -0,0 +1,393 @@
+From: Padmanabh Ratnakar <padmanabh.ratnakar at emulex.com>
+Date: Fri, 25 Nov 2011 05:47:26 +0000
+Subject: [PATCH 11/58] be2net: Move to new SR-IOV implementation in Lancer
+
+commit 590c391dd362479b27a67c8d797ce348c5798b93 upstream.
+
+SR-IOV implementation is Lancer has changed in following ways -
+1)PF driver assigns one MAC addresses for VF using COMMON_SET_IFACE_MAC_LIST.
+2)VF driver queries its MAC address using COMMON_GET_IFACE_MAC_LIST command
+and assigns it to its interface.
+
+Signed-off-by: Mammatha Edhala <mammatha.edhala at emulex.com>
+Signed-off-by: Padmanabh Ratnakar <padmanabh.ratnakar at emulex.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/emulex/benet/be_cmds.c | 99 ++++++++++++++++++++++++++-
+ drivers/net/ethernet/emulex/benet/be_cmds.h | 37 +++++++++-
+ drivers/net/ethernet/emulex/benet/be_main.c | 89 +++++++++++++++++-------
+ 3 files changed, 200 insertions(+), 25 deletions(-)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
+index 64f0c1a..7988798 100644
+--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
++++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
+@@ -609,7 +609,7 @@ int be_cmd_eq_create(struct be_adapter *adapter,
+
+ /* Use MCC */
+ int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr,
+- u8 type, bool permanent, u32 if_handle)
++ u8 type, bool permanent, u32 if_handle, u32 pmac_id)
+ {
+ struct be_mcc_wrb *wrb;
+ struct be_cmd_req_mac_query *req;
+@@ -631,6 +631,7 @@ int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr,
+ req->permanent = 1;
+ } else {
+ req->if_id = cpu_to_le16((u16) if_handle);
++ req->pmac_id = cpu_to_le32(pmac_id);
+ req->permanent = 0;
+ }
+
+@@ -2280,3 +2281,99 @@ err:
+ mutex_unlock(&adapter->mbox_lock);
+ return status;
+ }
++
++/* Uses synchronous MCCQ */
++int be_cmd_get_mac_from_list(struct be_adapter *adapter, u32 domain,
++ u32 *pmac_id)
++{
++ struct be_mcc_wrb *wrb;
++ struct be_cmd_req_get_mac_list *req;
++ int status;
++ int mac_count;
++
++ spin_lock_bh(&adapter->mcc_lock);
++
++ wrb = wrb_from_mccq(adapter);
++ if (!wrb) {
++ status = -EBUSY;
++ goto err;
++ }
++ req = embedded_payload(wrb);
++
++ be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
++ OPCODE_COMMON_GET_MAC_LIST, sizeof(*req),
++ wrb, NULL);
++
++ req->hdr.domain = domain;
++
++ status = be_mcc_notify_wait(adapter);
++ if (!status) {
++ struct be_cmd_resp_get_mac_list *resp =
++ embedded_payload(wrb);
++ int i;
++ u8 *ctxt = &resp->context[0][0];
++ status = -EIO;
++ mac_count = resp->mac_count;
++ be_dws_le_to_cpu(&resp->context, sizeof(resp->context));
++ for (i = 0; i < mac_count; i++) {
++ if (!AMAP_GET_BITS(struct amap_get_mac_list_context,
++ act, ctxt)) {
++ *pmac_id = AMAP_GET_BITS
++ (struct amap_get_mac_list_context,
++ macid, ctxt);
++ status = 0;
++ break;
++ }
++ ctxt += sizeof(struct amap_get_mac_list_context) / 8;
++ }
++ }
++
++err:
++ spin_unlock_bh(&adapter->mcc_lock);
++ return status;
++}
++
++/* Uses synchronous MCCQ */
++int be_cmd_set_mac_list(struct be_adapter *adapter, u8 *mac_array,
++ u8 mac_count, u32 domain)
++{
++ struct be_mcc_wrb *wrb;
++ struct be_cmd_req_set_mac_list *req;
++ int status;
++ struct be_dma_mem cmd;
++
++ memset(&cmd, 0, sizeof(struct be_dma_mem));
++ cmd.size = sizeof(struct be_cmd_req_set_mac_list);
++ cmd.va = dma_alloc_coherent(&adapter->pdev->dev, cmd.size,
++ &cmd.dma, GFP_KERNEL);
++ if (!cmd.va) {
++ dev_err(&adapter->pdev->dev, "Memory alloc failure\n");
++ return -ENOMEM;
++ }
++
++ spin_lock_bh(&adapter->mcc_lock);
++
++ wrb = wrb_from_mccq(adapter);
++ if (!wrb) {
++ status = -EBUSY;
++ goto err;
++ }
++
++ req = cmd.va;
++ be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
++ OPCODE_COMMON_SET_MAC_LIST, sizeof(*req),
++ wrb, &cmd);
++
++ req->hdr.domain = domain;
++ req->mac_count = mac_count;
++ if (mac_count)
++ memcpy(req->mac, mac_array, ETH_ALEN*mac_count);
++
++ status = be_mcc_notify_wait(adapter);
++
++err:
++ dma_free_coherent(&adapter->pdev->dev, cmd.size,
++ cmd.va, cmd.dma);
++ spin_unlock_bh(&adapter->mcc_lock);
++ return status;
++}
+diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h
+index ac11246..0b694c6 100644
+--- a/drivers/net/ethernet/emulex/benet/be_cmds.h
++++ b/drivers/net/ethernet/emulex/benet/be_cmds.h
+@@ -189,6 +189,8 @@ struct be_mcc_mailbox {
+ #define OPCODE_COMMON_GET_PHY_DETAILS 102
+ #define OPCODE_COMMON_SET_DRIVER_FUNCTION_CAP 103
+ #define OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES 121
++#define OPCODE_COMMON_GET_MAC_LIST 147
++#define OPCODE_COMMON_SET_MAC_LIST 148
+ #define OPCODE_COMMON_READ_OBJECT 171
+ #define OPCODE_COMMON_WRITE_OBJECT 172
+
+@@ -295,6 +297,7 @@ struct be_cmd_req_mac_query {
+ u8 type;
+ u8 permanent;
+ u16 if_id;
++ u32 pmac_id;
+ } __packed;
+
+ struct be_cmd_resp_mac_query {
+@@ -1340,6 +1343,34 @@ struct be_cmd_resp_set_func_cap {
+ u8 rsvd[212];
+ };
+
++/******************** GET/SET_MACLIST **************************/
++#define BE_MAX_MAC 64
++struct amap_get_mac_list_context {
++ u8 macid[31];
++ u8 act;
++} __packed;
++
++struct be_cmd_req_get_mac_list {
++ struct be_cmd_req_hdr hdr;
++ u32 rsvd;
++} __packed;
++
++struct be_cmd_resp_get_mac_list {
++ struct be_cmd_resp_hdr hdr;
++ u8 mac_count;
++ u8 rsvd1;
++ u16 rsvd2;
++ u8 context[sizeof(struct amap_get_mac_list_context) / 8][BE_MAX_MAC];
++} __packed;
++
++struct be_cmd_req_set_mac_list {
++ struct be_cmd_req_hdr hdr;
++ u8 mac_count;
++ u8 rsvd1;
++ u16 rsvd2;
++ struct macaddr mac[BE_MAX_MAC];
++} __packed;
++
+ /*************** HW Stats Get v1 **********************************/
+ #define BE_TXP_SW_SZ 48
+ struct be_port_rxf_stats_v1 {
+@@ -1446,7 +1477,7 @@ static inline void *be_erx_stats_from_cmd(struct be_adapter *adapter)
+ extern int be_pci_fnum_get(struct be_adapter *adapter);
+ extern int be_cmd_POST(struct be_adapter *adapter);
+ extern int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr,
+- u8 type, bool permanent, u32 if_handle);
++ u8 type, bool permanent, u32 if_handle, u32 pmac_id);
+ extern int be_cmd_pmac_add(struct be_adapter *adapter, u8 *mac_addr,
+ u32 if_id, u32 *pmac_id, u32 domain);
+ extern int be_cmd_pmac_del(struct be_adapter *adapter, u32 if_id,
+@@ -1542,4 +1573,8 @@ extern int be_cmd_get_cntl_attributes(struct be_adapter *adapter);
+ extern int be_cmd_req_native_mode(struct be_adapter *adapter);
+ extern int be_cmd_get_reg_len(struct be_adapter *adapter, u32 *log_size);
+ extern void be_cmd_get_regs(struct be_adapter *adapter, u32 buf_len, void *buf);
++extern int be_cmd_get_mac_from_list(struct be_adapter *adapter, u32 domain,
++ u32 *pmac_id);
++extern int be_cmd_set_mac_list(struct be_adapter *adapter, u8 *mac_array,
++ u8 mac_count, u32 domain);
+
+diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
+index 93869d4..c6fb7c3 100644
+--- a/drivers/net/ethernet/emulex/benet/be_main.c
++++ b/drivers/net/ethernet/emulex/benet/be_main.c
+@@ -237,7 +237,8 @@ static int be_mac_addr_set(struct net_device *netdev, void *p)
+ return -EADDRNOTAVAIL;
+
+ status = be_cmd_mac_addr_query(adapter, current_mac,
+- MAC_ADDRESS_TYPE_NETWORK, false, adapter->if_handle);
++ MAC_ADDRESS_TYPE_NETWORK, false,
++ adapter->if_handle, 0);
+ if (status)
+ goto err;
+
+@@ -848,11 +849,18 @@ static int be_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
+ if (!is_valid_ether_addr(mac) || (vf >= num_vfs))
+ return -EINVAL;
+
+- status = be_cmd_pmac_del(adapter, adapter->vf_cfg[vf].vf_if_handle,
++ if (lancer_chip(adapter)) {
++ status = be_cmd_set_mac_list(adapter, mac, 1, vf + 1);
++ } else {
++ status = be_cmd_pmac_del(adapter,
++ adapter->vf_cfg[vf].vf_if_handle,
+ adapter->vf_cfg[vf].vf_pmac_id, vf + 1);
+
+- status = be_cmd_pmac_add(adapter, mac, adapter->vf_cfg[vf].vf_if_handle,
++ status = be_cmd_pmac_add(adapter, mac,
++ adapter->vf_cfg[vf].vf_if_handle,
+ &adapter->vf_cfg[vf].vf_pmac_id, vf + 1);
++ }
++
+ if (status)
+ dev_err(&adapter->pdev->dev, "MAC %pM set on VF %d Failed\n",
+ mac, vf);
+@@ -2465,13 +2473,18 @@ static inline int be_vf_eth_addr_config(struct be_adapter *adapter)
+ be_vf_eth_addr_generate(adapter, mac);
+
+ for (vf = 0; vf < num_vfs; vf++) {
+- status = be_cmd_pmac_add(adapter, mac,
++ if (lancer_chip(adapter)) {
++ status = be_cmd_set_mac_list(adapter, mac, 1, vf + 1);
++ } else {
++ status = be_cmd_pmac_add(adapter, mac,
+ adapter->vf_cfg[vf].vf_if_handle,
+ &adapter->vf_cfg[vf].vf_pmac_id,
+ vf + 1);
++ }
++
+ if (status)
+ dev_err(&adapter->pdev->dev,
+- "Mac address add failed for VF %d\n", vf);
++ "Mac address assignment failed for VF %d\n", vf);
+ else
+ memcpy(adapter->vf_cfg[vf].vf_mac_addr, mac, ETH_ALEN);
+
+@@ -2484,9 +2497,14 @@ static void be_vf_clear(struct be_adapter *adapter)
+ {
+ u32 vf;
+
+- for (vf = 0; vf < num_vfs; vf++)
+- be_cmd_pmac_del(adapter, adapter->vf_cfg[vf].vf_if_handle,
+- adapter->vf_cfg[vf].vf_pmac_id, vf + 1);
++ for (vf = 0; vf < num_vfs; vf++) {
++ if (lancer_chip(adapter))
++ be_cmd_set_mac_list(adapter, NULL, 0, vf + 1);
++ else
++ be_cmd_pmac_del(adapter,
++ adapter->vf_cfg[vf].vf_if_handle,
++ adapter->vf_cfg[vf].vf_pmac_id, vf + 1);
++ }
+
+ for (vf = 0; vf < num_vfs; vf++)
+ be_cmd_if_destroy(adapter, adapter->vf_cfg[vf].vf_if_handle,
+@@ -2527,7 +2545,9 @@ static int be_vf_setup(struct be_adapter *adapter)
+
+ be_vf_setup_init(adapter);
+
+- cap_flags = en_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST;
++ cap_flags = en_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST |
++ BE_IF_FLAGS_MULTICAST;
++
+ for (vf = 0; vf < num_vfs; vf++) {
+ status = be_cmd_if_create(adapter, cap_flags, en_flags, NULL,
+ &adapter->vf_cfg[vf].vf_if_handle,
+@@ -2536,11 +2556,9 @@ static int be_vf_setup(struct be_adapter *adapter)
+ goto err;
+ }
+
+- if (!lancer_chip(adapter)) {
+- status = be_vf_eth_addr_config(adapter);
+- if (status)
+- goto err;
+- }
++ status = be_vf_eth_addr_config(adapter);
++ if (status)
++ goto err;
+
+ for (vf = 0; vf < num_vfs; vf++) {
+ status = be_cmd_link_status_query(adapter, NULL, &lnk_speed,
+@@ -2564,6 +2582,23 @@ static void be_setup_init(struct be_adapter *adapter)
+ adapter->eq_next_idx = 0;
+ }
+
++static int be_configure_mac_from_list(struct be_adapter *adapter, u8 *mac)
++{
++ u32 pmac_id;
++ int status = be_cmd_get_mac_from_list(adapter, 0, &pmac_id);
++ if (status != 0)
++ goto do_none;
++ status = be_cmd_mac_addr_query(adapter, mac,
++ MAC_ADDRESS_TYPE_NETWORK,
++ false, adapter->if_handle, pmac_id);
++ if (status != 0)
++ goto do_none;
++ status = be_cmd_pmac_add(adapter, mac, adapter->if_handle,
++ &adapter->pmac_id, 0);
++do_none:
++ return status;
++}
++
+ static int be_setup(struct be_adapter *adapter)
+ {
+ struct net_device *netdev = adapter->netdev;
+@@ -2591,7 +2626,7 @@ static int be_setup(struct be_adapter *adapter)
+
+ memset(mac, 0, ETH_ALEN);
+ status = be_cmd_mac_addr_query(adapter, mac, MAC_ADDRESS_TYPE_NETWORK,
+- true /*permanent */, 0);
++ true /*permanent */, 0, 0);
+ if (status)
+ return status;
+ memcpy(adapter->netdev->dev_addr, mac, ETH_ALEN);
+@@ -2618,12 +2653,17 @@ static int be_setup(struct be_adapter *adapter)
+ goto err;
+ }
+
+- /* For BEx, the VF's permanent mac queried from card is incorrect.
+- * Query the mac configued by the PF using if_handle
+- */
+- if (!be_physfn(adapter) && !lancer_chip(adapter)) {
+- status = be_cmd_mac_addr_query(adapter, mac,
+- MAC_ADDRESS_TYPE_NETWORK, false, adapter->if_handle);
++ /* The VF's permanent mac queried from card is incorrect.
++ * For BEx: Query the mac configued by the PF using if_handle
++ * For Lancer: Get and use mac_list to obtain mac address.
++ */
++ if (!be_physfn(adapter)) {
++ if (lancer_chip(adapter))
++ status = be_configure_mac_from_list(adapter, mac);
++ else
++ status = be_cmd_mac_addr_query(adapter, mac,
++ MAC_ADDRESS_TYPE_NETWORK, false,
++ adapter->if_handle, 0);
+ if (!status) {
+ memcpy(adapter->netdev->dev_addr, mac, ETH_ALEN);
+ memcpy(adapter->netdev->perm_addr, mac, ETH_ALEN);
+@@ -2639,12 +2679,15 @@ static int be_setup(struct be_adapter *adapter)
+ be_set_rx_mode(adapter->netdev);
+
+ status = be_cmd_get_flow_control(adapter, &tx_fc, &rx_fc);
+- if (status)
++ /* For Lancer: It is legal for this cmd to fail on VF */
++ if (status && (be_physfn(adapter) || !lancer_chip(adapter)))
+ goto err;
++
+ if (rx_fc != adapter->rx_fc || tx_fc != adapter->tx_fc) {
+ status = be_cmd_set_flow_control(adapter, adapter->tx_fc,
+ adapter->rx_fc);
+- if (status)
++ /* For Lancer: It is legal for this cmd to fail on VF */
++ if (status && (be_physfn(adapter) || !lancer_chip(adapter)))
+ goto err;
+ }
+
+--
+1.7.10
+
Added: dists/sid/linux-2.6/debian/patches/features/all/be2net/0012-be2net-Fix-error-recovery-paths.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/be2net/0012-be2net-Fix-error-recovery-paths.patch Sun May 27 00:21:22 2012 (r19037)
@@ -0,0 +1,37 @@
+From: Padmanabh Ratnakar <padmanabh.ratnakar at emulex.com>
+Date: Fri, 25 Nov 2011 05:48:06 +0000
+Subject: [PATCH 12/58] be2net: Fix error recovery paths
+
+commit 3bb62f4f95ba004048bafb460179b5db33aff787 upstream.
+
+When TX queues are created again after error recovery,
+netif_set_real_num_tx_queues() is invoked to update number of real
+TX queues created. rtnl lock needs to be held when invoking this routine.
+
+Signed-off-by: Padmanabh Ratnakar <padmanabh.ratnakar at emulex.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/emulex/benet/be_main.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
+index c6fb7c3..a1b8ebc 100644
+--- a/drivers/net/ethernet/emulex/benet/be_main.c
++++ b/drivers/net/ethernet/emulex/benet/be_main.c
+@@ -1666,9 +1666,12 @@ static int be_tx_queues_create(struct be_adapter *adapter)
+ u8 i;
+
+ adapter->num_tx_qs = be_num_txqs_want(adapter);
+- if (adapter->num_tx_qs != MAX_TX_QS)
++ if (adapter->num_tx_qs != MAX_TX_QS) {
++ rtnl_lock();
+ netif_set_real_num_tx_queues(adapter->netdev,
+ adapter->num_tx_qs);
++ rtnl_unlock();
++ }
+
+ adapter->tx_eq.max_eqd = 0;
+ adapter->tx_eq.min_eqd = 0;
+--
+1.7.10
+
Added: dists/sid/linux-2.6/debian/patches/features/all/be2net/0013-be2net-Add-error-handling-for-Lancer.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/be2net/0013-be2net-Add-error-handling-for-Lancer.patch Sun May 27 00:21:22 2012 (r19037)
@@ -0,0 +1,212 @@
+From: Padmanabh Ratnakar <padmanabh.ratnakar at emulex.com>
+Date: Fri, 25 Nov 2011 05:48:23 +0000
+Subject: [PATCH 13/58] be2net: Add error handling for Lancer
+
+commit d8110f62c020ebc49108de57510a1482bfcbe86a upstream.
+
+Detect error in Lancer by polling a HW register and
+recover from this error if it is recoverable.
+
+Signed-off-by: Padmanabh Ratnakar <padmanabh.ratnakar at emulex.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/emulex/benet/be_main.c | 155 ++++++++++++++++++---------
+ 1 file changed, 106 insertions(+), 49 deletions(-)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
+index a1b8ebc..66429ea 100644
+--- a/drivers/net/ethernet/emulex/benet/be_main.c
++++ b/drivers/net/ethernet/emulex/benet/be_main.c
+@@ -2044,52 +2044,6 @@ void be_detect_dump_ue(struct be_adapter *adapter)
+ }
+ }
+
+-static void be_worker(struct work_struct *work)
+-{
+- struct be_adapter *adapter =
+- container_of(work, struct be_adapter, work.work);
+- struct be_rx_obj *rxo;
+- int i;
+-
+- be_detect_dump_ue(adapter);
+-
+- /* when interrupts are not yet enabled, just reap any pending
+- * mcc completions */
+- if (!netif_running(adapter->netdev)) {
+- int mcc_compl, status = 0;
+-
+- mcc_compl = be_process_mcc(adapter, &status);
+-
+- if (mcc_compl) {
+- struct be_mcc_obj *mcc_obj = &adapter->mcc_obj;
+- be_cq_notify(adapter, mcc_obj->cq.id, false, mcc_compl);
+- }
+-
+- goto reschedule;
+- }
+-
+- if (!adapter->stats_cmd_sent) {
+- if (lancer_chip(adapter))
+- lancer_cmd_get_pport_stats(adapter,
+- &adapter->stats_cmd);
+- else
+- be_cmd_get_stats(adapter, &adapter->stats_cmd);
+- }
+-
+- for_all_rx_queues(adapter, rxo, i) {
+- be_rx_eqd_update(adapter, rxo);
+-
+- if (rxo->rx_post_starved) {
+- rxo->rx_post_starved = false;
+- be_post_rx_frags(rxo, GFP_KERNEL);
+- }
+- }
+-
+-reschedule:
+- adapter->work_counter++;
+- schedule_delayed_work(&adapter->work, msecs_to_jiffies(1000));
+-}
+-
+ static void be_msix_disable(struct be_adapter *adapter)
+ {
+ if (msix_enabled(adapter)) {
+@@ -3328,7 +3282,7 @@ static int be_dev_family_check(struct be_adapter *adapter)
+
+ static int lancer_wait_ready(struct be_adapter *adapter)
+ {
+-#define SLIPORT_READY_TIMEOUT 500
++#define SLIPORT_READY_TIMEOUT 30
+ u32 sliport_status;
+ int status = 0, i;
+
+@@ -3337,7 +3291,7 @@ static int lancer_wait_ready(struct be_adapter *adapter)
+ if (sliport_status & SLIPORT_STATUS_RDY_MASK)
+ break;
+
+- msleep(20);
++ msleep(1000);
+ }
+
+ if (i == SLIPORT_READY_TIMEOUT)
+@@ -3374,6 +3328,104 @@ static int lancer_test_and_set_rdy_state(struct be_adapter *adapter)
+ return status;
+ }
+
++static void lancer_test_and_recover_fn_err(struct be_adapter *adapter)
++{
++ int status;
++ u32 sliport_status;
++
++ if (adapter->eeh_err || adapter->ue_detected)
++ return;
++
++ sliport_status = ioread32(adapter->db + SLIPORT_STATUS_OFFSET);
++
++ if (sliport_status & SLIPORT_STATUS_ERR_MASK) {
++ dev_err(&adapter->pdev->dev,
++ "Adapter in error state."
++ "Trying to recover.\n");
++
++ status = lancer_test_and_set_rdy_state(adapter);
++ if (status)
++ goto err;
++
++ netif_device_detach(adapter->netdev);
++
++ if (netif_running(adapter->netdev))
++ be_close(adapter->netdev);
++
++ be_clear(adapter);
++
++ adapter->fw_timeout = false;
++
++ status = be_setup(adapter);
++ if (status)
++ goto err;
++
++ if (netif_running(adapter->netdev)) {
++ status = be_open(adapter->netdev);
++ if (status)
++ goto err;
++ }
++
++ netif_device_attach(adapter->netdev);
++
++ dev_err(&adapter->pdev->dev,
++ "Adapter error recovery succeeded\n");
++ }
++ return;
++err:
++ dev_err(&adapter->pdev->dev,
++ "Adapter error recovery failed\n");
++}
++
++static void be_worker(struct work_struct *work)
++{
++ struct be_adapter *adapter =
++ container_of(work, struct be_adapter, work.work);
++ struct be_rx_obj *rxo;
++ int i;
++
++ if (lancer_chip(adapter))
++ lancer_test_and_recover_fn_err(adapter);
++
++ be_detect_dump_ue(adapter);
++
++ /* when interrupts are not yet enabled, just reap any pending
++ * mcc completions */
++ if (!netif_running(adapter->netdev)) {
++ int mcc_compl, status = 0;
++
++ mcc_compl = be_process_mcc(adapter, &status);
++
++ if (mcc_compl) {
++ struct be_mcc_obj *mcc_obj = &adapter->mcc_obj;
++ be_cq_notify(adapter, mcc_obj->cq.id, false, mcc_compl);
++ }
++
++ goto reschedule;
++ }
++
++ if (!adapter->stats_cmd_sent) {
++ if (lancer_chip(adapter))
++ lancer_cmd_get_pport_stats(adapter,
++ &adapter->stats_cmd);
++ else
++ be_cmd_get_stats(adapter, &adapter->stats_cmd);
++ }
++
++ for_all_rx_queues(adapter, rxo, i) {
++ be_rx_eqd_update(adapter, rxo);
++
++ if (rxo->rx_post_starved) {
++ rxo->rx_post_starved = false;
++ be_post_rx_frags(rxo, GFP_KERNEL);
++ }
++ }
++
++reschedule:
++ adapter->work_counter++;
++ schedule_delayed_work(&adapter->work, msecs_to_jiffies(1000));
++}
++
+ static int __devinit be_probe(struct pci_dev *pdev,
+ const struct pci_device_id *pdev_id)
+ {
+@@ -3426,7 +3478,12 @@ static int __devinit be_probe(struct pci_dev *pdev,
+ goto disable_sriov;
+
+ if (lancer_chip(adapter)) {
+- status = lancer_test_and_set_rdy_state(adapter);
++ status = lancer_wait_ready(adapter);
++ if (!status) {
++ iowrite32(SLI_PORT_CONTROL_IP_MASK,
++ adapter->db + SLIPORT_CONTROL_OFFSET);
++ status = lancer_test_and_set_rdy_state(adapter);
++ }
+ if (status) {
+ dev_err(&pdev->dev, "Adapter in non recoverable error\n");
+ goto ctrl_clean;
+--
+1.7.10
+
Added: dists/sid/linux-2.6/debian/patches/features/all/be2net/0014-be2net-Use-new-hash-key.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/be2net/0014-be2net-Use-new-hash-key.patch Sun May 27 00:21:22 2012 (r19037)
@@ -0,0 +1,34 @@
+From: Padmanabh Ratnakar <padmanabh.ratnakar at emulex.com>
+Date: Fri, 25 Nov 2011 05:48:38 +0000
+Subject: [PATCH 14/58] be2net: Use new hash key
+
+commit 65f8584e253f4676c8b39e976a10e918ec984b7c upstream.
+
+This new hash key gives better distribution of packets across RX
+queues.
+
+Signed-off-by: Padmanabh Ratnakar <padmanabh.ratnakar at emulex.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/emulex/benet/be_cmds.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
+index 7988798..62868ea 100644
+--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
++++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
+@@ -1669,8 +1669,9 @@ int be_cmd_rss_config(struct be_adapter *adapter, u8 *rsstable, u16 table_size)
+ {
+ struct be_mcc_wrb *wrb;
+ struct be_cmd_req_rss_config *req;
+- u32 myhash[10] = {0x0123, 0x4567, 0x89AB, 0xCDEF, 0x01EF,
+- 0x0123, 0x4567, 0x89AB, 0xCDEF, 0x01EF};
++ u32 myhash[10] = {0x15d43fa5, 0x2534685a, 0x5f87693a, 0x5668494e,
++ 0x33cf6a53, 0x383334c6, 0x76ac4257, 0x59b242b2,
++ 0x3ea83c02, 0x4a110304};
+ int status;
+
+ if (mutex_lock_interruptible(&adapter->mbox_lock))
+--
+1.7.10
+
Added: dists/sid/linux-2.6/debian/patches/features/all/be2net/0015-be2net-Fix-non-utilization-of-RX-queues.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/be2net/0015-be2net-Fix-non-utilization-of-RX-queues.patch Sun May 27 00:21:22 2012 (r19037)
@@ -0,0 +1,54 @@
+From: Padmanabh Ratnakar <padmanabh.ratnakar at emulex.com>
+Date: Fri, 25 Nov 2011 05:48:53 +0000
+Subject: [PATCH 15/58] be2net: Fix non utilization of RX queues
+
+commit e9008ee99c77207b2f6aee67e5f849b1e1400a11 upstream.
+
+When non power of two MSIX vectors are given to driver, some RX queues
+are not utilized. Program RSS table in such a way that all queues
+are utilized.
+
+Signed-off-by: Padmanabh Ratnakar <padmanabh.ratnakar at emulex.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/emulex/benet/be_main.c | 16 ++++++++++------
+ 1 file changed, 10 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
+index 66429ea..7236280 100644
+--- a/drivers/net/ethernet/emulex/benet/be_main.c
++++ b/drivers/net/ethernet/emulex/benet/be_main.c
+@@ -2312,8 +2312,8 @@ static int be_close(struct net_device *netdev)
+ static int be_rx_queues_setup(struct be_adapter *adapter)
+ {
+ struct be_rx_obj *rxo;
+- int rc, i;
+- u8 rsstable[MAX_RSS_QS];
++ int rc, i, j;
++ u8 rsstable[128];
+
+ for_all_rx_queues(adapter, rxo, i) {
+ rc = be_cmd_rxq_create(adapter, &rxo->q, rxo->cq.id,
+@@ -2325,11 +2325,15 @@ static int be_rx_queues_setup(struct be_adapter *adapter)
+ }
+
+ if (be_multi_rxq(adapter)) {
+- for_all_rss_queues(adapter, rxo, i)
+- rsstable[i] = rxo->rss_id;
++ for (j = 0; j < 128; j += adapter->num_rx_qs - 1) {
++ for_all_rss_queues(adapter, rxo, i) {
++ if ((j + i) >= 128)
++ break;
++ rsstable[j + i] = rxo->rss_id;
++ }
++ }
++ rc = be_cmd_rss_config(adapter, rsstable, 128);
+
+- rc = be_cmd_rss_config(adapter, rsstable,
+- adapter->num_rx_qs - 1);
+ if (rc)
+ return rc;
+ }
+--
+1.7.10
+
Added: dists/sid/linux-2.6/debian/patches/features/all/be2net/0016-be2net-netpoll-support.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/be2net/0016-be2net-netpoll-support.patch Sun May 27 00:21:22 2012 (r19037)
@@ -0,0 +1,53 @@
+From: Ivan Vecera <ivecera at redhat.com>
+Date: Thu, 8 Dec 2011 01:31:21 +0000
+Subject: [PATCH 16/58] be2net: netpoll support
+
+commit 6626873980475f303367f7b709f4703b571cf854 upstream.
+
+Add missing netpoll support.
+
+Signed-off-by: Ivan Vecera <ivecera at redhat.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/emulex/benet/be_main.c | 18 +++++++++++++++++-
+ 1 file changed, 17 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
+index 7236280..3854fb0 100644
+--- a/drivers/net/ethernet/emulex/benet/be_main.c
++++ b/drivers/net/ethernet/emulex/benet/be_main.c
+@@ -2666,6 +2666,19 @@ err:
+ return status;
+ }
+
++#ifdef CONFIG_NET_POLL_CONTROLLER
++static void be_netpoll(struct net_device *netdev)
++{
++ struct be_adapter *adapter = netdev_priv(netdev);
++ struct be_rx_obj *rxo;
++ int i;
++
++ event_handle(adapter, &adapter->tx_eq, false);
++ for_all_rx_queues(adapter, rxo, i)
++ event_handle(adapter, &rxo->rx_eq, true);
++}
++#endif
++
+ #define FW_FILE_HDR_SIGN "ServerEngines Corp. "
+ static bool be_flash_redboot(struct be_adapter *adapter,
+ const u8 *p, u32 img_start, int image_size,
+@@ -3014,7 +3027,10 @@ static struct net_device_ops be_netdev_ops = {
+ .ndo_set_vf_mac = be_set_vf_mac,
+ .ndo_set_vf_vlan = be_set_vf_vlan,
+ .ndo_set_vf_tx_rate = be_set_vf_tx_rate,
+- .ndo_get_vf_config = be_get_vf_config
++ .ndo_get_vf_config = be_get_vf_config,
++#ifdef CONFIG_NET_POLL_CONTROLLER
++ .ndo_poll_controller = be_netpoll,
++#endif
+ };
+
+ static void be_netdev_init(struct net_device *netdev)
+--
+1.7.10
+
Added: dists/sid/linux-2.6/debian/patches/features/all/be2net/0017-be2net-update-some-counters-to-display-via-ethtool.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/be2net/0017-be2net-update-some-counters-to-display-via-ethtool.patch Sun May 27 00:21:22 2012 (r19037)
@@ -0,0 +1,30 @@
+From: Ajit Khaparde <ajit.khaparde at emulex.com>
+Date: Fri, 9 Dec 2011 13:53:09 +0000
+Subject: [PATCH 17/58] be2net: update some counters to display via ethtool
+
+commit 02fe7027961969a052fbbe453304f329d4e9735a upstream.
+
+update pmem_fifo_overflow_drop, rx_priority_pause_frames counters.
+
+Signed-off-by: Ajit Khaparde <ajit.khaparde at emulex.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/emulex/benet/be_main.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
+index 3854fb0..0da3df0 100644
+--- a/drivers/net/ethernet/emulex/benet/be_main.c
++++ b/drivers/net/ethernet/emulex/benet/be_main.c
+@@ -316,6 +316,8 @@ static void populate_be3_stats(struct be_adapter *adapter)
+ struct be_drv_stats *drvs = &adapter->drv_stats;
+
+ be_dws_le_to_cpu(hw_stats, sizeof(*hw_stats));
++ drvs->pmem_fifo_overflow_drop = port_stats->pmem_fifo_overflow_drop;
++ drvs->rx_priority_pause_frames = port_stats->rx_priority_pause_frames;
+ drvs->rx_pause_frames = port_stats->rx_pause_frames;
+ drvs->rx_crc_errors = port_stats->rx_crc_errors;
+ drvs->rx_control_frames = port_stats->rx_control_frames;
+--
+1.7.10
+
Added: dists/sid/linux-2.6/debian/patches/features/all/be2net/0018-be2net-workaround-to-fix-a-bug-in-BE.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/be2net/0018-be2net-workaround-to-fix-a-bug-in-BE.patch Sun May 27 00:21:22 2012 (r19037)
@@ -0,0 +1,98 @@
+From: Ajit Khaparde <ajit.khaparde at emulex.com>
+Date: Fri, 9 Dec 2011 13:53:17 +0000
+Subject: [PATCH 18/58] be2net: workaround to fix a bug in BE
+
+commit 1ded132d4c3442aa3a619c94c245d7b5e0eb9731 upstream.
+
+disable Tx vlan offloading in certain cases.
+
+Signed-off-by: Ajit Khaparde <ajit.khaparde at emulex.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/emulex/benet/be_main.c | 46 ++++++++++++++++++++++-----
+ 1 file changed, 38 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
+index 0da3df0..f180f49 100644
+--- a/drivers/net/ethernet/emulex/benet/be_main.c
++++ b/drivers/net/ethernet/emulex/benet/be_main.c
+@@ -552,11 +552,26 @@ static inline void wrb_fill(struct be_eth_wrb *wrb, u64 addr, int len)
+ wrb->frag_len = len & ETH_WRB_FRAG_LEN_MASK;
+ }
+
++static inline u16 be_get_tx_vlan_tag(struct be_adapter *adapter,
++ struct sk_buff *skb)
++{
++ u8 vlan_prio;
++ u16 vlan_tag;
++
++ vlan_tag = vlan_tx_tag_get(skb);
++ vlan_prio = (vlan_tag & VLAN_PRIO_MASK) >> VLAN_PRIO_SHIFT;
++ /* If vlan priority provided by OS is NOT in available bmap */
++ if (!(adapter->vlan_prio_bmap & (1 << vlan_prio)))
++ vlan_tag = (vlan_tag & ~VLAN_PRIO_MASK) |
++ adapter->recommended_prio;
++
++ return vlan_tag;
++}
++
+ static void wrb_fill_hdr(struct be_adapter *adapter, struct be_eth_hdr_wrb *hdr,
+ struct sk_buff *skb, u32 wrb_cnt, u32 len)
+ {
+- u8 vlan_prio = 0;
+- u16 vlan_tag = 0;
++ u16 vlan_tag;
+
+ memset(hdr, 0, sizeof(*hdr));
+
+@@ -587,12 +602,7 @@ static void wrb_fill_hdr(struct be_adapter *adapter, struct be_eth_hdr_wrb *hdr,
+
+ if (vlan_tx_tag_present(skb)) {
+ AMAP_SET_BITS(struct amap_eth_hdr_wrb, vlan, hdr, 1);
+- vlan_tag = vlan_tx_tag_get(skb);
+- vlan_prio = (vlan_tag & VLAN_PRIO_MASK) >> VLAN_PRIO_SHIFT;
+- /* If vlan priority provided by OS is NOT in available bmap */
+- if (!(adapter->vlan_prio_bmap & (1 << vlan_prio)))
+- vlan_tag = (vlan_tag & ~VLAN_PRIO_MASK) |
+- adapter->recommended_prio;
++ vlan_tag = be_get_tx_vlan_tag(adapter, skb);
+ AMAP_SET_BITS(struct amap_eth_hdr_wrb, vlan_tag, hdr, vlan_tag);
+ }
+
+@@ -695,6 +705,25 @@ static netdev_tx_t be_xmit(struct sk_buff *skb,
+ u32 start = txq->head;
+ bool dummy_wrb, stopped = false;
+
++ /* For vlan tagged pkts, BE
++ * 1) calculates checksum even when CSO is not requested
++ * 2) calculates checksum wrongly for padded pkt less than
++ * 60 bytes long.
++ * As a workaround disable TX vlan offloading in such cases.
++ */
++ if (unlikely(vlan_tx_tag_present(skb) &&
++ (skb->ip_summed != CHECKSUM_PARTIAL || skb->len <= 60))) {
++ skb = skb_share_check(skb, GFP_ATOMIC);
++ if (unlikely(!skb))
++ goto tx_drop;
++
++ skb = __vlan_put_tag(skb, be_get_tx_vlan_tag(adapter, skb));
++ if (unlikely(!skb))
++ goto tx_drop;
++
++ skb->vlan_tci = 0;
++ }
++
+ wrb_cnt = wrb_cnt_for_skb(adapter, skb, &dummy_wrb);
+
+ copied = make_tx_wrbs(adapter, txq, skb, wrb_cnt, dummy_wrb);
+@@ -722,6 +751,7 @@ static netdev_tx_t be_xmit(struct sk_buff *skb,
+ txq->head = start;
+ dev_kfree_skb_any(skb);
+ }
++tx_drop:
+ return NETDEV_TX_OK;
+ }
+
+--
+1.7.10
+
Added: dists/sid/linux-2.6/debian/patches/features/all/be2net/0019-be2net-fix-ethtool-ringparam-reporting.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/be2net/0019-be2net-fix-ethtool-ringparam-reporting.patch Sun May 27 00:21:22 2012 (r19037)
@@ -0,0 +1,46 @@
+From: Sathya Perla <sathya.perla at emulex.com>
+Date: Tue, 13 Dec 2011 00:58:49 +0000
+Subject: [PATCH 19/58] be2net: fix ethtool ringparam reporting
+
+commit 110b82bc6265a48c1a0bf198109bed325ed055e2 upstream.
+
+The ethtool "-g" option is supposed to report the max queue length and
+user modified queue length for RX and TX queues. be2net doesn't support
+user modification of queue lengths. So, the correct values for these
+would be the max numbers.
+be2net incorrectly reports the queue used values for these fields.
+
+Signed-off-by: Sathya Perla <sathya.perla at emulex.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/emulex/benet/be_ethtool.c | 11 ++++-------
+ 1 file changed, 4 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be_ethtool.c b/drivers/net/ethernet/emulex/benet/be_ethtool.c
+index 575c783..6ba2dc6 100644
+--- a/drivers/net/ethernet/emulex/benet/be_ethtool.c
++++ b/drivers/net/ethernet/emulex/benet/be_ethtool.c
+@@ -520,16 +520,13 @@ static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
+ return 0;
+ }
+
+-static void
+-be_get_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring)
++static void be_get_ringparam(struct net_device *netdev,
++ struct ethtool_ringparam *ring)
+ {
+ struct be_adapter *adapter = netdev_priv(netdev);
+
+- ring->rx_max_pending = adapter->rx_obj[0].q.len;
+- ring->tx_max_pending = adapter->tx_obj[0].q.len;
+-
+- ring->rx_pending = atomic_read(&adapter->rx_obj[0].q.used);
+- ring->tx_pending = atomic_read(&adapter->tx_obj[0].q.used);
++ ring->rx_max_pending = ring->rx_pending = adapter->rx_obj[0].q.len;
++ ring->tx_max_pending = ring->tx_pending = adapter->tx_obj[0].q.len;
+ }
+
+ static void
+--
+1.7.10
+
Added: dists/sid/linux-2.6/debian/patches/features/all/be2net/0020-be2net-refactor-cleanup-vf-configuration-code.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/be2net/0020-be2net-refactor-cleanup-vf-configuration-code.patch Sun May 27 00:21:22 2012 (r19037)
@@ -0,0 +1,416 @@
+From: Sathya Perla <sathya.perla at emulex.com>
+Date: Tue, 13 Dec 2011 00:58:50 +0000
+Subject: [PATCH 20/58] be2net: refactor/cleanup vf configuration code
+
+commit 11ac75ed1eb9d8f5ff067fa9a82ebf5075989281 upstream.
+
+- use adapter->num_vfs (and not the module param) to store the actual
+number of vfs created. Use the same variable to reflect SRIOV
+enable/disable state. So, drop the adapter->sriov_enabled field.
+
+- use for_all_vfs() macro in VF configuration code
+
+- drop the "vf_" prefix for the fields of be_vf_cfg; the prefix is
+redundant and removing it helps reduce line wrap
+
+Signed-off-by: Sathya Perla <sathya.perla at emulex.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/emulex/benet/be.h | 20 ++--
+ drivers/net/ethernet/emulex/benet/be_main.c | 137 +++++++++++++--------------
+ 2 files changed, 80 insertions(+), 77 deletions(-)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h
+index 34f162d..a3588fb 100644
+--- a/drivers/net/ethernet/emulex/benet/be.h
++++ b/drivers/net/ethernet/emulex/benet/be.h
+@@ -288,11 +288,11 @@ struct be_drv_stats {
+ };
+
+ struct be_vf_cfg {
+- unsigned char vf_mac_addr[ETH_ALEN];
+- int vf_if_handle;
+- int vf_pmac_id;
+- u16 vf_vlan_tag;
+- u32 vf_tx_rate;
++ unsigned char mac_addr[ETH_ALEN];
++ int if_handle;
++ int pmac_id;
++ u16 vlan_tag;
++ u32 tx_rate;
+ };
+
+ struct be_adapter {
+@@ -368,16 +368,20 @@ struct be_adapter {
+ u32 flash_status;
+ struct completion flash_compl;
+
+- bool be3_native;
+- bool sriov_enabled;
+- struct be_vf_cfg *vf_cfg;
++ u32 num_vfs;
+ u8 is_virtfn;
++ struct be_vf_cfg *vf_cfg;
++ bool be3_native;
+ u32 sli_family;
+ u8 hba_port_num;
+ u16 pvid;
+ };
+
+ #define be_physfn(adapter) (!adapter->is_virtfn)
++#define sriov_enabled(adapter) (adapter->num_vfs > 0)
++#define for_all_vfs(adapter, vf_cfg, i) \
++ for (i = 0, vf_cfg = &adapter->vf_cfg[i]; i < adapter->num_vfs; \
++ i++, vf_cfg++)
+
+ /* BladeEngine Generation numbers */
+ #define BE_GEN2 2
+diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
+index f180f49..cf83b33 100644
+--- a/drivers/net/ethernet/emulex/benet/be_main.c
++++ b/drivers/net/ethernet/emulex/benet/be_main.c
+@@ -27,13 +27,14 @@ MODULE_DESCRIPTION(DRV_DESC " " DRV_VER);
+ MODULE_AUTHOR("ServerEngines Corporation");
+ MODULE_LICENSE("GPL");
+
+-static ushort rx_frag_size = 2048;
+ static unsigned int num_vfs;
+-module_param(rx_frag_size, ushort, S_IRUGO);
+ module_param(num_vfs, uint, S_IRUGO);
+-MODULE_PARM_DESC(rx_frag_size, "Size of a fragment that holds rcvd data.");
+ MODULE_PARM_DESC(num_vfs, "Number of PCI VFs to initialize");
+
++static ushort rx_frag_size = 2048;
++module_param(rx_frag_size, ushort, S_IRUGO);
++MODULE_PARM_DESC(rx_frag_size, "Size of a fragment that holds rcvd data.");
++
+ static DEFINE_PCI_DEVICE_TABLE(be_dev_ids) = {
+ { PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID1) },
+ { PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID2) },
+@@ -779,15 +780,15 @@ static int be_change_mtu(struct net_device *netdev, int new_mtu)
+ */
+ static int be_vid_config(struct be_adapter *adapter, bool vf, u32 vf_num)
+ {
++ struct be_vf_cfg *vf_cfg = &adapter->vf_cfg[vf_num];
+ u16 vtag[BE_NUM_VLANS_SUPPORTED];
+ u16 ntags = 0, i;
+ int status = 0;
+- u32 if_handle;
+
+ if (vf) {
+- if_handle = adapter->vf_cfg[vf_num].vf_if_handle;
+- vtag[0] = cpu_to_le16(adapter->vf_cfg[vf_num].vf_vlan_tag);
+- status = be_cmd_vlan_config(adapter, if_handle, vtag, 1, 1, 0);
++ vtag[0] = cpu_to_le16(vf_cfg->vlan_tag);
++ status = be_cmd_vlan_config(adapter, vf_cfg->if_handle, vtag,
++ 1, 1, 0);
+ }
+
+ /* No need to further configure vids if in promiscuous mode */
+@@ -873,31 +874,30 @@ done:
+ static int be_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
+ {
+ struct be_adapter *adapter = netdev_priv(netdev);
++ struct be_vf_cfg *vf_cfg = &adapter->vf_cfg[vf];
+ int status;
+
+- if (!adapter->sriov_enabled)
++ if (!sriov_enabled(adapter))
+ return -EPERM;
+
+- if (!is_valid_ether_addr(mac) || (vf >= num_vfs))
++ if (!is_valid_ether_addr(mac) || vf >= adapter->num_vfs)
+ return -EINVAL;
+
+ if (lancer_chip(adapter)) {
+ status = be_cmd_set_mac_list(adapter, mac, 1, vf + 1);
+ } else {
+- status = be_cmd_pmac_del(adapter,
+- adapter->vf_cfg[vf].vf_if_handle,
+- adapter->vf_cfg[vf].vf_pmac_id, vf + 1);
++ status = be_cmd_pmac_del(adapter, vf_cfg->if_handle,
++ vf_cfg->pmac_id, vf + 1);
+
+- status = be_cmd_pmac_add(adapter, mac,
+- adapter->vf_cfg[vf].vf_if_handle,
+- &adapter->vf_cfg[vf].vf_pmac_id, vf + 1);
++ status = be_cmd_pmac_add(adapter, mac, vf_cfg->if_handle,
++ &vf_cfg->pmac_id, vf + 1);
+ }
+
+ if (status)
+ dev_err(&adapter->pdev->dev, "MAC %pM set on VF %d Failed\n",
+ mac, vf);
+ else
+- memcpy(adapter->vf_cfg[vf].vf_mac_addr, mac, ETH_ALEN);
++ memcpy(vf_cfg->mac_addr, mac, ETH_ALEN);
+
+ return status;
+ }
+@@ -906,18 +906,19 @@ static int be_get_vf_config(struct net_device *netdev, int vf,
+ struct ifla_vf_info *vi)
+ {
+ struct be_adapter *adapter = netdev_priv(netdev);
++ struct be_vf_cfg *vf_cfg = &adapter->vf_cfg[vf];
+
+- if (!adapter->sriov_enabled)
++ if (!sriov_enabled(adapter))
+ return -EPERM;
+
+- if (vf >= num_vfs)
++ if (vf >= adapter->num_vfs)
+ return -EINVAL;
+
+ vi->vf = vf;
+- vi->tx_rate = adapter->vf_cfg[vf].vf_tx_rate;
+- vi->vlan = adapter->vf_cfg[vf].vf_vlan_tag;
++ vi->tx_rate = vf_cfg->tx_rate;
++ vi->vlan = vf_cfg->vlan_tag;
+ vi->qos = 0;
+- memcpy(&vi->mac, adapter->vf_cfg[vf].vf_mac_addr, ETH_ALEN);
++ memcpy(&vi->mac, vf_cfg->mac_addr, ETH_ALEN);
+
+ return 0;
+ }
+@@ -928,17 +929,17 @@ static int be_set_vf_vlan(struct net_device *netdev,
+ struct be_adapter *adapter = netdev_priv(netdev);
+ int status = 0;
+
+- if (!adapter->sriov_enabled)
++ if (!sriov_enabled(adapter))
+ return -EPERM;
+
+- if ((vf >= num_vfs) || (vlan > 4095))
++ if (vf >= adapter->num_vfs || vlan > 4095)
+ return -EINVAL;
+
+ if (vlan) {
+- adapter->vf_cfg[vf].vf_vlan_tag = vlan;
++ adapter->vf_cfg[vf].vlan_tag = vlan;
+ adapter->vlans_added++;
+ } else {
+- adapter->vf_cfg[vf].vf_vlan_tag = 0;
++ adapter->vf_cfg[vf].vlan_tag = 0;
+ adapter->vlans_added--;
+ }
+
+@@ -956,16 +957,16 @@ static int be_set_vf_tx_rate(struct net_device *netdev,
+ struct be_adapter *adapter = netdev_priv(netdev);
+ int status = 0;
+
+- if (!adapter->sriov_enabled)
++ if (!sriov_enabled(adapter))
+ return -EPERM;
+
+- if ((vf >= num_vfs) || (rate < 0))
++ if (vf >= adapter->num_vfs || rate < 0)
+ return -EINVAL;
+
+ if (rate > 10000)
+ rate = 10000;
+
+- adapter->vf_cfg[vf].vf_tx_rate = rate;
++ adapter->vf_cfg[vf].tx_rate = rate;
+ status = be_cmd_set_qos(adapter, rate / 10, vf + 1);
+
+ if (status)
+@@ -1681,8 +1682,7 @@ static void be_tx_queues_destroy(struct be_adapter *adapter)
+
+ static int be_num_txqs_want(struct be_adapter *adapter)
+ {
+- if ((num_vfs && adapter->sriov_enabled) ||
+- be_is_mc(adapter) ||
++ if (sriov_enabled(adapter) || be_is_mc(adapter) ||
+ lancer_chip(adapter) || !be_physfn(adapter) ||
+ adapter->generation == BE_GEN2)
+ return 1;
+@@ -1764,8 +1764,8 @@ static void be_rx_queues_destroy(struct be_adapter *adapter)
+ static u32 be_num_rxqs_want(struct be_adapter *adapter)
+ {
+ if ((adapter->function_caps & BE_FUNCTION_CAPS_RSS) &&
+- !adapter->sriov_enabled && be_physfn(adapter) &&
+- !be_is_mc(adapter)) {
++ !sriov_enabled(adapter) && be_physfn(adapter) &&
++ !be_is_mc(adapter)) {
+ return 1 + MAX_RSS_QS; /* one default non-RSS queue */
+ } else {
+ dev_warn(&adapter->pdev->dev,
+@@ -2112,27 +2112,28 @@ done:
+ static int be_sriov_enable(struct be_adapter *adapter)
+ {
+ be_check_sriov_fn_type(adapter);
++
+ #ifdef CONFIG_PCI_IOV
+ if (be_physfn(adapter) && num_vfs) {
+ int status, pos;
+- u16 nvfs;
++ u16 dev_vfs;
+
+ pos = pci_find_ext_capability(adapter->pdev,
+ PCI_EXT_CAP_ID_SRIOV);
+ pci_read_config_word(adapter->pdev,
+- pos + PCI_SRIOV_TOTAL_VF, &nvfs);
++ pos + PCI_SRIOV_TOTAL_VF, &dev_vfs);
+
+- if (num_vfs > nvfs) {
++ adapter->num_vfs = min_t(u16, num_vfs, dev_vfs);
++ if (adapter->num_vfs != num_vfs)
+ dev_info(&adapter->pdev->dev,
+- "Device supports %d VFs and not %d\n",
+- nvfs, num_vfs);
+- num_vfs = nvfs;
+- }
++ "Device supports %d VFs and not %d\n",
++ adapter->num_vfs, num_vfs);
+
+- status = pci_enable_sriov(adapter->pdev, num_vfs);
+- adapter->sriov_enabled = status ? false : true;
++ status = pci_enable_sriov(adapter->pdev, adapter->num_vfs);
++ if (status)
++ adapter->num_vfs = 0;
+
+- if (adapter->sriov_enabled) {
++ if (adapter->num_vfs) {
+ adapter->vf_cfg = kcalloc(num_vfs,
+ sizeof(struct be_vf_cfg),
+ GFP_KERNEL);
+@@ -2147,10 +2148,10 @@ static int be_sriov_enable(struct be_adapter *adapter)
+ static void be_sriov_disable(struct be_adapter *adapter)
+ {
+ #ifdef CONFIG_PCI_IOV
+- if (adapter->sriov_enabled) {
++ if (sriov_enabled(adapter)) {
+ pci_disable_sriov(adapter->pdev);
+ kfree(adapter->vf_cfg);
+- adapter->sriov_enabled = false;
++ adapter->num_vfs = 0;
+ }
+ #endif
+ }
+@@ -2462,24 +2463,24 @@ static inline int be_vf_eth_addr_config(struct be_adapter *adapter)
+ u32 vf;
+ int status = 0;
+ u8 mac[ETH_ALEN];
++ struct be_vf_cfg *vf_cfg;
+
+ be_vf_eth_addr_generate(adapter, mac);
+
+- for (vf = 0; vf < num_vfs; vf++) {
++ for_all_vfs(adapter, vf_cfg, vf) {
+ if (lancer_chip(adapter)) {
+ status = be_cmd_set_mac_list(adapter, mac, 1, vf + 1);
+ } else {
+ status = be_cmd_pmac_add(adapter, mac,
+- adapter->vf_cfg[vf].vf_if_handle,
+- &adapter->vf_cfg[vf].vf_pmac_id,
+- vf + 1);
++ vf_cfg->if_handle,
++ &vf_cfg->pmac_id, vf + 1);
+ }
+
+ if (status)
+ dev_err(&adapter->pdev->dev,
+ "Mac address assignment failed for VF %d\n", vf);
+ else
+- memcpy(adapter->vf_cfg[vf].vf_mac_addr, mac, ETH_ALEN);
++ memcpy(vf_cfg->mac_addr, mac, ETH_ALEN);
+
+ mac[5] += 1;
+ }
+@@ -2488,25 +2489,23 @@ static inline int be_vf_eth_addr_config(struct be_adapter *adapter)
+
+ static void be_vf_clear(struct be_adapter *adapter)
+ {
++ struct be_vf_cfg *vf_cfg;
+ u32 vf;
+
+- for (vf = 0; vf < num_vfs; vf++) {
++ for_all_vfs(adapter, vf_cfg, vf) {
+ if (lancer_chip(adapter))
+ be_cmd_set_mac_list(adapter, NULL, 0, vf + 1);
+ else
+- be_cmd_pmac_del(adapter,
+- adapter->vf_cfg[vf].vf_if_handle,
+- adapter->vf_cfg[vf].vf_pmac_id, vf + 1);
+- }
++ be_cmd_pmac_del(adapter, vf_cfg->if_handle,
++ vf_cfg->pmac_id, vf + 1);
+
+- for (vf = 0; vf < num_vfs; vf++)
+- be_cmd_if_destroy(adapter, adapter->vf_cfg[vf].vf_if_handle,
+- vf + 1);
++ be_cmd_if_destroy(adapter, vf_cfg->if_handle, vf + 1);
++ }
+ }
+
+ static int be_clear(struct be_adapter *adapter)
+ {
+- if (be_physfn(adapter) && adapter->sriov_enabled)
++ if (sriov_enabled(adapter))
+ be_vf_clear(adapter);
+
+ be_cmd_if_destroy(adapter, adapter->if_handle, 0);
+@@ -2522,16 +2521,18 @@ static int be_clear(struct be_adapter *adapter)
+
+ static void be_vf_setup_init(struct be_adapter *adapter)
+ {
++ struct be_vf_cfg *vf_cfg;
+ int vf;
+
+- for (vf = 0; vf < num_vfs; vf++) {
+- adapter->vf_cfg[vf].vf_if_handle = -1;
+- adapter->vf_cfg[vf].vf_pmac_id = -1;
++ for_all_vfs(adapter, vf_cfg, vf) {
++ vf_cfg->if_handle = -1;
++ vf_cfg->pmac_id = -1;
+ }
+ }
+
+ static int be_vf_setup(struct be_adapter *adapter)
+ {
++ struct be_vf_cfg *vf_cfg;
+ u32 cap_flags, en_flags, vf;
+ u16 lnk_speed;
+ int status;
+@@ -2540,11 +2541,9 @@ static int be_vf_setup(struct be_adapter *adapter)
+
+ cap_flags = en_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST |
+ BE_IF_FLAGS_MULTICAST;
+-
+- for (vf = 0; vf < num_vfs; vf++) {
++ for_all_vfs(adapter, vf_cfg, vf) {
+ status = be_cmd_if_create(adapter, cap_flags, en_flags, NULL,
+- &adapter->vf_cfg[vf].vf_if_handle,
+- NULL, vf+1);
++ &vf_cfg->if_handle, NULL, vf + 1);
+ if (status)
+ goto err;
+ }
+@@ -2553,12 +2552,12 @@ static int be_vf_setup(struct be_adapter *adapter)
+ if (status)
+ goto err;
+
+- for (vf = 0; vf < num_vfs; vf++) {
++ for_all_vfs(adapter, vf_cfg, vf) {
+ status = be_cmd_link_status_query(adapter, NULL, &lnk_speed,
+- vf + 1);
++ vf + 1);
+ if (status)
+ goto err;
+- adapter->vf_cfg[vf].vf_tx_rate = lnk_speed * 10;
++ vf_cfg->tx_rate = lnk_speed * 10;
+ }
+ return 0;
+ err:
+@@ -2686,7 +2685,7 @@ static int be_setup(struct be_adapter *adapter)
+
+ pcie_set_readrq(adapter->pdev, 4096);
+
+- if (be_physfn(adapter) && adapter->sriov_enabled) {
++ if (sriov_enabled(adapter)) {
+ status = be_vf_setup(adapter);
+ if (status)
+ goto err;
+--
+1.7.10
+
Added: dists/sid/linux-2.6/debian/patches/features/all/be2net/0021-be2net-Add-support-for-Skyhawk-cards.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/be2net/0021-be2net-Add-support-for-Skyhawk-cards.patch Sun May 27 00:21:22 2012 (r19037)
@@ -0,0 +1,65 @@
+From: Ajit Khaparde <ajit.khaparde at emulex.com>
+Date: Thu, 15 Dec 2011 06:31:38 +0000
+Subject: [PATCH 21/58] be2net: Add support for Skyhawk cards
+
+commit ecedb6ae908e3a8a19942da921a3ffb1c5a0d6ab upstream.
+
+Signed-off-by: Ajit Khaparde <ajit.khaparde at emulex.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/emulex/benet/be.h | 4 ++++
+ drivers/net/ethernet/emulex/benet/be_main.c | 2 ++
+ 2 files changed, 6 insertions(+)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h
+index a3588fb..995198d 100644
+--- a/drivers/net/ethernet/emulex/benet/be.h
++++ b/drivers/net/ethernet/emulex/benet/be.h
+@@ -40,6 +40,7 @@
+ #define OC_NAME "Emulex OneConnect 10Gbps NIC"
+ #define OC_NAME_BE OC_NAME "(be3)"
+ #define OC_NAME_LANCER OC_NAME "(Lancer)"
++#define OC_NAME_SH OC_NAME "(Skyhawk)"
+ #define DRV_DESC "ServerEngines BladeEngine 10Gbps NIC Driver"
+
+ #define BE_VENDOR_ID 0x19a2
+@@ -50,6 +51,7 @@
+ #define OC_DEVICE_ID2 0x710 /* Device Id for BE3 cards */
+ #define OC_DEVICE_ID3 0xe220 /* Device id for Lancer cards */
+ #define OC_DEVICE_ID4 0xe228 /* Device id for VF in Lancer */
++#define OC_DEVICE_ID5 0x720 /* Device Id for Skyhawk cards */
+
+ static inline char *nic_name(struct pci_dev *pdev)
+ {
+@@ -63,6 +65,8 @@ static inline char *nic_name(struct pci_dev *pdev)
+ return OC_NAME_LANCER;
+ case BE_DEVICE_ID2:
+ return BE3_NAME;
++ case OC_DEVICE_ID5:
++ return OC_NAME_SH;
+ default:
+ return BE_NAME;
+ }
+diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
+index cf83b33..3ed2987 100644
+--- a/drivers/net/ethernet/emulex/benet/be_main.c
++++ b/drivers/net/ethernet/emulex/benet/be_main.c
+@@ -42,6 +42,7 @@ static DEFINE_PCI_DEVICE_TABLE(be_dev_ids) = {
+ { PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID2) },
+ { PCI_DEVICE(EMULEX_VENDOR_ID, OC_DEVICE_ID3)},
+ { PCI_DEVICE(EMULEX_VENDOR_ID, OC_DEVICE_ID4)},
++ { PCI_DEVICE(EMULEX_VENDOR_ID, OC_DEVICE_ID5)},
+ { 0 }
+ };
+ MODULE_DEVICE_TABLE(pci, be_dev_ids);
+@@ -3308,6 +3309,7 @@ static int be_dev_family_check(struct be_adapter *adapter)
+ break;
+ case BE_DEVICE_ID2:
+ case OC_DEVICE_ID2:
++ case OC_DEVICE_ID5:
+ adapter->generation = BE_GEN3;
+ break;
+ case OC_DEVICE_ID3:
+--
+1.7.10
+
Added: dists/sid/linux-2.6/debian/patches/features/all/be2net/0022-be2net-Fix-INTx-processing-for-Lancer.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/be2net/0022-be2net-Fix-INTx-processing-for-Lancer.patch Sun May 27 00:21:22 2012 (r19037)
@@ -0,0 +1,53 @@
+From: Padmanabh Ratnakar <padmanabh.ratnakar at emulex.com>
+Date: Mon, 19 Dec 2011 01:53:35 +0000
+Subject: [PATCH 22/58] be2net: Fix INTx processing for Lancer
+
+commit 93c86700c0ae3a1407b979073f423e62e29372c1 upstream.
+
+Lancer does not have HW registers to indicate the EQ causing the INTx
+interrupt. As a result EQE entries of one EQ may be consumed when interrupt
+is caused by another EQ. Fix this by arming CQs at the end of NAPI poll
+routine to regenerate the EQEs.
+
+Signed-off-by: Padmanabh Ratnakar <padmanabh.ratnakar at emulex.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/emulex/benet/be_main.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
+index 3ed2987..a185e61 100644
+--- a/drivers/net/ethernet/emulex/benet/be_main.c
++++ b/drivers/net/ethernet/emulex/benet/be_main.c
+@@ -1966,6 +1966,7 @@ static int be_poll_tx_mcc(struct napi_struct *napi, int budget)
+ struct be_eq_obj *tx_eq = container_of(napi, struct be_eq_obj, napi);
+ struct be_adapter *adapter =
+ container_of(tx_eq, struct be_adapter, tx_eq);
++ struct be_mcc_obj *mcc_obj = &adapter->mcc_obj;
+ struct be_tx_obj *txo;
+ struct be_eth_tx_compl *txcp;
+ int tx_compl, mcc_compl, status = 0;
+@@ -2002,12 +2003,19 @@ static int be_poll_tx_mcc(struct napi_struct *napi, int budget)
+ mcc_compl = be_process_mcc(adapter, &status);
+
+ if (mcc_compl) {
+- struct be_mcc_obj *mcc_obj = &adapter->mcc_obj;
+ be_cq_notify(adapter, mcc_obj->cq.id, true, mcc_compl);
+ }
+
+ napi_complete(napi);
+
++ /* Arm CQ again to regenerate EQEs for Lancer in INTx mode */
++ if (lancer_chip(adapter) && !msix_enabled(adapter)) {
++ for_all_tx_queues(adapter, txo, i)
++ be_cq_notify(adapter, txo->cq.id, true, 0);
++
++ be_cq_notify(adapter, mcc_obj->cq.id, true, 0);
++ }
++
+ be_eq_notify(adapter, tx_eq->q.id, true, false, 0);
+ adapter->drv_stats.tx_events++;
+ return 1;
+--
+1.7.10
+
Added: dists/sid/linux-2.6/debian/patches/features/all/be2net/0023-be2net-fix-be_vlan_add-rem_vid.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/be2net/0023-be2net-fix-be_vlan_add-rem_vid.patch Sun May 27 00:21:22 2012 (r19037)
@@ -0,0 +1,65 @@
+From: Ajit Khaparde <ajit.khaparde at emulex.com>
+Date: Fri, 25 May 2012 21:21:23 +0530
+Subject: [PATCH 23/58] be2net: fix be_vlan_add/rem_vid
+
+commit 80817cbf5ac13da76f3ee2b9259f26c09b385e84 upstream.
+
+1) fix be_vlan_add/rem_vid to return proper status
+2) perform appropriate housekeeping if firmware command succeeds.
+
+Signed-off-by: Ajit Khaparde <ajit.khaparde at emulex.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/emulex/benet/be_main.c | 19 ++++++++++++++-----
+ 1 file changed, 14 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
+index a185e61..acef082 100644
+--- a/drivers/net/ethernet/emulex/benet/be_main.c
++++ b/drivers/net/ethernet/emulex/benet/be_main.c
+@@ -817,28 +817,37 @@ static int be_vid_config(struct be_adapter *adapter, bool vf, u32 vf_num)
+ static void be_vlan_add_vid(struct net_device *netdev, u16 vid)
+ {
+ struct be_adapter *adapter = netdev_priv(netdev);
++ int status = 0;
+
+- adapter->vlans_added++;
+ if (!be_physfn(adapter))
+ return;
+
+ adapter->vlan_tag[vid] = 1;
+ if (adapter->vlans_added <= (adapter->max_vlans + 1))
+- be_vid_config(adapter, false, 0);
++ status = be_vid_config(adapter, false, 0);
++
++ if (!status)
++ adapter->vlans_added++;
++ else
++ adapter->vlan_tag[vid] = 0;
+ }
+
+ static void be_vlan_rem_vid(struct net_device *netdev, u16 vid)
+ {
+ struct be_adapter *adapter = netdev_priv(netdev);
+-
+- adapter->vlans_added--;
++ int status = 0;
+
+ if (!be_physfn(adapter))
+ return;
+
+ adapter->vlan_tag[vid] = 0;
+ if (adapter->vlans_added <= adapter->max_vlans)
+- be_vid_config(adapter, false, 0);
++ status = be_vid_config(adapter, false, 0);
++
++ if (!status)
++ adapter->vlans_added--;
++ else
++ adapter->vlan_tag[vid] = 1;
+ }
+
+ static void be_set_rx_mode(struct net_device *netdev)
+--
+1.7.10
+
Added: dists/sid/linux-2.6/debian/patches/features/all/be2net/0024-be2net-fix-range-check-for-set_qos-for-a-VF.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/be2net/0024-be2net-fix-range-check-for-set_qos-for-a-VF.patch Sun May 27 00:21:22 2012 (r19037)
@@ -0,0 +1,47 @@
+From: Ajit Khaparde <ajit.khaparde at emulex.com>
+Date: Fri, 30 Dec 2011 12:15:30 +0000
+Subject: [PATCH 24/58] be2net: fix range check for set_qos for a VF
+
+commit 94f434c2055db5fe20f10d4e0ec50ab395e1f62b upstream.
+
+Signed-off-by: Ajit Khaparde <ajit.khaparde at emulex.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/emulex/benet/be_main.c | 14 +++++++++-----
+ 1 file changed, 9 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
+index acef082..cd7f5e3 100644
+--- a/drivers/net/ethernet/emulex/benet/be_main.c
++++ b/drivers/net/ethernet/emulex/benet/be_main.c
+@@ -970,18 +970,22 @@ static int be_set_vf_tx_rate(struct net_device *netdev,
+ if (!sriov_enabled(adapter))
+ return -EPERM;
+
+- if (vf >= adapter->num_vfs || rate < 0)
++ if (vf >= adapter->num_vfs)
+ return -EINVAL;
+
+- if (rate > 10000)
+- rate = 10000;
++ if (rate < 100 || rate > 10000) {
++ dev_err(&adapter->pdev->dev,
++ "tx rate must be between 100 and 10000 Mbps\n");
++ return -EINVAL;
++ }
+
+- adapter->vf_cfg[vf].tx_rate = rate;
+ status = be_cmd_set_qos(adapter, rate / 10, vf + 1);
+
+ if (status)
+- dev_info(&adapter->pdev->dev,
++ dev_err(&adapter->pdev->dev,
+ "tx rate %d on VF %d failed\n", rate, vf);
++ else
++ adapter->vf_cfg[vf].tx_rate = rate;
+ return status;
+ }
+
+--
+1.7.10
+
Added: dists/sid/linux-2.6/debian/patches/features/all/be2net/0025-be2net-query-link-status-in-be_open.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/be2net/0025-be2net-query-link-status-in-be_open.patch Sun May 27 00:21:22 2012 (r19037)
@@ -0,0 +1,234 @@
+From: Ajit Khaparde <ajit.khaparde at emulex.com>
+Date: Fri, 30 Dec 2011 12:15:40 +0000
+Subject: [PATCH 25/58] be2net: query link status in be_open()
+
+commit b236916a68d923acff15787b5439d7d684c17ae5 upstream.
+
+be2net gets an async link status notification from the FW when it creates
+an MCC queue. There are some cases in which this gratuitous notification
+is not received from FW. To cover this explicitly query the link status
+in be_open().
+
+Signed-off-by: Vasundhara Volam <vasundhara.volam at emulex.com>
+Signed-off-by: Sathya Perla <sathya.perla at emulex.com>
+Signed-off-by: Ajit Khaparde <ajit.khaparde at emulex.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/emulex/benet/be.h | 5 ++++-
+ drivers/net/ethernet/emulex/benet/be_cmds.c | 21 +++++++++++++++++----
+ drivers/net/ethernet/emulex/benet/be_cmds.h | 7 ++++---
+ drivers/net/ethernet/emulex/benet/be_ethtool.c | 7 +++++--
+ drivers/net/ethernet/emulex/benet/be_main.c | 24 +++++++++++++++---------
+ 5 files changed, 45 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h
+index 995198d..cbdec25 100644
+--- a/drivers/net/ethernet/emulex/benet/be.h
++++ b/drivers/net/ethernet/emulex/benet/be.h
+@@ -299,6 +299,8 @@ struct be_vf_cfg {
+ u32 tx_rate;
+ };
+
++#define BE_FLAGS_LINK_STATUS_INIT 1
++
+ struct be_adapter {
+ struct pci_dev *pdev;
+ struct net_device *netdev;
+@@ -347,6 +349,7 @@ struct be_adapter {
+ struct delayed_work work;
+ u16 work_counter;
+
++ u32 flags;
+ /* Ethtool knobs and info */
+ char fw_ver[FW_VER_LEN];
+ int if_handle; /* Used to configure filtering */
+@@ -538,7 +541,7 @@ static inline bool be_error(struct be_adapter *adapter)
+
+ extern void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm,
+ u16 num_popped);
+-extern void be_link_status_update(struct be_adapter *adapter, u32 link_status);
++extern void be_link_status_update(struct be_adapter *adapter, u8 link_status);
+ extern void be_parse_stats(struct be_adapter *adapter);
+ extern int be_load_fw(struct be_adapter *adapter, u8 *func);
+ #endif /* BE_H */
+diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
+index 62868ea..0fcb456 100644
+--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
++++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
+@@ -125,7 +125,14 @@ done:
+ static void be_async_link_state_process(struct be_adapter *adapter,
+ struct be_async_event_link_state *evt)
+ {
+- be_link_status_update(adapter, evt->port_link_status);
++ /* When link status changes, link speed must be re-queried from FW */
++ adapter->link_speed = -1;
++
++ /* For the initial link status do not rely on the ASYNC event as
++ * it may not be received in some cases.
++ */
++ if (adapter->flags & BE_FLAGS_LINK_STATUS_INIT)
++ be_link_status_update(adapter, evt->port_link_status);
+ }
+
+ /* Grp5 CoS Priority evt */
+@@ -1232,7 +1239,7 @@ err:
+
+ /* Uses synchronous mcc */
+ int be_cmd_link_status_query(struct be_adapter *adapter, u8 *mac_speed,
+- u16 *link_speed, u32 dom)
++ u16 *link_speed, u8 *link_status, u32 dom)
+ {
+ struct be_mcc_wrb *wrb;
+ struct be_cmd_req_link_status *req;
+@@ -1240,6 +1247,9 @@ int be_cmd_link_status_query(struct be_adapter *adapter, u8 *mac_speed,
+
+ spin_lock_bh(&adapter->mcc_lock);
+
++ if (link_status)
++ *link_status = LINK_DOWN;
++
+ wrb = wrb_from_mccq(adapter);
+ if (!wrb) {
+ status = -EBUSY;
+@@ -1247,7 +1257,7 @@ int be_cmd_link_status_query(struct be_adapter *adapter, u8 *mac_speed,
+ }
+ req = embedded_payload(wrb);
+
+- if (lancer_chip(adapter))
++ if (adapter->generation == BE_GEN3 || lancer_chip(adapter))
+ req->hdr.version = 1;
+
+ be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+@@ -1257,10 +1267,13 @@ int be_cmd_link_status_query(struct be_adapter *adapter, u8 *mac_speed,
+ if (!status) {
+ struct be_cmd_resp_link_status *resp = embedded_payload(wrb);
+ if (resp->mac_speed != PHY_LINK_SPEED_ZERO) {
+- *link_speed = le16_to_cpu(resp->link_speed);
++ if (link_speed)
++ *link_speed = le16_to_cpu(resp->link_speed);
+ if (mac_speed)
+ *mac_speed = resp->mac_speed;
+ }
++ if (link_status)
++ *link_status = resp->logical_link_status;
+ }
+
+ err:
+diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h
+index 0b694c6..dca8924 100644
+--- a/drivers/net/ethernet/emulex/benet/be_cmds.h
++++ b/drivers/net/ethernet/emulex/benet/be_cmds.h
+@@ -960,7 +960,8 @@ struct be_cmd_resp_link_status {
+ u8 mgmt_mac_duplex;
+ u8 mgmt_mac_speed;
+ u16 link_speed;
+- u32 rsvd0;
++ u8 logical_link_status;
++ u8 rsvd1[3];
+ } __packed;
+
+ /******************** Port Identification ***************************/
+@@ -1507,8 +1508,8 @@ extern int be_cmd_q_destroy(struct be_adapter *adapter, struct be_queue_info *q,
+ int type);
+ extern int be_cmd_rxq_destroy(struct be_adapter *adapter,
+ struct be_queue_info *q);
+-extern int be_cmd_link_status_query(struct be_adapter *adapter,
+- u8 *mac_speed, u16 *link_speed, u32 dom);
++extern int be_cmd_link_status_query(struct be_adapter *adapter, u8 *mac_speed,
++ u16 *link_speed, u8 *link_status, u32 dom);
+ extern int be_cmd_reset(struct be_adapter *adapter);
+ extern int be_cmd_get_stats(struct be_adapter *adapter,
+ struct be_dma_mem *nonemb_cmd);
+diff --git a/drivers/net/ethernet/emulex/benet/be_ethtool.c b/drivers/net/ethernet/emulex/benet/be_ethtool.c
+index 6ba2dc6..6db6b6a 100644
+--- a/drivers/net/ethernet/emulex/benet/be_ethtool.c
++++ b/drivers/net/ethernet/emulex/benet/be_ethtool.c
+@@ -429,11 +429,14 @@ static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
+ struct be_phy_info phy_info;
+ u8 mac_speed = 0;
+ u16 link_speed = 0;
++ u8 link_status;
+ int status;
+
+ if ((adapter->link_speed < 0) || (!(netdev->flags & IFF_UP))) {
+ status = be_cmd_link_status_query(adapter, &mac_speed,
+- &link_speed, 0);
++ &link_speed, &link_status, 0);
++ if (!status)
++ be_link_status_update(adapter, link_status);
+
+ /* link_speed is in units of 10 Mbps */
+ if (link_speed) {
+@@ -700,7 +703,7 @@ be_self_test(struct net_device *netdev, struct ethtool_test *test, u64 *data)
+ }
+
+ if (be_cmd_link_status_query(adapter, &mac_speed,
+- &qos_link_speed, 0) != 0) {
++ &qos_link_speed, NULL, 0) != 0) {
+ test->flags |= ETH_TEST_FL_FAILED;
+ data[4] = -1;
+ } else if (!mac_speed) {
+diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
+index cd7f5e3..42ee4c9 100644
+--- a/drivers/net/ethernet/emulex/benet/be_main.c
++++ b/drivers/net/ethernet/emulex/benet/be_main.c
+@@ -496,19 +496,19 @@ static struct rtnl_link_stats64 *be_get_stats64(struct net_device *netdev,
+ return stats;
+ }
+
+-void be_link_status_update(struct be_adapter *adapter, u32 link_status)
++void be_link_status_update(struct be_adapter *adapter, u8 link_status)
+ {
+ struct net_device *netdev = adapter->netdev;
+
+- /* when link status changes, link speed must be re-queried from card */
+- adapter->link_speed = -1;
+- if ((link_status & LINK_STATUS_MASK) == LINK_UP) {
+- netif_carrier_on(netdev);
+- dev_info(&adapter->pdev->dev, "%s: Link up\n", netdev->name);
+- } else {
++ if (!(adapter->flags & BE_FLAGS_LINK_STATUS_INIT)) {
+ netif_carrier_off(netdev);
+- dev_info(&adapter->pdev->dev, "%s: Link down\n", netdev->name);
++ adapter->flags |= BE_FLAGS_LINK_STATUS_INIT;
+ }
++
++ if ((link_status & LINK_STATUS_MASK) == LINK_UP)
++ netif_carrier_on(netdev);
++ else
++ netif_carrier_off(netdev);
+ }
+
+ static void be_tx_stats_update(struct be_tx_obj *txo,
+@@ -2406,6 +2406,7 @@ static int be_open(struct net_device *netdev)
+ struct be_adapter *adapter = netdev_priv(netdev);
+ struct be_eq_obj *tx_eq = &adapter->tx_eq;
+ struct be_rx_obj *rxo;
++ u8 link_status;
+ int status, i;
+
+ status = be_rx_queues_setup(adapter);
+@@ -2429,6 +2430,11 @@ static int be_open(struct net_device *netdev)
+ /* Now that interrupts are on we can process async mcc */
+ be_async_mcc_enable(adapter);
+
++ status = be_cmd_link_status_query(adapter, NULL, NULL,
++ &link_status, 0);
++ if (!status)
++ be_link_status_update(adapter, link_status);
++
+ return 0;
+ err:
+ be_close(adapter->netdev);
+@@ -2576,7 +2582,7 @@ static int be_vf_setup(struct be_adapter *adapter)
+
+ for_all_vfs(adapter, vf_cfg, vf) {
+ status = be_cmd_link_status_query(adapter, NULL, &lnk_speed,
+- vf + 1);
++ NULL, vf + 1);
+ if (status)
+ goto err;
+ vf_cfg->tx_rate = lnk_speed * 10;
+--
+1.7.10
+
Added: dists/sid/linux-2.6/debian/patches/features/all/be2net/0026-netdev-make-net_device_ops-const.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/be2net/0026-netdev-make-net_device_ops-const.patch Sun May 27 00:21:22 2012 (r19037)
@@ -0,0 +1,31 @@
+From: stephen hemminger <shemminger at vyatta.com>
+Date: Thu, 5 Jan 2012 19:10:25 +0000
+Subject: [PATCH 26/58] netdev: make net_device_ops const
+
+commit e5686ad82ca2aeed7a8f24ffca115c0b7478dec9 upstream.
+
+More drivers where net_device_ops should be const.
+
+Signed-off-by: Stephen Hemminger <shemminger at vyatta.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+[bwh: Restrict to drivers/net/ethernet/emulex/benet/]
+---
+ drivers/net/ethernet/emulex/benet/be_main.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
+index 42ee4c9..804ab7e 100644
+--- a/drivers/net/ethernet/emulex/benet/be_main.c
++++ b/drivers/net/ethernet/emulex/benet/be_main.c
+@@ -3072,7 +3072,7 @@ fw_exit:
+ return status;
+ }
+
+-static struct net_device_ops be_netdev_ops = {
++static const struct net_device_ops be_netdev_ops = {
+ .ndo_open = be_open,
+ .ndo_stop = be_close,
+ .ndo_start_xmit = be_xmit,
+--
+1.7.10
+
Added: dists/sid/linux-2.6/debian/patches/features/all/be2net/0027-be2net-create-RSS-rings-even-in-multi-channel-config.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/be2net/0027-be2net-create-RSS-rings-even-in-multi-channel-config.patch Sun May 27 00:21:22 2012 (r19037)
@@ -0,0 +1,36 @@
+From: Sathya Perla <sathya.perla at emulex.com>
+Date: Thu, 19 Jan 2012 20:34:04 +0000
+Subject: [PATCH 27/58] be2net: create RSS rings even in multi-channel configs
+
+commit df505eb804d5221c3164ebecd1286cb7fc7f49ba upstream.
+
+Currently RSS rings are not created in a multi-channel config.
+RSS rings can be created on one (out of four) interfaces per port in a
+multi-channel config. Doing this insulates the driver from a FW bug wherin
+multi-channel config is wrongly reported even when not enabled. This also
+helps performance in a multi-channel config, as one interface per port gets
+RSS rings.
+
+Signed-off-by: Sathya Perla <sathya.perla at emulex.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/emulex/benet/be_main.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
+index 804ab7e..adfd66a 100644
+--- a/drivers/net/ethernet/emulex/benet/be_main.c
++++ b/drivers/net/ethernet/emulex/benet/be_main.c
+@@ -1778,8 +1778,7 @@ static void be_rx_queues_destroy(struct be_adapter *adapter)
+ static u32 be_num_rxqs_want(struct be_adapter *adapter)
+ {
+ if ((adapter->function_caps & BE_FUNCTION_CAPS_RSS) &&
+- !sriov_enabled(adapter) && be_physfn(adapter) &&
+- !be_is_mc(adapter)) {
++ !sriov_enabled(adapter) && be_physfn(adapter)) {
+ return 1 + MAX_RSS_QS; /* one default non-RSS queue */
+ } else {
+ dev_warn(&adapter->pdev->dev,
+--
+1.7.10
+
Added: dists/sid/linux-2.6/debian/patches/features/all/be2net/0028-be2net-allocate-more-headroom-in-incoming-skbs.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/be2net/0028-be2net-allocate-more-headroom-in-incoming-skbs.patch Sun May 27 00:21:22 2012 (r19037)
@@ -0,0 +1,57 @@
+From: Eric Dumazet <eric.dumazet at gmail.com>
+Date: Wed, 25 Jan 2012 03:56:30 +0000
+Subject: [PATCH 28/58] be2net: allocate more headroom in incoming skbs
+
+commit bb349bb4b19b39830e0486aedfd7c7dca23b7baf upstream.
+
+Allocation of 64 bytes in skb headroom is not enough if we have to pull
+ethernet + ipv6 + tcp headers, and/or extra tunneling header.
+
+Its currently not noticed because netdev_alloc_skb_ip_align(64) give us
+more room, thanks to power-of-two kmalloc() roundups.
+
+Make sure we ask for 128 bytes so that side effects of upcoming patches
+from Ian Campbell dont decrease benet rx performance, because of extra
+skb head reallocations.
+
+Signed-off-by: Eric Dumazet <eric.dumazet at gmail.com>
+Cc: Ian Campbell <Ian.Campbell at citrix.com>
+Cc: Vasundhara Volam <vasundhara.volam at emulex.com>
+Cc: Sathya Perla <sathya.perla at emulex.com>
+Cc: Ajit Khaparde <ajit.khaparde at emulex.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/emulex/benet/be.h | 3 +++
+ drivers/net/ethernet/emulex/benet/be_main.c | 2 +-
+ 2 files changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h
+index cbdec25..453d486 100644
+--- a/drivers/net/ethernet/emulex/benet/be.h
++++ b/drivers/net/ethernet/emulex/benet/be.h
+@@ -74,6 +74,9 @@ static inline char *nic_name(struct pci_dev *pdev)
+
+ /* Number of bytes of an RX frame that are copied to skb->data */
+ #define BE_HDR_LEN ((u16) 64)
++/* allocate extra space to allow tunneling decapsulation without head reallocation */
++#define BE_RX_SKB_ALLOC_SIZE (BE_HDR_LEN + 64)
++
+ #define BE_MAX_JUMBO_FRAME_SIZE 9018
+ #define BE_MIN_MTU 256
+
+diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
+index adfd66a..860c461 100644
+--- a/drivers/net/ethernet/emulex/benet/be_main.c
++++ b/drivers/net/ethernet/emulex/benet/be_main.c
+@@ -1181,7 +1181,7 @@ static void be_rx_compl_process(struct be_adapter *adapter,
+ struct net_device *netdev = adapter->netdev;
+ struct sk_buff *skb;
+
+- skb = netdev_alloc_skb_ip_align(netdev, BE_HDR_LEN);
++ skb = netdev_alloc_skb_ip_align(netdev, BE_RX_SKB_ALLOC_SIZE);
+ if (unlikely(!skb)) {
+ rx_stats(rxo)->rx_drops_no_skbs++;
+ be_rx_compl_discard(adapter, rxo, rxcp);
+--
+1.7.10
+
Added: dists/sid/linux-2.6/debian/patches/features/all/be2net/0029-be2net-add-descriptions-for-stat-counters-reported-v.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/be2net/0029-be2net-add-descriptions-for-stat-counters-reported-v.patch Sun May 27 00:21:22 2012 (r19037)
@@ -0,0 +1,259 @@
+From: Sathya Perla <sathya.perla at emulex.com>
+Date: Sun, 29 Jan 2012 20:17:39 +0000
+Subject: [PATCH 29/58] be2net: add descriptions for stat counters reported
+ via ethtool
+
+commit d45b9d39a1aed7851948460d29b843ce70eb0a68 upstream.
+
+Also rename a few counters appropritely and delete 2 counters that are not
+implemented in HW.
+
+vlan_mismatch_drops does not exist in BE3 and is accounted for in
+address_mismatch_drops. Do the same thing for BE2 and Lancer.
+
+Signed-off-by: Sathya Perla <sathya.perla at emulex.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/emulex/benet/be.h | 3 +-
+ drivers/net/ethernet/emulex/benet/be_cmds.h | 10 ++--
+ drivers/net/ethernet/emulex/benet/be_ethtool.c | 64 ++++++++++++++++++++++--
+ drivers/net/ethernet/emulex/benet/be_main.c | 15 +++---
+ 4 files changed, 74 insertions(+), 18 deletions(-)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h
+index 453d486..74aa148 100644
+--- a/drivers/net/ethernet/emulex/benet/be.h
++++ b/drivers/net/ethernet/emulex/benet/be.h
+@@ -265,7 +265,6 @@ struct be_drv_stats {
+ u32 rx_drops_no_erx_descr;
+ u32 rx_drops_no_tpre_descr;
+ u32 rx_drops_too_many_frags;
+- u32 rx_drops_invalid_ring;
+ u32 forwarded_packets;
+ u32 rx_drops_mtu;
+ u32 rx_crc_errors;
+@@ -276,7 +275,7 @@ struct be_drv_stats {
+ u32 rx_in_range_errors;
+ u32 rx_out_range_errors;
+ u32 rx_frame_too_long;
+- u32 rx_address_match_errors;
++ u32 rx_address_mismatch_drops;
+ u32 rx_dropped_too_small;
+ u32 rx_dropped_too_short;
+ u32 rx_dropped_header_too_small;
+diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h
+index dca8924..bbd012b 100644
+--- a/drivers/net/ethernet/emulex/benet/be_cmds.h
++++ b/drivers/net/ethernet/emulex/benet/be_cmds.h
+@@ -592,8 +592,8 @@ struct be_port_rxf_stats_v0 {
+ u32 rx_in_range_errors; /* dword 10*/
+ u32 rx_out_range_errors; /* dword 11*/
+ u32 rx_frame_too_long; /* dword 12*/
+- u32 rx_address_match_errors; /* dword 13*/
+- u32 rx_vlan_mismatch; /* dword 14*/
++ u32 rx_address_mismatch_drops; /* dword 13*/
++ u32 rx_vlan_mismatch_drops; /* dword 14*/
+ u32 rx_dropped_too_small; /* dword 15*/
+ u32 rx_dropped_too_short; /* dword 16*/
+ u32 rx_dropped_header_too_small; /* dword 17*/
+@@ -799,8 +799,8 @@ struct lancer_pport_stats {
+ u32 rx_control_frames_unknown_opcode_hi;
+ u32 rx_in_range_errors;
+ u32 rx_out_of_range_errors;
+- u32 rx_address_match_errors;
+- u32 rx_vlan_mismatch_errors;
++ u32 rx_address_mismatch_drops;
++ u32 rx_vlan_mismatch_drops;
+ u32 rx_dropped_too_small;
+ u32 rx_dropped_too_short;
+ u32 rx_dropped_header_too_small;
+@@ -1384,7 +1384,7 @@ struct be_port_rxf_stats_v1 {
+ u32 rx_in_range_errors;
+ u32 rx_out_range_errors;
+ u32 rx_frame_too_long;
+- u32 rx_address_match_errors;
++ u32 rx_address_mismatch_drops;
+ u32 rx_dropped_too_small;
+ u32 rx_dropped_too_short;
+ u32 rx_dropped_header_too_small;
+diff --git a/drivers/net/ethernet/emulex/benet/be_ethtool.c b/drivers/net/ethernet/emulex/benet/be_ethtool.c
+index 6db6b6a..0a5ee22 100644
+--- a/drivers/net/ethernet/emulex/benet/be_ethtool.c
++++ b/drivers/net/ethernet/emulex/benet/be_ethtool.c
+@@ -42,15 +42,42 @@ static const struct be_ethtool_stat et_stats[] = {
+ {DRVSTAT_INFO(rx_alignment_symbol_errors)},
+ {DRVSTAT_INFO(rx_pause_frames)},
+ {DRVSTAT_INFO(rx_control_frames)},
++ /* Received packets dropped when the Ethernet length field
++ * is not equal to the actual Ethernet data length.
++ */
+ {DRVSTAT_INFO(rx_in_range_errors)},
++ /* Received packets dropped when their length field is >= 1501 bytes
++ * and <= 1535 bytes.
++ */
+ {DRVSTAT_INFO(rx_out_range_errors)},
++ /* Received packets dropped when they are longer than 9216 bytes */
+ {DRVSTAT_INFO(rx_frame_too_long)},
+- {DRVSTAT_INFO(rx_address_match_errors)},
++ /* Received packets dropped when they don't pass the unicast or
++ * multicast address filtering.
++ */
++ {DRVSTAT_INFO(rx_address_mismatch_drops)},
++ /* Received packets dropped when IP packet length field is less than
++ * the IP header length field.
++ */
+ {DRVSTAT_INFO(rx_dropped_too_small)},
++ /* Received packets dropped when IP length field is greater than
++ * the actual packet length.
++ */
+ {DRVSTAT_INFO(rx_dropped_too_short)},
++ /* Received packets dropped when the IP header length field is less
++ * than 5.
++ */
+ {DRVSTAT_INFO(rx_dropped_header_too_small)},
++ /* Received packets dropped when the TCP header length field is less
++ * than 5 or the TCP header length + IP header length is more
++ * than IP packet length.
++ */
+ {DRVSTAT_INFO(rx_dropped_tcp_length)},
+ {DRVSTAT_INFO(rx_dropped_runt)},
++ /* Number of received packets dropped when a fifo for descriptors going
++ * into the packet demux block overflows. In normal operation, this
++ * fifo must never overflow.
++ */
+ {DRVSTAT_INFO(rxpp_fifo_overflow_drop)},
+ {DRVSTAT_INFO(rx_input_fifo_overflow_drop)},
+ {DRVSTAT_INFO(rx_ip_checksum_errs)},
+@@ -59,16 +86,35 @@ static const struct be_ethtool_stat et_stats[] = {
+ {DRVSTAT_INFO(tx_pauseframes)},
+ {DRVSTAT_INFO(tx_controlframes)},
+ {DRVSTAT_INFO(rx_priority_pause_frames)},
++ /* Received packets dropped when an internal fifo going into
++ * main packet buffer tank (PMEM) overflows.
++ */
+ {DRVSTAT_INFO(pmem_fifo_overflow_drop)},
+ {DRVSTAT_INFO(jabber_events)},
++ /* Received packets dropped due to lack of available HW packet buffers
++ * used to temporarily hold the received packets.
++ */
+ {DRVSTAT_INFO(rx_drops_no_pbuf)},
+- {DRVSTAT_INFO(rx_drops_no_txpb)},
++ /* Received packets dropped due to input receive buffer
++ * descriptor fifo overflowing.
++ */
+ {DRVSTAT_INFO(rx_drops_no_erx_descr)},
++ /* Packets dropped because the internal FIFO to the offloaded TCP
++ * receive processing block is full. This could happen only for
++ * offloaded iSCSI or FCoE trarffic.
++ */
+ {DRVSTAT_INFO(rx_drops_no_tpre_descr)},
++ /* Received packets dropped when they need more than 8
++ * receive buffers. This cannot happen as the driver configures
++ * 2048 byte receive buffers.
++ */
+ {DRVSTAT_INFO(rx_drops_too_many_frags)},
+- {DRVSTAT_INFO(rx_drops_invalid_ring)},
+ {DRVSTAT_INFO(forwarded_packets)},
++ /* Received packets dropped when the frame length
++ * is more than 9018 bytes
++ */
+ {DRVSTAT_INFO(rx_drops_mtu)},
++ /* Number of packets dropped due to random early drop function */
+ {DRVSTAT_INFO(eth_red_drops)},
+ {DRVSTAT_INFO(be_on_die_temperature)}
+ };
+@@ -84,8 +130,15 @@ static const struct be_ethtool_stat et_rx_stats[] = {
+ {DRVSTAT_RX_INFO(rx_events)},
+ {DRVSTAT_RX_INFO(rx_compl)},
+ {DRVSTAT_RX_INFO(rx_mcast_pkts)},
++ /* Number of page allocation failures while posting receive buffers
++ * to HW.
++ */
+ {DRVSTAT_RX_INFO(rx_post_fail)},
++ /* Recevied packets dropped due to skb allocation failure */
+ {DRVSTAT_RX_INFO(rx_drops_no_skbs)},
++ /* Received packets dropped due to lack of available fetched buffers
++ * posted by the driver.
++ */
+ {DRVSTAT_RX_INFO(rx_drops_no_frags)}
+ };
+ #define ETHTOOL_RXSTATS_NUM (ARRAY_SIZE(et_rx_stats))
+@@ -97,9 +150,14 @@ static const struct be_ethtool_stat et_tx_stats[] = {
+ {DRVSTAT_TX_INFO(tx_compl)}, /* If moving this member see above note */
+ {DRVSTAT_TX_INFO(tx_bytes)},
+ {DRVSTAT_TX_INFO(tx_pkts)},
++ /* Number of skbs queued for trasmission by the driver */
+ {DRVSTAT_TX_INFO(tx_reqs)},
++ /* Number of TX work request blocks DMAed to HW */
+ {DRVSTAT_TX_INFO(tx_wrbs)},
+ {DRVSTAT_TX_INFO(tx_compl)},
++ /* Number of times the TX queue was stopped due to lack
++ * of spaces in the TXQ.
++ */
+ {DRVSTAT_TX_INFO(tx_stops)}
+ };
+ #define ETHTOOL_TXSTATS_NUM (ARRAY_SIZE(et_tx_stats))
+diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
+index 860c461..d1536e2 100644
+--- a/drivers/net/ethernet/emulex/benet/be_main.c
++++ b/drivers/net/ethernet/emulex/benet/be_main.c
+@@ -286,7 +286,9 @@ static void populate_be2_stats(struct be_adapter *adapter)
+ drvs->rx_input_fifo_overflow_drop = port_stats->rx_input_fifo_overflow;
+ drvs->rx_dropped_header_too_small =
+ port_stats->rx_dropped_header_too_small;
+- drvs->rx_address_match_errors = port_stats->rx_address_match_errors;
++ drvs->rx_address_mismatch_drops =
++ port_stats->rx_address_mismatch_drops +
++ port_stats->rx_vlan_mismatch_drops;
+ drvs->rx_alignment_symbol_errors =
+ port_stats->rx_alignment_symbol_errors;
+
+@@ -298,9 +300,7 @@ static void populate_be2_stats(struct be_adapter *adapter)
+ else
+ drvs->jabber_events = rxf_stats->port0_jabber_events;
+ drvs->rx_drops_no_pbuf = rxf_stats->rx_drops_no_pbuf;
+- drvs->rx_drops_no_txpb = rxf_stats->rx_drops_no_txpb;
+ drvs->rx_drops_no_erx_descr = rxf_stats->rx_drops_no_erx_descr;
+- drvs->rx_drops_invalid_ring = rxf_stats->rx_drops_invalid_ring;
+ drvs->forwarded_packets = rxf_stats->forwarded_packets;
+ drvs->rx_drops_mtu = rxf_stats->rx_drops_mtu;
+ drvs->rx_drops_no_tpre_descr = rxf_stats->rx_drops_no_tpre_descr;
+@@ -337,7 +337,7 @@ static void populate_be3_stats(struct be_adapter *adapter)
+ port_stats->rx_dropped_header_too_small;
+ drvs->rx_input_fifo_overflow_drop =
+ port_stats->rx_input_fifo_overflow_drop;
+- drvs->rx_address_match_errors = port_stats->rx_address_match_errors;
++ drvs->rx_address_mismatch_drops = port_stats->rx_address_mismatch_drops;
+ drvs->rx_alignment_symbol_errors =
+ port_stats->rx_alignment_symbol_errors;
+ drvs->rxpp_fifo_overflow_drop = port_stats->rxpp_fifo_overflow_drop;
+@@ -345,9 +345,7 @@ static void populate_be3_stats(struct be_adapter *adapter)
+ drvs->tx_controlframes = port_stats->tx_controlframes;
+ drvs->jabber_events = port_stats->jabber_events;
+ drvs->rx_drops_no_pbuf = rxf_stats->rx_drops_no_pbuf;
+- drvs->rx_drops_no_txpb = rxf_stats->rx_drops_no_txpb;
+ drvs->rx_drops_no_erx_descr = rxf_stats->rx_drops_no_erx_descr;
+- drvs->rx_drops_invalid_ring = rxf_stats->rx_drops_invalid_ring;
+ drvs->forwarded_packets = rxf_stats->forwarded_packets;
+ drvs->rx_drops_mtu = rxf_stats->rx_drops_mtu;
+ drvs->rx_drops_no_tpre_descr = rxf_stats->rx_drops_no_tpre_descr;
+@@ -380,13 +378,14 @@ static void populate_lancer_stats(struct be_adapter *adapter)
+ drvs->rx_dropped_header_too_small =
+ pport_stats->rx_dropped_header_too_small;
+ drvs->rx_input_fifo_overflow_drop = pport_stats->rx_fifo_overflow;
+- drvs->rx_address_match_errors = pport_stats->rx_address_match_errors;
++ drvs->rx_address_mismatch_drops =
++ pport_stats->rx_address_mismatch_drops +
++ pport_stats->rx_vlan_mismatch_drops;
+ drvs->rx_alignment_symbol_errors = pport_stats->rx_symbol_errors_lo;
+ drvs->rxpp_fifo_overflow_drop = pport_stats->rx_fifo_overflow;
+ drvs->tx_pauseframes = pport_stats->tx_pause_frames_lo;
+ drvs->tx_controlframes = pport_stats->tx_control_frames_lo;
+ drvs->jabber_events = pport_stats->rx_jabbers;
+- drvs->rx_drops_invalid_ring = pport_stats->rx_drops_invalid_queue;
+ drvs->forwarded_packets = pport_stats->num_forwards_lo;
+ drvs->rx_drops_mtu = pport_stats->rx_drops_mtu_lo;
+ drvs->rx_drops_too_many_frags =
+--
+1.7.10
+
Added: dists/sid/linux-2.6/debian/patches/features/all/be2net/0030-be2net-Fix-link-status-query-command.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/be2net/0030-be2net-Fix-link-status-query-command.patch Sun May 27 00:21:22 2012 (r19037)
@@ -0,0 +1,39 @@
+From: Padmanabh Ratnakar <padmanabh.ratnakar at emulex.com>
+Date: Fri, 3 Feb 2012 09:49:46 +0000
+Subject: [PATCH 30/58] be2net: Fix link status query command
+
+commit 57cd80d4d511748f3973accc6919e7e1e1936ebb upstream.
+
+Version number in query link status command is getting overwritten in
+be_wrb_cmd_hdr_prepare() routine. Move the initialization to fix this
+issue. Also initialize the domain field.
+
+Signed-off-by: Padmanabh Ratnakar <padmanabh.ratnakar at emulex.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/emulex/benet/be_cmds.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
+index 0fcb456..dd6e8e2 100644
+--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
++++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
+@@ -1257,11 +1257,13 @@ int be_cmd_link_status_query(struct be_adapter *adapter, u8 *mac_speed,
+ }
+ req = embedded_payload(wrb);
+
++ be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
++ OPCODE_COMMON_NTWK_LINK_STATUS_QUERY, sizeof(*req), wrb, NULL);
++
+ if (adapter->generation == BE_GEN3 || lancer_chip(adapter))
+ req->hdr.version = 1;
+
+- be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+- OPCODE_COMMON_NTWK_LINK_STATUS_QUERY, sizeof(*req), wrb, NULL);
++ req->hdr.domain = dom;
+
+ status = be_mcc_notify_wait(adapter);
+ if (!status) {
+--
+1.7.10
+
Added: dists/sid/linux-2.6/debian/patches/features/all/be2net/0031-be2net-Use-new-implementation-of-get-mac-list-comman.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/be2net/0031-be2net-Use-new-implementation-of-get-mac-list-comman.patch Sun May 27 00:21:22 2012 (r19037)
@@ -0,0 +1,237 @@
+From: Padmanabh Ratnakar <padmanabh.ratnakar at emulex.com>
+Date: Fri, 3 Feb 2012 09:50:17 +0000
+Subject: [PATCH 31/58] be2net: Use new implementation of get mac list command
+
+commit e5e1ee89461543043a0144e6dac90547fefe2f89 upstream.
+
+VFs use get mac list command to get their mac address. The format of
+this command has changed. Update driver to use the new format.
+
+Signed-off-by: Mammatha Edhala <mammatha.edhala at emulex.com>
+Signed-off-by: Padmanabh Ratnakar <padmanabh.ratnakar at emulex.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/emulex/benet/be_cmds.c | 67 +++++++++++++++++++--------
+ drivers/net/ethernet/emulex/benet/be_cmds.h | 36 +++++++++-----
+ drivers/net/ethernet/emulex/benet/be_main.c | 29 ++++++++----
+ 3 files changed, 92 insertions(+), 40 deletions(-)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
+index dd6e8e2..29dff7d 100644
+--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
++++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
+@@ -2300,52 +2300,81 @@ err:
+
+ /* Uses synchronous MCCQ */
+ int be_cmd_get_mac_from_list(struct be_adapter *adapter, u32 domain,
+- u32 *pmac_id)
++ bool *pmac_id_active, u32 *pmac_id, u8 *mac)
+ {
+ struct be_mcc_wrb *wrb;
+ struct be_cmd_req_get_mac_list *req;
+ int status;
+ int mac_count;
++ struct be_dma_mem get_mac_list_cmd;
++ int i;
++
++ memset(&get_mac_list_cmd, 0, sizeof(struct be_dma_mem));
++ get_mac_list_cmd.size = sizeof(struct be_cmd_resp_get_mac_list);
++ get_mac_list_cmd.va = pci_alloc_consistent(adapter->pdev,
++ get_mac_list_cmd.size,
++ &get_mac_list_cmd.dma);
++
++ if (!get_mac_list_cmd.va) {
++ dev_err(&adapter->pdev->dev,
++ "Memory allocation failure during GET_MAC_LIST\n");
++ return -ENOMEM;
++ }
+
+ spin_lock_bh(&adapter->mcc_lock);
+
+ wrb = wrb_from_mccq(adapter);
+ if (!wrb) {
+ status = -EBUSY;
+- goto err;
++ goto out;
+ }
+- req = embedded_payload(wrb);
++
++ req = get_mac_list_cmd.va;
+
+ be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+ OPCODE_COMMON_GET_MAC_LIST, sizeof(*req),
+- wrb, NULL);
++ wrb, &get_mac_list_cmd);
+
+ req->hdr.domain = domain;
++ req->mac_type = MAC_ADDRESS_TYPE_NETWORK;
++ req->perm_override = 1;
+
+ status = be_mcc_notify_wait(adapter);
+ if (!status) {
+ struct be_cmd_resp_get_mac_list *resp =
+- embedded_payload(wrb);
+- int i;
+- u8 *ctxt = &resp->context[0][0];
+- status = -EIO;
+- mac_count = resp->mac_count;
+- be_dws_le_to_cpu(&resp->context, sizeof(resp->context));
++ get_mac_list_cmd.va;
++ mac_count = resp->true_mac_count + resp->pseudo_mac_count;
++ /* Mac list returned could contain one or more active mac_ids
++ * or one or more pseudo permanant mac addresses. If an active
++ * mac_id is present, return first active mac_id found
++ */
+ for (i = 0; i < mac_count; i++) {
+- if (!AMAP_GET_BITS(struct amap_get_mac_list_context,
+- act, ctxt)) {
+- *pmac_id = AMAP_GET_BITS
+- (struct amap_get_mac_list_context,
+- macid, ctxt);
+- status = 0;
+- break;
++ struct get_list_macaddr *mac_entry;
++ u16 mac_addr_size;
++ u32 mac_id;
++
++ mac_entry = &resp->macaddr_list[i];
++ mac_addr_size = le16_to_cpu(mac_entry->mac_addr_size);
++ /* mac_id is a 32 bit value and mac_addr size
++ * is 6 bytes
++ */
++ if (mac_addr_size == sizeof(u32)) {
++ *pmac_id_active = true;
++ mac_id = mac_entry->mac_addr_id.s_mac_id.mac_id;
++ *pmac_id = le32_to_cpu(mac_id);
++ goto out;
+ }
+- ctxt += sizeof(struct amap_get_mac_list_context) / 8;
+ }
++ /* If no active mac_id found, return first pseudo mac addr */
++ *pmac_id_active = false;
++ memcpy(mac, resp->macaddr_list[0].mac_addr_id.macaddr,
++ ETH_ALEN);
+ }
+
+-err:
++out:
+ spin_unlock_bh(&adapter->mcc_lock);
++ pci_free_consistent(adapter->pdev, get_mac_list_cmd.size,
++ get_mac_list_cmd.va, get_mac_list_cmd.dma);
+ return status;
+ }
+
+diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h
+index bbd012b..5bb66c8 100644
+--- a/drivers/net/ethernet/emulex/benet/be_cmds.h
++++ b/drivers/net/ethernet/emulex/benet/be_cmds.h
+@@ -1346,22 +1346,36 @@ struct be_cmd_resp_set_func_cap {
+
+ /******************** GET/SET_MACLIST **************************/
+ #define BE_MAX_MAC 64
+-struct amap_get_mac_list_context {
+- u8 macid[31];
+- u8 act;
+-} __packed;
+-
+ struct be_cmd_req_get_mac_list {
+ struct be_cmd_req_hdr hdr;
+- u32 rsvd;
++ u8 mac_type;
++ u8 perm_override;
++ u16 iface_id;
++ u32 mac_id;
++ u32 rsvd[3];
++} __packed;
++
++struct get_list_macaddr {
++ u16 mac_addr_size;
++ union {
++ u8 macaddr[6];
++ struct {
++ u8 rsvd[2];
++ u32 mac_id;
++ } __packed s_mac_id;
++ } __packed mac_addr_id;
+ } __packed;
+
+ struct be_cmd_resp_get_mac_list {
+ struct be_cmd_resp_hdr hdr;
+- u8 mac_count;
+- u8 rsvd1;
+- u16 rsvd2;
+- u8 context[sizeof(struct amap_get_mac_list_context) / 8][BE_MAX_MAC];
++ struct get_list_macaddr fd_macaddr; /* Factory default mac */
++ struct get_list_macaddr macid_macaddr; /* soft mac */
++ u8 true_mac_count;
++ u8 pseudo_mac_count;
++ u8 mac_list_size;
++ u8 rsvd;
++ /* perm override mac */
++ struct get_list_macaddr macaddr_list[BE_MAX_MAC];
+ } __packed;
+
+ struct be_cmd_req_set_mac_list {
+@@ -1575,7 +1589,7 @@ extern int be_cmd_req_native_mode(struct be_adapter *adapter);
+ extern int be_cmd_get_reg_len(struct be_adapter *adapter, u32 *log_size);
+ extern void be_cmd_get_regs(struct be_adapter *adapter, u32 buf_len, void *buf);
+ extern int be_cmd_get_mac_from_list(struct be_adapter *adapter, u32 domain,
+- u32 *pmac_id);
++ bool *pmac_id_active, u32 *pmac_id, u8 *mac);
+ extern int be_cmd_set_mac_list(struct be_adapter *adapter, u8 *mac_array,
+ u8 mac_count, u32 domain);
+
+diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
+index d1536e2..4364f01 100644
+--- a/drivers/net/ethernet/emulex/benet/be_main.c
++++ b/drivers/net/ethernet/emulex/benet/be_main.c
+@@ -2600,19 +2600,28 @@ static void be_setup_init(struct be_adapter *adapter)
+ adapter->eq_next_idx = 0;
+ }
+
+-static int be_configure_mac_from_list(struct be_adapter *adapter, u8 *mac)
++static int be_add_mac_from_list(struct be_adapter *adapter, u8 *mac)
+ {
+ u32 pmac_id;
+- int status = be_cmd_get_mac_from_list(adapter, 0, &pmac_id);
+- if (status != 0)
+- goto do_none;
+- status = be_cmd_mac_addr_query(adapter, mac,
+- MAC_ADDRESS_TYPE_NETWORK,
+- false, adapter->if_handle, pmac_id);
++ int status;
++ bool pmac_id_active;
++
++ status = be_cmd_get_mac_from_list(adapter, 0, &pmac_id_active,
++ &pmac_id, mac);
+ if (status != 0)
+ goto do_none;
+- status = be_cmd_pmac_add(adapter, mac, adapter->if_handle,
+- &adapter->pmac_id, 0);
++
++ if (pmac_id_active) {
++ status = be_cmd_mac_addr_query(adapter, mac,
++ MAC_ADDRESS_TYPE_NETWORK,
++ false, adapter->if_handle, pmac_id);
++
++ if (!status)
++ adapter->pmac_id = pmac_id;
++ } else {
++ status = be_cmd_pmac_add(adapter, mac,
++ adapter->if_handle, &adapter->pmac_id, 0);
++ }
+ do_none:
+ return status;
+ }
+@@ -2677,7 +2686,7 @@ static int be_setup(struct be_adapter *adapter)
+ */
+ if (!be_physfn(adapter)) {
+ if (lancer_chip(adapter))
+- status = be_configure_mac_from_list(adapter, mac);
++ status = be_add_mac_from_list(adapter, mac);
+ else
+ status = be_cmd_mac_addr_query(adapter, mac,
+ MAC_ADDRESS_TYPE_NETWORK, false,
+--
+1.7.10
+
Added: dists/sid/linux-2.6/debian/patches/features/all/be2net/0032-be2net-event-queue-re-design.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/be2net/0032-be2net-event-queue-re-design.patch Sun May 27 00:21:22 2012 (r19037)
@@ -0,0 +1,1895 @@
+From: Sathya Perla <sathya.perla at emulex.com>
+Date: Thu, 9 Feb 2012 18:05:27 +0000
+Subject: [PATCH 32/58] be2net: event queue re-design
+
+commit 10ef9ab4329edd08bccc7a8d34b96b85714195ce upstream.
+
+v2: Fixed up the bad typecasting pointed out by David...
+
+In the current design 8 TXQs are serviced by 1 EQ, while each RSS queue
+is serviced by a separate EQ. This is being changed as follows:
+
+- Upto 8 EQs will be used (based on the availabilty of msix vectors).
+Each EQ will handle 1 RSS and 1 TX ring. The default non-RSS RX queue and
+MCC queue are handled by the last EQ.
+
+- On cards which provide support, upto 8 RSS rings will be used, instead
+of the current limit of 4.
+
+The new design allows spreading the TX multi-queue completion processing
+across multiple CPUs unlike the previous design.
+
+Signed-off-by: Sathya Perla <sathya.perla at emulex.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/emulex/benet/be.h | 65 +-
+ drivers/net/ethernet/emulex/benet/be_cmds.c | 31 +-
+ drivers/net/ethernet/emulex/benet/be_cmds.h | 8 +-
+ drivers/net/ethernet/emulex/benet/be_ethtool.c | 96 +--
+ drivers/net/ethernet/emulex/benet/be_main.c | 812 +++++++++++-------------
+ 5 files changed, 434 insertions(+), 578 deletions(-)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h
+index 74aa148..86f51de 100644
+--- a/drivers/net/ethernet/emulex/benet/be.h
++++ b/drivers/net/ethernet/emulex/benet/be.h
+@@ -81,7 +81,7 @@ static inline char *nic_name(struct pci_dev *pdev)
+ #define BE_MIN_MTU 256
+
+ #define BE_NUM_VLANS_SUPPORTED 64
+-#define BE_MAX_EQD 96
++#define BE_MAX_EQD 96u
+ #define BE_MAX_TX_FRAG_COUNT 30
+
+ #define EVNT_Q_LEN 1024
+@@ -92,12 +92,16 @@ static inline char *nic_name(struct pci_dev *pdev)
+ #define MCC_Q_LEN 128 /* total size not to exceed 8 pages */
+ #define MCC_CQ_LEN 256
+
+-#define MAX_RSS_QS 4 /* BE limit is 4 queues/port */
++#define BE3_MAX_RSS_QS 8
++#define BE2_MAX_RSS_QS 4
++#define MAX_RSS_QS BE3_MAX_RSS_QS
+ #define MAX_RX_QS (MAX_RSS_QS + 1) /* RSS qs + 1 def Rx */
++
+ #define MAX_TX_QS 8
+-#define BE_MAX_MSIX_VECTORS (MAX_RX_QS + 1)/* RX + TX */
++#define MAX_MSIX_VECTORS MAX_RSS_QS
++#define BE_TX_BUDGET 256
+ #define BE_NAPI_WEIGHT 64
+-#define MAX_RX_POST BE_NAPI_WEIGHT /* Frags posted at a time */
++#define MAX_RX_POST BE_NAPI_WEIGHT /* Frags posted at a time */
+ #define RX_FRAGS_REFILL_WM (RX_Q_LEN - MAX_RX_POST)
+
+ #define FW_VER_LEN 32
+@@ -165,13 +169,16 @@ struct be_eq_obj {
+
+ /* Adaptive interrupt coalescing (AIC) info */
+ bool enable_aic;
+- u16 min_eqd; /* in usecs */
+- u16 max_eqd; /* in usecs */
+- u16 cur_eqd; /* in usecs */
+- u8 eq_idx;
++ u32 min_eqd; /* in usecs */
++ u32 max_eqd; /* in usecs */
++ u32 eqd; /* configured val when aic is off */
++ u32 cur_eqd; /* in usecs */
+
++ u8 idx; /* array index */
++ u16 tx_budget;
+ struct napi_struct napi;
+-};
++ struct be_adapter *adapter;
++} ____cacheline_aligned_in_smp;
+
+ struct be_mcc_obj {
+ struct be_queue_info q;
+@@ -197,7 +204,7 @@ struct be_tx_obj {
+ /* Remember the skbs that were transmitted */
+ struct sk_buff *sent_skb_list[TX_Q_LEN];
+ struct be_tx_stats stats;
+-};
++} ____cacheline_aligned_in_smp;
+
+ /* Struct to remember the pages posted for rx frags */
+ struct be_rx_page_info {
+@@ -215,8 +222,6 @@ struct be_rx_stats {
+ u32 rx_drops_no_skbs; /* skb allocation errors */
+ u32 rx_drops_no_frags; /* HW has no fetched frags */
+ u32 rx_post_fail; /* page post alloc failures */
+- u32 rx_polls; /* NAPI calls */
+- u32 rx_events;
+ u32 rx_compl;
+ u32 rx_mcast_pkts;
+ u32 rx_compl_err; /* completions with err set */
+@@ -249,16 +254,13 @@ struct be_rx_obj {
+ struct be_queue_info cq;
+ struct be_rx_compl_info rxcp;
+ struct be_rx_page_info page_info_tbl[RX_Q_LEN];
+- struct be_eq_obj rx_eq;
+ struct be_rx_stats stats;
+ u8 rss_id;
+ bool rx_post_starved; /* Zero rx frags have been posted to BE */
+- u32 cache_line_barrier[16];
+-};
++} ____cacheline_aligned_in_smp;
+
+ struct be_drv_stats {
+ u32 be_on_die_temperature;
+- u32 tx_events;
+ u32 eth_red_drops;
+ u32 rx_drops_no_pbuf;
+ u32 rx_drops_no_txpb;
+@@ -320,20 +322,19 @@ struct be_adapter {
+ spinlock_t mcc_lock; /* For serializing mcc cmds to BE card */
+ spinlock_t mcc_cq_lock;
+
+- struct msix_entry msix_entries[BE_MAX_MSIX_VECTORS];
+ u32 num_msix_vec;
++ u32 num_evt_qs;
++ struct be_eq_obj eq_obj[MAX_MSIX_VECTORS];
++ struct msix_entry msix_entries[MAX_MSIX_VECTORS];
+ bool isr_registered;
+
+ /* TX Rings */
+- struct be_eq_obj tx_eq;
++ u32 num_tx_qs;
+ struct be_tx_obj tx_obj[MAX_TX_QS];
+- u8 num_tx_qs;
+-
+- u32 cache_line_break[8];
+
+ /* Rx rings */
+- struct be_rx_obj rx_obj[MAX_RX_QS];
+ u32 num_rx_qs;
++ struct be_rx_obj rx_obj[MAX_RX_QS];
+ u32 big_page_size; /* Compounded page size shared by rx wrbs */
+
+ u8 eq_next_idx;
+@@ -404,24 +405,34 @@ struct be_adapter {
+ extern const struct ethtool_ops be_ethtool_ops;
+
+ #define msix_enabled(adapter) (adapter->num_msix_vec > 0)
+-#define tx_stats(txo) (&txo->stats)
+-#define rx_stats(rxo) (&rxo->stats)
++#define num_irqs(adapter) (msix_enabled(adapter) ? \
++ adapter->num_msix_vec : 1)
++#define tx_stats(txo) (&(txo)->stats)
++#define rx_stats(rxo) (&(rxo)->stats)
+
+-#define BE_SET_NETDEV_OPS(netdev, ops) (netdev->netdev_ops = ops)
++/* The default RXQ is the last RXQ */
++#define default_rxo(adpt) (&adpt->rx_obj[adpt->num_rx_qs - 1])
+
+ #define for_all_rx_queues(adapter, rxo, i) \
+ for (i = 0, rxo = &adapter->rx_obj[i]; i < adapter->num_rx_qs; \
+ i++, rxo++)
+
+-/* Just skip the first default non-rss queue */
++/* Skip the default non-rss queue (last one)*/
+ #define for_all_rss_queues(adapter, rxo, i) \
+- for (i = 0, rxo = &adapter->rx_obj[i+1]; i < (adapter->num_rx_qs - 1);\
++ for (i = 0, rxo = &adapter->rx_obj[i]; i < (adapter->num_rx_qs - 1);\
+ i++, rxo++)
+
+ #define for_all_tx_queues(adapter, txo, i) \
+ for (i = 0, txo = &adapter->tx_obj[i]; i < adapter->num_tx_qs; \
+ i++, txo++)
+
++#define for_all_evt_queues(adapter, eqo, i) \
++ for (i = 0, eqo = &adapter->eq_obj[i]; i < adapter->num_evt_qs; \
++ i++, eqo++)
++
++#define is_mcc_eqo(eqo) (eqo->idx == 0)
++#define mcc_eqo(adapter) (&adapter->eq_obj[0])
++
+ #define PAGE_SHIFT_4K 12
+ #define PAGE_SIZE_4K (1 << PAGE_SHIFT_4K)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
+index 29dff7d..6432efa 100644
+--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
++++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
+@@ -235,10 +235,10 @@ void be_async_mcc_disable(struct be_adapter *adapter)
+ adapter->mcc_obj.rearm_cq = false;
+ }
+
+-int be_process_mcc(struct be_adapter *adapter, int *status)
++int be_process_mcc(struct be_adapter *adapter)
+ {
+ struct be_mcc_compl *compl;
+- int num = 0;
++ int num = 0, status = 0;
+ struct be_mcc_obj *mcc_obj = &adapter->mcc_obj;
+
+ spin_lock_bh(&adapter->mcc_cq_lock);
+@@ -252,32 +252,32 @@ int be_process_mcc(struct be_adapter *adapter, int *status)
+ be_async_grp5_evt_process(adapter,
+ compl->flags, compl);
+ } else if (compl->flags & CQE_FLAGS_COMPLETED_MASK) {
+- *status = be_mcc_compl_process(adapter, compl);
++ status = be_mcc_compl_process(adapter, compl);
+ atomic_dec(&mcc_obj->q.used);
+ }
+ be_mcc_compl_use(compl);
+ num++;
+ }
+
++ if (num)
++ be_cq_notify(adapter, mcc_obj->cq.id, mcc_obj->rearm_cq, num);
++
+ spin_unlock_bh(&adapter->mcc_cq_lock);
+- return num;
++ return status;
+ }
+
+ /* Wait till no more pending mcc requests are present */
+ static int be_mcc_wait_compl(struct be_adapter *adapter)
+ {
+ #define mcc_timeout 120000 /* 12s timeout */
+- int i, num, status = 0;
++ int i, status = 0;
+ struct be_mcc_obj *mcc_obj = &adapter->mcc_obj;
+
+ for (i = 0; i < mcc_timeout; i++) {
+ if (be_error(adapter))
+ return -EIO;
+
+- num = be_process_mcc(adapter, &status);
+- if (num)
+- be_cq_notify(adapter, mcc_obj->cq.id,
+- mcc_obj->rearm_cq, num);
++ status = be_process_mcc(adapter);
+
+ if (atomic_read(&mcc_obj->q.used) == 0)
+ break;
+@@ -726,9 +726,8 @@ err:
+ }
+
+ /* Uses Mbox */
+-int be_cmd_cq_create(struct be_adapter *adapter,
+- struct be_queue_info *cq, struct be_queue_info *eq,
+- bool sol_evts, bool no_delay, int coalesce_wm)
++int be_cmd_cq_create(struct be_adapter *adapter, struct be_queue_info *cq,
++ struct be_queue_info *eq, bool no_delay, int coalesce_wm)
+ {
+ struct be_mcc_wrb *wrb;
+ struct be_cmd_req_cq_create *req;
+@@ -759,7 +758,6 @@ int be_cmd_cq_create(struct be_adapter *adapter,
+ ctxt, 1);
+ AMAP_SET_BITS(struct amap_cq_context_lancer, eqid,
+ ctxt, eq->id);
+- AMAP_SET_BITS(struct amap_cq_context_lancer, armed, ctxt, 1);
+ } else {
+ AMAP_SET_BITS(struct amap_cq_context_be, coalescwm, ctxt,
+ coalesce_wm);
+@@ -768,11 +766,8 @@ int be_cmd_cq_create(struct be_adapter *adapter,
+ AMAP_SET_BITS(struct amap_cq_context_be, count, ctxt,
+ __ilog2_u32(cq->len/256));
+ AMAP_SET_BITS(struct amap_cq_context_be, valid, ctxt, 1);
+- AMAP_SET_BITS(struct amap_cq_context_be, solevent,
+- ctxt, sol_evts);
+ AMAP_SET_BITS(struct amap_cq_context_be, eventable, ctxt, 1);
+ AMAP_SET_BITS(struct amap_cq_context_be, eqid, ctxt, eq->id);
+- AMAP_SET_BITS(struct amap_cq_context_be, armed, ctxt, 1);
+ }
+
+ be_dws_cpu_to_le(ctxt, sizeof(req->context));
+@@ -973,7 +968,7 @@ err:
+ /* Uses MCC */
+ int be_cmd_rxq_create(struct be_adapter *adapter,
+ struct be_queue_info *rxq, u16 cq_id, u16 frag_size,
+- u16 max_frame_size, u32 if_id, u32 rss, u8 *rss_id)
++ u32 if_id, u32 rss, u8 *rss_id)
+ {
+ struct be_mcc_wrb *wrb;
+ struct be_cmd_req_eth_rx_create *req;
+@@ -997,7 +992,7 @@ int be_cmd_rxq_create(struct be_adapter *adapter,
+ req->num_pages = 2;
+ be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
+ req->interface_id = cpu_to_le32(if_id);
+- req->max_frame_size = cpu_to_le16(max_frame_size);
++ req->max_frame_size = cpu_to_le16(BE_MAX_JUMBO_FRAME_SIZE);
+ req->rss_queue = cpu_to_le32(rss);
+
+ status = be_mcc_notify_wait(adapter);
+diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h
+index 5bb66c8..687c420 100644
+--- a/drivers/net/ethernet/emulex/benet/be_cmds.h
++++ b/drivers/net/ethernet/emulex/benet/be_cmds.h
+@@ -1506,8 +1506,7 @@ extern int be_cmd_eq_create(struct be_adapter *adapter,
+ struct be_queue_info *eq, int eq_delay);
+ extern int be_cmd_cq_create(struct be_adapter *adapter,
+ struct be_queue_info *cq, struct be_queue_info *eq,
+- bool sol_evts, bool no_delay,
+- int num_cqe_dma_coalesce);
++ bool no_delay, int num_cqe_dma_coalesce);
+ extern int be_cmd_mccq_create(struct be_adapter *adapter,
+ struct be_queue_info *mccq,
+ struct be_queue_info *cq);
+@@ -1516,8 +1515,7 @@ extern int be_cmd_txq_create(struct be_adapter *adapter,
+ struct be_queue_info *cq);
+ extern int be_cmd_rxq_create(struct be_adapter *adapter,
+ struct be_queue_info *rxq, u16 cq_id,
+- u16 frag_size, u16 max_frame_size, u32 if_id,
+- u32 rss, u8 *rss_id);
++ u16 frag_size, u32 if_id, u32 rss, u8 *rss_id);
+ extern int be_cmd_q_destroy(struct be_adapter *adapter, struct be_queue_info *q,
+ int type);
+ extern int be_cmd_rxq_destroy(struct be_adapter *adapter,
+@@ -1546,7 +1544,7 @@ extern int be_cmd_query_fw_cfg(struct be_adapter *adapter,
+ extern int be_cmd_reset_function(struct be_adapter *adapter);
+ extern int be_cmd_rss_config(struct be_adapter *adapter, u8 *rsstable,
+ u16 table_size);
+-extern int be_process_mcc(struct be_adapter *adapter, int *status);
++extern int be_process_mcc(struct be_adapter *adapter);
+ extern int be_cmd_set_beacon_state(struct be_adapter *adapter,
+ u8 port_num, u8 beacon, u8 status, u8 state);
+ extern int be_cmd_get_beacon_state(struct be_adapter *adapter,
+diff --git a/drivers/net/ethernet/emulex/benet/be_ethtool.c b/drivers/net/ethernet/emulex/benet/be_ethtool.c
+index 0a5ee22..d98ad7e 100644
+--- a/drivers/net/ethernet/emulex/benet/be_ethtool.c
++++ b/drivers/net/ethernet/emulex/benet/be_ethtool.c
+@@ -37,7 +37,6 @@ enum {DRVSTAT_TX, DRVSTAT_RX, DRVSTAT};
+ FIELDINFO(struct be_drv_stats, field)
+
+ static const struct be_ethtool_stat et_stats[] = {
+- {DRVSTAT_INFO(tx_events)},
+ {DRVSTAT_INFO(rx_crc_errors)},
+ {DRVSTAT_INFO(rx_alignment_symbol_errors)},
+ {DRVSTAT_INFO(rx_pause_frames)},
+@@ -126,8 +125,6 @@ static const struct be_ethtool_stat et_stats[] = {
+ static const struct be_ethtool_stat et_rx_stats[] = {
+ {DRVSTAT_RX_INFO(rx_bytes)},/* If moving this member see above note */
+ {DRVSTAT_RX_INFO(rx_pkts)}, /* If moving this member see above note */
+- {DRVSTAT_RX_INFO(rx_polls)},
+- {DRVSTAT_RX_INFO(rx_events)},
+ {DRVSTAT_RX_INFO(rx_compl)},
+ {DRVSTAT_RX_INFO(rx_mcast_pkts)},
+ /* Number of page allocation failures while posting receive buffers
+@@ -154,7 +151,6 @@ static const struct be_ethtool_stat et_tx_stats[] = {
+ {DRVSTAT_TX_INFO(tx_reqs)},
+ /* Number of TX work request blocks DMAed to HW */
+ {DRVSTAT_TX_INFO(tx_wrbs)},
+- {DRVSTAT_TX_INFO(tx_compl)},
+ /* Number of times the TX queue was stopped due to lack
+ * of spaces in the TXQ.
+ */
+@@ -290,86 +286,42 @@ be_get_regs(struct net_device *netdev, struct ethtool_regs *regs, void *buf)
+ }
+ }
+
+-static int
+-be_get_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce)
++static int be_get_coalesce(struct net_device *netdev,
++ struct ethtool_coalesce *et)
+ {
+ struct be_adapter *adapter = netdev_priv(netdev);
+- struct be_eq_obj *rx_eq = &adapter->rx_obj[0].rx_eq;
+- struct be_eq_obj *tx_eq = &adapter->tx_eq;
++ struct be_eq_obj *eqo = &adapter->eq_obj[0];
++
+
+- coalesce->rx_coalesce_usecs = rx_eq->cur_eqd;
+- coalesce->rx_coalesce_usecs_high = rx_eq->max_eqd;
+- coalesce->rx_coalesce_usecs_low = rx_eq->min_eqd;
++ et->rx_coalesce_usecs = eqo->cur_eqd;
++ et->rx_coalesce_usecs_high = eqo->max_eqd;
++ et->rx_coalesce_usecs_low = eqo->min_eqd;
+
+- coalesce->tx_coalesce_usecs = tx_eq->cur_eqd;
+- coalesce->tx_coalesce_usecs_high = tx_eq->max_eqd;
+- coalesce->tx_coalesce_usecs_low = tx_eq->min_eqd;
++ et->tx_coalesce_usecs = eqo->cur_eqd;
++ et->tx_coalesce_usecs_high = eqo->max_eqd;
++ et->tx_coalesce_usecs_low = eqo->min_eqd;
+
+- coalesce->use_adaptive_rx_coalesce = rx_eq->enable_aic;
+- coalesce->use_adaptive_tx_coalesce = tx_eq->enable_aic;
++ et->use_adaptive_rx_coalesce = eqo->enable_aic;
++ et->use_adaptive_tx_coalesce = eqo->enable_aic;
+
+ return 0;
+ }
+
+-/*
+- * This routine is used to set interrup coalescing delay
++/* TX attributes are ignored. Only RX attributes are considered
++ * eqd cmd is issued in the worker thread.
+ */
+-static int
+-be_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce)
++static int be_set_coalesce(struct net_device *netdev,
++ struct ethtool_coalesce *et)
+ {
+ struct be_adapter *adapter = netdev_priv(netdev);
+- struct be_rx_obj *rxo;
+- struct be_eq_obj *rx_eq;
+- struct be_eq_obj *tx_eq = &adapter->tx_eq;
+- u32 rx_max, rx_min, rx_cur;
+- int status = 0, i;
+- u32 tx_cur;
+-
+- if (coalesce->use_adaptive_tx_coalesce == 1)
+- return -EINVAL;
+-
+- for_all_rx_queues(adapter, rxo, i) {
+- rx_eq = &rxo->rx_eq;
+-
+- if (!rx_eq->enable_aic && coalesce->use_adaptive_rx_coalesce)
+- rx_eq->cur_eqd = 0;
+- rx_eq->enable_aic = coalesce->use_adaptive_rx_coalesce;
+-
+- rx_max = coalesce->rx_coalesce_usecs_high;
+- rx_min = coalesce->rx_coalesce_usecs_low;
+- rx_cur = coalesce->rx_coalesce_usecs;
+-
+- if (rx_eq->enable_aic) {
+- if (rx_max > BE_MAX_EQD)
+- rx_max = BE_MAX_EQD;
+- if (rx_min > rx_max)
+- rx_min = rx_max;
+- rx_eq->max_eqd = rx_max;
+- rx_eq->min_eqd = rx_min;
+- if (rx_eq->cur_eqd > rx_max)
+- rx_eq->cur_eqd = rx_max;
+- if (rx_eq->cur_eqd < rx_min)
+- rx_eq->cur_eqd = rx_min;
+- } else {
+- if (rx_cur > BE_MAX_EQD)
+- rx_cur = BE_MAX_EQD;
+- if (rx_eq->cur_eqd != rx_cur) {
+- status = be_cmd_modify_eqd(adapter, rx_eq->q.id,
+- rx_cur);
+- if (!status)
+- rx_eq->cur_eqd = rx_cur;
+- }
+- }
+- }
+-
+- tx_cur = coalesce->tx_coalesce_usecs;
+-
+- if (tx_cur > BE_MAX_EQD)
+- tx_cur = BE_MAX_EQD;
+- if (tx_eq->cur_eqd != tx_cur) {
+- status = be_cmd_modify_eqd(adapter, tx_eq->q.id, tx_cur);
+- if (!status)
+- tx_eq->cur_eqd = tx_cur;
++ struct be_eq_obj *eqo;
++ int i;
++
++ for_all_evt_queues(adapter, eqo, i) {
++ eqo->enable_aic = et->use_adaptive_rx_coalesce;
++ eqo->max_eqd = min(et->rx_coalesce_usecs_high, BE_MAX_EQD);
++ eqo->min_eqd = min(et->rx_coalesce_usecs_low, eqo->max_eqd);
++ eqo->eqd = et->rx_coalesce_usecs;
+ }
+
+ return 0;
+diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
+index 4364f01..4a3a186 100644
+--- a/drivers/net/ethernet/emulex/benet/be_main.c
++++ b/drivers/net/ethernet/emulex/benet/be_main.c
+@@ -144,7 +144,7 @@ static int be_queue_alloc(struct be_adapter *adapter, struct be_queue_info *q,
+ mem->va = dma_alloc_coherent(&adapter->pdev->dev, mem->size, &mem->dma,
+ GFP_KERNEL);
+ if (!mem->va)
+- return -1;
++ return -ENOMEM;
+ memset(mem->va, 0, mem->size);
+ return 0;
+ }
+@@ -988,18 +988,24 @@ static int be_set_vf_tx_rate(struct net_device *netdev,
+ return status;
+ }
+
+-static void be_rx_eqd_update(struct be_adapter *adapter, struct be_rx_obj *rxo)
++static void be_eqd_update(struct be_adapter *adapter, struct be_eq_obj *eqo)
+ {
+- struct be_eq_obj *rx_eq = &rxo->rx_eq;
+- struct be_rx_stats *stats = rx_stats(rxo);
++ struct be_rx_stats *stats = rx_stats(&adapter->rx_obj[eqo->idx]);
+ ulong now = jiffies;
+ ulong delta = now - stats->rx_jiffies;
+ u64 pkts;
+ unsigned int start, eqd;
+
+- if (!rx_eq->enable_aic)
++ if (!eqo->enable_aic) {
++ eqd = eqo->eqd;
++ goto modify_eqd;
++ }
++
++ if (eqo->idx >= adapter->num_rx_qs)
+ return;
+
++ stats = rx_stats(&adapter->rx_obj[eqo->idx]);
++
+ /* Wrapped around */
+ if (time_before(now, stats->rx_jiffies)) {
+ stats->rx_jiffies = now;
+@@ -1018,17 +1024,16 @@ static void be_rx_eqd_update(struct be_adapter *adapter, struct be_rx_obj *rxo)
+ stats->rx_pps = (unsigned long)(pkts - stats->rx_pkts_prev) / (delta / HZ);
+ stats->rx_pkts_prev = pkts;
+ stats->rx_jiffies = now;
+- eqd = stats->rx_pps / 110000;
+- eqd = eqd << 3;
+- if (eqd > rx_eq->max_eqd)
+- eqd = rx_eq->max_eqd;
+- if (eqd < rx_eq->min_eqd)
+- eqd = rx_eq->min_eqd;
++ eqd = (stats->rx_pps / 110000) << 3;
++ eqd = min(eqd, eqo->max_eqd);
++ eqd = max(eqd, eqo->min_eqd);
+ if (eqd < 10)
+ eqd = 0;
+- if (eqd != rx_eq->cur_eqd) {
+- be_cmd_modify_eqd(adapter, rx_eq->q.id, eqd);
+- rx_eq->cur_eqd = eqd;
++
++modify_eqd:
++ if (eqd != eqo->cur_eqd) {
++ be_cmd_modify_eqd(adapter, eqo->q.id, eqd);
++ eqo->cur_eqd = eqd;
+ }
+ }
+
+@@ -1056,11 +1061,10 @@ static inline bool csum_passed(struct be_rx_compl_info *rxcp)
+ (rxcp->ip_csum || rxcp->ipv6);
+ }
+
+-static struct be_rx_page_info *
+-get_rx_page_info(struct be_adapter *adapter,
+- struct be_rx_obj *rxo,
+- u16 frag_idx)
++static struct be_rx_page_info *get_rx_page_info(struct be_rx_obj *rxo,
++ u16 frag_idx)
+ {
++ struct be_adapter *adapter = rxo->adapter;
+ struct be_rx_page_info *rx_page_info;
+ struct be_queue_info *rxq = &rxo->q;
+
+@@ -1079,16 +1083,15 @@ get_rx_page_info(struct be_adapter *adapter,
+ }
+
+ /* Throwaway the data in the Rx completion */
+-static void be_rx_compl_discard(struct be_adapter *adapter,
+- struct be_rx_obj *rxo,
+- struct be_rx_compl_info *rxcp)
++static void be_rx_compl_discard(struct be_rx_obj *rxo,
++ struct be_rx_compl_info *rxcp)
+ {
+ struct be_queue_info *rxq = &rxo->q;
+ struct be_rx_page_info *page_info;
+ u16 i, num_rcvd = rxcp->num_rcvd;
+
+ for (i = 0; i < num_rcvd; i++) {
+- page_info = get_rx_page_info(adapter, rxo, rxcp->rxq_idx);
++ page_info = get_rx_page_info(rxo, rxcp->rxq_idx);
+ put_page(page_info->page);
+ memset(page_info, 0, sizeof(*page_info));
+ index_inc(&rxcp->rxq_idx, rxq->len);
+@@ -1099,8 +1102,8 @@ static void be_rx_compl_discard(struct be_adapter *adapter,
+ * skb_fill_rx_data forms a complete skb for an ether frame
+ * indicated by rxcp.
+ */
+-static void skb_fill_rx_data(struct be_adapter *adapter, struct be_rx_obj *rxo,
+- struct sk_buff *skb, struct be_rx_compl_info *rxcp)
++static void skb_fill_rx_data(struct be_rx_obj *rxo, struct sk_buff *skb,
++ struct be_rx_compl_info *rxcp)
+ {
+ struct be_queue_info *rxq = &rxo->q;
+ struct be_rx_page_info *page_info;
+@@ -1108,7 +1111,7 @@ static void skb_fill_rx_data(struct be_adapter *adapter, struct be_rx_obj *rxo,
+ u16 hdr_len, curr_frag_len, remaining;
+ u8 *start;
+
+- page_info = get_rx_page_info(adapter, rxo, rxcp->rxq_idx);
++ page_info = get_rx_page_info(rxo, rxcp->rxq_idx);
+ start = page_address(page_info->page) + page_info->page_offset;
+ prefetch(start);
+
+@@ -1145,7 +1148,7 @@ static void skb_fill_rx_data(struct be_adapter *adapter, struct be_rx_obj *rxo,
+ index_inc(&rxcp->rxq_idx, rxq->len);
+ remaining = rxcp->pkt_size - curr_frag_len;
+ for (i = 1, j = 0; i < rxcp->num_rcvd; i++) {
+- page_info = get_rx_page_info(adapter, rxo, rxcp->rxq_idx);
++ page_info = get_rx_page_info(rxo, rxcp->rxq_idx);
+ curr_frag_len = min(remaining, rx_frag_size);
+
+ /* Coalesce all frags from the same physical page in one slot */
+@@ -1173,21 +1176,21 @@ static void skb_fill_rx_data(struct be_adapter *adapter, struct be_rx_obj *rxo,
+ }
+
+ /* Process the RX completion indicated by rxcp when GRO is disabled */
+-static void be_rx_compl_process(struct be_adapter *adapter,
+- struct be_rx_obj *rxo,
+- struct be_rx_compl_info *rxcp)
++static void be_rx_compl_process(struct be_rx_obj *rxo,
++ struct be_rx_compl_info *rxcp)
+ {
++ struct be_adapter *adapter = rxo->adapter;
+ struct net_device *netdev = adapter->netdev;
+ struct sk_buff *skb;
+
+ skb = netdev_alloc_skb_ip_align(netdev, BE_RX_SKB_ALLOC_SIZE);
+ if (unlikely(!skb)) {
+ rx_stats(rxo)->rx_drops_no_skbs++;
+- be_rx_compl_discard(adapter, rxo, rxcp);
++ be_rx_compl_discard(rxo, rxcp);
+ return;
+ }
+
+- skb_fill_rx_data(adapter, rxo, skb, rxcp);
++ skb_fill_rx_data(rxo, skb, rxcp);
+
+ if (likely((netdev->features & NETIF_F_RXCSUM) && csum_passed(rxcp)))
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+@@ -1195,7 +1198,7 @@ static void be_rx_compl_process(struct be_adapter *adapter,
+ skb_checksum_none_assert(skb);
+
+ skb->protocol = eth_type_trans(skb, netdev);
+- if (adapter->netdev->features & NETIF_F_RXHASH)
++ if (netdev->features & NETIF_F_RXHASH)
+ skb->rxhash = rxcp->rss_hash;
+
+
+@@ -1206,26 +1209,25 @@ static void be_rx_compl_process(struct be_adapter *adapter,
+ }
+
+ /* Process the RX completion indicated by rxcp when GRO is enabled */
+-static void be_rx_compl_process_gro(struct be_adapter *adapter,
+- struct be_rx_obj *rxo,
+- struct be_rx_compl_info *rxcp)
++void be_rx_compl_process_gro(struct be_rx_obj *rxo, struct napi_struct *napi,
++ struct be_rx_compl_info *rxcp)
+ {
++ struct be_adapter *adapter = rxo->adapter;
+ struct be_rx_page_info *page_info;
+ struct sk_buff *skb = NULL;
+ struct be_queue_info *rxq = &rxo->q;
+- struct be_eq_obj *eq_obj = &rxo->rx_eq;
+ u16 remaining, curr_frag_len;
+ u16 i, j;
+
+- skb = napi_get_frags(&eq_obj->napi);
++ skb = napi_get_frags(napi);
+ if (!skb) {
+- be_rx_compl_discard(adapter, rxo, rxcp);
++ be_rx_compl_discard(rxo, rxcp);
+ return;
+ }
+
+ remaining = rxcp->pkt_size;
+ for (i = 0, j = -1; i < rxcp->num_rcvd; i++) {
+- page_info = get_rx_page_info(adapter, rxo, rxcp->rxq_idx);
++ page_info = get_rx_page_info(rxo, rxcp->rxq_idx);
+
+ curr_frag_len = min(remaining, rx_frag_size);
+
+@@ -1258,12 +1260,11 @@ static void be_rx_compl_process_gro(struct be_adapter *adapter,
+ if (rxcp->vlanf)
+ __vlan_hwaccel_put_tag(skb, rxcp->vlan_tag);
+
+- napi_gro_frags(&eq_obj->napi);
++ napi_gro_frags(napi);
+ }
+
+-static void be_parse_rx_compl_v1(struct be_adapter *adapter,
+- struct be_eth_rx_compl *compl,
+- struct be_rx_compl_info *rxcp)
++static void be_parse_rx_compl_v1(struct be_eth_rx_compl *compl,
++ struct be_rx_compl_info *rxcp)
+ {
+ rxcp->pkt_size =
+ AMAP_GET_BITS(struct amap_eth_rx_compl_v1, pktsize, compl);
+@@ -1294,9 +1295,8 @@ static void be_parse_rx_compl_v1(struct be_adapter *adapter,
+ rxcp->port = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, port, compl);
+ }
+
+-static void be_parse_rx_compl_v0(struct be_adapter *adapter,
+- struct be_eth_rx_compl *compl,
+- struct be_rx_compl_info *rxcp)
++static void be_parse_rx_compl_v0(struct be_eth_rx_compl *compl,
++ struct be_rx_compl_info *rxcp)
+ {
+ rxcp->pkt_size =
+ AMAP_GET_BITS(struct amap_eth_rx_compl_v0, pktsize, compl);
+@@ -1342,9 +1342,9 @@ static struct be_rx_compl_info *be_rx_compl_get(struct be_rx_obj *rxo)
+ be_dws_le_to_cpu(compl, sizeof(*compl));
+
+ if (adapter->be3_native)
+- be_parse_rx_compl_v1(adapter, compl, rxcp);
++ be_parse_rx_compl_v1(compl, rxcp);
+ else
+- be_parse_rx_compl_v0(adapter, compl, rxcp);
++ be_parse_rx_compl_v0(compl, rxcp);
+
+ if (rxcp->vlanf) {
+ /* vlanf could be wrongly set in some cards.
+@@ -1383,7 +1383,6 @@ static inline struct page *be_alloc_pages(u32 size, gfp_t gfp)
+ static void be_post_rx_frags(struct be_rx_obj *rxo, gfp_t gfp)
+ {
+ struct be_adapter *adapter = rxo->adapter;
+- struct be_rx_page_info *page_info_tbl = rxo->page_info_tbl;
+ struct be_rx_page_info *page_info = NULL, *prev_page_info = NULL;
+ struct be_queue_info *rxq = &rxo->q;
+ struct page *pagep = NULL;
+@@ -1425,7 +1424,7 @@ static void be_post_rx_frags(struct be_rx_obj *rxo, gfp_t gfp)
+
+ prev_page_info = page_info;
+ queue_head_inc(rxq);
+- page_info = &page_info_tbl[rxq->head];
++ page_info = &rxo->page_info_tbl[rxq->head];
+ }
+ if (pagep)
+ prev_page_info->last_page_user = true;
+@@ -1487,62 +1486,51 @@ static u16 be_tx_compl_process(struct be_adapter *adapter,
+ return num_wrbs;
+ }
+
+-static inline struct be_eq_entry *event_get(struct be_eq_obj *eq_obj)
++/* Return the number of events in the event queue */
++static inline int events_get(struct be_eq_obj *eqo)
+ {
+- struct be_eq_entry *eqe = queue_tail_node(&eq_obj->q);
++ struct be_eq_entry *eqe;
++ int num = 0;
+
+- if (!eqe->evt)
+- return NULL;
++ do {
++ eqe = queue_tail_node(&eqo->q);
++ if (eqe->evt == 0)
++ break;
+
+- rmb();
+- eqe->evt = le32_to_cpu(eqe->evt);
+- queue_tail_inc(&eq_obj->q);
+- return eqe;
++ rmb();
++ eqe->evt = 0;
++ num++;
++ queue_tail_inc(&eqo->q);
++ } while (true);
++
++ return num;
+ }
+
+-static int event_handle(struct be_adapter *adapter,
+- struct be_eq_obj *eq_obj,
+- bool rearm)
++static int event_handle(struct be_eq_obj *eqo)
+ {
+- struct be_eq_entry *eqe;
+- u16 num = 0;
+-
+- while ((eqe = event_get(eq_obj)) != NULL) {
+- eqe->evt = 0;
+- num++;
+- }
++ bool rearm = false;
++ int num = events_get(eqo);
+
+- /* Deal with any spurious interrupts that come
+- * without events
+- */
++ /* Deal with any spurious interrupts that come without events */
+ if (!num)
+ rearm = true;
+
+- be_eq_notify(adapter, eq_obj->q.id, rearm, true, num);
++ be_eq_notify(eqo->adapter, eqo->q.id, rearm, true, num);
+ if (num)
+- napi_schedule(&eq_obj->napi);
++ napi_schedule(&eqo->napi);
+
+ return num;
+ }
+
+-/* Just read and notify events without processing them.
+- * Used at the time of destroying event queues */
+-static void be_eq_clean(struct be_adapter *adapter,
+- struct be_eq_obj *eq_obj)
++/* Leaves the EQ is disarmed state */
++static void be_eq_clean(struct be_eq_obj *eqo)
+ {
+- struct be_eq_entry *eqe;
+- u16 num = 0;
+-
+- while ((eqe = event_get(eq_obj)) != NULL) {
+- eqe->evt = 0;
+- num++;
+- }
++ int num = events_get(eqo);
+
+- if (num)
+- be_eq_notify(adapter, eq_obj->q.id, false, true, num);
++ be_eq_notify(eqo->adapter, eqo->q.id, false, true, num);
+ }
+
+-static void be_rx_q_clean(struct be_adapter *adapter, struct be_rx_obj *rxo)
++static void be_rx_cq_clean(struct be_rx_obj *rxo)
+ {
+ struct be_rx_page_info *page_info;
+ struct be_queue_info *rxq = &rxo->q;
+@@ -1552,14 +1540,14 @@ static void be_rx_q_clean(struct be_adapter *adapter, struct be_rx_obj *rxo)
+
+ /* First cleanup pending rx completions */
+ while ((rxcp = be_rx_compl_get(rxo)) != NULL) {
+- be_rx_compl_discard(adapter, rxo, rxcp);
+- be_cq_notify(adapter, rx_cq->id, false, 1);
++ be_rx_compl_discard(rxo, rxcp);
++ be_cq_notify(rxo->adapter, rx_cq->id, false, 1);
+ }
+
+ /* Then free posted rx buffer that were not used */
+ tail = (rxq->head + rxq->len - atomic_read(&rxq->used)) % rxq->len;
+ for (; atomic_read(&rxq->used) > 0; index_inc(&tail, rxq->len)) {
+- page_info = get_rx_page_info(adapter, rxo, tail);
++ page_info = get_rx_page_info(rxo, tail);
+ put_page(page_info->page);
+ memset(page_info, 0, sizeof(*page_info));
+ }
+@@ -1615,6 +1603,47 @@ static void be_tx_compl_clean(struct be_adapter *adapter,
+ }
+ }
+
++static void be_evt_queues_destroy(struct be_adapter *adapter)
++{
++ struct be_eq_obj *eqo;
++ int i;
++
++ for_all_evt_queues(adapter, eqo, i) {
++ be_eq_clean(eqo);
++ if (eqo->q.created)
++ be_cmd_q_destroy(adapter, &eqo->q, QTYPE_EQ);
++ be_queue_free(adapter, &eqo->q);
++ }
++}
++
++static int be_evt_queues_create(struct be_adapter *adapter)
++{
++ struct be_queue_info *eq;
++ struct be_eq_obj *eqo;
++ int i, rc;
++
++ adapter->num_evt_qs = num_irqs(adapter);
++
++ for_all_evt_queues(adapter, eqo, i) {
++ eqo->adapter = adapter;
++ eqo->tx_budget = BE_TX_BUDGET;
++ eqo->idx = i;
++ eqo->max_eqd = BE_MAX_EQD;
++ eqo->enable_aic = true;
++
++ eq = &eqo->q;
++ rc = be_queue_alloc(adapter, eq, EVNT_Q_LEN,
++ sizeof(struct be_eq_entry));
++ if (rc)
++ return rc;
++
++ rc = be_cmd_eq_create(adapter, eq, eqo->cur_eqd);
++ if (rc)
++ return rc;
++ }
++ return rc;
++}
++
+ static void be_mcc_queues_destroy(struct be_adapter *adapter)
+ {
+ struct be_queue_info *q;
+@@ -1635,22 +1664,19 @@ static int be_mcc_queues_create(struct be_adapter *adapter)
+ {
+ struct be_queue_info *q, *cq;
+
+- /* Alloc MCC compl queue */
+ cq = &adapter->mcc_obj.cq;
+ if (be_queue_alloc(adapter, cq, MCC_CQ_LEN,
+ sizeof(struct be_mcc_compl)))
+ goto err;
+
+- /* Ask BE to create MCC compl queue; share TX's eq */
+- if (be_cmd_cq_create(adapter, cq, &adapter->tx_eq.q, false, true, 0))
++ /* Use the default EQ for MCC completions */
++ if (be_cmd_cq_create(adapter, cq, &mcc_eqo(adapter)->q, true, 0))
+ goto mcc_cq_free;
+
+- /* Alloc MCC queue */
+ q = &adapter->mcc_obj.q;
+ if (be_queue_alloc(adapter, q, MCC_Q_LEN, sizeof(struct be_mcc_wrb)))
+ goto mcc_cq_destroy;
+
+- /* Ask BE to create MCC queue */
+ if (be_cmd_mccq_create(adapter, q, cq))
+ goto mcc_q_free;
+
+@@ -1683,14 +1709,6 @@ static void be_tx_queues_destroy(struct be_adapter *adapter)
+ be_cmd_q_destroy(adapter, q, QTYPE_CQ);
+ be_queue_free(adapter, q);
+ }
+-
+- /* Clear any residual events */
+- be_eq_clean(adapter, &adapter->tx_eq);
+-
+- q = &adapter->tx_eq.q;
+- if (q->created)
+- be_cmd_q_destroy(adapter, q, QTYPE_EQ);
+- be_queue_free(adapter, q);
+ }
+
+ static int be_num_txqs_want(struct be_adapter *adapter)
+@@ -1703,10 +1721,10 @@ static int be_num_txqs_want(struct be_adapter *adapter)
+ return MAX_TX_QS;
+ }
+
+-/* One TX event queue is shared by all TX compl qs */
+-static int be_tx_queues_create(struct be_adapter *adapter)
++static int be_tx_cqs_create(struct be_adapter *adapter)
+ {
+- struct be_queue_info *eq, *q, *cq;
++ struct be_queue_info *cq, *eq;
++ int status;
+ struct be_tx_obj *txo;
+ u8 i;
+
+@@ -1718,192 +1736,109 @@ static int be_tx_queues_create(struct be_adapter *adapter)
+ rtnl_unlock();
+ }
+
+- adapter->tx_eq.max_eqd = 0;
+- adapter->tx_eq.min_eqd = 0;
+- adapter->tx_eq.cur_eqd = 96;
+- adapter->tx_eq.enable_aic = false;
++ for_all_tx_queues(adapter, txo, i) {
++ cq = &txo->cq;
++ status = be_queue_alloc(adapter, cq, TX_CQ_LEN,
++ sizeof(struct be_eth_tx_compl));
++ if (status)
++ return status;
+
+- eq = &adapter->tx_eq.q;
+- if (be_queue_alloc(adapter, eq, EVNT_Q_LEN,
+- sizeof(struct be_eq_entry)))
+- return -1;
++ /* If num_evt_qs is less than num_tx_qs, then more than
++ * one txq share an eq
++ */
++ eq = &adapter->eq_obj[i % adapter->num_evt_qs].q;
++ status = be_cmd_cq_create(adapter, cq, eq, false, 3);
++ if (status)
++ return status;
++ }
++ return 0;
++}
+
+- if (be_cmd_eq_create(adapter, eq, adapter->tx_eq.cur_eqd))
+- goto err;
+- adapter->tx_eq.eq_idx = adapter->eq_next_idx++;
++static int be_tx_qs_create(struct be_adapter *adapter)
++{
++ struct be_tx_obj *txo;
++ int i, status;
+
+ for_all_tx_queues(adapter, txo, i) {
+- cq = &txo->cq;
+- if (be_queue_alloc(adapter, cq, TX_CQ_LEN,
+- sizeof(struct be_eth_tx_compl)))
+- goto err;
+-
+- if (be_cmd_cq_create(adapter, cq, eq, false, false, 3))
+- goto err;
++ status = be_queue_alloc(adapter, &txo->q, TX_Q_LEN,
++ sizeof(struct be_eth_wrb));
++ if (status)
++ return status;
+
+- q = &txo->q;
+- if (be_queue_alloc(adapter, q, TX_Q_LEN,
+- sizeof(struct be_eth_wrb)))
+- goto err;
++ status = be_cmd_txq_create(adapter, &txo->q, &txo->cq);
++ if (status)
++ return status;
+ }
+- return 0;
+
+-err:
+- be_tx_queues_destroy(adapter);
+- return -1;
++ return 0;
+ }
+
+-static void be_rx_queues_destroy(struct be_adapter *adapter)
++static void be_rx_cqs_destroy(struct be_adapter *adapter)
+ {
+ struct be_queue_info *q;
+ struct be_rx_obj *rxo;
+ int i;
+
+ for_all_rx_queues(adapter, rxo, i) {
+- be_queue_free(adapter, &rxo->q);
+-
+ q = &rxo->cq;
+ if (q->created)
+ be_cmd_q_destroy(adapter, q, QTYPE_CQ);
+ be_queue_free(adapter, q);
+-
+- q = &rxo->rx_eq.q;
+- if (q->created)
+- be_cmd_q_destroy(adapter, q, QTYPE_EQ);
+- be_queue_free(adapter, q);
+- }
+-}
+-
+-static u32 be_num_rxqs_want(struct be_adapter *adapter)
+-{
+- if ((adapter->function_caps & BE_FUNCTION_CAPS_RSS) &&
+- !sriov_enabled(adapter) && be_physfn(adapter)) {
+- return 1 + MAX_RSS_QS; /* one default non-RSS queue */
+- } else {
+- dev_warn(&adapter->pdev->dev,
+- "No support for multiple RX queues\n");
+- return 1;
+ }
+ }
+
+-static int be_rx_queues_create(struct be_adapter *adapter)
++static int be_rx_cqs_create(struct be_adapter *adapter)
+ {
+- struct be_queue_info *eq, *q, *cq;
++ struct be_queue_info *eq, *cq;
+ struct be_rx_obj *rxo;
+ int rc, i;
+
+- adapter->num_rx_qs = min(be_num_rxqs_want(adapter),
+- msix_enabled(adapter) ?
+- adapter->num_msix_vec - 1 : 1);
+- if (adapter->num_rx_qs != MAX_RX_QS)
+- dev_warn(&adapter->pdev->dev,
+- "Can create only %d RX queues", adapter->num_rx_qs);
++ /* We'll create as many RSS rings as there are irqs.
++ * But when there's only one irq there's no use creating RSS rings
++ */
++ adapter->num_rx_qs = (num_irqs(adapter) > 1) ?
++ num_irqs(adapter) + 1 : 1;
+
+ adapter->big_page_size = (1 << get_order(rx_frag_size)) * PAGE_SIZE;
+ for_all_rx_queues(adapter, rxo, i) {
+ rxo->adapter = adapter;
+- rxo->rx_eq.max_eqd = BE_MAX_EQD;
+- rxo->rx_eq.enable_aic = true;
+-
+- /* EQ */
+- eq = &rxo->rx_eq.q;
+- rc = be_queue_alloc(adapter, eq, EVNT_Q_LEN,
+- sizeof(struct be_eq_entry));
+- if (rc)
+- goto err;
+-
+- rc = be_cmd_eq_create(adapter, eq, rxo->rx_eq.cur_eqd);
+- if (rc)
+- goto err;
+-
+- rxo->rx_eq.eq_idx = adapter->eq_next_idx++;
+-
+- /* CQ */
+ cq = &rxo->cq;
+ rc = be_queue_alloc(adapter, cq, RX_CQ_LEN,
+ sizeof(struct be_eth_rx_compl));
+ if (rc)
+- goto err;
++ return rc;
+
+- rc = be_cmd_cq_create(adapter, cq, eq, false, false, 3);
++ eq = &adapter->eq_obj[i % adapter->num_evt_qs].q;
++ rc = be_cmd_cq_create(adapter, cq, eq, false, 3);
+ if (rc)
+- goto err;
+-
+- /* Rx Q - will be created in be_open() */
+- q = &rxo->q;
+- rc = be_queue_alloc(adapter, q, RX_Q_LEN,
+- sizeof(struct be_eth_rx_d));
+- if (rc)
+- goto err;
+-
++ return rc;
+ }
+
+- return 0;
+-err:
+- be_rx_queues_destroy(adapter);
+- return -1;
+-}
++ if (adapter->num_rx_qs != MAX_RX_QS)
++ dev_info(&adapter->pdev->dev,
++ "Created only %d receive queues", adapter->num_rx_qs);
+
+-static bool event_peek(struct be_eq_obj *eq_obj)
+-{
+- struct be_eq_entry *eqe = queue_tail_node(&eq_obj->q);
+- if (!eqe->evt)
+- return false;
+- else
+- return true;
++ return 0;
+ }
+
+ static irqreturn_t be_intx(int irq, void *dev)
+ {
+ struct be_adapter *adapter = dev;
+- struct be_rx_obj *rxo;
+- int isr, i, tx = 0 , rx = 0;
+-
+- if (lancer_chip(adapter)) {
+- if (event_peek(&adapter->tx_eq))
+- tx = event_handle(adapter, &adapter->tx_eq, false);
+- for_all_rx_queues(adapter, rxo, i) {
+- if (event_peek(&rxo->rx_eq))
+- rx |= event_handle(adapter, &rxo->rx_eq, true);
+- }
+-
+- if (!(tx || rx))
+- return IRQ_NONE;
+-
+- } else {
+- isr = ioread32(adapter->csr + CEV_ISR0_OFFSET +
+- (adapter->tx_eq.q.id / 8) * CEV_ISR_SIZE);
+- if (!isr)
+- return IRQ_NONE;
+-
+- if ((1 << adapter->tx_eq.eq_idx & isr))
+- event_handle(adapter, &adapter->tx_eq, false);
+-
+- for_all_rx_queues(adapter, rxo, i) {
+- if ((1 << rxo->rx_eq.eq_idx & isr))
+- event_handle(adapter, &rxo->rx_eq, true);
+- }
+- }
+-
+- return IRQ_HANDLED;
+-}
+-
+-static irqreturn_t be_msix_rx(int irq, void *dev)
+-{
+- struct be_rx_obj *rxo = dev;
+- struct be_adapter *adapter = rxo->adapter;
++ int num_evts;
+
+- event_handle(adapter, &rxo->rx_eq, true);
+-
+- return IRQ_HANDLED;
++ /* With INTx only one EQ is used */
++ num_evts = event_handle(&adapter->eq_obj[0]);
++ if (num_evts)
++ return IRQ_HANDLED;
++ else
++ return IRQ_NONE;
+ }
+
+-static irqreturn_t be_msix_tx_mcc(int irq, void *dev)
++static irqreturn_t be_msix(int irq, void *dev)
+ {
+- struct be_adapter *adapter = dev;
+-
+- event_handle(adapter, &adapter->tx_eq, false);
++ struct be_eq_obj *eqo = dev;
+
++ event_handle(eqo);
+ return IRQ_HANDLED;
+ }
+
+@@ -1912,16 +1847,14 @@ static inline bool do_gro(struct be_rx_compl_info *rxcp)
+ return (rxcp->tcpf && !rxcp->err) ? true : false;
+ }
+
+-static int be_poll_rx(struct napi_struct *napi, int budget)
++static int be_process_rx(struct be_rx_obj *rxo, struct napi_struct *napi,
++ int budget)
+ {
+- struct be_eq_obj *rx_eq = container_of(napi, struct be_eq_obj, napi);
+- struct be_rx_obj *rxo = container_of(rx_eq, struct be_rx_obj, rx_eq);
+ struct be_adapter *adapter = rxo->adapter;
+ struct be_queue_info *rx_cq = &rxo->cq;
+ struct be_rx_compl_info *rxcp;
+ u32 work_done;
+
+- rx_stats(rxo)->rx_polls++;
+ for (work_done = 0; work_done < budget; work_done++) {
+ rxcp = be_rx_compl_get(rxo);
+ if (!rxcp)
+@@ -1933,7 +1866,7 @@ static int be_poll_rx(struct napi_struct *napi, int budget)
+
+ /* Discard compl with partial DMA Lancer B0 */
+ if (unlikely(!rxcp->pkt_size)) {
+- be_rx_compl_discard(adapter, rxo, rxcp);
++ be_rx_compl_discard(rxo, rxcp);
+ goto loop_continue;
+ }
+
+@@ -1942,94 +1875,96 @@ static int be_poll_rx(struct napi_struct *napi, int budget)
+ */
+ if (unlikely(rxcp->port != adapter->port_num &&
+ !lancer_chip(adapter))) {
+- be_rx_compl_discard(adapter, rxo, rxcp);
++ be_rx_compl_discard(rxo, rxcp);
+ goto loop_continue;
+ }
+
+ if (do_gro(rxcp))
+- be_rx_compl_process_gro(adapter, rxo, rxcp);
++ be_rx_compl_process_gro(rxo, napi, rxcp);
+ else
+- be_rx_compl_process(adapter, rxo, rxcp);
++ be_rx_compl_process(rxo, rxcp);
+ loop_continue:
+ be_rx_stats_update(rxo, rxcp);
+ }
+
+- be_cq_notify(adapter, rx_cq->id, false, work_done);
++ if (work_done) {
++ be_cq_notify(adapter, rx_cq->id, true, work_done);
+
+- /* Refill the queue */
+- if (work_done && atomic_read(&rxo->q.used) < RX_FRAGS_REFILL_WM)
+- be_post_rx_frags(rxo, GFP_ATOMIC);
+-
+- /* All consumed */
+- if (work_done < budget) {
+- napi_complete(napi);
+- /* Arm CQ */
+- be_cq_notify(adapter, rx_cq->id, true, 0);
++ if (atomic_read(&rxo->q.used) < RX_FRAGS_REFILL_WM)
++ be_post_rx_frags(rxo, GFP_ATOMIC);
+ }
++
+ return work_done;
+ }
+
+-/* As TX and MCC share the same EQ check for both TX and MCC completions.
+- * For TX/MCC we don't honour budget; consume everything
+- */
+-static int be_poll_tx_mcc(struct napi_struct *napi, int budget)
++static bool be_process_tx(struct be_adapter *adapter, struct be_tx_obj *txo,
++ int budget, int idx)
+ {
+- struct be_eq_obj *tx_eq = container_of(napi, struct be_eq_obj, napi);
+- struct be_adapter *adapter =
+- container_of(tx_eq, struct be_adapter, tx_eq);
+- struct be_mcc_obj *mcc_obj = &adapter->mcc_obj;
+- struct be_tx_obj *txo;
+ struct be_eth_tx_compl *txcp;
+- int tx_compl, mcc_compl, status = 0;
+- u8 i;
+- u16 num_wrbs;
++ int num_wrbs = 0, work_done;
+
+- for_all_tx_queues(adapter, txo, i) {
+- tx_compl = 0;
+- num_wrbs = 0;
+- while ((txcp = be_tx_compl_get(&txo->cq))) {
+- num_wrbs += be_tx_compl_process(adapter, txo,
++ for (work_done = 0; work_done < budget; work_done++) {
++ txcp = be_tx_compl_get(&txo->cq);
++ if (!txcp)
++ break;
++ num_wrbs += be_tx_compl_process(adapter, txo,
+ AMAP_GET_BITS(struct amap_eth_tx_compl,
+ wrb_index, txcp));
+- tx_compl++;
+- }
+- if (tx_compl) {
+- be_cq_notify(adapter, txo->cq.id, true, tx_compl);
+-
+- atomic_sub(num_wrbs, &txo->q.used);
++ }
+
+- /* As Tx wrbs have been freed up, wake up netdev queue
+- * if it was stopped due to lack of tx wrbs. */
+- if (__netif_subqueue_stopped(adapter->netdev, i) &&
+- atomic_read(&txo->q.used) < txo->q.len / 2) {
+- netif_wake_subqueue(adapter->netdev, i);
+- }
++ if (work_done) {
++ be_cq_notify(adapter, txo->cq.id, true, work_done);
++ atomic_sub(num_wrbs, &txo->q.used);
+
+- u64_stats_update_begin(&tx_stats(txo)->sync_compl);
+- tx_stats(txo)->tx_compl += tx_compl;
+- u64_stats_update_end(&tx_stats(txo)->sync_compl);
++ /* As Tx wrbs have been freed up, wake up netdev queue
++ * if it was stopped due to lack of tx wrbs. */
++ if (__netif_subqueue_stopped(adapter->netdev, idx) &&
++ atomic_read(&txo->q.used) < txo->q.len / 2) {
++ netif_wake_subqueue(adapter->netdev, idx);
+ }
++
++ u64_stats_update_begin(&tx_stats(txo)->sync_compl);
++ tx_stats(txo)->tx_compl += work_done;
++ u64_stats_update_end(&tx_stats(txo)->sync_compl);
+ }
++ return (work_done < budget); /* Done */
++}
+
+- mcc_compl = be_process_mcc(adapter, &status);
++int be_poll(struct napi_struct *napi, int budget)
++{
++ struct be_eq_obj *eqo = container_of(napi, struct be_eq_obj, napi);
++ struct be_adapter *adapter = eqo->adapter;
++ int max_work = 0, work, i;
++ bool tx_done;
+
+- if (mcc_compl) {
+- be_cq_notify(adapter, mcc_obj->cq.id, true, mcc_compl);
++ /* Process all TXQs serviced by this EQ */
++ for (i = eqo->idx; i < adapter->num_tx_qs; i += adapter->num_evt_qs) {
++ tx_done = be_process_tx(adapter, &adapter->tx_obj[i],
++ eqo->tx_budget, i);
++ if (!tx_done)
++ max_work = budget;
+ }
+
+- napi_complete(napi);
++ /* This loop will iterate twice for EQ0 in which
++ * completions of the last RXQ (default one) are also processed
++ * For other EQs the loop iterates only once
++ */
++ for (i = eqo->idx; i < adapter->num_rx_qs; i += adapter->num_evt_qs) {
++ work = be_process_rx(&adapter->rx_obj[i], napi, budget);
++ max_work = max(work, max_work);
++ }
+
+- /* Arm CQ again to regenerate EQEs for Lancer in INTx mode */
+- if (lancer_chip(adapter) && !msix_enabled(adapter)) {
+- for_all_tx_queues(adapter, txo, i)
+- be_cq_notify(adapter, txo->cq.id, true, 0);
++ if (is_mcc_eqo(eqo))
++ be_process_mcc(adapter);
+
+- be_cq_notify(adapter, mcc_obj->cq.id, true, 0);
++ if (max_work < budget) {
++ napi_complete(napi);
++ be_eq_notify(adapter, eqo->q.id, true, false, 0);
++ } else {
++ /* As we'll continue in polling mode, count and clear events */
++ be_eq_notify(adapter, eqo->q.id, false, false, events_get(eqo));
+ }
+-
+- be_eq_notify(adapter, tx_eq->q.id, true, false, 0);
+- adapter->drv_stats.tx_events++;
+- return 1;
++ return max_work;
+ }
+
+ void be_detect_dump_ue(struct be_adapter *adapter)
+@@ -2104,12 +2039,24 @@ static void be_msix_disable(struct be_adapter *adapter)
+ }
+ }
+
++static uint be_num_rss_want(struct be_adapter *adapter)
++{
++ if ((adapter->function_caps & BE_FUNCTION_CAPS_RSS) &&
++ adapter->num_vfs == 0 && be_physfn(adapter) &&
++ !be_is_mc(adapter))
++ return (adapter->be3_native) ? BE3_MAX_RSS_QS : BE2_MAX_RSS_QS;
++ else
++ return 0;
++}
++
+ static void be_msix_enable(struct be_adapter *adapter)
+ {
+-#define BE_MIN_MSIX_VECTORS (1 + 1) /* Rx + Tx */
++#define BE_MIN_MSIX_VECTORS 1
+ int i, status, num_vec;
+
+- num_vec = be_num_rxqs_want(adapter) + 1;
++ /* If RSS queues are not used, need a vec for default RX Q */
++ num_vec = min(be_num_rss_want(adapter), num_online_cpus());
++ num_vec = max(num_vec, BE_MIN_MSIX_VECTORS);
+
+ for (i = 0; i < num_vec; i++)
+ adapter->msix_entries[i].entry = i;
+@@ -2177,60 +2124,31 @@ static void be_sriov_disable(struct be_adapter *adapter)
+ }
+
+ static inline int be_msix_vec_get(struct be_adapter *adapter,
+- struct be_eq_obj *eq_obj)
+-{
+- return adapter->msix_entries[eq_obj->eq_idx].vector;
+-}
+-
+-static int be_request_irq(struct be_adapter *adapter,
+- struct be_eq_obj *eq_obj,
+- void *handler, char *desc, void *context)
+-{
+- struct net_device *netdev = adapter->netdev;
+- int vec;
+-
+- sprintf(eq_obj->desc, "%s-%s", netdev->name, desc);
+- vec = be_msix_vec_get(adapter, eq_obj);
+- return request_irq(vec, handler, 0, eq_obj->desc, context);
+-}
+-
+-static void be_free_irq(struct be_adapter *adapter, struct be_eq_obj *eq_obj,
+- void *context)
++ struct be_eq_obj *eqo)
+ {
+- int vec = be_msix_vec_get(adapter, eq_obj);
+- free_irq(vec, context);
++ return adapter->msix_entries[eqo->idx].vector;
+ }
+
+ static int be_msix_register(struct be_adapter *adapter)
+ {
+- struct be_rx_obj *rxo;
+- int status, i;
+- char qname[10];
+-
+- status = be_request_irq(adapter, &adapter->tx_eq, be_msix_tx_mcc, "tx",
+- adapter);
+- if (status)
+- goto err;
++ struct net_device *netdev = adapter->netdev;
++ struct be_eq_obj *eqo;
++ int status, i, vec;
+
+- for_all_rx_queues(adapter, rxo, i) {
+- sprintf(qname, "rxq%d", i);
+- status = be_request_irq(adapter, &rxo->rx_eq, be_msix_rx,
+- qname, rxo);
++ for_all_evt_queues(adapter, eqo, i) {
++ sprintf(eqo->desc, "%s-q%d", netdev->name, i);
++ vec = be_msix_vec_get(adapter, eqo);
++ status = request_irq(vec, be_msix, 0, eqo->desc, eqo);
+ if (status)
+ goto err_msix;
+ }
+
+ return 0;
+-
+ err_msix:
+- be_free_irq(adapter, &adapter->tx_eq, adapter);
+-
+- for (i--, rxo = &adapter->rx_obj[i]; i >= 0; i--, rxo--)
+- be_free_irq(adapter, &rxo->rx_eq, rxo);
+-
+-err:
+- dev_warn(&adapter->pdev->dev,
+- "MSIX Request IRQ failed - err %d\n", status);
++ for (i--, eqo = &adapter->eq_obj[i]; i >= 0; i--, eqo--)
++ free_irq(be_msix_vec_get(adapter, eqo), eqo);
++ dev_warn(&adapter->pdev->dev, "MSIX Request IRQ failed - err %d\n",
++ status);
+ be_msix_disable(adapter);
+ return status;
+ }
+@@ -2266,7 +2184,7 @@ done:
+ static void be_irq_unregister(struct be_adapter *adapter)
+ {
+ struct net_device *netdev = adapter->netdev;
+- struct be_rx_obj *rxo;
++ struct be_eq_obj *eqo;
+ int i;
+
+ if (!adapter->isr_registered)
+@@ -2279,16 +2197,14 @@ static void be_irq_unregister(struct be_adapter *adapter)
+ }
+
+ /* MSIx */
+- be_free_irq(adapter, &adapter->tx_eq, adapter);
+-
+- for_all_rx_queues(adapter, rxo, i)
+- be_free_irq(adapter, &rxo->rx_eq, rxo);
++ for_all_evt_queues(adapter, eqo, i)
++ free_irq(be_msix_vec_get(adapter, eqo), eqo);
+
+ done:
+ adapter->isr_registered = false;
+ }
+
+-static void be_rx_queues_clear(struct be_adapter *adapter)
++static void be_rx_qs_destroy(struct be_adapter *adapter)
+ {
+ struct be_queue_info *q;
+ struct be_rx_obj *rxo;
+@@ -2303,53 +2219,33 @@ static void be_rx_queues_clear(struct be_adapter *adapter)
+ * arrive
+ */
+ mdelay(1);
+- be_rx_q_clean(adapter, rxo);
++ be_rx_cq_clean(rxo);
+ }
+-
+- /* Clear any residual events */
+- q = &rxo->rx_eq.q;
+- if (q->created)
+- be_eq_clean(adapter, &rxo->rx_eq);
++ be_queue_free(adapter, q);
+ }
+ }
+
+ static int be_close(struct net_device *netdev)
+ {
+ struct be_adapter *adapter = netdev_priv(netdev);
+- struct be_rx_obj *rxo;
+ struct be_tx_obj *txo;
+- struct be_eq_obj *tx_eq = &adapter->tx_eq;
+- int vec, i;
++ struct be_eq_obj *eqo;
++ int i;
+
+ be_async_mcc_disable(adapter);
+
+ if (!lancer_chip(adapter))
+ be_intr_set(adapter, false);
+
+- for_all_rx_queues(adapter, rxo, i)
+- napi_disable(&rxo->rx_eq.napi);
+-
+- napi_disable(&tx_eq->napi);
+-
+- if (lancer_chip(adapter)) {
+- be_cq_notify(adapter, adapter->mcc_obj.cq.id, false, 0);
+- for_all_rx_queues(adapter, rxo, i)
+- be_cq_notify(adapter, rxo->cq.id, false, 0);
+- for_all_tx_queues(adapter, txo, i)
+- be_cq_notify(adapter, txo->cq.id, false, 0);
++ for_all_evt_queues(adapter, eqo, i) {
++ napi_disable(&eqo->napi);
++ if (msix_enabled(adapter))
++ synchronize_irq(be_msix_vec_get(adapter, eqo));
++ else
++ synchronize_irq(netdev->irq);
++ be_eq_clean(eqo);
+ }
+
+- if (msix_enabled(adapter)) {
+- vec = be_msix_vec_get(adapter, tx_eq);
+- synchronize_irq(vec);
+-
+- for_all_rx_queues(adapter, rxo, i) {
+- vec = be_msix_vec_get(adapter, &rxo->rx_eq);
+- synchronize_irq(vec);
+- }
+- } else {
+- synchronize_irq(netdev->irq);
+- }
+ be_irq_unregister(adapter);
+
+ /* Wait for all pending tx completions to arrive so that
+@@ -2358,21 +2254,34 @@ static int be_close(struct net_device *netdev)
+ for_all_tx_queues(adapter, txo, i)
+ be_tx_compl_clean(adapter, txo);
+
+- be_rx_queues_clear(adapter);
++ be_rx_qs_destroy(adapter);
+ return 0;
+ }
+
+-static int be_rx_queues_setup(struct be_adapter *adapter)
++static int be_rx_qs_create(struct be_adapter *adapter)
+ {
+ struct be_rx_obj *rxo;
+ int rc, i, j;
+ u8 rsstable[128];
+
+ for_all_rx_queues(adapter, rxo, i) {
++ rc = be_queue_alloc(adapter, &rxo->q, RX_Q_LEN,
++ sizeof(struct be_eth_rx_d));
++ if (rc)
++ return rc;
++ }
++
++ /* The FW would like the default RXQ to be created first */
++ rxo = default_rxo(adapter);
++ rc = be_cmd_rxq_create(adapter, &rxo->q, rxo->cq.id, rx_frag_size,
++ adapter->if_handle, false, &rxo->rss_id);
++ if (rc)
++ return rc;
++
++ for_all_rss_queues(adapter, rxo, i) {
+ rc = be_cmd_rxq_create(adapter, &rxo->q, rxo->cq.id,
+- rx_frag_size, BE_MAX_JUMBO_FRAME_SIZE,
+- adapter->if_handle,
+- (i > 0) ? 1 : 0/* rss enable */, &rxo->rss_id);
++ rx_frag_size, adapter->if_handle,
++ true, &rxo->rss_id);
+ if (rc)
+ return rc;
+ }
+@@ -2386,48 +2295,47 @@ static int be_rx_queues_setup(struct be_adapter *adapter)
+ }
+ }
+ rc = be_cmd_rss_config(adapter, rsstable, 128);
+-
+ if (rc)
+ return rc;
+ }
+
+ /* First time posting */
+- for_all_rx_queues(adapter, rxo, i) {
++ for_all_rx_queues(adapter, rxo, i)
+ be_post_rx_frags(rxo, GFP_KERNEL);
+- napi_enable(&rxo->rx_eq.napi);
+- }
+ return 0;
+ }
+
+ static int be_open(struct net_device *netdev)
+ {
+ struct be_adapter *adapter = netdev_priv(netdev);
+- struct be_eq_obj *tx_eq = &adapter->tx_eq;
++ struct be_eq_obj *eqo;
+ struct be_rx_obj *rxo;
++ struct be_tx_obj *txo;
+ u8 link_status;
+ int status, i;
+
+- status = be_rx_queues_setup(adapter);
++ status = be_rx_qs_create(adapter);
+ if (status)
+ goto err;
+
+- napi_enable(&tx_eq->napi);
+-
+ be_irq_register(adapter);
+
+ if (!lancer_chip(adapter))
+ be_intr_set(adapter, true);
+
+- /* The evt queues are created in unarmed state; arm them */
+- for_all_rx_queues(adapter, rxo, i) {
+- be_eq_notify(adapter, rxo->rx_eq.q.id, true, false, 0);
++ for_all_rx_queues(adapter, rxo, i)
+ be_cq_notify(adapter, rxo->cq.id, true, 0);
+- }
+- be_eq_notify(adapter, tx_eq->q.id, true, false, 0);
+
+- /* Now that interrupts are on we can process async mcc */
++ for_all_tx_queues(adapter, txo, i)
++ be_cq_notify(adapter, txo->cq.id, true, 0);
++
+ be_async_mcc_enable(adapter);
+
++ for_all_evt_queues(adapter, eqo, i) {
++ napi_enable(&eqo->napi);
++ be_eq_notify(adapter, eqo->q.id, true, false, 0);
++ }
++
+ status = be_cmd_link_status_query(adapter, NULL, NULL,
+ &link_status, 0);
+ if (!status)
+@@ -2537,11 +2445,14 @@ static int be_clear(struct be_adapter *adapter)
+ be_cmd_if_destroy(adapter, adapter->if_handle, 0);
+
+ be_mcc_queues_destroy(adapter);
+- be_rx_queues_destroy(adapter);
++ be_rx_cqs_destroy(adapter);
+ be_tx_queues_destroy(adapter);
++ be_evt_queues_destroy(adapter);
+
+ /* tell fw we're done with firing cmds */
+ be_cmd_fw_clean(adapter);
++
++ be_msix_disable(adapter);
+ return 0;
+ }
+
+@@ -2631,24 +2542,29 @@ static int be_setup(struct be_adapter *adapter)
+ struct net_device *netdev = adapter->netdev;
+ u32 cap_flags, en_flags;
+ u32 tx_fc, rx_fc;
+- int status, i;
++ int status;
+ u8 mac[ETH_ALEN];
+- struct be_tx_obj *txo;
+
+ be_setup_init(adapter);
+
+ be_cmd_req_native_mode(adapter);
+
+- status = be_tx_queues_create(adapter);
+- if (status != 0)
++ be_msix_enable(adapter);
++
++ status = be_evt_queues_create(adapter);
++ if (status)
+ goto err;
+
+- status = be_rx_queues_create(adapter);
+- if (status != 0)
++ status = be_tx_cqs_create(adapter);
++ if (status)
++ goto err;
++
++ status = be_rx_cqs_create(adapter);
++ if (status)
+ goto err;
+
+ status = be_mcc_queues_create(adapter);
+- if (status != 0)
++ if (status)
+ goto err;
+
+ memset(mac, 0, ETH_ALEN);
+@@ -2674,12 +2590,6 @@ static int be_setup(struct be_adapter *adapter)
+ if (status != 0)
+ goto err;
+
+- for_all_tx_queues(adapter, txo, i) {
+- status = be_cmd_txq_create(adapter, &txo->q, &txo->cq);
+- if (status)
+- goto err;
+- }
+-
+ /* The VF's permanent mac queried from card is incorrect.
+ * For BEx: Query the mac configued by the PF using if_handle
+ * For Lancer: Get and use mac_list to obtain mac address.
+@@ -2697,6 +2607,10 @@ static int be_setup(struct be_adapter *adapter)
+ }
+ }
+
++ status = be_tx_qs_create(adapter);
++ if (status)
++ goto err;
++
+ be_cmd_get_fw_ver(adapter, adapter->fw_ver, NULL);
+
+ status = be_vid_config(adapter, false, 0);
+@@ -2736,12 +2650,13 @@ err:
+ static void be_netpoll(struct net_device *netdev)
+ {
+ struct be_adapter *adapter = netdev_priv(netdev);
+- struct be_rx_obj *rxo;
++ struct be_eq_obj *eqo;
+ int i;
+
+- event_handle(adapter, &adapter->tx_eq, false);
+- for_all_rx_queues(adapter, rxo, i)
+- event_handle(adapter, &rxo->rx_eq, true);
++ for_all_evt_queues(adapter, eqo, i)
++ event_handle(eqo);
++
++ return;
+ }
+ #endif
+
+@@ -3102,7 +3017,7 @@ static const struct net_device_ops be_netdev_ops = {
+ static void be_netdev_init(struct net_device *netdev)
+ {
+ struct be_adapter *adapter = netdev_priv(netdev);
+- struct be_rx_obj *rxo;
++ struct be_eq_obj *eqo;
+ int i;
+
+ netdev->hw_features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 |
+@@ -3121,16 +3036,12 @@ static void be_netdev_init(struct net_device *netdev)
+
+ netif_set_gso_max_size(netdev, 65535);
+
+- BE_SET_NETDEV_OPS(netdev, &be_netdev_ops);
++ netdev->netdev_ops = &be_netdev_ops;
+
+ SET_ETHTOOL_OPS(netdev, &be_ethtool_ops);
+
+- for_all_rx_queues(adapter, rxo, i)
+- netif_napi_add(netdev, &rxo->rx_eq.napi, be_poll_rx,
+- BE_NAPI_WEIGHT);
+-
+- netif_napi_add(netdev, &adapter->tx_eq.napi, be_poll_tx_mcc,
+- BE_NAPI_WEIGHT);
++ for_all_evt_queues(adapter, eqo, i)
++ netif_napi_add(netdev, &eqo->napi, be_poll, BE_NAPI_WEIGHT);
+ }
+
+ static void be_unmap_pci_bars(struct be_adapter *adapter)
+@@ -3301,8 +3212,6 @@ static void __devexit be_remove(struct pci_dev *pdev)
+
+ be_sriov_disable(adapter);
+
+- be_msix_disable(adapter);
+-
+ pci_set_drvdata(pdev, NULL);
+ pci_release_regions(pdev);
+ pci_disable_device(pdev);
+@@ -3469,6 +3378,7 @@ static void be_worker(struct work_struct *work)
+ struct be_adapter *adapter =
+ container_of(work, struct be_adapter, work.work);
+ struct be_rx_obj *rxo;
++ struct be_eq_obj *eqo;
+ int i;
+
+ if (lancer_chip(adapter))
+@@ -3479,15 +3389,7 @@ static void be_worker(struct work_struct *work)
+ /* when interrupts are not yet enabled, just reap any pending
+ * mcc completions */
+ if (!netif_running(adapter->netdev)) {
+- int mcc_compl, status = 0;
+-
+- mcc_compl = be_process_mcc(adapter, &status);
+-
+- if (mcc_compl) {
+- struct be_mcc_obj *mcc_obj = &adapter->mcc_obj;
+- be_cq_notify(adapter, mcc_obj->cq.id, false, mcc_compl);
+- }
+-
++ be_process_mcc(adapter);
+ goto reschedule;
+ }
+
+@@ -3500,14 +3402,15 @@ static void be_worker(struct work_struct *work)
+ }
+
+ for_all_rx_queues(adapter, rxo, i) {
+- be_rx_eqd_update(adapter, rxo);
+-
+ if (rxo->rx_post_starved) {
+ rxo->rx_post_starved = false;
+ be_post_rx_frags(rxo, GFP_KERNEL);
+ }
+ }
+
++ for_all_evt_queues(adapter, eqo, i)
++ be_eqd_update(adapter, eqo);
++
+ reschedule:
+ adapter->work_counter++;
+ schedule_delayed_work(&adapter->work, msecs_to_jiffies(1000));
+@@ -3593,6 +3496,12 @@ static int __devinit be_probe(struct pci_dev *pdev,
+ if (status)
+ goto ctrl_clean;
+
++ /* The INTR bit may be set in the card when probed by a kdump kernel
++ * after a crash.
++ */
++ if (!lancer_chip(adapter))
++ be_intr_set(adapter, false);
++
+ status = be_stats_init(adapter);
+ if (status)
+ goto ctrl_clean;
+@@ -3601,14 +3510,6 @@ static int __devinit be_probe(struct pci_dev *pdev,
+ if (status)
+ goto stats_clean;
+
+- /* The INTR bit may be set in the card when probed by a kdump kernel
+- * after a crash.
+- */
+- if (!lancer_chip(adapter))
+- be_intr_set(adapter, false);
+-
+- be_msix_enable(adapter);
+-
+ INIT_DELAYED_WORK(&adapter->work, be_worker);
+ adapter->rx_fc = adapter->tx_fc = true;
+
+@@ -3621,7 +3522,8 @@ static int __devinit be_probe(struct pci_dev *pdev,
+ if (status != 0)
+ goto unsetup;
+
+- dev_info(&pdev->dev, "%s port %d\n", nic_name(pdev), adapter->port_num);
++ dev_info(&pdev->dev, "%s: %s port %d\n", netdev->name, nic_name(pdev),
++ adapter->port_num);
+
+ schedule_delayed_work(&adapter->work, msecs_to_jiffies(100));
+ return 0;
+@@ -3665,7 +3567,6 @@ static int be_suspend(struct pci_dev *pdev, pm_message_t state)
+ }
+ be_clear(adapter);
+
+- be_msix_disable(adapter);
+ pci_save_state(pdev);
+ pci_disable_device(pdev);
+ pci_set_power_state(pdev, pci_choose_state(pdev, state));
+@@ -3687,7 +3588,6 @@ static int be_resume(struct pci_dev *pdev)
+ pci_set_power_state(pdev, 0);
+ pci_restore_state(pdev);
+
+- be_msix_enable(adapter);
+ /* tell fw we're ready to fire cmds */
+ status = be_cmd_fw_init(adapter);
+ if (status)
+--
+1.7.10
+
Added: dists/sid/linux-2.6/debian/patches/features/all/be2net/0033-be2net-cancel-be_worker-during-EEH-recovery.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/be2net/0033-be2net-cancel-be_worker-during-EEH-recovery.patch Sun May 27 00:21:22 2012 (r19037)
@@ -0,0 +1,90 @@
+From: Sathya Perla <sathya.perla at emulex.com>
+Date: Thu, 23 Feb 2012 18:50:13 +0000
+Subject: [PATCH 33/58] be2net: cancel be_worker during EEH recovery
+
+commit 191eb7563164529bc7d6a693742fe5bed33cf004 upstream.
+
+EEH recovery involves ring cleanup and re-creation. The worker
+thread must not run during EEH cleanup/resume.
+
+Signed-off-by: Sathya Perla <sathya.perla at emulex.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/emulex/benet/be.h | 1 +
+ drivers/net/ethernet/emulex/benet/be_main.c | 13 ++++++++-----
+ 2 files changed, 9 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h
+index 86f51de..4b1994d 100644
+--- a/drivers/net/ethernet/emulex/benet/be.h
++++ b/drivers/net/ethernet/emulex/benet/be.h
+@@ -304,6 +304,7 @@ struct be_vf_cfg {
+ };
+
+ #define BE_FLAGS_LINK_STATUS_INIT 1
++#define BE_FLAGS_WORKER_SCHEDULED (1 << 3)
+
+ struct be_adapter {
+ struct pci_dev *pdev;
+diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
+index 4a3a186..2c146ac 100644
+--- a/drivers/net/ethernet/emulex/benet/be_main.c
++++ b/drivers/net/ethernet/emulex/benet/be_main.c
+@@ -2439,6 +2439,11 @@ static void be_vf_clear(struct be_adapter *adapter)
+
+ static int be_clear(struct be_adapter *adapter)
+ {
++ if (adapter->flags & BE_FLAGS_WORKER_SCHEDULED) {
++ cancel_delayed_work_sync(&adapter->work);
++ adapter->flags &= ~BE_FLAGS_WORKER_SCHEDULED;
++ }
++
+ if (sriov_enabled(adapter))
+ be_vf_clear(adapter);
+
+@@ -2640,6 +2645,9 @@ static int be_setup(struct be_adapter *adapter)
+ goto err;
+ }
+
++ schedule_delayed_work(&adapter->work, msecs_to_jiffies(1000));
++ adapter->flags |= BE_FLAGS_WORKER_SCHEDULED;
++
+ return 0;
+ err:
+ be_clear(adapter);
+@@ -3200,8 +3208,6 @@ static void __devexit be_remove(struct pci_dev *pdev)
+ if (!adapter)
+ return;
+
+- cancel_delayed_work_sync(&adapter->work);
+-
+ unregister_netdev(adapter->netdev);
+
+ be_clear(adapter);
+@@ -3525,7 +3531,6 @@ static int __devinit be_probe(struct pci_dev *pdev,
+ dev_info(&pdev->dev, "%s: %s port %d\n", netdev->name, nic_name(pdev),
+ adapter->port_num);
+
+- schedule_delayed_work(&adapter->work, msecs_to_jiffies(100));
+ return 0;
+
+ unsetup:
+@@ -3555,7 +3560,6 @@ static int be_suspend(struct pci_dev *pdev, pm_message_t state)
+ struct be_adapter *adapter = pci_get_drvdata(pdev);
+ struct net_device *netdev = adapter->netdev;
+
+- cancel_delayed_work_sync(&adapter->work);
+ if (adapter->wol)
+ be_setup_wol(adapter, true);
+
+@@ -3604,7 +3608,6 @@ static int be_resume(struct pci_dev *pdev)
+ if (adapter->wol)
+ be_setup_wol(adapter, false);
+
+- schedule_delayed_work(&adapter->work, msecs_to_jiffies(100));
+ return 0;
+ }
+
+--
+1.7.10
+
Added: dists/sid/linux-2.6/debian/patches/features/all/be2net/0034-be2net-fix-tx-completion-cleanup.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/be2net/0034-be2net-fix-tx-completion-cleanup.patch Sun May 27 00:21:22 2012 (r19037)
@@ -0,0 +1,133 @@
+From: Sathya Perla <sathya.perla at emulex.com>
+Date: Thu, 23 Feb 2012 18:50:14 +0000
+Subject: [PATCH 34/58] be2net: fix tx completion cleanup
+
+commit 0ae57bb3df562e57ac89ad7bc524b6f2e83235f9 upstream.
+
+As a part of be_close(), instead of waiting for a max of 200ms for each TXQ,
+wait for a total of 200ms for completions from all TXQs to arrive.
+
+Signed-off-by: Sathya Perla <sathya.perla at emulex.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/emulex/benet/be_main.c | 75 +++++++++++++++------------
+ 1 file changed, 42 insertions(+), 33 deletions(-)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
+index 2c146ac..dce97dc 100644
+--- a/drivers/net/ethernet/emulex/benet/be_main.c
++++ b/drivers/net/ethernet/emulex/benet/be_main.c
+@@ -1555,51 +1555,62 @@ static void be_rx_cq_clean(struct be_rx_obj *rxo)
+ rxq->tail = rxq->head = 0;
+ }
+
+-static void be_tx_compl_clean(struct be_adapter *adapter,
+- struct be_tx_obj *txo)
++static void be_tx_compl_clean(struct be_adapter *adapter)
+ {
+- struct be_queue_info *tx_cq = &txo->cq;
+- struct be_queue_info *txq = &txo->q;
++ struct be_tx_obj *txo;
++ struct be_queue_info *txq;
+ struct be_eth_tx_compl *txcp;
+ u16 end_idx, cmpl = 0, timeo = 0, num_wrbs = 0;
+- struct sk_buff **sent_skbs = txo->sent_skb_list;
+ struct sk_buff *sent_skb;
+ bool dummy_wrb;
++ int i, pending_txqs;
+
+ /* Wait for a max of 200ms for all the tx-completions to arrive. */
+ do {
+- while ((txcp = be_tx_compl_get(tx_cq))) {
+- end_idx = AMAP_GET_BITS(struct amap_eth_tx_compl,
+- wrb_index, txcp);
+- num_wrbs += be_tx_compl_process(adapter, txo, end_idx);
+- cmpl++;
+- }
+- if (cmpl) {
+- be_cq_notify(adapter, tx_cq->id, false, cmpl);
+- atomic_sub(num_wrbs, &txq->used);
+- cmpl = 0;
+- num_wrbs = 0;
++ pending_txqs = adapter->num_tx_qs;
++
++ for_all_tx_queues(adapter, txo, i) {
++ txq = &txo->q;
++ while ((txcp = be_tx_compl_get(&txo->cq))) {
++ end_idx =
++ AMAP_GET_BITS(struct amap_eth_tx_compl,
++ wrb_index, txcp);
++ num_wrbs += be_tx_compl_process(adapter, txo,
++ end_idx);
++ cmpl++;
++ }
++ if (cmpl) {
++ be_cq_notify(adapter, txo->cq.id, false, cmpl);
++ atomic_sub(num_wrbs, &txq->used);
++ cmpl = 0;
++ num_wrbs = 0;
++ }
++ if (atomic_read(&txq->used) == 0)
++ pending_txqs--;
+ }
+
+- if (atomic_read(&txq->used) == 0 || ++timeo > 200)
++ if (pending_txqs == 0 || ++timeo > 200)
+ break;
+
+ mdelay(1);
+ } while (true);
+
+- if (atomic_read(&txq->used))
+- dev_err(&adapter->pdev->dev, "%d pending tx-completions\n",
+- atomic_read(&txq->used));
+-
+- /* free posted tx for which compls will never arrive */
+- while (atomic_read(&txq->used)) {
+- sent_skb = sent_skbs[txq->tail];
+- end_idx = txq->tail;
+- index_adv(&end_idx,
+- wrb_cnt_for_skb(adapter, sent_skb, &dummy_wrb) - 1,
+- txq->len);
+- num_wrbs = be_tx_compl_process(adapter, txo, end_idx);
+- atomic_sub(num_wrbs, &txq->used);
++ for_all_tx_queues(adapter, txo, i) {
++ txq = &txo->q;
++ if (atomic_read(&txq->used))
++ dev_err(&adapter->pdev->dev, "%d pending tx-compls\n",
++ atomic_read(&txq->used));
++
++ /* free posted tx for which compls will never arrive */
++ while (atomic_read(&txq->used)) {
++ sent_skb = txo->sent_skb_list[txq->tail];
++ end_idx = txq->tail;
++ num_wrbs = wrb_cnt_for_skb(adapter, sent_skb,
++ &dummy_wrb);
++ index_adv(&end_idx, num_wrbs - 1, txq->len);
++ num_wrbs = be_tx_compl_process(adapter, txo, end_idx);
++ atomic_sub(num_wrbs, &txq->used);
++ }
+ }
+ }
+
+@@ -2228,7 +2239,6 @@ static void be_rx_qs_destroy(struct be_adapter *adapter)
+ static int be_close(struct net_device *netdev)
+ {
+ struct be_adapter *adapter = netdev_priv(netdev);
+- struct be_tx_obj *txo;
+ struct be_eq_obj *eqo;
+ int i;
+
+@@ -2251,8 +2261,7 @@ static int be_close(struct net_device *netdev)
+ /* Wait for all pending tx completions to arrive so that
+ * all tx skbs are freed.
+ */
+- for_all_tx_queues(adapter, txo, i)
+- be_tx_compl_clean(adapter, txo);
++ be_tx_compl_clean(adapter);
+
+ be_rx_qs_destroy(adapter);
+ return 0;
+--
+1.7.10
+
Added: dists/sid/linux-2.6/debian/patches/features/all/be2net/0035-be2net-reset-queue-address-after-freeing.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/be2net/0035-be2net-reset-queue-address-after-freeing.patch Sun May 27 00:21:22 2012 (r19037)
@@ -0,0 +1,44 @@
+From: Sathya Perla <sathya.perla at emulex.com>
+Date: Thu, 23 Feb 2012 18:50:15 +0000
+Subject: [PATCH 35/58] be2net: reset queue address after freeing
+
+commit 1cfafab965198bc0d9cb794af5065d0797969727 upstream.
+
+This will prevent double free in some cases where be_clear() is called
+for cleanup when be_setup() fails half-way.
+
+Signed-off-by: Sathya Perla <sathya.perla at emulex.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/emulex/benet/be_main.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
+index dce97dc..c1b9cdf 100644
+--- a/drivers/net/ethernet/emulex/benet/be_main.c
++++ b/drivers/net/ethernet/emulex/benet/be_main.c
+@@ -127,9 +127,11 @@ static inline bool be_is_mc(struct be_adapter *adapter) {
+ static void be_queue_free(struct be_adapter *adapter, struct be_queue_info *q)
+ {
+ struct be_dma_mem *mem = &q->dma_mem;
+- if (mem->va)
++ if (mem->va) {
+ dma_free_coherent(&adapter->pdev->dev, mem->size, mem->va,
+ mem->dma);
++ mem->va = NULL;
++ }
+ }
+
+ static int be_queue_alloc(struct be_adapter *adapter, struct be_queue_info *q,
+@@ -1652,7 +1654,7 @@ static int be_evt_queues_create(struct be_adapter *adapter)
+ if (rc)
+ return rc;
+ }
+- return rc;
++ return 0;
+ }
+
+ static void be_mcc_queues_destroy(struct be_adapter *adapter)
+--
+1.7.10
+
Added: dists/sid/linux-2.6/debian/patches/features/all/be2net/0036-be2net-enable-RSS-for-ipv6-pkts.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/be2net/0036-be2net-enable-RSS-for-ipv6-pkts.patch Sun May 27 00:21:22 2012 (r19037)
@@ -0,0 +1,29 @@
+From: Sathya Perla <sathya.perla at emulex.com>
+Date: Thu, 23 Feb 2012 18:50:16 +0000
+Subject: [PATCH 36/58] be2net: enable RSS for ipv6 pkts
+
+commit 1ca7ba921e8af04266881bc485be08d4fac5f1bc upstream.
+
+Signed-off-by: Sathya Perla <sathya.perla at emulex.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/emulex/benet/be_cmds.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
+index 6432efa..398fb5c 100644
+--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
++++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
+@@ -1694,7 +1694,8 @@ int be_cmd_rss_config(struct be_adapter *adapter, u8 *rsstable, u16 table_size)
+ OPCODE_ETH_RSS_CONFIG, sizeof(*req), wrb, NULL);
+
+ req->if_id = cpu_to_le32(adapter->if_handle);
+- req->enable_rss = cpu_to_le16(RSS_ENABLE_TCP_IPV4 | RSS_ENABLE_IPV4);
++ req->enable_rss = cpu_to_le16(RSS_ENABLE_TCP_IPV4 | RSS_ENABLE_IPV4 |
++ RSS_ENABLE_TCP_IPV6 | RSS_ENABLE_IPV6);
+ req->cpu_table_size_log2 = cpu_to_le16(fls(table_size) - 1);
+ memcpy(req->cpu_table, rsstable, table_size);
+ memcpy(req->hash, myhash, sizeof(myhash));
+--
+1.7.10
+
Added: dists/sid/linux-2.6/debian/patches/features/all/be2net/0037-be2net-update-driver-version.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/be2net/0037-be2net-update-driver-version.patch Sun May 27 00:21:22 2012 (r19037)
@@ -0,0 +1,28 @@
+From: Sathya Perla <sathya.perla at emulex.com>
+Date: Thu, 23 Feb 2012 18:50:17 +0000
+Subject: [PATCH 37/58] be2net: update driver version
+
+commit d708f6039b21ca8f0508ba1da1aaf3d00a36446f upstream.
+
+Signed-off-by: Sathya Perla <sathya.perla at emulex.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/emulex/benet/be.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h
+index 4b1994d..c357172 100644
+--- a/drivers/net/ethernet/emulex/benet/be.h
++++ b/drivers/net/ethernet/emulex/benet/be.h
+@@ -33,7 +33,7 @@
+
+ #include "be_hw.h"
+
+-#define DRV_VER "4.0.100u"
++#define DRV_VER "4.2.116u"
+ #define DRV_NAME "be2net"
+ #define BE_NAME "ServerEngines BladeEngine2 10Gbps NIC"
+ #define BE3_NAME "ServerEngines BladeEngine3 10Gbps NIC"
+--
+1.7.10
+
Added: dists/sid/linux-2.6/debian/patches/features/all/be2net/0038-be2net-Remove-unused-OFFSET_IN_PAGE-macro.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/be2net/0038-be2net-Remove-unused-OFFSET_IN_PAGE-macro.patch Sun May 27 00:21:22 2012 (r19037)
@@ -0,0 +1,30 @@
+From: Roland Dreier <roland at purestorage.com>
+Date: Wed, 29 Feb 2012 20:40:46 +0000
+Subject: [PATCH 38/58] be2net: Remove unused OFFSET_IN_PAGE() macro
+
+commit 97767a87f3be8834192dc3fc9412aaccf708d87f upstream.
+
+Signed-off-by: Roland Dreier <roland at purestorage.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/emulex/benet/be.h | 4 ----
+ 1 file changed, 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h
+index c357172..ab24e46 100644
+--- a/drivers/net/ethernet/emulex/benet/be.h
++++ b/drivers/net/ethernet/emulex/benet/be.h
+@@ -442,10 +442,6 @@ extern const struct ethtool_ops be_ethtool_ops;
+ ((u32)((((size_t)(_address) & (PAGE_SIZE_4K - 1)) + \
+ (size) + (PAGE_SIZE_4K - 1)) >> PAGE_SHIFT_4K))
+
+-/* Byte offset into the page corresponding to given address */
+-#define OFFSET_IN_PAGE(addr) \
+- ((size_t)(addr) & (PAGE_SIZE_4K-1))
+-
+ /* Returns bit offset within a DWORD of a bitfield */
+ #define AMAP_BIT_OFFSET(_struct, field) \
+ (((size_t)&(((_struct *)0)->field))%32)
+--
+1.7.10
+
Added: dists/sid/linux-2.6/debian/patches/features/all/be2net/0039-be2net-enable-WOL-by-default-if-h-w-supports-it.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/be2net/0039-be2net-enable-WOL-by-default-if-h-w-supports-it.patch Sun May 27 00:21:22 2012 (r19037)
@@ -0,0 +1,274 @@
+From: Ajit Khaparde <ajit.khaparde at emulex.com>
+Date: Sun, 18 Mar 2012 06:23:11 +0000
+Subject: [PATCH 39/58] be2net: enable WOL by default if h/w supports it
+
+commit 4762f6cec4455f3bbe4ca82c100fe5d85d3c02a2 upstream.
+
+Signed-off-by: Ajit Khaparde <ajit.khaparde at emulex.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/emulex/benet/be.h | 26 ++++++++++-
+ drivers/net/ethernet/emulex/benet/be_cmds.c | 55 ++++++++++++++++++++++++
+ drivers/net/ethernet/emulex/benet/be_cmds.h | 28 ++++++++++++
+ drivers/net/ethernet/emulex/benet/be_ethtool.c | 27 +++++-------
+ drivers/net/ethernet/emulex/benet/be_main.c | 17 ++++++++
+ 5 files changed, 136 insertions(+), 17 deletions(-)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h
+index ab24e46..cabe1b8 100644
+--- a/drivers/net/ethernet/emulex/benet/be.h
++++ b/drivers/net/ethernet/emulex/benet/be.h
+@@ -52,6 +52,10 @@
+ #define OC_DEVICE_ID3 0xe220 /* Device id for Lancer cards */
+ #define OC_DEVICE_ID4 0xe228 /* Device id for VF in Lancer */
+ #define OC_DEVICE_ID5 0x720 /* Device Id for Skyhawk cards */
++#define OC_SUBSYS_DEVICE_ID1 0xE602
++#define OC_SUBSYS_DEVICE_ID2 0xE642
++#define OC_SUBSYS_DEVICE_ID3 0xE612
++#define OC_SUBSYS_DEVICE_ID4 0xE652
+
+ static inline char *nic_name(struct pci_dev *pdev)
+ {
+@@ -365,7 +369,6 @@ struct be_adapter {
+ bool fw_timeout;
+ u32 port_num;
+ bool promiscuous;
+- bool wol;
+ u32 function_mode;
+ u32 function_caps;
+ u32 rx_fc; /* Rx flow control */
+@@ -386,6 +389,8 @@ struct be_adapter {
+ u32 sli_family;
+ u8 hba_port_num;
+ u16 pvid;
++ u8 wol_cap;
++ bool wol;
+ };
+
+ #define be_physfn(adapter) (!adapter->is_virtfn)
+@@ -549,9 +554,28 @@ static inline bool be_error(struct be_adapter *adapter)
+ return adapter->eeh_err || adapter->ue_detected || adapter->fw_timeout;
+ }
+
++static inline bool be_is_wol_excluded(struct be_adapter *adapter)
++{
++ struct pci_dev *pdev = adapter->pdev;
++
++ if (!be_physfn(adapter))
++ return true;
++
++ switch (pdev->subsystem_device) {
++ case OC_SUBSYS_DEVICE_ID1:
++ case OC_SUBSYS_DEVICE_ID2:
++ case OC_SUBSYS_DEVICE_ID3:
++ case OC_SUBSYS_DEVICE_ID4:
++ return true;
++ default:
++ return false;
++ }
++}
++
+ extern void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm,
+ u16 num_popped);
+ extern void be_link_status_update(struct be_adapter *adapter, u8 link_status);
+ extern void be_parse_stats(struct be_adapter *adapter);
+ extern int be_load_fw(struct be_adapter *adapter, u8 *func);
++extern bool be_is_wol_supported(struct be_adapter *adapter);
+ #endif /* BE_H */
+diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
+index 398fb5c..d72c2b4 100644
+--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
++++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
+@@ -2418,3 +2418,58 @@ err:
+ spin_unlock_bh(&adapter->mcc_lock);
+ return status;
+ }
++
++int be_cmd_get_acpi_wol_cap(struct be_adapter *adapter)
++{
++ struct be_mcc_wrb *wrb;
++ struct be_cmd_req_acpi_wol_magic_config_v1 *req;
++ int status;
++ int payload_len = sizeof(*req);
++ struct be_dma_mem cmd;
++
++ memset(&cmd, 0, sizeof(struct be_dma_mem));
++ cmd.size = sizeof(struct be_cmd_resp_acpi_wol_magic_config_v1);
++ cmd.va = pci_alloc_consistent(adapter->pdev, cmd.size,
++ &cmd.dma);
++ if (!cmd.va) {
++ dev_err(&adapter->pdev->dev,
++ "Memory allocation failure\n");
++ return -ENOMEM;
++ }
++
++ if (mutex_lock_interruptible(&adapter->mbox_lock))
++ return -1;
++
++ wrb = wrb_from_mbox(adapter);
++ if (!wrb) {
++ status = -EBUSY;
++ goto err;
++ }
++
++ req = cmd.va;
++
++ be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH,
++ OPCODE_ETH_ACPI_WOL_MAGIC_CONFIG,
++ payload_len, wrb, &cmd);
++
++ req->hdr.version = 1;
++ req->query_options = BE_GET_WOL_CAP;
++
++ status = be_mbox_notify_wait(adapter);
++ if (!status) {
++ struct be_cmd_resp_acpi_wol_magic_config_v1 *resp;
++ resp = (struct be_cmd_resp_acpi_wol_magic_config_v1 *) cmd.va;
++
++ /* the command could succeed misleadingly on old f/w
++ * which is not aware of the V1 version. fake an error. */
++ if (resp->hdr.response_length < payload_len) {
++ status = -1;
++ goto err;
++ }
++ adapter->wol_cap = resp->wol_settings;
++ }
++err:
++ mutex_unlock(&adapter->mbox_lock);
++ pci_free_consistent(adapter->pdev, cmd.size, cmd.va, cmd.dma);
++ return status;
++}
+diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h
+index 687c420..345d49e 100644
+--- a/drivers/net/ethernet/emulex/benet/be_cmds.h
++++ b/drivers/net/ethernet/emulex/benet/be_cmds.h
+@@ -1206,6 +1206,33 @@ struct be_cmd_req_acpi_wol_magic_config{
+ u8 rsvd2[2];
+ } __packed;
+
++struct be_cmd_req_acpi_wol_magic_config_v1 {
++ struct be_cmd_req_hdr hdr;
++ u8 rsvd0[2];
++ u8 query_options;
++ u8 rsvd1[5];
++ u32 rsvd2[288];
++ u8 magic_mac[6];
++ u8 rsvd3[22];
++} __packed;
++
++struct be_cmd_resp_acpi_wol_magic_config_v1 {
++ struct be_cmd_resp_hdr hdr;
++ u8 rsvd0[2];
++ u8 wol_settings;
++ u8 rsvd1[5];
++ u32 rsvd2[295];
++} __packed;
++
++#define BE_GET_WOL_CAP 2
++
++#define BE_WOL_CAP 0x1
++#define BE_PME_D0_CAP 0x8
++#define BE_PME_D1_CAP 0x10
++#define BE_PME_D2_CAP 0x20
++#define BE_PME_D3HOT_CAP 0x40
++#define BE_PME_D3COLD_CAP 0x80
++
+ /********************** LoopBack test *********************/
+ struct be_cmd_req_loopback_test {
+ struct be_cmd_req_hdr hdr;
+@@ -1590,4 +1617,5 @@ extern int be_cmd_get_mac_from_list(struct be_adapter *adapter, u32 domain,
+ bool *pmac_id_active, u32 *pmac_id, u8 *mac);
+ extern int be_cmd_set_mac_list(struct be_adapter *adapter, u8 *mac_array,
+ u8 mac_count, u32 domain);
++extern int be_cmd_get_acpi_wol_cap(struct be_adapter *adapter);
+
+diff --git a/drivers/net/ethernet/emulex/benet/be_ethtool.c b/drivers/net/ethernet/emulex/benet/be_ethtool.c
+index d98ad7e..e0eb995 100644
+--- a/drivers/net/ethernet/emulex/benet/be_ethtool.c
++++ b/drivers/net/ethernet/emulex/benet/be_ethtool.c
+@@ -600,26 +600,16 @@ be_set_phys_id(struct net_device *netdev,
+ return 0;
+ }
+
+-static bool
+-be_is_wol_supported(struct be_adapter *adapter)
+-{
+- if (!be_physfn(adapter))
+- return false;
+- else
+- return true;
+-}
+
+ static void
+ be_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
+ {
+ struct be_adapter *adapter = netdev_priv(netdev);
+
+- if (be_is_wol_supported(adapter))
+- wol->supported = WAKE_MAGIC;
+-
+- if (adapter->wol)
+- wol->wolopts = WAKE_MAGIC;
+- else
++ if (be_is_wol_supported(adapter)) {
++ wol->supported |= WAKE_MAGIC;
++ wol->wolopts |= WAKE_MAGIC;
++ } else
+ wol->wolopts = 0;
+ memset(&wol->sopass, 0, sizeof(wol->sopass));
+ }
+@@ -630,9 +620,14 @@ be_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
+ struct be_adapter *adapter = netdev_priv(netdev);
+
+ if (wol->wolopts & ~WAKE_MAGIC)
+- return -EINVAL;
++ return -EOPNOTSUPP;
++
++ if (!be_is_wol_supported(adapter)) {
++ dev_warn(&adapter->pdev->dev, "WOL not supported\n");
++ return -EOPNOTSUPP;
++ }
+
+- if ((wol->wolopts & WAKE_MAGIC) && be_is_wol_supported(adapter))
++ if (wol->wolopts & WAKE_MAGIC)
+ adapter->wol = true;
+ else
+ adapter->wol = false;
+diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
+index c1b9cdf..70b138f 100644
+--- a/drivers/net/ethernet/emulex/benet/be_main.c
++++ b/drivers/net/ethernet/emulex/benet/be_main.c
+@@ -3236,6 +3236,12 @@ static void __devexit be_remove(struct pci_dev *pdev)
+ free_netdev(adapter->netdev);
+ }
+
++bool be_is_wol_supported(struct be_adapter *adapter)
++{
++ return ((adapter->wol_cap & BE_WOL_CAP) &&
++ !be_is_wol_excluded(adapter)) ? true : false;
++}
++
+ static int be_get_config(struct be_adapter *adapter)
+ {
+ int status;
+@@ -3254,6 +3260,17 @@ static int be_get_config(struct be_adapter *adapter)
+ if (status)
+ return status;
+
++ status = be_cmd_get_acpi_wol_cap(adapter);
++ if (status) {
++ /* in case of a failure to get wol capabillities
++ * check the exclusion list to determine WOL capability */
++ if (!be_is_wol_excluded(adapter))
++ adapter->wol_cap |= BE_WOL_CAP;
++ }
++
++ if (be_is_wol_supported(adapter))
++ adapter->wol = true;
++
+ return 0;
+ }
+
+--
+1.7.10
+
Added: dists/sid/linux-2.6/debian/patches/features/all/be2net/0040-be2net-Program-secondary-UC-MAC-address-into-MAC-fil.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/be2net/0040-be2net-Program-secondary-UC-MAC-address-into-MAC-fil.patch Sun May 27 00:21:22 2012 (r19037)
@@ -0,0 +1,177 @@
+From: Ajit Khaparde <ajit.khaparde at emulex.com>
+Date: Sun, 18 Mar 2012 06:23:21 +0000
+Subject: [PATCH 40/58] be2net: Program secondary UC MAC address into MAC
+ filter
+
+commit fbc13f018c0043146f8eccc7d6a6c0e66339e2d5 upstream.
+
+Signed-off-by: Ajit Khaparde <ajit.khaparde at emulex.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/emulex/benet/be.h | 6 ++-
+ drivers/net/ethernet/emulex/benet/be_main.c | 53 ++++++++++++++++++++++++---
+ 2 files changed, 53 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h
+index cabe1b8..03fc3db 100644
+--- a/drivers/net/ethernet/emulex/benet/be.h
++++ b/drivers/net/ethernet/emulex/benet/be.h
+@@ -309,6 +309,8 @@ struct be_vf_cfg {
+
+ #define BE_FLAGS_LINK_STATUS_INIT 1
+ #define BE_FLAGS_WORKER_SCHEDULED (1 << 3)
++#define BE_UC_PMAC_COUNT 30
++#define BE_VF_UC_PMAC_COUNT 2
+
+ struct be_adapter {
+ struct pci_dev *pdev;
+@@ -361,7 +363,7 @@ struct be_adapter {
+ /* Ethtool knobs and info */
+ char fw_ver[FW_VER_LEN];
+ int if_handle; /* Used to configure filtering */
+- u32 pmac_id; /* MAC addr handle used by BE card */
++ u32 *pmac_id; /* MAC addr handle used by BE card */
+ u32 beacon_state; /* for set_phys_id */
+
+ bool eeh_err;
+@@ -391,6 +393,8 @@ struct be_adapter {
+ u16 pvid;
+ u8 wol_cap;
+ bool wol;
++ u32 max_pmac_cnt; /* Max secondary UC MACs programmable */
++ u32 uc_macs; /* Count of secondary UC MAC programmed */
+ };
+
+ #define be_physfn(adapter) (!adapter->is_virtfn)
+diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
+index 70b138f..b8b34f5 100644
+--- a/drivers/net/ethernet/emulex/benet/be_main.c
++++ b/drivers/net/ethernet/emulex/benet/be_main.c
+@@ -235,7 +235,7 @@ static int be_mac_addr_set(struct net_device *netdev, void *p)
+ struct sockaddr *addr = p;
+ int status = 0;
+ u8 current_mac[ETH_ALEN];
+- u32 pmac_id = adapter->pmac_id;
++ u32 pmac_id = adapter->pmac_id[0];
+
+ if (!is_valid_ether_addr(addr->sa_data))
+ return -EADDRNOTAVAIL;
+@@ -248,7 +248,7 @@ static int be_mac_addr_set(struct net_device *netdev, void *p)
+
+ if (memcmp(addr->sa_data, current_mac, ETH_ALEN)) {
+ status = be_cmd_pmac_add(adapter, (u8 *)addr->sa_data,
+- adapter->if_handle, &adapter->pmac_id, 0);
++ adapter->if_handle, &adapter->pmac_id[0], 0);
+ if (status)
+ goto err;
+
+@@ -877,6 +877,29 @@ static void be_set_rx_mode(struct net_device *netdev)
+ goto done;
+ }
+
++ if (netdev_uc_count(netdev) != adapter->uc_macs) {
++ struct netdev_hw_addr *ha;
++ int i = 1; /* First slot is claimed by the Primary MAC */
++
++ for (; adapter->uc_macs > 0; adapter->uc_macs--, i++) {
++ be_cmd_pmac_del(adapter, adapter->if_handle,
++ adapter->pmac_id[i], 0);
++ }
++
++ if (netdev_uc_count(netdev) > adapter->max_pmac_cnt) {
++ be_cmd_rx_filter(adapter, IFF_PROMISC, ON);
++ adapter->promiscuous = true;
++ goto done;
++ }
++
++ netdev_for_each_uc_addr(ha, adapter->netdev) {
++ adapter->uc_macs++; /* First slot is for Primary MAC */
++ be_cmd_pmac_add(adapter, (u8 *)ha->addr,
++ adapter->if_handle,
++ &adapter->pmac_id[adapter->uc_macs], 0);
++ }
++ }
++
+ be_cmd_rx_filter(adapter, IFF_MULTICAST, ON);
+ done:
+ return;
+@@ -2450,6 +2473,8 @@ static void be_vf_clear(struct be_adapter *adapter)
+
+ static int be_clear(struct be_adapter *adapter)
+ {
++ int i = 1;
++
+ if (adapter->flags & BE_FLAGS_WORKER_SCHEDULED) {
+ cancel_delayed_work_sync(&adapter->work);
+ adapter->flags &= ~BE_FLAGS_WORKER_SCHEDULED;
+@@ -2458,6 +2483,10 @@ static int be_clear(struct be_adapter *adapter)
+ if (sriov_enabled(adapter))
+ be_vf_clear(adapter);
+
++ for (; adapter->uc_macs > 0; adapter->uc_macs--, i++)
++ be_cmd_pmac_del(adapter, adapter->if_handle,
++ adapter->pmac_id[i], 0);
++
+ be_cmd_if_destroy(adapter, adapter->if_handle, 0);
+
+ be_mcc_queues_destroy(adapter);
+@@ -2469,6 +2498,7 @@ static int be_clear(struct be_adapter *adapter)
+ be_cmd_fw_clean(adapter);
+
+ be_msix_disable(adapter);
++ kfree(adapter->pmac_id);
+ return 0;
+ }
+
+@@ -2544,10 +2574,10 @@ static int be_add_mac_from_list(struct be_adapter *adapter, u8 *mac)
+ false, adapter->if_handle, pmac_id);
+
+ if (!status)
+- adapter->pmac_id = pmac_id;
++ adapter->pmac_id[0] = pmac_id;
+ } else {
+ status = be_cmd_pmac_add(adapter, mac,
+- adapter->if_handle, &adapter->pmac_id, 0);
++ adapter->if_handle, &adapter->pmac_id[0], 0);
+ }
+ do_none:
+ return status;
+@@ -2602,7 +2632,7 @@ static int be_setup(struct be_adapter *adapter)
+ }
+ status = be_cmd_if_create(adapter, cap_flags, en_flags,
+ netdev->dev_addr, &adapter->if_handle,
+- &adapter->pmac_id, 0);
++ &adapter->pmac_id[0], 0);
+ if (status != 0)
+ goto err;
+
+@@ -3051,6 +3081,8 @@ static void be_netdev_init(struct net_device *netdev)
+ netdev->vlan_features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 |
+ NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
+
++ netdev->priv_flags |= IFF_UNICAST_FLT;
++
+ netdev->flags |= IFF_MULTICAST;
+
+ netif_set_gso_max_size(netdev, 65535);
+@@ -3256,6 +3288,17 @@ static int be_get_config(struct be_adapter *adapter)
+ else
+ adapter->max_vlans = BE_NUM_VLANS_SUPPORTED;
+
++ if (be_physfn(adapter))
++ adapter->max_pmac_cnt = BE_UC_PMAC_COUNT;
++ else
++ adapter->max_pmac_cnt = BE_VF_UC_PMAC_COUNT;
++
++ /* primary mac needs 1 pmac entry */
++ adapter->pmac_id = kcalloc(adapter->max_pmac_cnt + 1,
++ sizeof(u32), GFP_KERNEL);
++ if (!adapter->pmac_id)
++ return -ENOMEM;
++
+ status = be_cmd_get_cntl_attributes(adapter);
+ if (status)
+ return status;
+--
+1.7.10
+
Added: dists/sid/linux-2.6/debian/patches/features/all/be2net/0041-be2net-Fix-number-of-vlan-slots-in-flex-mode.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/be2net/0041-be2net-Fix-number-of-vlan-slots-in-flex-mode.patch Sun May 27 00:21:22 2012 (r19037)
@@ -0,0 +1,30 @@
+From: Ajit Khaparde <ajit.khaparde at emulex.com>
+Date: Sun, 18 Mar 2012 06:23:31 +0000
+Subject: [PATCH 41/58] be2net: Fix number of vlan slots in flex mode
+
+commit 456d9c962bb5824423fa93277c8f7f5b2e3d5e1c upstream.
+
+In flex10 mode the number of vlan slots supported is halved.
+
+Signed-off-by: Ajit Khaparde <ajit.khaparde at emulex.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/emulex/benet/be_main.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
+index b8b34f5..c9a9bf0 100644
+--- a/drivers/net/ethernet/emulex/benet/be_main.c
++++ b/drivers/net/ethernet/emulex/benet/be_main.c
+@@ -3284,7 +3284,7 @@ static int be_get_config(struct be_adapter *adapter)
+ return status;
+
+ if (adapter->function_mode & FLEX10_MODE)
+- adapter->max_vlans = BE_NUM_VLANS_SUPPORTED/4;
++ adapter->max_vlans = BE_NUM_VLANS_SUPPORTED/8;
+ else
+ adapter->max_vlans = BE_NUM_VLANS_SUPPORTED;
+
+--
+1.7.10
+
Added: dists/sid/linux-2.6/debian/patches/features/all/be2net/0042-be2net-fix-programming-of-VLAN-tags-for-VF.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/be2net/0042-be2net-fix-programming-of-VLAN-tags-for-VF.patch Sun May 27 00:21:22 2012 (r19037)
@@ -0,0 +1,255 @@
+From: Ajit Khaparde <ajit.khaparde at emulex.com>
+Date: Sun, 18 Mar 2012 06:23:41 +0000
+Subject: [PATCH 42/58] be2net: fix programming of VLAN tags for VF
+
+commit f1f3ee1bcc996e21f122442fd8c34de51622c76a upstream.
+
+Signed-off-by: Ajit Khaparde <ajit.khaparde at emulex.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/emulex/benet/be.h | 1 +
+ drivers/net/ethernet/emulex/benet/be_cmds.c | 83 +++++++++++++++++++++++++++
+ drivers/net/ethernet/emulex/benet/be_cmds.h | 55 ++++++++++++++++++
+ drivers/net/ethernet/emulex/benet/be_main.c | 23 ++++++--
+ 4 files changed, 157 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h
+index 03fc3db..9576ac0 100644
+--- a/drivers/net/ethernet/emulex/benet/be.h
++++ b/drivers/net/ethernet/emulex/benet/be.h
+@@ -303,6 +303,7 @@ struct be_vf_cfg {
+ unsigned char mac_addr[ETH_ALEN];
+ int if_handle;
+ int pmac_id;
++ u16 def_vid;
+ u16 vlan_tag;
+ u32 tx_rate;
+ };
+diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
+index d72c2b4..67b030d 100644
+--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
++++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
+@@ -2419,6 +2419,89 @@ err:
+ return status;
+ }
+
++int be_cmd_set_hsw_config(struct be_adapter *adapter, u16 pvid,
++ u32 domain, u16 intf_id)
++{
++ struct be_mcc_wrb *wrb;
++ struct be_cmd_req_set_hsw_config *req;
++ void *ctxt;
++ int status;
++
++ spin_lock_bh(&adapter->mcc_lock);
++
++ wrb = wrb_from_mccq(adapter);
++ if (!wrb) {
++ status = -EBUSY;
++ goto err;
++ }
++
++ req = embedded_payload(wrb);
++ ctxt = &req->context;
++
++ be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
++ OPCODE_COMMON_SET_HSW_CONFIG, sizeof(*req), wrb, NULL);
++
++ req->hdr.domain = domain;
++ AMAP_SET_BITS(struct amap_set_hsw_context, interface_id, ctxt, intf_id);
++ if (pvid) {
++ AMAP_SET_BITS(struct amap_set_hsw_context, pvid_valid, ctxt, 1);
++ AMAP_SET_BITS(struct amap_set_hsw_context, pvid, ctxt, pvid);
++ }
++
++ be_dws_cpu_to_le(req->context, sizeof(req->context));
++ status = be_mcc_notify_wait(adapter);
++
++err:
++ spin_unlock_bh(&adapter->mcc_lock);
++ return status;
++}
++
++/* Get Hyper switch config */
++int be_cmd_get_hsw_config(struct be_adapter *adapter, u16 *pvid,
++ u32 domain, u16 intf_id)
++{
++ struct be_mcc_wrb *wrb;
++ struct be_cmd_req_get_hsw_config *req;
++ void *ctxt;
++ int status;
++ u16 vid;
++
++ spin_lock_bh(&adapter->mcc_lock);
++
++ wrb = wrb_from_mccq(adapter);
++ if (!wrb) {
++ status = -EBUSY;
++ goto err;
++ }
++
++ req = embedded_payload(wrb);
++ ctxt = &req->context;
++
++ be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
++ OPCODE_COMMON_GET_HSW_CONFIG, sizeof(*req), wrb, NULL);
++
++ req->hdr.domain = domain;
++ AMAP_SET_BITS(struct amap_get_hsw_req_context, interface_id, ctxt,
++ intf_id);
++ AMAP_SET_BITS(struct amap_get_hsw_req_context, pvid_valid, ctxt, 1);
++ be_dws_cpu_to_le(req->context, sizeof(req->context));
++
++ status = be_mcc_notify_wait(adapter);
++ if (!status) {
++ struct be_cmd_resp_get_hsw_config *resp =
++ embedded_payload(wrb);
++ be_dws_le_to_cpu(&resp->context,
++ sizeof(resp->context));
++ vid = AMAP_GET_BITS(struct amap_get_hsw_resp_context,
++ pvid, &resp->context);
++ *pvid = le16_to_cpu(vid);
++ }
++
++err:
++ spin_unlock_bh(&adapter->mcc_lock);
++ return status;
++}
++
+ int be_cmd_get_acpi_wol_cap(struct be_adapter *adapter)
+ {
+ struct be_mcc_wrb *wrb;
+diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h
+index 345d49e..d5b680c 100644
+--- a/drivers/net/ethernet/emulex/benet/be_cmds.h
++++ b/drivers/net/ethernet/emulex/benet/be_cmds.h
+@@ -191,6 +191,8 @@ struct be_mcc_mailbox {
+ #define OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES 121
+ #define OPCODE_COMMON_GET_MAC_LIST 147
+ #define OPCODE_COMMON_SET_MAC_LIST 148
++#define OPCODE_COMMON_GET_HSW_CONFIG 152
++#define OPCODE_COMMON_SET_HSW_CONFIG 153
+ #define OPCODE_COMMON_READ_OBJECT 171
+ #define OPCODE_COMMON_WRITE_OBJECT 172
+
+@@ -1413,6 +1415,55 @@ struct be_cmd_req_set_mac_list {
+ struct macaddr mac[BE_MAX_MAC];
+ } __packed;
+
++/*********************** HSW Config ***********************/
++struct amap_set_hsw_context {
++ u8 interface_id[16];
++ u8 rsvd0[14];
++ u8 pvid_valid;
++ u8 rsvd1;
++ u8 rsvd2[16];
++ u8 pvid[16];
++ u8 rsvd3[32];
++ u8 rsvd4[32];
++ u8 rsvd5[32];
++} __packed;
++
++struct be_cmd_req_set_hsw_config {
++ struct be_cmd_req_hdr hdr;
++ u8 context[sizeof(struct amap_set_hsw_context) / 8];
++} __packed;
++
++struct be_cmd_resp_set_hsw_config {
++ struct be_cmd_resp_hdr hdr;
++ u32 rsvd;
++};
++
++struct amap_get_hsw_req_context {
++ u8 interface_id[16];
++ u8 rsvd0[14];
++ u8 pvid_valid;
++ u8 pport;
++} __packed;
++
++struct amap_get_hsw_resp_context {
++ u8 rsvd1[16];
++ u8 pvid[16];
++ u8 rsvd2[32];
++ u8 rsvd3[32];
++ u8 rsvd4[32];
++} __packed;
++
++struct be_cmd_req_get_hsw_config {
++ struct be_cmd_req_hdr hdr;
++ u8 context[sizeof(struct amap_get_hsw_req_context) / 8];
++} __packed;
++
++struct be_cmd_resp_get_hsw_config {
++ struct be_cmd_resp_hdr hdr;
++ u8 context[sizeof(struct amap_get_hsw_resp_context) / 8];
++ u32 rsvd;
++};
++
+ /*************** HW Stats Get v1 **********************************/
+ #define BE_TXP_SW_SZ 48
+ struct be_port_rxf_stats_v1 {
+@@ -1617,5 +1668,9 @@ extern int be_cmd_get_mac_from_list(struct be_adapter *adapter, u32 domain,
+ bool *pmac_id_active, u32 *pmac_id, u8 *mac);
+ extern int be_cmd_set_mac_list(struct be_adapter *adapter, u8 *mac_array,
+ u8 mac_count, u32 domain);
++extern int be_cmd_set_hsw_config(struct be_adapter *adapter, u16 pvid,
++ u32 domain, u16 intf_id);
++extern int be_cmd_get_hsw_config(struct be_adapter *adapter, u16 *pvid,
++ u32 domain, u16 intf_id);
+ extern int be_cmd_get_acpi_wol_cap(struct be_adapter *adapter);
+
+diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
+index c9a9bf0..2e54335 100644
+--- a/drivers/net/ethernet/emulex/benet/be_main.c
++++ b/drivers/net/ethernet/emulex/benet/be_main.c
+@@ -970,14 +970,21 @@ static int be_set_vf_vlan(struct net_device *netdev,
+ return -EINVAL;
+
+ if (vlan) {
+- adapter->vf_cfg[vf].vlan_tag = vlan;
+- adapter->vlans_added++;
++ if (adapter->vf_cfg[vf].vlan_tag != vlan) {
++ /* If this is new value, program it. Else skip. */
++ adapter->vf_cfg[vf].vlan_tag = vlan;
++
++ status = be_cmd_set_hsw_config(adapter, vlan,
++ vf + 1, adapter->vf_cfg[vf].if_handle);
++ }
+ } else {
++ /* Reset Transparent Vlan Tagging. */
+ adapter->vf_cfg[vf].vlan_tag = 0;
+- adapter->vlans_added--;
++ vlan = adapter->vf_cfg[vf].def_vid;
++ status = be_cmd_set_hsw_config(adapter, vlan, vf + 1,
++ adapter->vf_cfg[vf].if_handle);
+ }
+
+- status = be_vid_config(adapter, true, vf);
+
+ if (status)
+ dev_info(&adapter->pdev->dev,
+@@ -2517,7 +2524,7 @@ static int be_vf_setup(struct be_adapter *adapter)
+ {
+ struct be_vf_cfg *vf_cfg;
+ u32 cap_flags, en_flags, vf;
+- u16 lnk_speed;
++ u16 def_vlan, lnk_speed;
+ int status;
+
+ be_vf_setup_init(adapter);
+@@ -2541,6 +2548,12 @@ static int be_vf_setup(struct be_adapter *adapter)
+ if (status)
+ goto err;
+ vf_cfg->tx_rate = lnk_speed * 10;
++
++ status = be_cmd_get_hsw_config(adapter, &def_vlan,
++ vf + 1, vf_cfg->if_handle);
++ if (status)
++ goto err;
++ vf_cfg->def_vid = def_vlan;
+ }
+ return 0;
+ err:
+--
+1.7.10
+
Added: dists/sid/linux-2.6/debian/patches/features/all/be2net/0043-be2net-fix-ethtool-get-settings.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/be2net/0043-be2net-fix-ethtool-get-settings.patch Sun May 27 00:21:22 2012 (r19037)
@@ -0,0 +1,521 @@
+From: Ajit Khaparde <ajitkhaparde at gmail.com>
+Date: Sat, 21 Apr 2012 18:53:22 +0000
+Subject: [PATCH 43/58] be2net: fix ethtool get settings
+
+commit 42f11cf20cc5b76766fd1f0e591eda26283a38ec upstream.
+
+ethtool get settings was not displaying all the settings correctly.
+use the get_phy_info to get more information about the PHY to fix this.
+
+Signed-off-by: Ajit Khaparde <ajit.khaparde at emulex.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/emulex/benet/be.h | 23 ++-
+ drivers/net/ethernet/emulex/benet/be_cmds.c | 17 +-
+ drivers/net/ethernet/emulex/benet/be_cmds.h | 36 +++-
+ drivers/net/ethernet/emulex/benet/be_ethtool.c | 245 ++++++++++++++++--------
+ drivers/net/ethernet/emulex/benet/be_main.c | 20 +-
+ 5 files changed, 239 insertions(+), 102 deletions(-)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h
+index 9576ac0..ad69cf8 100644
+--- a/drivers/net/ethernet/emulex/benet/be.h
++++ b/drivers/net/ethernet/emulex/benet/be.h
+@@ -313,6 +313,23 @@ struct be_vf_cfg {
+ #define BE_UC_PMAC_COUNT 30
+ #define BE_VF_UC_PMAC_COUNT 2
+
++struct phy_info {
++ u8 transceiver;
++ u8 autoneg;
++ u8 fc_autoneg;
++ u8 port_type;
++ u16 phy_type;
++ u16 interface_type;
++ u32 misc_params;
++ u16 auto_speeds_supported;
++ u16 fixed_speeds_supported;
++ int link_speed;
++ int forced_port_speed;
++ u32 dac_cable_len;
++ u32 advertising;
++ u32 supported;
++};
++
+ struct be_adapter {
+ struct pci_dev *pdev;
+ struct net_device *netdev;
+@@ -377,10 +394,6 @@ struct be_adapter {
+ u32 rx_fc; /* Rx flow control */
+ u32 tx_fc; /* Tx flow control */
+ bool stats_cmd_sent;
+- int link_speed;
+- u8 port_type;
+- u8 transceiver;
+- u8 autoneg;
+ u8 generation; /* BladeEngine ASIC generation */
+ u32 flash_status;
+ struct completion flash_compl;
+@@ -392,6 +405,7 @@ struct be_adapter {
+ u32 sli_family;
+ u8 hba_port_num;
+ u16 pvid;
++ struct phy_info phy;
+ u8 wol_cap;
+ bool wol;
+ u32 max_pmac_cnt; /* Max secondary UC MACs programmable */
+@@ -583,4 +597,5 @@ extern void be_link_status_update(struct be_adapter *adapter, u8 link_status);
+ extern void be_parse_stats(struct be_adapter *adapter);
+ extern int be_load_fw(struct be_adapter *adapter, u8 *func);
+ extern bool be_is_wol_supported(struct be_adapter *adapter);
++extern bool be_pause_supported(struct be_adapter *adapter);
+ #endif /* BE_H */
+diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
+index 67b030d..22be08c 100644
+--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
++++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
+@@ -126,7 +126,7 @@ static void be_async_link_state_process(struct be_adapter *adapter,
+ struct be_async_event_link_state *evt)
+ {
+ /* When link status changes, link speed must be re-queried from FW */
+- adapter->link_speed = -1;
++ adapter->phy.link_speed = -1;
+
+ /* For the initial link status do not rely on the ASYNC event as
+ * it may not be received in some cases.
+@@ -153,7 +153,7 @@ static void be_async_grp5_qos_speed_process(struct be_adapter *adapter,
+ {
+ if (evt->physical_port == adapter->port_num) {
+ /* qos_link_speed is in units of 10 Mbps */
+- adapter->link_speed = evt->qos_link_speed * 10;
++ adapter->phy.link_speed = evt->qos_link_speed * 10;
+ }
+ }
+
+@@ -2136,8 +2136,7 @@ err:
+ return status;
+ }
+
+-int be_cmd_get_phy_info(struct be_adapter *adapter,
+- struct be_phy_info *phy_info)
++int be_cmd_get_phy_info(struct be_adapter *adapter)
+ {
+ struct be_mcc_wrb *wrb;
+ struct be_cmd_req_get_phy_info *req;
+@@ -2170,9 +2169,15 @@ int be_cmd_get_phy_info(struct be_adapter *adapter,
+ if (!status) {
+ struct be_phy_info *resp_phy_info =
+ cmd.va + sizeof(struct be_cmd_req_hdr);
+- phy_info->phy_type = le16_to_cpu(resp_phy_info->phy_type);
+- phy_info->interface_type =
++ adapter->phy.phy_type = le16_to_cpu(resp_phy_info->phy_type);
++ adapter->phy.interface_type =
+ le16_to_cpu(resp_phy_info->interface_type);
++ adapter->phy.auto_speeds_supported =
++ le16_to_cpu(resp_phy_info->auto_speeds_supported);
++ adapter->phy.fixed_speeds_supported =
++ le16_to_cpu(resp_phy_info->fixed_speeds_supported);
++ adapter->phy.misc_params =
++ le32_to_cpu(resp_phy_info->misc_params);
+ }
+ pci_free_consistent(adapter->pdev, cmd.size,
+ cmd.va, cmd.dma);
+diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h
+index d5b680c..3c54361 100644
+--- a/drivers/net/ethernet/emulex/benet/be_cmds.h
++++ b/drivers/net/ethernet/emulex/benet/be_cmds.h
+@@ -1309,9 +1309,36 @@ enum {
+ PHY_TYPE_KX4_10GB,
+ PHY_TYPE_BASET_10GB,
+ PHY_TYPE_BASET_1GB,
++ PHY_TYPE_BASEX_1GB,
++ PHY_TYPE_SGMII,
+ PHY_TYPE_DISABLED = 255
+ };
+
++#define BE_SUPPORTED_SPEED_NONE 0
++#define BE_SUPPORTED_SPEED_10MBPS 1
++#define BE_SUPPORTED_SPEED_100MBPS 2
++#define BE_SUPPORTED_SPEED_1GBPS 4
++#define BE_SUPPORTED_SPEED_10GBPS 8
++
++#define BE_AN_EN 0x2
++#define BE_PAUSE_SYM_EN 0x80
++
++/* MAC speed valid values */
++#define SPEED_DEFAULT 0x0
++#define SPEED_FORCED_10GB 0x1
++#define SPEED_FORCED_1GB 0x2
++#define SPEED_AUTONEG_10GB 0x3
++#define SPEED_AUTONEG_1GB 0x4
++#define SPEED_AUTONEG_100MB 0x5
++#define SPEED_AUTONEG_10GB_1GB 0x6
++#define SPEED_AUTONEG_10GB_1GB_100MB 0x7
++#define SPEED_AUTONEG_1GB_100MB 0x8
++#define SPEED_AUTONEG_10MB 0x9
++#define SPEED_AUTONEG_1GB_100MB_10MB 0xa
++#define SPEED_AUTONEG_100MB_10MB 0xb
++#define SPEED_FORCED_100MB 0xc
++#define SPEED_FORCED_10MB 0xd
++
+ struct be_cmd_req_get_phy_info {
+ struct be_cmd_req_hdr hdr;
+ u8 rsvd0[24];
+@@ -1321,7 +1348,11 @@ struct be_phy_info {
+ u16 phy_type;
+ u16 interface_type;
+ u32 misc_params;
+- u32 future_use[4];
++ u16 ext_phy_details;
++ u16 rsvd;
++ u16 auto_speeds_supported;
++ u16 fixed_speeds_supported;
++ u32 future_use[2];
+ };
+
+ struct be_cmd_resp_get_phy_info {
+@@ -1655,8 +1686,7 @@ extern int be_cmd_get_seeprom_data(struct be_adapter *adapter,
+ struct be_dma_mem *nonemb_cmd);
+ extern int be_cmd_set_loopback(struct be_adapter *adapter, u8 port_num,
+ u8 loopback_type, u8 enable);
+-extern int be_cmd_get_phy_info(struct be_adapter *adapter,
+- struct be_phy_info *phy_info);
++extern int be_cmd_get_phy_info(struct be_adapter *adapter);
+ extern int be_cmd_set_qos(struct be_adapter *adapter, u32 bps, u32 domain);
+ extern void be_detect_dump_ue(struct be_adapter *adapter);
+ extern int be_cmd_get_die_temperature(struct be_adapter *adapter);
+diff --git a/drivers/net/ethernet/emulex/benet/be_ethtool.c b/drivers/net/ethernet/emulex/benet/be_ethtool.c
+index e0eb995..076adeb 100644
+--- a/drivers/net/ethernet/emulex/benet/be_ethtool.c
++++ b/drivers/net/ethernet/emulex/benet/be_ethtool.c
+@@ -433,102 +433,193 @@ static int be_get_sset_count(struct net_device *netdev, int stringset)
+ }
+ }
+
++static u32 be_get_port_type(u32 phy_type, u32 dac_cable_len)
++{
++ u32 port;
++
++ switch (phy_type) {
++ case PHY_TYPE_BASET_1GB:
++ case PHY_TYPE_BASEX_1GB:
++ case PHY_TYPE_SGMII:
++ port = PORT_TP;
++ break;
++ case PHY_TYPE_SFP_PLUS_10GB:
++ port = dac_cable_len ? PORT_DA : PORT_FIBRE;
++ break;
++ case PHY_TYPE_XFP_10GB:
++ case PHY_TYPE_SFP_1GB:
++ port = PORT_FIBRE;
++ break;
++ case PHY_TYPE_BASET_10GB:
++ port = PORT_TP;
++ break;
++ default:
++ port = PORT_OTHER;
++ }
++
++ return port;
++}
++
++static u32 convert_to_et_setting(u32 if_type, u32 if_speeds)
++{
++ u32 val = 0;
++
++ switch (if_type) {
++ case PHY_TYPE_BASET_1GB:
++ case PHY_TYPE_BASEX_1GB:
++ case PHY_TYPE_SGMII:
++ val |= SUPPORTED_TP;
++ if (if_speeds & BE_SUPPORTED_SPEED_1GBPS)
++ val |= SUPPORTED_1000baseT_Full;
++ if (if_speeds & BE_SUPPORTED_SPEED_100MBPS)
++ val |= SUPPORTED_100baseT_Full;
++ if (if_speeds & BE_SUPPORTED_SPEED_10MBPS)
++ val |= SUPPORTED_10baseT_Full;
++ break;
++ case PHY_TYPE_KX4_10GB:
++ val |= SUPPORTED_Backplane;
++ if (if_speeds & BE_SUPPORTED_SPEED_1GBPS)
++ val |= SUPPORTED_1000baseKX_Full;
++ if (if_speeds & BE_SUPPORTED_SPEED_10GBPS)
++ val |= SUPPORTED_10000baseKX4_Full;
++ break;
++ case PHY_TYPE_KR_10GB:
++ val |= SUPPORTED_Backplane |
++ SUPPORTED_10000baseKR_Full;
++ break;
++ case PHY_TYPE_SFP_PLUS_10GB:
++ case PHY_TYPE_XFP_10GB:
++ case PHY_TYPE_SFP_1GB:
++ val |= SUPPORTED_FIBRE;
++ if (if_speeds & BE_SUPPORTED_SPEED_10GBPS)
++ val |= SUPPORTED_10000baseT_Full;
++ if (if_speeds & BE_SUPPORTED_SPEED_1GBPS)
++ val |= SUPPORTED_1000baseT_Full;
++ break;
++ case PHY_TYPE_BASET_10GB:
++ val |= SUPPORTED_TP;
++ if (if_speeds & BE_SUPPORTED_SPEED_10GBPS)
++ val |= SUPPORTED_10000baseT_Full;
++ if (if_speeds & BE_SUPPORTED_SPEED_1GBPS)
++ val |= SUPPORTED_1000baseT_Full;
++ if (if_speeds & BE_SUPPORTED_SPEED_100MBPS)
++ val |= SUPPORTED_100baseT_Full;
++ break;
++ default:
++ val |= SUPPORTED_TP;
++ }
++
++ return val;
++}
++
++static int convert_to_et_speed(u32 be_speed)
++{
++ int et_speed = SPEED_10000;
++
++ switch (be_speed) {
++ case PHY_LINK_SPEED_10MBPS:
++ et_speed = SPEED_10;
++ break;
++ case PHY_LINK_SPEED_100MBPS:
++ et_speed = SPEED_100;
++ break;
++ case PHY_LINK_SPEED_1GBPS:
++ et_speed = SPEED_1000;
++ break;
++ case PHY_LINK_SPEED_10GBPS:
++ et_speed = SPEED_10000;
++ break;
++ }
++
++ return et_speed;
++}
++
++bool be_pause_supported(struct be_adapter *adapter)
++{
++ return (adapter->phy.interface_type == PHY_TYPE_SFP_PLUS_10GB ||
++ adapter->phy.interface_type == PHY_TYPE_XFP_10GB) ?
++ false : true;
++}
++
+ static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
+ {
+ struct be_adapter *adapter = netdev_priv(netdev);
+- struct be_phy_info phy_info;
+- u8 mac_speed = 0;
++ u8 port_speed = 0;
+ u16 link_speed = 0;
+ u8 link_status;
++ u32 et_speed = 0;
+ int status;
+
+- if ((adapter->link_speed < 0) || (!(netdev->flags & IFF_UP))) {
+- status = be_cmd_link_status_query(adapter, &mac_speed,
+- &link_speed, &link_status, 0);
+- if (!status)
+- be_link_status_update(adapter, link_status);
+-
+- /* link_speed is in units of 10 Mbps */
+- if (link_speed) {
+- ethtool_cmd_speed_set(ecmd, link_speed*10);
++ if (adapter->phy.link_speed < 0 || !(netdev->flags & IFF_UP)) {
++ if (adapter->phy.forced_port_speed < 0) {
++ status = be_cmd_link_status_query(adapter, &port_speed,
++ &link_speed, &link_status, 0);
++ if (!status)
++ be_link_status_update(adapter, link_status);
++ if (link_speed)
++ et_speed = link_speed;
++ else
++ et_speed = convert_to_et_speed(port_speed);
+ } else {
+- switch (mac_speed) {
+- case PHY_LINK_SPEED_10MBPS:
+- ethtool_cmd_speed_set(ecmd, SPEED_10);
+- break;
+- case PHY_LINK_SPEED_100MBPS:
+- ethtool_cmd_speed_set(ecmd, SPEED_100);
+- break;
+- case PHY_LINK_SPEED_1GBPS:
+- ethtool_cmd_speed_set(ecmd, SPEED_1000);
+- break;
+- case PHY_LINK_SPEED_10GBPS:
+- ethtool_cmd_speed_set(ecmd, SPEED_10000);
+- break;
+- case PHY_LINK_SPEED_ZERO:
+- ethtool_cmd_speed_set(ecmd, 0);
+- break;
+- }
++ et_speed = adapter->phy.forced_port_speed;
+ }
+
+- status = be_cmd_get_phy_info(adapter, &phy_info);
+- if (!status) {
+- switch (phy_info.interface_type) {
+- case PHY_TYPE_XFP_10GB:
+- case PHY_TYPE_SFP_1GB:
+- case PHY_TYPE_SFP_PLUS_10GB:
+- ecmd->port = PORT_FIBRE;
+- break;
+- default:
+- ecmd->port = PORT_TP;
+- break;
+- }
++ ethtool_cmd_speed_set(ecmd, et_speed);
++
++ status = be_cmd_get_phy_info(adapter);
++ if (status)
++ return status;
++
++ ecmd->supported =
++ convert_to_et_setting(adapter->phy.interface_type,
++ adapter->phy.auto_speeds_supported |
++ adapter->phy.fixed_speeds_supported);
++ ecmd->advertising =
++ convert_to_et_setting(adapter->phy.interface_type,
++ adapter->phy.auto_speeds_supported);
+
+- switch (phy_info.interface_type) {
+- case PHY_TYPE_KR_10GB:
+- case PHY_TYPE_KX4_10GB:
+- ecmd->autoneg = AUTONEG_ENABLE;
++ ecmd->port = be_get_port_type(adapter->phy.interface_type,
++ adapter->phy.dac_cable_len);
++
++ if (adapter->phy.auto_speeds_supported) {
++ ecmd->supported |= SUPPORTED_Autoneg;
++ ecmd->autoneg = AUTONEG_ENABLE;
++ ecmd->advertising |= ADVERTISED_Autoneg;
++ }
++
++ if (be_pause_supported(adapter)) {
++ ecmd->supported |= SUPPORTED_Pause;
++ ecmd->advertising |= ADVERTISED_Pause;
++ }
++
++ switch (adapter->phy.interface_type) {
++ case PHY_TYPE_KR_10GB:
++ case PHY_TYPE_KX4_10GB:
+ ecmd->transceiver = XCVR_INTERNAL;
+- break;
+- default:
+- ecmd->autoneg = AUTONEG_DISABLE;
+- ecmd->transceiver = XCVR_EXTERNAL;
+- break;
+- }
++ break;
++ default:
++ ecmd->transceiver = XCVR_EXTERNAL;
++ break;
+ }
+
+ /* Save for future use */
+- adapter->link_speed = ethtool_cmd_speed(ecmd);
+- adapter->port_type = ecmd->port;
+- adapter->transceiver = ecmd->transceiver;
+- adapter->autoneg = ecmd->autoneg;
++ adapter->phy.link_speed = ethtool_cmd_speed(ecmd);
++ adapter->phy.port_type = ecmd->port;
++ adapter->phy.transceiver = ecmd->transceiver;
++ adapter->phy.autoneg = ecmd->autoneg;
++ adapter->phy.advertising = ecmd->advertising;
++ adapter->phy.supported = ecmd->supported;
+ } else {
+- ethtool_cmd_speed_set(ecmd, adapter->link_speed);
+- ecmd->port = adapter->port_type;
+- ecmd->transceiver = adapter->transceiver;
+- ecmd->autoneg = adapter->autoneg;
++ ethtool_cmd_speed_set(ecmd, adapter->phy.link_speed);
++ ecmd->port = adapter->phy.port_type;
++ ecmd->transceiver = adapter->phy.transceiver;
++ ecmd->autoneg = adapter->phy.autoneg;
++ ecmd->advertising = adapter->phy.advertising;
++ ecmd->supported = adapter->phy.supported;
+ }
+
+ ecmd->duplex = DUPLEX_FULL;
+ ecmd->phy_address = adapter->port_num;
+- switch (ecmd->port) {
+- case PORT_FIBRE:
+- ecmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE);
+- break;
+- case PORT_TP:
+- ecmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_TP);
+- break;
+- case PORT_AUI:
+- ecmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_AUI);
+- break;
+- }
+-
+- if (ecmd->autoneg) {
+- ecmd->supported |= SUPPORTED_1000baseT_Full;
+- ecmd->supported |= SUPPORTED_Autoneg;
+- ecmd->advertising |= (ADVERTISED_10000baseT_Full |
+- ADVERTISED_1000baseT_Full);
+- }
+
+ return 0;
+ }
+@@ -548,7 +639,7 @@ be_get_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *ecmd)
+ struct be_adapter *adapter = netdev_priv(netdev);
+
+ be_cmd_get_flow_control(adapter, &ecmd->tx_pause, &ecmd->rx_pause);
+- ecmd->autoneg = 0;
++ ecmd->autoneg = adapter->phy.fc_autoneg;
+ }
+
+ static int
+diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
+index 2e54335..376a2fa 100644
+--- a/drivers/net/ethernet/emulex/benet/be_main.c
++++ b/drivers/net/ethernet/emulex/benet/be_main.c
+@@ -2563,11 +2563,12 @@ err:
+ static void be_setup_init(struct be_adapter *adapter)
+ {
+ adapter->vlan_prio_bmap = 0xff;
+- adapter->link_speed = -1;
++ adapter->phy.link_speed = -1;
+ adapter->if_handle = -1;
+ adapter->be3_native = false;
+ adapter->promiscuous = false;
+ adapter->eq_next_idx = 0;
++ adapter->phy.forced_port_speed = -1;
+ }
+
+ static int be_add_mac_from_list(struct be_adapter *adapter, u8 *mac)
+@@ -2699,6 +2700,10 @@ static int be_setup(struct be_adapter *adapter)
+ goto err;
+ }
+
++ be_cmd_get_phy_info(adapter);
++ if (be_pause_supported(adapter))
++ adapter->phy.fc_autoneg = 1;
++
+ schedule_delayed_work(&adapter->work, msecs_to_jiffies(1000));
+ adapter->flags |= BE_FLAGS_WORKER_SCHEDULED;
+
+@@ -2752,17 +2757,8 @@ static bool be_flash_redboot(struct be_adapter *adapter,
+
+ static bool phy_flashing_required(struct be_adapter *adapter)
+ {
+- int status = 0;
+- struct be_phy_info phy_info;
+-
+- status = be_cmd_get_phy_info(adapter, &phy_info);
+- if (status)
+- return false;
+- if ((phy_info.phy_type == TN_8022) &&
+- (phy_info.interface_type == PHY_TYPE_BASET_10GB)) {
+- return true;
+- }
+- return false;
++ return (adapter->phy.phy_type == TN_8022 &&
++ adapter->phy.interface_type == PHY_TYPE_BASET_10GB);
+ }
+
+ static int be_flash_data(struct be_adapter *adapter,
+--
+1.7.10
+
Added: dists/sid/linux-2.6/debian/patches/features/all/be2net/0044-be2net-Fix-VLAN-multicast-packet-reception.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/be2net/0044-be2net-Fix-VLAN-multicast-packet-reception.patch Sun May 27 00:21:22 2012 (r19037)
@@ -0,0 +1,94 @@
+From: Padmanabh Ratnakar <padmanabh.ratnakar at emulex.com>
+Date: Fri, 25 May 2012 21:28:09 +0530
+Subject: [PATCH 44/58] be2net: Fix VLAN/multicast packet reception
+
+commit 0fc16ebf69fc57b42110712eaaf8a6aa2492afbe upstream.
+
+VLAN and multicast hardware filters are limited and can get
+exhausted in adapters with many PCI functions. If setting
+a VLAN or multicast filter fails due to lack of sufficient
+hardware resources, these packets get dropped. Fix this by
+switching to VLAN or multicast promiscous mode so that these
+packets are not dropped.
+
+Signed-off-by: Padmanabh Ratnakar <padmanabh.ratnakar at emulex.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/emulex/benet/be_main.c | 44 ++++++++++++++++++---------
+ 1 file changed, 30 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
+index 376a2fa..34b8ad2 100644
+--- a/drivers/net/ethernet/emulex/benet/be_main.c
++++ b/drivers/net/ethernet/emulex/benet/be_main.c
+@@ -797,22 +797,30 @@ static int be_vid_config(struct be_adapter *adapter, bool vf, u32 vf_num)
+ if (adapter->promiscuous)
+ return 0;
+
+- if (adapter->vlans_added <= adapter->max_vlans) {
+- /* Construct VLAN Table to give to HW */
+- for (i = 0; i < VLAN_N_VID; i++) {
+- if (adapter->vlan_tag[i]) {
+- vtag[ntags] = cpu_to_le16(i);
+- ntags++;
+- }
+- }
+- status = be_cmd_vlan_config(adapter, adapter->if_handle,
+- vtag, ntags, 1, 0);
+- } else {
+- status = be_cmd_vlan_config(adapter, adapter->if_handle,
+- NULL, 0, 1, 1);
++ if (adapter->vlans_added > adapter->max_vlans)
++ goto set_vlan_promisc;
++
++ /* Construct VLAN Table to give to HW */
++ for (i = 0; i < VLAN_N_VID; i++)
++ if (adapter->vlan_tag[i])
++ vtag[ntags++] = cpu_to_le16(i);
++
++ status = be_cmd_vlan_config(adapter, adapter->if_handle,
++ vtag, ntags, 1, 0);
++
++ /* Set to VLAN promisc mode as setting VLAN filter failed */
++ if (status) {
++ dev_info(&adapter->pdev->dev, "Exhausted VLAN HW filters.\n");
++ dev_info(&adapter->pdev->dev, "Disabling HW VLAN filtering.\n");
++ goto set_vlan_promisc;
+ }
+
+ return status;
++
++set_vlan_promisc:
++ status = be_cmd_vlan_config(adapter, adapter->if_handle,
++ NULL, 0, 1, 1);
++ return status;
+ }
+
+ static void be_vlan_add_vid(struct net_device *netdev, u16 vid)
+@@ -854,6 +862,7 @@ static void be_vlan_rem_vid(struct net_device *netdev, u16 vid)
+ static void be_set_rx_mode(struct net_device *netdev)
+ {
+ struct be_adapter *adapter = netdev_priv(netdev);
++ int status;
+
+ if (netdev->flags & IFF_PROMISC) {
+ be_cmd_rx_filter(adapter, IFF_PROMISC, ON);
+@@ -900,7 +909,14 @@ static void be_set_rx_mode(struct net_device *netdev)
+ }
+ }
+
+- be_cmd_rx_filter(adapter, IFF_MULTICAST, ON);
++ status = be_cmd_rx_filter(adapter, IFF_MULTICAST, ON);
++
++ /* Set to MCAST promisc mode if setting MULTICAST address fails */
++ if (status) {
++ dev_info(&adapter->pdev->dev, "Exhausted multicast HW filters.\n");
++ dev_info(&adapter->pdev->dev, "Disabling HW multicast filtering.\n");
++ be_cmd_rx_filter(adapter, IFF_ALLMULTI, ON);
++ }
+ done:
+ return;
+ }
+--
+1.7.10
+
Added: dists/sid/linux-2.6/debian/patches/features/all/be2net/0045-be2net-Fix-FW-download-in-Lancer.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/be2net/0045-be2net-Fix-FW-download-in-Lancer.patch Sun May 27 00:21:22 2012 (r19037)
@@ -0,0 +1,44 @@
+From: Padmanabh Ratnakar <padmanabh.ratnakar at emulex.com>
+Date: Wed, 25 Apr 2012 01:46:18 +0000
+Subject: [PATCH 45/58] be2net: Fix FW download in Lancer
+
+commit 804c751599855a83efdc781cd9a2bda725d1391c upstream.
+
+Increase time given by driver to adapter for completing FW download
+to 30 seconds. Also return correct status when FW download times out.
+
+Signed-off-by: Padmanabh Ratnakar <padmanabh.ratnakar at emulex.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/emulex/benet/be_cmds.c | 8 +++-----
+ 1 file changed, 3 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
+index 22be08c..3ba4aed 100644
+--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
++++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
+@@ -1824,18 +1824,16 @@ int lancer_cmd_write_object(struct be_adapter *adapter, struct be_dma_mem *cmd,
+ spin_unlock_bh(&adapter->mcc_lock);
+
+ if (!wait_for_completion_timeout(&adapter->flash_compl,
+- msecs_to_jiffies(12000)))
++ msecs_to_jiffies(30000)))
+ status = -1;
+ else
+ status = adapter->flash_status;
+
+ resp = embedded_payload(wrb);
+- if (!status) {
++ if (!status)
+ *data_written = le32_to_cpu(resp->actual_write_len);
+- } else {
++ else
+ *addn_status = resp->additional_status;
+- status = resp->status;
+- }
+
+ return status;
+
+--
+1.7.10
+
Added: dists/sid/linux-2.6/debian/patches/features/all/be2net/0046-be2net-Fix-ethtool-self-test-for-Lancer.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/be2net/0046-be2net-Fix-ethtool-self-test-for-Lancer.patch Sun May 27 00:21:22 2012 (r19037)
@@ -0,0 +1,31 @@
+From: Padmanabh Ratnakar <padmanabh.ratnakar at emulex.com>
+Date: Wed, 25 Apr 2012 01:46:28 +0000
+Subject: [PATCH 46/58] be2net: Fix ethtool self test for Lancer
+
+commit a70473949698c1c46e5523e1810a0a0f904a1fd2 upstream.
+
+Lancer does not support DDR self test. Fix ethtool self test by
+skipping this test for Lancer.
+
+Signed-off-by: Padmanabh Ratnakar <padmanabh.ratnakar at emulex.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/emulex/benet/be_ethtool.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be_ethtool.c b/drivers/net/ethernet/emulex/benet/be_ethtool.c
+index 076adeb..9d71bad 100644
+--- a/drivers/net/ethernet/emulex/benet/be_ethtool.c
++++ b/drivers/net/ethernet/emulex/benet/be_ethtool.c
+@@ -793,7 +793,7 @@ be_self_test(struct net_device *netdev, struct ethtool_test *test, u64 *data)
+ }
+ }
+
+- if (be_test_ddr_dma(adapter) != 0) {
++ if (!lancer_chip(adapter) && be_test_ddr_dma(adapter) != 0) {
+ data[3] = 1;
+ test->flags |= ETH_TEST_FL_FAILED;
+ }
+--
+1.7.10
+
Added: dists/sid/linux-2.6/debian/patches/features/all/be2net/0047-be2net-Fix-traffic-stall-INTx-mode.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/be2net/0047-be2net-Fix-traffic-stall-INTx-mode.patch Sun May 27 00:21:22 2012 (r19037)
@@ -0,0 +1,36 @@
+From: Padmanabh Ratnakar <padmanabh.ratnakar at emulex.com>
+Date: Wed, 25 Apr 2012 01:46:39 +0000
+Subject: [PATCH 47/58] be2net: Fix traffic stall INTx mode
+
+commit af311fe31015e2b27bd65e22fc103230fb3a78b7 upstream.
+
+EQ is getting armed wrongly in INTx mode as INTx interrupt is taking
+some time to deassert. This can cause another interrupt while NAPI is
+scheduled and scheduling a NAPI in interrupt does not take effect.
+This causes interrupt to be missed and traffic stalls. Fixing this by
+preventing wrong arming of EQ.
+
+Signed-off-by: Padmanabh Ratnakar <padmanabh.ratnakar at emulex.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/emulex/benet/be_main.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
+index 34b8ad2..915b95e 100644
+--- a/drivers/net/ethernet/emulex/benet/be_main.c
++++ b/drivers/net/ethernet/emulex/benet/be_main.c
+@@ -1563,7 +1563,9 @@ static int event_handle(struct be_eq_obj *eqo)
+ if (!num)
+ rearm = true;
+
+- be_eq_notify(eqo->adapter, eqo->q.id, rearm, true, num);
++ if (num || msix_enabled(eqo->adapter))
++ be_eq_notify(eqo->adapter, eqo->q.id, rearm, true, num);
++
+ if (num)
+ napi_schedule(&eqo->napi);
+
+--
+1.7.10
+
Added: dists/sid/linux-2.6/debian/patches/features/all/be2net/0048-be2net-Fix-Lancer-statistics.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/be2net/0048-be2net-Fix-Lancer-statistics.patch Sun May 27 00:21:22 2012 (r19037)
@@ -0,0 +1,55 @@
+From: Padmanabh Ratnakar <padmanabh.ratnakar at emulex.com>
+Date: Wed, 25 Apr 2012 01:46:52 +0000
+Subject: [PATCH 48/58] be2net: Fix Lancer statistics
+
+commit d51ebd331166e102591e5c25805d8015df0e1e21 upstream.
+
+Fix port num sent in command to get stats. Also skip unnecessary
+parsing of stats for Lancer.
+
+Signed-off-by: Padmanabh Ratnakar <padmanabh.ratnakar at emulex.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/emulex/benet/be_cmds.c | 2 +-
+ drivers/net/ethernet/emulex/benet/be_main.c | 5 +++++
+ 2 files changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
+index 3ba4aed..4e07e58 100644
+--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
++++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
+@@ -1221,7 +1221,7 @@ int lancer_cmd_get_pport_stats(struct be_adapter *adapter,
+ OPCODE_ETH_GET_PPORT_STATS, nonemb_cmd->size, wrb,
+ nonemb_cmd);
+
+- req->cmd_params.params.pport_num = cpu_to_le16(adapter->port_num);
++ req->cmd_params.params.pport_num = cpu_to_le16(adapter->hba_port_num);
+ req->cmd_params.params.reset_stats = 0;
+
+ be_mcc_notify(adapter);
+diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
+index 915b95e..9b1c03e 100644
+--- a/drivers/net/ethernet/emulex/benet/be_main.c
++++ b/drivers/net/ethernet/emulex/benet/be_main.c
+@@ -421,6 +421,9 @@ void be_parse_stats(struct be_adapter *adapter)
+ populate_be2_stats(adapter);
+ }
+
++ if (lancer_chip(adapter))
++ goto done;
++
+ /* as erx_v1 is longer than v0, ok to use v1 defn for v0 access */
+ for_all_rx_queues(adapter, rxo, i) {
+ /* below erx HW counter can actually wrap around after
+@@ -429,6 +432,8 @@ void be_parse_stats(struct be_adapter *adapter)
+ accumulate_16bit_val(&rx_stats(rxo)->rx_drops_no_frags,
+ (u16)erx->rx_drops_no_fragments[rxo->q.id]);
+ }
++done:
++ return;
+ }
+
+ static struct rtnl_link_stats64 *be_get_stats64(struct net_device *netdev,
+--
+1.7.10
+
Added: dists/sid/linux-2.6/debian/patches/features/all/be2net/0049-be2net-Fix-wrong-status-getting-returned-for-MCC-com.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/be2net/0049-be2net-Fix-wrong-status-getting-returned-for-MCC-com.patch Sun May 27 00:21:22 2012 (r19037)
@@ -0,0 +1,232 @@
+From: Padmanabh Ratnakar <padmanabh.ratnakar at emulex.com>
+Date: Wed, 25 Apr 2012 01:47:03 +0000
+Subject: [PATCH 49/58] be2net: Fix wrong status getting returned for MCC
+ commands
+
+commit 652bf64622f32c938dd4a8738ba12d51dc9fbdd4 upstream.
+
+MCC Response CQEs are processed as part of NAPI poll routine and
+also synchronously. If MCC completions are consumed by NAPI poll
+routine, wrong status is returned to synchronously waiting routine.
+Fix this by getting status of MCC command from command response
+instead of response CQEs.
+
+Signed-off-by: Padmanabh Ratnakar <padmanabh.ratnakar at emulex.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/emulex/benet/be.h | 5 ++
+ drivers/net/ethernet/emulex/benet/be_cmds.c | 81 ++++++++++++++++++---------
+ drivers/net/ethernet/emulex/benet/be_cmds.h | 8 ++-
+ 3 files changed, 67 insertions(+), 27 deletions(-)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h
+index ad69cf8..4bc18ef 100644
+--- a/drivers/net/ethernet/emulex/benet/be.h
++++ b/drivers/net/ethernet/emulex/benet/be.h
+@@ -162,6 +162,11 @@ static inline void queue_head_inc(struct be_queue_info *q)
+ index_inc(&q->head, q->len);
+ }
+
++static inline void index_dec(u16 *index, u16 limit)
++{
++ *index = MODULO((*index - 1), limit);
++}
++
+ static inline void queue_tail_inc(struct be_queue_info *q)
+ {
+ index_inc(&q->tail, q->len);
+diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
+index 4e07e58..2673081 100644
+--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
++++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
+@@ -61,10 +61,21 @@ static inline void be_mcc_compl_use(struct be_mcc_compl *compl)
+ compl->flags = 0;
+ }
+
++static struct be_cmd_resp_hdr *be_decode_resp_hdr(u32 tag0, u32 tag1)
++{
++ unsigned long addr;
++
++ addr = tag1;
++ addr = ((addr << 16) << 16) | tag0;
++ return (void *)addr;
++}
++
+ static int be_mcc_compl_process(struct be_adapter *adapter,
+- struct be_mcc_compl *compl)
++ struct be_mcc_compl *compl)
+ {
+ u16 compl_status, extd_status;
++ struct be_cmd_resp_hdr *resp_hdr;
++ u8 opcode = 0, subsystem = 0;
+
+ /* Just swap the status to host endian; mcc tag is opaquely copied
+ * from mcc_wrb */
+@@ -73,32 +84,36 @@ static int be_mcc_compl_process(struct be_adapter *adapter,
+ compl_status = (compl->status >> CQE_STATUS_COMPL_SHIFT) &
+ CQE_STATUS_COMPL_MASK;
+
+- if (((compl->tag0 == OPCODE_COMMON_WRITE_FLASHROM) ||
+- (compl->tag0 == OPCODE_COMMON_WRITE_OBJECT)) &&
+- (compl->tag1 == CMD_SUBSYSTEM_COMMON)) {
++ resp_hdr = be_decode_resp_hdr(compl->tag0, compl->tag1);
++
++ if (resp_hdr) {
++ opcode = resp_hdr->opcode;
++ subsystem = resp_hdr->subsystem;
++ }
++
++ if (((opcode == OPCODE_COMMON_WRITE_FLASHROM) ||
++ (opcode == OPCODE_COMMON_WRITE_OBJECT)) &&
++ (subsystem == CMD_SUBSYSTEM_COMMON)) {
+ adapter->flash_status = compl_status;
+ complete(&adapter->flash_compl);
+ }
+
+ if (compl_status == MCC_STATUS_SUCCESS) {
+- if (((compl->tag0 == OPCODE_ETH_GET_STATISTICS) ||
+- (compl->tag0 == OPCODE_ETH_GET_PPORT_STATS)) &&
+- (compl->tag1 == CMD_SUBSYSTEM_ETH)) {
++ if (((opcode == OPCODE_ETH_GET_STATISTICS) ||
++ (opcode == OPCODE_ETH_GET_PPORT_STATS)) &&
++ (subsystem == CMD_SUBSYSTEM_ETH)) {
+ be_parse_stats(adapter);
+ adapter->stats_cmd_sent = false;
+ }
+- if (compl->tag0 ==
+- OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES) {
+- struct be_mcc_wrb *mcc_wrb =
+- queue_index_node(&adapter->mcc_obj.q,
+- compl->tag1);
++ if (opcode == OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES &&
++ subsystem == CMD_SUBSYSTEM_COMMON) {
+ struct be_cmd_resp_get_cntl_addnl_attribs *resp =
+- embedded_payload(mcc_wrb);
++ (void *)resp_hdr;
+ adapter->drv_stats.be_on_die_temperature =
+ resp->on_die_temperature;
+ }
+ } else {
+- if (compl->tag0 == OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES)
++ if (opcode == OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES)
+ be_get_temp_freq = 0;
+
+ if (compl_status == MCC_STATUS_NOT_SUPPORTED ||
+@@ -108,13 +123,13 @@ static int be_mcc_compl_process(struct be_adapter *adapter,
+ if (compl_status == MCC_STATUS_UNAUTHORIZED_REQUEST) {
+ dev_warn(&adapter->pdev->dev, "This domain(VM) is not "
+ "permitted to execute this cmd (opcode %d)\n",
+- compl->tag0);
++ opcode);
+ } else {
+ extd_status = (compl->status >> CQE_STATUS_EXTD_SHIFT) &
+ CQE_STATUS_EXTD_MASK;
+ dev_err(&adapter->pdev->dev, "Cmd (opcode %d) failed:"
+ "status %d, extd-status %d\n",
+- compl->tag0, compl_status, extd_status);
++ opcode, compl_status, extd_status);
+ }
+ }
+ done:
+@@ -286,7 +301,7 @@ static int be_mcc_wait_compl(struct be_adapter *adapter)
+ if (i == mcc_timeout) {
+ dev_err(&adapter->pdev->dev, "FW not responding\n");
+ adapter->fw_timeout = true;
+- return -1;
++ return -EIO;
+ }
+ return status;
+ }
+@@ -294,8 +309,26 @@ static int be_mcc_wait_compl(struct be_adapter *adapter)
+ /* Notify MCC requests and wait for completion */
+ static int be_mcc_notify_wait(struct be_adapter *adapter)
+ {
++ int status;
++ struct be_mcc_wrb *wrb;
++ struct be_mcc_obj *mcc_obj = &adapter->mcc_obj;
++ u16 index = mcc_obj->q.head;
++ struct be_cmd_resp_hdr *resp;
++
++ index_dec(&index, mcc_obj->q.len);
++ wrb = queue_index_node(&mcc_obj->q, index);
++
++ resp = be_decode_resp_hdr(wrb->tag0, wrb->tag1);
++
+ be_mcc_notify(adapter);
+- return be_mcc_wait_compl(adapter);
++
++ status = be_mcc_wait_compl(adapter);
++ if (status == -EIO)
++ goto out;
++
++ status = resp->status;
++out:
++ return status;
+ }
+
+ static int be_mbox_db_ready_wait(struct be_adapter *adapter, void __iomem *db)
+@@ -435,14 +468,17 @@ static void be_wrb_cmd_hdr_prepare(struct be_cmd_req_hdr *req_hdr,
+ struct be_mcc_wrb *wrb, struct be_dma_mem *mem)
+ {
+ struct be_sge *sge;
++ unsigned long addr = (unsigned long)req_hdr;
++ u64 req_addr = addr;
+
+ req_hdr->opcode = opcode;
+ req_hdr->subsystem = subsystem;
+ req_hdr->request_length = cpu_to_le32(cmd_len - sizeof(*req_hdr));
+ req_hdr->version = 0;
+
+- wrb->tag0 = opcode;
+- wrb->tag1 = subsystem;
++ wrb->tag0 = req_addr & 0xFFFFFFFF;
++ wrb->tag1 = upper_32_bits(req_addr);
++
+ wrb->payload_length = cmd_len;
+ if (mem) {
+ wrb->embedded |= (1 & MCC_WRB_SGE_CNT_MASK) <<
+@@ -1283,13 +1319,10 @@ int be_cmd_get_die_temperature(struct be_adapter *adapter)
+ {
+ struct be_mcc_wrb *wrb;
+ struct be_cmd_req_get_cntl_addnl_attribs *req;
+- u16 mccq_index;
+ int status;
+
+ spin_lock_bh(&adapter->mcc_lock);
+
+- mccq_index = adapter->mcc_obj.q.head;
+-
+ wrb = wrb_from_mccq(adapter);
+ if (!wrb) {
+ status = -EBUSY;
+@@ -1301,8 +1334,6 @@ int be_cmd_get_die_temperature(struct be_adapter *adapter)
+ OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES, sizeof(*req),
+ wrb, NULL);
+
+- wrb->tag1 = mccq_index;
+-
+ be_mcc_notify(adapter);
+
+ err:
+diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h
+index 3c54361..944f031 100644
+--- a/drivers/net/ethernet/emulex/benet/be_cmds.h
++++ b/drivers/net/ethernet/emulex/benet/be_cmds.h
+@@ -225,8 +225,12 @@ struct be_cmd_req_hdr {
+ #define RESP_HDR_INFO_OPCODE_SHIFT 0 /* bits 0 - 7 */
+ #define RESP_HDR_INFO_SUBSYS_SHIFT 8 /* bits 8 - 15 */
+ struct be_cmd_resp_hdr {
+- u32 info; /* dword 0 */
+- u32 status; /* dword 1 */
++ u8 opcode; /* dword 0 */
++ u8 subsystem; /* dword 0 */
++ u8 rsvd[2]; /* dword 0 */
++ u8 status; /* dword 1 */
++ u8 add_status; /* dword 1 */
++ u8 rsvd1[2]; /* dword 1 */
+ u32 response_length; /* dword 2 */
+ u32 actual_resp_len; /* dword 3 */
+ };
+--
+1.7.10
+
Added: dists/sid/linux-2.6/debian/patches/features/all/be2net/0050-be2net-Fix-FW-download-for-BE.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/be2net/0050-be2net-Fix-FW-download-for-BE.patch Sun May 27 00:21:22 2012 (r19037)
@@ -0,0 +1,383 @@
+From: Padmanabh Ratnakar <padmanabh.ratnakar at emulex.com>
+Date: Wed, 25 Apr 2012 01:47:15 +0000
+Subject: [PATCH 50/58] be2net: Fix FW download for BE
+
+commit c165541efc4d1024d7db22ecdf64359b1f6107fc upstream.
+
+Skip flashing a FW component if that component is not present in a
+particular FW UFI image.
+
+Signed-off-by: Somnath Kotur <somnath.kotur at emulex.com>
+Signed-off-by: Padmanabh Ratnakar <padmanabh.ratnakar at emulex.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/emulex/benet/be_cmds.c | 2 +-
+ drivers/net/ethernet/emulex/benet/be_hw.h | 74 ++++++++----
+ drivers/net/ethernet/emulex/benet/be_main.c | 168 ++++++++++++++++++---------
+ 3 files changed, 166 insertions(+), 78 deletions(-)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
+index 2673081..43167e8 100644
+--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
++++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
+@@ -1979,7 +1979,7 @@ int be_cmd_get_flash_crc(struct be_adapter *adapter, u8 *flashed_crc,
+ be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+ OPCODE_COMMON_READ_FLASHROM, sizeof(*req)+4, wrb, NULL);
+
+- req->params.op_type = cpu_to_le32(IMG_TYPE_REDBOOT);
++ req->params.op_type = cpu_to_le32(OPTYPE_REDBOOT);
+ req->params.op_code = cpu_to_le32(FLASHROM_OPER_REPORT);
+ req->params.offset = cpu_to_le32(offset);
+ req->params.data_buf_size = cpu_to_le32(0x4);
+diff --git a/drivers/net/ethernet/emulex/benet/be_hw.h b/drivers/net/ethernet/emulex/benet/be_hw.h
+index f2c89e3..0949aa6 100644
+--- a/drivers/net/ethernet/emulex/benet/be_hw.h
++++ b/drivers/net/ethernet/emulex/benet/be_hw.h
+@@ -162,22 +162,23 @@
+ #define QUERY_FAT 1
+
+ /* Flashrom related descriptors */
++#define MAX_FLASH_COMP 32
+ #define IMAGE_TYPE_FIRMWARE 160
+ #define IMAGE_TYPE_BOOTCODE 224
+ #define IMAGE_TYPE_OPTIONROM 32
+
+ #define NUM_FLASHDIR_ENTRIES 32
+
+-#define IMG_TYPE_ISCSI_ACTIVE 0
+-#define IMG_TYPE_REDBOOT 1
+-#define IMG_TYPE_BIOS 2
+-#define IMG_TYPE_PXE_BIOS 3
+-#define IMG_TYPE_FCOE_BIOS 8
+-#define IMG_TYPE_ISCSI_BACKUP 9
+-#define IMG_TYPE_FCOE_FW_ACTIVE 10
+-#define IMG_TYPE_FCOE_FW_BACKUP 11
+-#define IMG_TYPE_NCSI_FW 13
+-#define IMG_TYPE_PHY_FW 99
++#define OPTYPE_ISCSI_ACTIVE 0
++#define OPTYPE_REDBOOT 1
++#define OPTYPE_BIOS 2
++#define OPTYPE_PXE_BIOS 3
++#define OPTYPE_FCOE_BIOS 8
++#define OPTYPE_ISCSI_BACKUP 9
++#define OPTYPE_FCOE_FW_ACTIVE 10
++#define OPTYPE_FCOE_FW_BACKUP 11
++#define OPTYPE_NCSI_FW 13
++#define OPTYPE_PHY_FW 99
+ #define TN_8022 13
+
+ #define ILLEGAL_IOCTL_REQ 2
+@@ -223,6 +224,24 @@
+ #define FLASH_REDBOOT_START_g3 (262144)
+ #define FLASH_PHY_FW_START_g3 1310720
+
++#define IMAGE_NCSI 16
++#define IMAGE_OPTION_ROM_PXE 32
++#define IMAGE_OPTION_ROM_FCoE 33
++#define IMAGE_OPTION_ROM_ISCSI 34
++#define IMAGE_FLASHISM_JUMPVECTOR 48
++#define IMAGE_FLASH_ISM 49
++#define IMAGE_JUMP_VECTOR 50
++#define IMAGE_FIRMWARE_iSCSI 160
++#define IMAGE_FIRMWARE_COMP_iSCSI 161
++#define IMAGE_FIRMWARE_FCoE 162
++#define IMAGE_FIRMWARE_COMP_FCoE 163
++#define IMAGE_FIRMWARE_BACKUP_iSCSI 176
++#define IMAGE_FIRMWARE_BACKUP_COMP_iSCSI 177
++#define IMAGE_FIRMWARE_BACKUP_FCoE 178
++#define IMAGE_FIRMWARE_BACKUP_COMP_FCoE 179
++#define IMAGE_FIRMWARE_PHY 192
++#define IMAGE_BOOT_CODE 224
++
+ /************* Rx Packet Type Encoding **************/
+ #define BE_UNICAST_PACKET 0
+ #define BE_MULTICAST_PACKET 1
+@@ -445,6 +464,7 @@ struct flash_comp {
+ unsigned long offset;
+ int optype;
+ int size;
++ int img_type;
+ };
+
+ struct image_hdr {
+@@ -481,17 +501,19 @@ struct flash_section_hdr {
+ u32 format_rev;
+ u32 cksum;
+ u32 antidote;
+- u32 build_no;
+- u8 id_string[64];
+- u32 active_entry_mask;
+- u32 valid_entry_mask;
+- u32 org_content_mask;
+- u32 rsvd0;
+- u32 rsvd1;
+- u32 rsvd2;
+- u32 rsvd3;
+- u32 rsvd4;
+-};
++ u32 num_images;
++ u8 id_string[128];
++ u32 rsvd[4];
++} __packed;
++
++struct flash_section_hdr_g2 {
++ u32 format_rev;
++ u32 cksum;
++ u32 antidote;
++ u32 build_num;
++ u8 id_string[128];
++ u32 rsvd[8];
++} __packed;
+
+ struct flash_section_entry {
+ u32 type;
+@@ -503,10 +525,16 @@ struct flash_section_entry {
+ u32 rsvd0;
+ u32 rsvd1;
+ u8 ver_data[32];
+-};
++} __packed;
+
+ struct flash_section_info {
+ u8 cookie[32];
+ struct flash_section_hdr fsec_hdr;
+ struct flash_section_entry fsec_entry[32];
+-};
++} __packed;
++
++struct flash_section_info_g2 {
++ u8 cookie[32];
++ struct flash_section_hdr_g2 fsec_hdr;
++ struct flash_section_entry fsec_entry[32];
++} __packed;
+diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
+index 9b1c03e..730fb1b 100644
+--- a/drivers/net/ethernet/emulex/benet/be_main.c
++++ b/drivers/net/ethernet/emulex/benet/be_main.c
+@@ -2751,6 +2751,8 @@ static void be_netpoll(struct net_device *netdev)
+ #endif
+
+ #define FW_FILE_HDR_SIGN "ServerEngines Corp. "
++char flash_cookie[2][16] = {"*** SE FLAS", "H DIRECTORY *** "};
++
+ static bool be_flash_redboot(struct be_adapter *adapter,
+ const u8 *p, u32 img_start, int image_size,
+ int hdr_size)
+@@ -2784,58 +2786,101 @@ static bool phy_flashing_required(struct be_adapter *adapter)
+ adapter->phy.interface_type == PHY_TYPE_BASET_10GB);
+ }
+
++static bool is_comp_in_ufi(struct be_adapter *adapter,
++ struct flash_section_info *fsec, int type)
++{
++ int i = 0, img_type = 0;
++ struct flash_section_info_g2 *fsec_g2 = NULL;
++
++ if (adapter->generation != BE_GEN3)
++ fsec_g2 = (struct flash_section_info_g2 *)fsec;
++
++ for (i = 0; i < MAX_FLASH_COMP; i++) {
++ if (fsec_g2)
++ img_type = le32_to_cpu(fsec_g2->fsec_entry[i].type);
++ else
++ img_type = le32_to_cpu(fsec->fsec_entry[i].type);
++
++ if (img_type == type)
++ return true;
++ }
++ return false;
++
++}
++
++struct flash_section_info *get_fsec_info(struct be_adapter *adapter,
++ int header_size,
++ const struct firmware *fw)
++{
++ struct flash_section_info *fsec = NULL;
++ const u8 *p = fw->data;
++
++ p += header_size;
++ while (p < (fw->data + fw->size)) {
++ fsec = (struct flash_section_info *)p;
++ if (!memcmp(flash_cookie, fsec->cookie, sizeof(flash_cookie)))
++ return fsec;
++ p += 32;
++ }
++ return NULL;
++}
++
+ static int be_flash_data(struct be_adapter *adapter,
+- const struct firmware *fw,
+- struct be_dma_mem *flash_cmd, int num_of_images)
++ const struct firmware *fw,
++ struct be_dma_mem *flash_cmd,
++ int num_of_images)
+
+ {
+ int status = 0, i, filehdr_size = 0;
++ int img_hdrs_size = (num_of_images * sizeof(struct image_hdr));
+ u32 total_bytes = 0, flash_op;
+ int num_bytes;
+ const u8 *p = fw->data;
+ struct be_cmd_write_flashrom *req = flash_cmd->va;
+ const struct flash_comp *pflashcomp;
+- int num_comp;
+-
+- static const struct flash_comp gen3_flash_types[10] = {
+- { FLASH_iSCSI_PRIMARY_IMAGE_START_g3, IMG_TYPE_ISCSI_ACTIVE,
+- FLASH_IMAGE_MAX_SIZE_g3},
+- { FLASH_REDBOOT_START_g3, IMG_TYPE_REDBOOT,
+- FLASH_REDBOOT_IMAGE_MAX_SIZE_g3},
+- { FLASH_iSCSI_BIOS_START_g3, IMG_TYPE_BIOS,
+- FLASH_BIOS_IMAGE_MAX_SIZE_g3},
+- { FLASH_PXE_BIOS_START_g3, IMG_TYPE_PXE_BIOS,
+- FLASH_BIOS_IMAGE_MAX_SIZE_g3},
+- { FLASH_FCoE_BIOS_START_g3, IMG_TYPE_FCOE_BIOS,
+- FLASH_BIOS_IMAGE_MAX_SIZE_g3},
+- { FLASH_iSCSI_BACKUP_IMAGE_START_g3, IMG_TYPE_ISCSI_BACKUP,
+- FLASH_IMAGE_MAX_SIZE_g3},
+- { FLASH_FCoE_PRIMARY_IMAGE_START_g3, IMG_TYPE_FCOE_FW_ACTIVE,
+- FLASH_IMAGE_MAX_SIZE_g3},
+- { FLASH_FCoE_BACKUP_IMAGE_START_g3, IMG_TYPE_FCOE_FW_BACKUP,
+- FLASH_IMAGE_MAX_SIZE_g3},
+- { FLASH_NCSI_START_g3, IMG_TYPE_NCSI_FW,
+- FLASH_NCSI_IMAGE_MAX_SIZE_g3},
+- { FLASH_PHY_FW_START_g3, IMG_TYPE_PHY_FW,
+- FLASH_PHY_FW_IMAGE_MAX_SIZE_g3}
++ int num_comp, hdr_size;
++ struct flash_section_info *fsec = NULL;
++
++ struct flash_comp gen3_flash_types[] = {
++ { FLASH_iSCSI_PRIMARY_IMAGE_START_g3, OPTYPE_ISCSI_ACTIVE,
++ FLASH_IMAGE_MAX_SIZE_g3, IMAGE_FIRMWARE_iSCSI},
++ { FLASH_REDBOOT_START_g3, OPTYPE_REDBOOT,
++ FLASH_REDBOOT_IMAGE_MAX_SIZE_g3, IMAGE_BOOT_CODE},
++ { FLASH_iSCSI_BIOS_START_g3, OPTYPE_BIOS,
++ FLASH_BIOS_IMAGE_MAX_SIZE_g3, IMAGE_OPTION_ROM_ISCSI},
++ { FLASH_PXE_BIOS_START_g3, OPTYPE_PXE_BIOS,
++ FLASH_BIOS_IMAGE_MAX_SIZE_g3, IMAGE_OPTION_ROM_PXE},
++ { FLASH_FCoE_BIOS_START_g3, OPTYPE_FCOE_BIOS,
++ FLASH_BIOS_IMAGE_MAX_SIZE_g3, IMAGE_OPTION_ROM_FCoE},
++ { FLASH_iSCSI_BACKUP_IMAGE_START_g3, OPTYPE_ISCSI_BACKUP,
++ FLASH_IMAGE_MAX_SIZE_g3, IMAGE_FIRMWARE_BACKUP_iSCSI},
++ { FLASH_FCoE_PRIMARY_IMAGE_START_g3, OPTYPE_FCOE_FW_ACTIVE,
++ FLASH_IMAGE_MAX_SIZE_g3, IMAGE_FIRMWARE_FCoE},
++ { FLASH_FCoE_BACKUP_IMAGE_START_g3, OPTYPE_FCOE_FW_BACKUP,
++ FLASH_IMAGE_MAX_SIZE_g3, IMAGE_FIRMWARE_BACKUP_FCoE},
++ { FLASH_NCSI_START_g3, OPTYPE_NCSI_FW,
++ FLASH_NCSI_IMAGE_MAX_SIZE_g3, IMAGE_NCSI},
++ { FLASH_PHY_FW_START_g3, OPTYPE_PHY_FW,
++ FLASH_PHY_FW_IMAGE_MAX_SIZE_g3, IMAGE_FIRMWARE_PHY}
+ };
+- static const struct flash_comp gen2_flash_types[8] = {
+- { FLASH_iSCSI_PRIMARY_IMAGE_START_g2, IMG_TYPE_ISCSI_ACTIVE,
+- FLASH_IMAGE_MAX_SIZE_g2},
+- { FLASH_REDBOOT_START_g2, IMG_TYPE_REDBOOT,
+- FLASH_REDBOOT_IMAGE_MAX_SIZE_g2},
+- { FLASH_iSCSI_BIOS_START_g2, IMG_TYPE_BIOS,
+- FLASH_BIOS_IMAGE_MAX_SIZE_g2},
+- { FLASH_PXE_BIOS_START_g2, IMG_TYPE_PXE_BIOS,
+- FLASH_BIOS_IMAGE_MAX_SIZE_g2},
+- { FLASH_FCoE_BIOS_START_g2, IMG_TYPE_FCOE_BIOS,
+- FLASH_BIOS_IMAGE_MAX_SIZE_g2},
+- { FLASH_iSCSI_BACKUP_IMAGE_START_g2, IMG_TYPE_ISCSI_BACKUP,
+- FLASH_IMAGE_MAX_SIZE_g2},
+- { FLASH_FCoE_PRIMARY_IMAGE_START_g2, IMG_TYPE_FCOE_FW_ACTIVE,
+- FLASH_IMAGE_MAX_SIZE_g2},
+- { FLASH_FCoE_BACKUP_IMAGE_START_g2, IMG_TYPE_FCOE_FW_BACKUP,
+- FLASH_IMAGE_MAX_SIZE_g2}
++
++ struct flash_comp gen2_flash_types[] = {
++ { FLASH_iSCSI_PRIMARY_IMAGE_START_g2, OPTYPE_ISCSI_ACTIVE,
++ FLASH_IMAGE_MAX_SIZE_g2, IMAGE_FIRMWARE_iSCSI},
++ { FLASH_REDBOOT_START_g2, OPTYPE_REDBOOT,
++ FLASH_REDBOOT_IMAGE_MAX_SIZE_g2, IMAGE_BOOT_CODE},
++ { FLASH_iSCSI_BIOS_START_g2, OPTYPE_BIOS,
++ FLASH_BIOS_IMAGE_MAX_SIZE_g2, IMAGE_OPTION_ROM_ISCSI},
++ { FLASH_PXE_BIOS_START_g2, OPTYPE_PXE_BIOS,
++ FLASH_BIOS_IMAGE_MAX_SIZE_g2, IMAGE_OPTION_ROM_PXE},
++ { FLASH_FCoE_BIOS_START_g2, OPTYPE_FCOE_BIOS,
++ FLASH_BIOS_IMAGE_MAX_SIZE_g2, IMAGE_OPTION_ROM_FCoE},
++ { FLASH_iSCSI_BACKUP_IMAGE_START_g2, OPTYPE_ISCSI_BACKUP,
++ FLASH_IMAGE_MAX_SIZE_g2, IMAGE_FIRMWARE_BACKUP_iSCSI},
++ { FLASH_FCoE_PRIMARY_IMAGE_START_g2, OPTYPE_FCOE_FW_ACTIVE,
++ FLASH_IMAGE_MAX_SIZE_g2, IMAGE_FIRMWARE_FCoE},
++ { FLASH_FCoE_BACKUP_IMAGE_START_g2, OPTYPE_FCOE_FW_BACKUP,
++ FLASH_IMAGE_MAX_SIZE_g2, IMAGE_FIRMWARE_BACKUP_FCoE}
+ };
+
+ if (adapter->generation == BE_GEN3) {
+@@ -2847,22 +2892,37 @@ static int be_flash_data(struct be_adapter *adapter,
+ filehdr_size = sizeof(struct flash_file_hdr_g2);
+ num_comp = ARRAY_SIZE(gen2_flash_types);
+ }
++ /* Get flash section info*/
++ fsec = get_fsec_info(adapter, filehdr_size + img_hdrs_size, fw);
++ if (!fsec) {
++ dev_err(&adapter->pdev->dev,
++ "Invalid Cookie. UFI corrupted ?\n");
++ return -1;
++ }
+ for (i = 0; i < num_comp; i++) {
+- if ((pflashcomp[i].optype == IMG_TYPE_NCSI_FW) &&
+- memcmp(adapter->fw_ver, "3.102.148.0", 11) < 0)
++ if (!is_comp_in_ufi(adapter, fsec, pflashcomp[i].img_type))
+ continue;
+- if (pflashcomp[i].optype == IMG_TYPE_PHY_FW) {
++
++ if ((pflashcomp[i].optype == OPTYPE_NCSI_FW) &&
++ memcmp(adapter->fw_ver, "3.102.148.0", 11) < 0)
++ continue;
++
++ if (pflashcomp[i].optype == OPTYPE_PHY_FW) {
+ if (!phy_flashing_required(adapter))
+ continue;
+ }
+- if ((pflashcomp[i].optype == IMG_TYPE_REDBOOT) &&
+- (!be_flash_redboot(adapter, fw->data,
+- pflashcomp[i].offset, pflashcomp[i].size, filehdr_size +
+- (num_of_images * sizeof(struct image_hdr)))))
++
++ hdr_size = filehdr_size +
++ (num_of_images * sizeof(struct image_hdr));
++
++ if ((pflashcomp[i].optype == OPTYPE_REDBOOT) &&
++ (!be_flash_redboot(adapter, fw->data, pflashcomp[i].offset,
++ pflashcomp[i].size, hdr_size)))
+ continue;
++
++ /* Flash the component */
+ p = fw->data;
+- p += filehdr_size + pflashcomp[i].offset
+- + (num_of_images * sizeof(struct image_hdr));
++ p += filehdr_size + pflashcomp[i].offset + img_hdrs_size;
+ if (p + pflashcomp[i].size > fw->data + fw->size)
+ return -1;
+ total_bytes = pflashcomp[i].size;
+@@ -2873,12 +2933,12 @@ static int be_flash_data(struct be_adapter *adapter,
+ num_bytes = total_bytes;
+ total_bytes -= num_bytes;
+ if (!total_bytes) {
+- if (pflashcomp[i].optype == IMG_TYPE_PHY_FW)
++ if (pflashcomp[i].optype == OPTYPE_PHY_FW)
+ flash_op = FLASHROM_OPER_PHY_FLASH;
+ else
+ flash_op = FLASHROM_OPER_FLASH;
+ } else {
+- if (pflashcomp[i].optype == IMG_TYPE_PHY_FW)
++ if (pflashcomp[i].optype == OPTYPE_PHY_FW)
+ flash_op = FLASHROM_OPER_PHY_SAVE;
+ else
+ flash_op = FLASHROM_OPER_SAVE;
+@@ -2890,7 +2950,7 @@ static int be_flash_data(struct be_adapter *adapter,
+ if (status) {
+ if ((status == ILLEGAL_IOCTL_REQ) &&
+ (pflashcomp[i].optype ==
+- IMG_TYPE_PHY_FW))
++ OPTYPE_PHY_FW))
+ break;
+ dev_err(&adapter->pdev->dev,
+ "cmd to write to flash rom failed.\n");
+--
+1.7.10
+
Added: dists/sid/linux-2.6/debian/patches/features/all/be2net/0051-be2net-Ignore-status-of-some-ioctls-during-driver-lo.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/be2net/0051-be2net-Ignore-status-of-some-ioctls-during-driver-lo.patch Sun May 27 00:21:22 2012 (r19037)
@@ -0,0 +1,49 @@
+From: Ajit Khaparde <ajit.khaparde at emulex.com>
+Date: Thu, 26 Apr 2012 15:42:31 +0000
+Subject: [PATCH 51/58] be2net: Ignore status of some ioctls during driver
+ load
+
+commit ddc3f5cbaf1ddea122ec1d51c1cce97482b4d0c2 upstream.
+
+Signed-off-by: Ajit Khaparde <ajit.khaparde at emulex.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/emulex/benet/be_main.c | 17 ++++-------------
+ 1 file changed, 4 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
+index 730fb1b..9effea4 100644
+--- a/drivers/net/ethernet/emulex/benet/be_main.c
++++ b/drivers/net/ethernet/emulex/benet/be_main.c
+@@ -2696,24 +2696,15 @@ static int be_setup(struct be_adapter *adapter)
+
+ be_cmd_get_fw_ver(adapter, adapter->fw_ver, NULL);
+
+- status = be_vid_config(adapter, false, 0);
+- if (status)
+- goto err;
++ be_vid_config(adapter, false, 0);
+
+ be_set_rx_mode(adapter->netdev);
+
+- status = be_cmd_get_flow_control(adapter, &tx_fc, &rx_fc);
+- /* For Lancer: It is legal for this cmd to fail on VF */
+- if (status && (be_physfn(adapter) || !lancer_chip(adapter)))
+- goto err;
++ be_cmd_get_flow_control(adapter, &tx_fc, &rx_fc);
+
+- if (rx_fc != adapter->rx_fc || tx_fc != adapter->tx_fc) {
+- status = be_cmd_set_flow_control(adapter, adapter->tx_fc,
++ if (rx_fc != adapter->rx_fc || tx_fc != adapter->tx_fc)
++ be_cmd_set_flow_control(adapter, adapter->tx_fc,
+ adapter->rx_fc);
+- /* For Lancer: It is legal for this cmd to fail on VF */
+- if (status && (be_physfn(adapter) || !lancer_chip(adapter)))
+- goto err;
+- }
+
+ pcie_set_readrq(adapter->pdev, 4096);
+
+--
+1.7.10
+
Added: dists/sid/linux-2.6/debian/patches/features/all/be2net/0052-be2net-fix-speed-displayed-by-ethtool-on-certain-SKU.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/be2net/0052-be2net-fix-speed-displayed-by-ethtool-on-certain-SKU.patch Sun May 27 00:21:22 2012 (r19037)
@@ -0,0 +1,30 @@
+From: Ajit Khaparde <ajit.khaparde at emulex.com>
+Date: Thu, 26 Apr 2012 15:42:39 +0000
+Subject: [PATCH 52/58] be2net: fix speed displayed by ethtool on certain SKUs
+
+commit 2a89611a051cdcfcf4a7ae21d18eef64fab517b4 upstream.
+
+logical speed returned by link_status_query needs to be multiplied by 10.
+
+Signed-off-by: Ajit Khaparde <ajit.khaparde at emulex.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/emulex/benet/be_ethtool.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be_ethtool.c b/drivers/net/ethernet/emulex/benet/be_ethtool.c
+index 9d71bad..b3b5fae 100644
+--- a/drivers/net/ethernet/emulex/benet/be_ethtool.c
++++ b/drivers/net/ethernet/emulex/benet/be_ethtool.c
+@@ -557,7 +557,7 @@ static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
+ if (!status)
+ be_link_status_update(adapter, link_status);
+ if (link_speed)
+- et_speed = link_speed;
++ et_speed = link_speed * 10;
+ else
+ et_speed = convert_to_et_speed(port_speed);
+ } else {
+--
+1.7.10
+
Added: dists/sid/linux-2.6/debian/patches/features/all/be2net/0053-be2net-update-the-driver-version.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/be2net/0053-be2net-update-the-driver-version.patch Sun May 27 00:21:22 2012 (r19037)
@@ -0,0 +1,28 @@
+From: Ajit Khaparde <ajit.khaparde at emulex.com>
+Date: Thu, 26 Apr 2012 15:42:46 +0000
+Subject: [PATCH 53/58] be2net: update the driver version
+
+commit 06b0ab373df74f7916282b452b35d6389a605b8a upstream.
+
+Signed-off-by: Ajit Khaparde <ajit.khaparde at emulex.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/emulex/benet/be.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h
+index 4bc18ef..c3ee910 100644
+--- a/drivers/net/ethernet/emulex/benet/be.h
++++ b/drivers/net/ethernet/emulex/benet/be.h
+@@ -33,7 +33,7 @@
+
+ #include "be_hw.h"
+
+-#define DRV_VER "4.2.116u"
++#define DRV_VER "4.2.220u"
+ #define DRV_NAME "be2net"
+ #define BE_NAME "ServerEngines BladeEngine2 10Gbps NIC"
+ #define BE3_NAME "ServerEngines BladeEngine3 10Gbps NIC"
+--
+1.7.10
+
Added: dists/sid/linux-2.6/debian/patches/features/all/be2net/0054-be2net-Fix-to-not-set-link-speed-for-disabled-functi.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/be2net/0054-be2net-Fix-to-not-set-link-speed-for-disabled-functi.patch Sun May 27 00:21:22 2012 (r19037)
@@ -0,0 +1,33 @@
+From: Somnath Kotur <somnath.kotur at emulex.com>
+Date: Wed, 2 May 2012 03:40:16 +0000
+Subject: [PATCH 54/58] be2net: Fix to not set link speed for disabled
+ functions of a UMC card
+
+commit 22ca7a6e9a68a7e0c149b22ebed9dcd106245bb7 upstream.
+
+This renders the interface view somewhat inconsistent from the Host OS POV
+considering the rest of the interfaces are showing their respective speeds
+based on the bandwidth assigned to them.
+
+Signed-off-by: Somnath Kotur <somnath.kotur at emulex.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/emulex/benet/be_ethtool.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be_ethtool.c b/drivers/net/ethernet/emulex/benet/be_ethtool.c
+index b3b5fae..1763836 100644
+--- a/drivers/net/ethernet/emulex/benet/be_ethtool.c
++++ b/drivers/net/ethernet/emulex/benet/be_ethtool.c
+@@ -558,7 +558,7 @@ static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
+ be_link_status_update(adapter, link_status);
+ if (link_speed)
+ et_speed = link_speed * 10;
+- else
++ else if (link_status)
+ et_speed = convert_to_et_speed(port_speed);
+ } else {
+ et_speed = adapter->phy.forced_port_speed;
+--
+1.7.10
+
Added: dists/sid/linux-2.6/debian/patches/features/all/be2net/0055-be2net-Fix-to-apply-duplex-value-as-unknown-when-lin.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/be2net/0055-be2net-Fix-to-apply-duplex-value-as-unknown-when-lin.patch Sun May 27 00:21:22 2012 (r19037)
@@ -0,0 +1,31 @@
+From: Somnath Kotur <somnath.kotur at emulex.com>
+Date: Wed, 2 May 2012 03:40:32 +0000
+Subject: [PATCH 55/58] be2net: Fix to apply duplex value as unknown when link
+ is down.
+
+commit 682256dbef8e827385cf214f3ada8b62f6c227ed upstream.
+
+Suggested-by: Ben Hutchings <bhutchings at solarflare.com>
+Signed-off-by: Sarveshwar Bandi <sarveshwar.bandi at emulex.com>
+Signed-off-by: Somnath Kotur <somnath.kotur at emulex.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/emulex/benet/be_ethtool.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be_ethtool.c b/drivers/net/ethernet/emulex/benet/be_ethtool.c
+index 1763836..730e96a 100644
+--- a/drivers/net/ethernet/emulex/benet/be_ethtool.c
++++ b/drivers/net/ethernet/emulex/benet/be_ethtool.c
+@@ -618,7 +618,7 @@ static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
+ ecmd->supported = adapter->phy.supported;
+ }
+
+- ecmd->duplex = DUPLEX_FULL;
++ ecmd->duplex = netif_carrier_ok(netdev) ? DUPLEX_FULL : DUPLEX_UNKNOWN;
+ ecmd->phy_address = adapter->port_num;
+
+ return 0;
+--
+1.7.10
+
Added: dists/sid/linux-2.6/debian/patches/features/all/be2net/0056-be2net-Record-receive-queue-index-in-skb-to-aid-RPS.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/be2net/0056-be2net-Record-receive-queue-index-in-skb-to-aid-RPS.patch Sun May 27 00:21:22 2012 (r19037)
@@ -0,0 +1,36 @@
+From: Somnath Kotur <somnath.kotur at emulex.com>
+Date: Wed, 2 May 2012 03:40:49 +0000
+Subject: [PATCH 56/58] be2net: Record receive queue index in skb to aid RPS.
+
+commit aaa6daec586cd39a6cd44b3d0ab91a84b0e3d53a upstream.
+
+Signed-off-by: Sarveshwar Bandi <Sarveshwar.Bandi at emulex.com>
+Signed-off-by: Somnath Kotur <somnath.kotur at emulex.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/emulex/benet/be_main.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
+index 9effea4..0dd4b88 100644
+--- a/drivers/net/ethernet/emulex/benet/be_main.c
++++ b/drivers/net/ethernet/emulex/benet/be_main.c
+@@ -1251,6 +1251,7 @@ static void be_rx_compl_process(struct be_rx_obj *rxo,
+ skb_checksum_none_assert(skb);
+
+ skb->protocol = eth_type_trans(skb, netdev);
++ skb_record_rx_queue(skb, rxo - &adapter->rx_obj[0]);
+ if (netdev->features & NETIF_F_RXHASH)
+ skb->rxhash = rxcp->rss_hash;
+
+@@ -1307,6 +1308,7 @@ void be_rx_compl_process_gro(struct be_rx_obj *rxo, struct napi_struct *napi,
+ skb->len = rxcp->pkt_size;
+ skb->data_len = rxcp->pkt_size;
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
++ skb_record_rx_queue(skb, rxo - &adapter->rx_obj[0]);
+ if (adapter->netdev->features & NETIF_F_RXHASH)
+ skb->rxhash = rxcp->rss_hash;
+
+--
+1.7.10
+
Added: dists/sid/linux-2.6/debian/patches/features/all/be2net/0057-be2net-Fix-EEH-error-reset-before-a-flash-dump-compl.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/be2net/0057-be2net-Fix-EEH-error-reset-before-a-flash-dump-compl.patch Sun May 27 00:21:22 2012 (r19037)
@@ -0,0 +1,37 @@
+From: Somnath Kotur <somnath.kotur at emulex.com>
+Date: Wed, 2 May 2012 03:41:01 +0000
+Subject: [PATCH 57/58] be2net: Fix EEH error reset before a flash dump
+ completes
+
+commit eeb7fc7bc095546b21188e8e076a59bce73f9ca6 upstream.
+
+An EEH error can cause the FW to trigger a flash debug dump.
+Resetting the card while flash dump is in progress can cause it not to recover.
+Wait for it to finish before letting EEH flow to reset the card.
+
+Signed-off-by: Sathya Perla <Sathya.Perla at emulex.com>
+Signed-off-by: Somnath Kotur <somnath.kotur at emulex.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/emulex/benet/be_main.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
+index 0dd4b88..3492dc8 100644
+--- a/drivers/net/ethernet/emulex/benet/be_main.c
++++ b/drivers/net/ethernet/emulex/benet/be_main.c
+@@ -3813,6 +3813,11 @@ static pci_ers_result_t be_eeh_err_detected(struct pci_dev *pdev,
+
+ pci_disable_device(pdev);
+
++ /* The error could cause the FW to trigger a flash debug dump.
++ * Resetting the card while flash dump is in progress
++ * can cause it not to recover; wait for it to finish
++ */
++ ssleep(30);
+ return PCI_ERS_RESULT_NEED_RESET;
+ }
+
+--
+1.7.10
+
Added: dists/sid/linux-2.6/debian/patches/features/all/be2net/0058-be2net-avoid-disabling-sriov-while-VFs-are-assigned.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/be2net/0058-be2net-avoid-disabling-sriov-while-VFs-are-assigned.patch Sun May 27 00:21:22 2012 (r19037)
@@ -0,0 +1,473 @@
+From: Sathya Perla <sathya.perla at emulex.com>
+Date: Tue, 8 May 2012 19:41:24 +0000
+Subject: [PATCH 58/58] be2net: avoid disabling sriov while VFs are assigned
+
+commit 39f1d94d300a58eb3e9b851d077cada4e2fa9d46 upstream.
+
+Calling pci_disable_sriov() while VFs are assigned to VMs causes
+kernel panic. This patch uses PCI_DEV_FLAGS_ASSIGNED bit state of the
+VF's pci_dev to avoid this. Also, the unconditional function reset cmd
+issued on a PF probe can delete the VF configuration for the
+previously enabled VFs. A scratchpad register is now used to issue a
+function reset only when needed (i.e., in a crash dump scenario.)
+
+Signed-off-by: Sathya Perla <sathya.perla at emulex.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/emulex/benet/be.h | 22 +--
+ drivers/net/ethernet/emulex/benet/be_hw.h | 2 +
+ drivers/net/ethernet/emulex/benet/be_main.c | 199 ++++++++++++++++-----------
+ 3 files changed, 134 insertions(+), 89 deletions(-)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h
+index c3ee910..ecf1a81 100644
+--- a/drivers/net/ethernet/emulex/benet/be.h
++++ b/drivers/net/ethernet/emulex/benet/be.h
+@@ -313,6 +313,11 @@ struct be_vf_cfg {
+ u32 tx_rate;
+ };
+
++enum vf_state {
++ ENABLED = 0,
++ ASSIGNED = 1
++};
++
+ #define BE_FLAGS_LINK_STATUS_INIT 1
+ #define BE_FLAGS_WORKER_SCHEDULED (1 << 3)
+ #define BE_UC_PMAC_COUNT 30
+@@ -403,8 +408,9 @@ struct be_adapter {
+ u32 flash_status;
+ struct completion flash_compl;
+
+- u32 num_vfs;
+- u8 is_virtfn;
++ u32 num_vfs; /* Number of VFs provisioned by PF driver */
++ u32 dev_num_vfs; /* Number of VFs supported by HW */
++ u8 virtfn;
+ struct be_vf_cfg *vf_cfg;
+ bool be3_native;
+ u32 sli_family;
+@@ -417,8 +423,10 @@ struct be_adapter {
+ u32 uc_macs; /* Count of secondary UC MAC programmed */
+ };
+
+-#define be_physfn(adapter) (!adapter->is_virtfn)
++#define be_physfn(adapter) (!adapter->virtfn)
+ #define sriov_enabled(adapter) (adapter->num_vfs > 0)
++#define sriov_want(adapter) (adapter->dev_num_vfs && num_vfs && \
++ be_physfn(adapter))
+ #define for_all_vfs(adapter, vf_cfg, i) \
+ for (i = 0, vf_cfg = &adapter->vf_cfg[i]; i < adapter->num_vfs; \
+ i++, vf_cfg++)
+@@ -547,14 +555,6 @@ static inline u8 is_udp_pkt(struct sk_buff *skb)
+ return val;
+ }
+
+-static inline void be_check_sriov_fn_type(struct be_adapter *adapter)
+-{
+- u32 sli_intf;
+-
+- pci_read_config_dword(adapter->pdev, SLI_INTF_REG_OFFSET, &sli_intf);
+- adapter->is_virtfn = (sli_intf & SLI_INTF_FT_MASK) ? 1 : 0;
+-}
+-
+ static inline void be_vf_eth_addr_generate(struct be_adapter *adapter, u8 *mac)
+ {
+ u32 addr;
+diff --git a/drivers/net/ethernet/emulex/benet/be_hw.h b/drivers/net/ethernet/emulex/benet/be_hw.h
+index 0949aa6..f38b58c 100644
+--- a/drivers/net/ethernet/emulex/benet/be_hw.h
++++ b/drivers/net/ethernet/emulex/benet/be_hw.h
+@@ -58,6 +58,8 @@
+
+ #define SLI_PORT_CONTROL_IP_MASK 0x08000000
+
++#define PCICFG_CUST_SCRATCHPAD_CSR 0x1EC
++
+ /********* Memory BAR register ************/
+ #define PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET 0xfc
+ /* Host Interrupt Enable, if set interrupts are enabled although "PCI Interrupt
+diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
+index 3492dc8..910bae8 100644
+--- a/drivers/net/ethernet/emulex/benet/be_main.c
++++ b/drivers/net/ethernet/emulex/benet/be_main.c
+@@ -1041,6 +1041,29 @@ static int be_set_vf_tx_rate(struct net_device *netdev,
+ return status;
+ }
+
++static int be_find_vfs(struct be_adapter *adapter, int vf_state)
++{
++ struct pci_dev *dev, *pdev = adapter->pdev;
++ int vfs = 0, assigned_vfs = 0, pos, vf_fn;
++ u16 offset, stride;
++
++ pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_SRIOV);
++ pci_read_config_word(pdev, pos + PCI_SRIOV_VF_OFFSET, &offset);
++ pci_read_config_word(pdev, pos + PCI_SRIOV_VF_STRIDE, &stride);
++
++ dev = pci_get_device(pdev->vendor, PCI_ANY_ID, NULL);
++ while (dev) {
++ vf_fn = (pdev->devfn + offset + stride * vfs) & 0xFFFF;
++ if (dev->is_virtfn && dev->devfn == vf_fn) {
++ vfs++;
++ if (dev->dev_flags & PCI_DEV_FLAGS_ASSIGNED)
++ assigned_vfs++;
++ }
++ dev = pci_get_device(pdev->vendor, PCI_ANY_ID, dev);
++ }
++ return (vf_state == ASSIGNED) ? assigned_vfs : vfs;
++}
++
+ static void be_eqd_update(struct be_adapter *adapter, struct be_eq_obj *eqo)
+ {
+ struct be_rx_stats *stats = rx_stats(&adapter->rx_obj[eqo->idx]);
+@@ -1781,9 +1804,9 @@ static void be_tx_queues_destroy(struct be_adapter *adapter)
+
+ static int be_num_txqs_want(struct be_adapter *adapter)
+ {
+- if (sriov_enabled(adapter) || be_is_mc(adapter) ||
+- lancer_chip(adapter) || !be_physfn(adapter) ||
+- adapter->generation == BE_GEN2)
++ if (sriov_want(adapter) || be_is_mc(adapter) ||
++ lancer_chip(adapter) || !be_physfn(adapter) ||
++ adapter->generation == BE_GEN2)
+ return 1;
+ else
+ return MAX_TX_QS;
+@@ -2110,7 +2133,7 @@ static void be_msix_disable(struct be_adapter *adapter)
+ static uint be_num_rss_want(struct be_adapter *adapter)
+ {
+ if ((adapter->function_caps & BE_FUNCTION_CAPS_RSS) &&
+- adapter->num_vfs == 0 && be_physfn(adapter) &&
++ !sriov_want(adapter) && be_physfn(adapter) &&
+ !be_is_mc(adapter))
+ return (adapter->be3_native) ? BE3_MAX_RSS_QS : BE2_MAX_RSS_QS;
+ else
+@@ -2144,53 +2167,6 @@ done:
+ return;
+ }
+
+-static int be_sriov_enable(struct be_adapter *adapter)
+-{
+- be_check_sriov_fn_type(adapter);
+-
+-#ifdef CONFIG_PCI_IOV
+- if (be_physfn(adapter) && num_vfs) {
+- int status, pos;
+- u16 dev_vfs;
+-
+- pos = pci_find_ext_capability(adapter->pdev,
+- PCI_EXT_CAP_ID_SRIOV);
+- pci_read_config_word(adapter->pdev,
+- pos + PCI_SRIOV_TOTAL_VF, &dev_vfs);
+-
+- adapter->num_vfs = min_t(u16, num_vfs, dev_vfs);
+- if (adapter->num_vfs != num_vfs)
+- dev_info(&adapter->pdev->dev,
+- "Device supports %d VFs and not %d\n",
+- adapter->num_vfs, num_vfs);
+-
+- status = pci_enable_sriov(adapter->pdev, adapter->num_vfs);
+- if (status)
+- adapter->num_vfs = 0;
+-
+- if (adapter->num_vfs) {
+- adapter->vf_cfg = kcalloc(num_vfs,
+- sizeof(struct be_vf_cfg),
+- GFP_KERNEL);
+- if (!adapter->vf_cfg)
+- return -ENOMEM;
+- }
+- }
+-#endif
+- return 0;
+-}
+-
+-static void be_sriov_disable(struct be_adapter *adapter)
+-{
+-#ifdef CONFIG_PCI_IOV
+- if (sriov_enabled(adapter)) {
+- pci_disable_sriov(adapter->pdev);
+- kfree(adapter->vf_cfg);
+- adapter->num_vfs = 0;
+- }
+-#endif
+-}
+-
+ static inline int be_msix_vec_get(struct be_adapter *adapter,
+ struct be_eq_obj *eqo)
+ {
+@@ -2492,6 +2468,11 @@ static void be_vf_clear(struct be_adapter *adapter)
+ struct be_vf_cfg *vf_cfg;
+ u32 vf;
+
++ if (be_find_vfs(adapter, ASSIGNED)) {
++ dev_warn(&adapter->pdev->dev, "VFs are assigned to VMs\n");
++ goto done;
++ }
++
+ for_all_vfs(adapter, vf_cfg, vf) {
+ if (lancer_chip(adapter))
+ be_cmd_set_mac_list(adapter, NULL, 0, vf + 1);
+@@ -2501,6 +2482,10 @@ static void be_vf_clear(struct be_adapter *adapter)
+
+ be_cmd_if_destroy(adapter, vf_cfg->if_handle, vf + 1);
+ }
++ pci_disable_sriov(adapter->pdev);
++done:
++ kfree(adapter->vf_cfg);
++ adapter->num_vfs = 0;
+ }
+
+ static int be_clear(struct be_adapter *adapter)
+@@ -2530,29 +2515,60 @@ static int be_clear(struct be_adapter *adapter)
+ be_cmd_fw_clean(adapter);
+
+ be_msix_disable(adapter);
+- kfree(adapter->pmac_id);
++ pci_write_config_dword(adapter->pdev, PCICFG_CUST_SCRATCHPAD_CSR, 0);
+ return 0;
+ }
+
+-static void be_vf_setup_init(struct be_adapter *adapter)
++static int be_vf_setup_init(struct be_adapter *adapter)
+ {
+ struct be_vf_cfg *vf_cfg;
+ int vf;
+
++ adapter->vf_cfg = kcalloc(adapter->num_vfs, sizeof(*vf_cfg),
++ GFP_KERNEL);
++ if (!adapter->vf_cfg)
++ return -ENOMEM;
++
+ for_all_vfs(adapter, vf_cfg, vf) {
+ vf_cfg->if_handle = -1;
+ vf_cfg->pmac_id = -1;
+ }
++ return 0;
+ }
+
+ static int be_vf_setup(struct be_adapter *adapter)
+ {
+ struct be_vf_cfg *vf_cfg;
++ struct device *dev = &adapter->pdev->dev;
+ u32 cap_flags, en_flags, vf;
+ u16 def_vlan, lnk_speed;
+- int status;
++ int status, enabled_vfs;
++
++ enabled_vfs = be_find_vfs(adapter, ENABLED);
++ if (enabled_vfs) {
++ dev_warn(dev, "%d VFs are already enabled\n", enabled_vfs);
++ dev_warn(dev, "Ignoring num_vfs=%d setting\n", num_vfs);
++ return 0;
++ }
+
+- be_vf_setup_init(adapter);
++ if (num_vfs > adapter->dev_num_vfs) {
++ dev_warn(dev, "Device supports %d VFs and not %d\n",
++ adapter->dev_num_vfs, num_vfs);
++ num_vfs = adapter->dev_num_vfs;
++ }
++
++ status = pci_enable_sriov(adapter->pdev, num_vfs);
++ if (!status) {
++ adapter->num_vfs = num_vfs;
++ } else {
++ /* Platform doesn't support SRIOV though device supports it */
++ dev_warn(dev, "SRIOV enable failed\n");
++ return 0;
++ }
++
++ status = be_vf_setup_init(adapter);
++ if (status)
++ goto err;
+
+ cap_flags = en_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST |
+ BE_IF_FLAGS_MULTICAST;
+@@ -2563,9 +2579,11 @@ static int be_vf_setup(struct be_adapter *adapter)
+ goto err;
+ }
+
+- status = be_vf_eth_addr_config(adapter);
+- if (status)
+- goto err;
++ if (!enabled_vfs) {
++ status = be_vf_eth_addr_config(adapter);
++ if (status)
++ goto err;
++ }
+
+ for_all_vfs(adapter, vf_cfg, vf) {
+ status = be_cmd_link_status_query(adapter, NULL, &lnk_speed,
+@@ -2622,9 +2640,25 @@ do_none:
+ return status;
+ }
+
++/* Routine to query per function resource limits */
++static int be_get_config(struct be_adapter *adapter)
++{
++ int pos;
++ u16 dev_num_vfs;
++
++ pos = pci_find_ext_capability(adapter->pdev, PCI_EXT_CAP_ID_SRIOV);
++ if (pos) {
++ pci_read_config_word(adapter->pdev, pos + PCI_SRIOV_TOTAL_VF,
++ &dev_num_vfs);
++ adapter->dev_num_vfs = dev_num_vfs;
++ }
++ return 0;
++}
++
+ static int be_setup(struct be_adapter *adapter)
+ {
+ struct net_device *netdev = adapter->netdev;
++ struct device *dev = &adapter->pdev->dev;
+ u32 cap_flags, en_flags;
+ u32 tx_fc, rx_fc;
+ int status;
+@@ -2632,6 +2666,8 @@ static int be_setup(struct be_adapter *adapter)
+
+ be_setup_init(adapter);
+
++ be_get_config(adapter);
++
+ be_cmd_req_native_mode(adapter);
+
+ be_msix_enable(adapter);
+@@ -2710,10 +2746,11 @@ static int be_setup(struct be_adapter *adapter)
+
+ pcie_set_readrq(adapter->pdev, 4096);
+
+- if (sriov_enabled(adapter)) {
+- status = be_vf_setup(adapter);
+- if (status)
+- goto err;
++ if (be_physfn(adapter) && num_vfs) {
++ if (adapter->dev_num_vfs)
++ be_vf_setup(adapter);
++ else
++ dev_warn(dev, "device doesn't support SRIOV\n");
+ }
+
+ be_cmd_get_phy_info(adapter);
+@@ -2723,6 +2760,7 @@ static int be_setup(struct be_adapter *adapter)
+ schedule_delayed_work(&adapter->work, msecs_to_jiffies(1000));
+ adapter->flags |= BE_FLAGS_WORKER_SCHEDULED;
+
++ pci_write_config_dword(adapter->pdev, PCICFG_CUST_SCRATCHPAD_CSR, 1);
+ return 0;
+ err:
+ be_clear(adapter);
+@@ -3344,8 +3382,6 @@ static void __devexit be_remove(struct pci_dev *pdev)
+
+ be_ctrl_cleanup(adapter);
+
+- be_sriov_disable(adapter);
+-
+ pci_set_drvdata(pdev, NULL);
+ pci_release_regions(pdev);
+ pci_disable_device(pdev);
+@@ -3359,7 +3395,7 @@ bool be_is_wol_supported(struct be_adapter *adapter)
+ !be_is_wol_excluded(adapter)) ? true : false;
+ }
+
+-static int be_get_config(struct be_adapter *adapter)
++static int be_get_initial_config(struct be_adapter *adapter)
+ {
+ int status;
+
+@@ -3402,7 +3438,7 @@ static int be_get_config(struct be_adapter *adapter)
+ return 0;
+ }
+
+-static int be_dev_family_check(struct be_adapter *adapter)
++static int be_dev_type_check(struct be_adapter *adapter)
+ {
+ struct pci_dev *pdev = adapter->pdev;
+ u32 sli_intf = 0, if_type;
+@@ -3435,6 +3471,9 @@ static int be_dev_family_check(struct be_adapter *adapter)
+ default:
+ adapter->generation = 0;
+ }
++
++ pci_read_config_dword(adapter->pdev, SLI_INTF_REG_OFFSET, &sli_intf);
++ adapter->virtfn = (sli_intf & SLI_INTF_FT_MASK) ? 1 : 0;
+ return 0;
+ }
+
+@@ -3578,6 +3617,14 @@ reschedule:
+ schedule_delayed_work(&adapter->work, msecs_to_jiffies(1000));
+ }
+
++static bool be_reset_required(struct be_adapter *adapter)
++{
++ u32 reg;
++
++ pci_read_config_dword(adapter->pdev, PCICFG_CUST_SCRATCHPAD_CSR, ®);
++ return reg;
++}
++
+ static int __devinit be_probe(struct pci_dev *pdev,
+ const struct pci_device_id *pdev_id)
+ {
+@@ -3603,7 +3650,7 @@ static int __devinit be_probe(struct pci_dev *pdev,
+ adapter->pdev = pdev;
+ pci_set_drvdata(pdev, adapter);
+
+- status = be_dev_family_check(adapter);
++ status = be_dev_type_check(adapter);
+ if (status)
+ goto free_netdev;
+
+@@ -3621,13 +3668,9 @@ static int __devinit be_probe(struct pci_dev *pdev,
+ }
+ }
+
+- status = be_sriov_enable(adapter);
+- if (status)
+- goto free_netdev;
+-
+ status = be_ctrl_init(adapter);
+ if (status)
+- goto disable_sriov;
++ goto free_netdev;
+
+ if (lancer_chip(adapter)) {
+ status = lancer_wait_ready(adapter);
+@@ -3654,9 +3697,11 @@ static int __devinit be_probe(struct pci_dev *pdev,
+ if (status)
+ goto ctrl_clean;
+
+- status = be_cmd_reset_function(adapter);
+- if (status)
+- goto ctrl_clean;
++ if (be_reset_required(adapter)) {
++ status = be_cmd_reset_function(adapter);
++ if (status)
++ goto ctrl_clean;
++ }
+
+ /* The INTR bit may be set in the card when probed by a kdump kernel
+ * after a crash.
+@@ -3668,7 +3713,7 @@ static int __devinit be_probe(struct pci_dev *pdev,
+ if (status)
+ goto ctrl_clean;
+
+- status = be_get_config(adapter);
++ status = be_get_initial_config(adapter);
+ if (status)
+ goto stats_clean;
+
+@@ -3697,8 +3742,6 @@ stats_clean:
+ be_stats_cleanup(adapter);
+ ctrl_clean:
+ be_ctrl_cleanup(adapter);
+-disable_sriov:
+- be_sriov_disable(adapter);
+ free_netdev:
+ free_netdev(netdev);
+ pci_set_drvdata(pdev, NULL);
+--
+1.7.10
+
Modified: dists/sid/linux-2.6/debian/patches/series/base
==============================================================================
--- dists/sid/linux-2.6/debian/patches/series/base Fri May 25 14:02:43 2012 (r19036)
+++ dists/sid/linux-2.6/debian/patches/series/base Sun May 27 00:21:22 2012 (r19037)
@@ -232,3 +232,64 @@
+ features/all/rt2x00-add-rt5372-chipset-support.patch
+ bugfix/all/acpi-battery-only-refresh-the-sysfs-files-when-pertinent.patch
++ bugfix/all/ethtool-null-terminate-filename-passed-to.patch
+
+# Update be2net driver to 3.5ish
++ features/all/be2net/0001-sweep-the-floors-and-convert-some-.get_drvinfo-routi.patch
++ features/all/be2net/0002-be2net-init-vf-_if_handle-vf_pmac_id-to-handle-failu.patch
++ features/all/be2net/0003-be2net-stop-checking-the-UE-registers-after-an-EEH-e.patch
++ features/all/be2net/0004-be2net-don-t-log-more-than-one-error-on-detecting-EE.patch
++ features/all/be2net/0005-be2net-stop-issuing-FW-cmds-if-any-cmd-times-out.patch
++ features/all/be2net/0006-be2net-Fix-TX-queue-create-for-Lancer.patch
++ features/all/be2net/0007-be2net-add-register-dump-feature-for-Lancer.patch
++ features/all/be2net/0008-be2net-Add-EEPROM-dump-feature-for-Lancer.patch
++ features/all/be2net/0009-be2net-Fix-VLAN-promiscous-mode-for-Lancer.patch
++ features/all/be2net/0010-be2net-Use-V1-query-link-status-command-for-lancer.patch
++ features/all/be2net/0011-be2net-Move-to-new-SR-IOV-implementation-in-Lancer.patch
++ features/all/be2net/0012-be2net-Fix-error-recovery-paths.patch
++ features/all/be2net/0013-be2net-Add-error-handling-for-Lancer.patch
++ features/all/be2net/0014-be2net-Use-new-hash-key.patch
++ features/all/be2net/0015-be2net-Fix-non-utilization-of-RX-queues.patch
++ features/all/be2net/0016-be2net-netpoll-support.patch
++ features/all/be2net/0017-be2net-update-some-counters-to-display-via-ethtool.patch
++ features/all/be2net/0018-be2net-workaround-to-fix-a-bug-in-BE.patch
++ features/all/be2net/0019-be2net-fix-ethtool-ringparam-reporting.patch
++ features/all/be2net/0020-be2net-refactor-cleanup-vf-configuration-code.patch
++ features/all/be2net/0021-be2net-Add-support-for-Skyhawk-cards.patch
++ features/all/be2net/0022-be2net-Fix-INTx-processing-for-Lancer.patch
++ features/all/be2net/0023-be2net-fix-be_vlan_add-rem_vid.patch
++ features/all/be2net/0024-be2net-fix-range-check-for-set_qos-for-a-VF.patch
++ features/all/be2net/0025-be2net-query-link-status-in-be_open.patch
++ features/all/be2net/0026-netdev-make-net_device_ops-const.patch
++ features/all/be2net/0027-be2net-create-RSS-rings-even-in-multi-channel-config.patch
++ features/all/be2net/0028-be2net-allocate-more-headroom-in-incoming-skbs.patch
++ features/all/be2net/0029-be2net-add-descriptions-for-stat-counters-reported-v.patch
++ features/all/be2net/0030-be2net-Fix-link-status-query-command.patch
++ features/all/be2net/0031-be2net-Use-new-implementation-of-get-mac-list-comman.patch
++ features/all/be2net/0032-be2net-event-queue-re-design.patch
++ features/all/be2net/0033-be2net-cancel-be_worker-during-EEH-recovery.patch
++ features/all/be2net/0034-be2net-fix-tx-completion-cleanup.patch
++ features/all/be2net/0035-be2net-reset-queue-address-after-freeing.patch
++ features/all/be2net/0036-be2net-enable-RSS-for-ipv6-pkts.patch
++ features/all/be2net/0037-be2net-update-driver-version.patch
++ features/all/be2net/0038-be2net-Remove-unused-OFFSET_IN_PAGE-macro.patch
++ features/all/be2net/0039-be2net-enable-WOL-by-default-if-h-w-supports-it.patch
++ features/all/be2net/0040-be2net-Program-secondary-UC-MAC-address-into-MAC-fil.patch
++ features/all/be2net/0041-be2net-Fix-number-of-vlan-slots-in-flex-mode.patch
++ features/all/be2net/0042-be2net-fix-programming-of-VLAN-tags-for-VF.patch
++ features/all/be2net/0043-be2net-fix-ethtool-get-settings.patch
++ features/all/be2net/0044-be2net-Fix-VLAN-multicast-packet-reception.patch
++ features/all/be2net/0045-be2net-Fix-FW-download-in-Lancer.patch
++ features/all/be2net/0046-be2net-Fix-ethtool-self-test-for-Lancer.patch
++ features/all/be2net/0047-be2net-Fix-traffic-stall-INTx-mode.patch
++ features/all/be2net/0048-be2net-Fix-Lancer-statistics.patch
++ features/all/be2net/0049-be2net-Fix-wrong-status-getting-returned-for-MCC-com.patch
++ features/all/be2net/0050-be2net-Fix-FW-download-for-BE.patch
++ features/all/be2net/0051-be2net-Ignore-status-of-some-ioctls-during-driver-lo.patch
++ features/all/be2net/0052-be2net-fix-speed-displayed-by-ethtool-on-certain-SKU.patch
++ features/all/be2net/0053-be2net-update-the-driver-version.patch
++ features/all/be2net/0054-be2net-Fix-to-not-set-link-speed-for-disabled-functi.patch
++ features/all/be2net/0055-be2net-Fix-to-apply-duplex-value-as-unknown-when-lin.patch
++ features/all/be2net/0056-be2net-Record-receive-queue-index-in-skb-to-aid-RPS.patch
++ features/all/be2net/0057-be2net-Fix-EEH-error-reset-before-a-flash-dump-compl.patch
++ features/all/be2net/0058-be2net-avoid-disabling-sriov-while-VFs-are-assigned.patch
More information about the Kernel-svn-changes
mailing list