be2net: Backport most changes up to Linux 3.5-rc1 (Closes: #673391)

svn path=/dists/sid/linux-2.6/; revision=19037
This commit is contained in:
Ben Hutchings 2012-05-27 00:21:22 +00:00
parent 0a8ca792e1
commit edfac0ea4d
61 changed files with 8728 additions and 0 deletions

8
debian/changelog vendored
View File

@ -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@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:

View File

@ -0,0 +1,53 @@
From: Ben Hutchings <bhutchings@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@solarflare.com>
Signed-off-by: David S. Miller <davem@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

View File

@ -0,0 +1,47 @@
From: Rick Jones <rick.jones2@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@hp.com>
Signed-off-by: David S. Miller <davem@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

View File

@ -0,0 +1,227 @@
From: Sathya Perla <sathya.perla@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@emulex.com>
Signed-off-by: David S. Miller <davem@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

View File

@ -0,0 +1,40 @@
From: Sathya Perla <sathya.perla@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@emulex.com>
Signed-off-by: David S. Miller <davem@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

View File

@ -0,0 +1,73 @@
From: Sathya Perla <sathya.perla@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@emulex.com>
Signed-off-by: David S. Miller <davem@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

View File

@ -0,0 +1,158 @@
From: Sathya Perla <sathya.perla@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@emulex.com>
Signed-off-by: David S. Miller <davem@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

View File

@ -0,0 +1,99 @@
From: Padmanabh Ratnakar <padmanabh.ratnakar@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@emulex.com>
Signed-off-by: David S. Miller <davem@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

View File

@ -0,0 +1,234 @@
From: Padmanabh Ratnakar <padmanabh.ratnakar@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@emulex.com>
Signed-off-by: David S. Miller <davem@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

View File

@ -0,0 +1,70 @@
From: Padmanabh Ratnakar <padmanabh.ratnakar@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@emulex.com>
Signed-off-by: David S. Miller <davem@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

View File

@ -0,0 +1,33 @@
From: Padmanabh Ratnakar <padmanabh.ratnakar@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@emulex.com>
Signed-off-by: David S. Miller <davem@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

View File

@ -0,0 +1,31 @@
From: Padmanabh Ratnakar <padmanabh.ratnakar@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@emulex.com>
Signed-off-by: David S. Miller <davem@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

View File

@ -0,0 +1,393 @@
From: Padmanabh Ratnakar <padmanabh.ratnakar@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@emulex.com>
Signed-off-by: Padmanabh Ratnakar <padmanabh.ratnakar@emulex.com>
Signed-off-by: David S. Miller <davem@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

View File

@ -0,0 +1,37 @@
From: Padmanabh Ratnakar <padmanabh.ratnakar@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@emulex.com>
Signed-off-by: David S. Miller <davem@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

View File

@ -0,0 +1,212 @@
From: Padmanabh Ratnakar <padmanabh.ratnakar@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@emulex.com>
Signed-off-by: David S. Miller <davem@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

View File

@ -0,0 +1,34 @@
From: Padmanabh Ratnakar <padmanabh.ratnakar@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@emulex.com>
Signed-off-by: David S. Miller <davem@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

View File

@ -0,0 +1,54 @@
From: Padmanabh Ratnakar <padmanabh.ratnakar@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@emulex.com>
Signed-off-by: David S. Miller <davem@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

View File

@ -0,0 +1,53 @@
From: Ivan Vecera <ivecera@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@redhat.com>
Signed-off-by: David S. Miller <davem@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

View File

@ -0,0 +1,30 @@
From: Ajit Khaparde <ajit.khaparde@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@emulex.com>
Signed-off-by: David S. Miller <davem@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

View File

@ -0,0 +1,98 @@
From: Ajit Khaparde <ajit.khaparde@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@emulex.com>
Signed-off-by: David S. Miller <davem@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

View File

@ -0,0 +1,46 @@
From: Sathya Perla <sathya.perla@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@emulex.com>
Signed-off-by: David S. Miller <davem@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

View File

@ -0,0 +1,416 @@
From: Sathya Perla <sathya.perla@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@emulex.com>
Signed-off-by: David S. Miller <davem@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

View File

@ -0,0 +1,65 @@
From: Ajit Khaparde <ajit.khaparde@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@emulex.com>
Signed-off-by: David S. Miller <davem@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

View File

@ -0,0 +1,53 @@
From: Padmanabh Ratnakar <padmanabh.ratnakar@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@emulex.com>
Signed-off-by: David S. Miller <davem@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

View File

@ -0,0 +1,65 @@
From: Ajit Khaparde <ajit.khaparde@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@emulex.com>
Signed-off-by: David S. Miller <davem@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

View File

@ -0,0 +1,47 @@
From: Ajit Khaparde <ajit.khaparde@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@emulex.com>
Signed-off-by: David S. Miller <davem@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

View File

@ -0,0 +1,234 @@
From: Ajit Khaparde <ajit.khaparde@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@emulex.com>
Signed-off-by: Sathya Perla <sathya.perla@emulex.com>
Signed-off-by: Ajit Khaparde <ajit.khaparde@emulex.com>
Signed-off-by: David S. Miller <davem@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

View File

@ -0,0 +1,31 @@
From: stephen hemminger <shemminger@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@vyatta.com>
Signed-off-by: David S. Miller <davem@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

View File

@ -0,0 +1,36 @@
From: Sathya Perla <sathya.perla@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@emulex.com>
Signed-off-by: David S. Miller <davem@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

View File

@ -0,0 +1,57 @@
From: Eric Dumazet <eric.dumazet@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@gmail.com>
Cc: Ian Campbell <Ian.Campbell@citrix.com>
Cc: Vasundhara Volam <vasundhara.volam@emulex.com>
Cc: Sathya Perla <sathya.perla@emulex.com>
Cc: Ajit Khaparde <ajit.khaparde@emulex.com>
Signed-off-by: David S. Miller <davem@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

View File

@ -0,0 +1,259 @@
From: Sathya Perla <sathya.perla@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@emulex.com>
Signed-off-by: David S. Miller <davem@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

View File

@ -0,0 +1,39 @@
From: Padmanabh Ratnakar <padmanabh.ratnakar@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@emulex.com>
Signed-off-by: David S. Miller <davem@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

View File

@ -0,0 +1,237 @@
From: Padmanabh Ratnakar <padmanabh.ratnakar@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@emulex.com>
Signed-off-by: Padmanabh Ratnakar <padmanabh.ratnakar@emulex.com>
Signed-off-by: David S. Miller <davem@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

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,90 @@
From: Sathya Perla <sathya.perla@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@emulex.com>
Signed-off-by: David S. Miller <davem@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

View File

@ -0,0 +1,133 @@
From: Sathya Perla <sathya.perla@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@emulex.com>
Signed-off-by: David S. Miller <davem@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

View File

@ -0,0 +1,44 @@
From: Sathya Perla <sathya.perla@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@emulex.com>
Signed-off-by: David S. Miller <davem@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

View File

@ -0,0 +1,29 @@
From: Sathya Perla <sathya.perla@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@emulex.com>
Signed-off-by: David S. Miller <davem@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

View File

@ -0,0 +1,28 @@
From: Sathya Perla <sathya.perla@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@emulex.com>
Signed-off-by: David S. Miller <davem@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

View File

@ -0,0 +1,30 @@
From: Roland Dreier <roland@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@purestorage.com>
Signed-off-by: David S. Miller <davem@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

View File

@ -0,0 +1,274 @@
From: Ajit Khaparde <ajit.khaparde@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@emulex.com>
Signed-off-by: David S. Miller <davem@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

View File

@ -0,0 +1,177 @@
From: Ajit Khaparde <ajit.khaparde@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@emulex.com>
Signed-off-by: David S. Miller <davem@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

View File

@ -0,0 +1,30 @@
From: Ajit Khaparde <ajit.khaparde@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@emulex.com>
Signed-off-by: David S. Miller <davem@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

View File

@ -0,0 +1,255 @@
From: Ajit Khaparde <ajit.khaparde@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@emulex.com>
Signed-off-by: David S. Miller <davem@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

View File

@ -0,0 +1,521 @@
From: Ajit Khaparde <ajitkhaparde@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@emulex.com>
Signed-off-by: David S. Miller <davem@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

View File

@ -0,0 +1,94 @@
From: Padmanabh Ratnakar <padmanabh.ratnakar@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@emulex.com>
Signed-off-by: David S. Miller <davem@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

View File

@ -0,0 +1,44 @@
From: Padmanabh Ratnakar <padmanabh.ratnakar@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@emulex.com>
Signed-off-by: David S. Miller <davem@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

View File

@ -0,0 +1,31 @@
From: Padmanabh Ratnakar <padmanabh.ratnakar@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@emulex.com>
Signed-off-by: David S. Miller <davem@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

View File

@ -0,0 +1,36 @@
From: Padmanabh Ratnakar <padmanabh.ratnakar@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@emulex.com>
Signed-off-by: David S. Miller <davem@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

View File

@ -0,0 +1,55 @@
From: Padmanabh Ratnakar <padmanabh.ratnakar@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@emulex.com>
Signed-off-by: David S. Miller <davem@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

View File

@ -0,0 +1,232 @@
From: Padmanabh Ratnakar <padmanabh.ratnakar@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@emulex.com>
Signed-off-by: David S. Miller <davem@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

View File

@ -0,0 +1,383 @@
From: Padmanabh Ratnakar <padmanabh.ratnakar@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@emulex.com>
Signed-off-by: Padmanabh Ratnakar <padmanabh.ratnakar@emulex.com>
Signed-off-by: David S. Miller <davem@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

View File

@ -0,0 +1,49 @@
From: Ajit Khaparde <ajit.khaparde@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@emulex.com>
Signed-off-by: David S. Miller <davem@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

View File

@ -0,0 +1,30 @@
From: Ajit Khaparde <ajit.khaparde@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@emulex.com>
Signed-off-by: David S. Miller <davem@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

View File

@ -0,0 +1,28 @@
From: Ajit Khaparde <ajit.khaparde@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@emulex.com>
Signed-off-by: David S. Miller <davem@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

View File

@ -0,0 +1,33 @@
From: Somnath Kotur <somnath.kotur@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@emulex.com>
Signed-off-by: David S. Miller <davem@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

View File

@ -0,0 +1,31 @@
From: Somnath Kotur <somnath.kotur@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@solarflare.com>
Signed-off-by: Sarveshwar Bandi <sarveshwar.bandi@emulex.com>
Signed-off-by: Somnath Kotur <somnath.kotur@emulex.com>
Signed-off-by: David S. Miller <davem@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

View File

@ -0,0 +1,36 @@
From: Somnath Kotur <somnath.kotur@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@emulex.com>
Signed-off-by: Somnath Kotur <somnath.kotur@emulex.com>
Signed-off-by: David S. Miller <davem@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

View File

@ -0,0 +1,37 @@
From: Somnath Kotur <somnath.kotur@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@emulex.com>
Signed-off-by: Somnath Kotur <somnath.kotur@emulex.com>
Signed-off-by: David S. Miller <davem@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

View File

@ -0,0 +1,473 @@
From: Sathya Perla <sathya.perla@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@emulex.com>
Signed-off-by: David S. Miller <davem@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, &reg);
+ 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

View File

@ -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