lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <1401258665-6238-5-git-send-email-sathya.perla@emulex.com>
Date:	Wed, 28 May 2014 12:01:03 +0530
From:	Sathya Perla <sathya.perla@...lex.com>
To:	<netdev@...r.kernel.org>
Subject: [PATCH net-next 4/6] be2net: re-factor MCCQ error status handling code

From: Kalesh AP <kalesh.purayil@...lex.com>

This patch improves MCCQ error status handling in the following ways:
a) A MCC cmd completion returns a base-status and an addl-status.
So far, the routine be_mcc_compl_process() returned only the "status" value.
Now, embedd both statuses in the return value and let the caller routine access
the value of interest using base_status() and addl_status() macros.

b) Rename variables accordingly (base/addl) to avoid confusion while error
checking.

b) Some of the errors returned by FW are harmless and so an error msg is not
logged for such errors. Capture this logic in a separate routine to make the
code more readable.

Signed-off-by: Kalesh AP <kalesh.purayil@...lex.com>
Signed-off-by: Sathya Perla <sathya.perla@...lex.com>
---
 drivers/net/ethernet/emulex/benet/be_cmds.c |   56 +++++++++++++--------------
 drivers/net/ethernet/emulex/benet/be_cmds.h |   30 ++++++++++----
 drivers/net/ethernet/emulex/benet/be_main.c |   16 ++++---
 3 files changed, 57 insertions(+), 45 deletions(-)

diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
index f73185b..a2ecdff 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
@@ -119,10 +119,24 @@ static struct be_cmd_resp_hdr *be_decode_resp_hdr(u32 tag0, u32 tag1)
 	return (void *)addr;
 }
 
+static bool be_skip_err_log(u8 opcode, u16 base_status, u16 addl_status)
+{
+	if (base_status == MCC_STATUS_NOT_SUPPORTED ||
+	    base_status == MCC_STATUS_ILLEGAL_REQUEST ||
+	    addl_status == MCC_ADDL_STATUS_TOO_MANY_INTERFACES ||
+	    (opcode == OPCODE_COMMON_WRITE_FLASHROM &&
+	    (base_status == MCC_STATUS_ILLEGAL_FIELD ||
+	     addl_status == MCC_ADDL_STATUS_FLASH_IMAGE_CRC_MISMATCH)))
+		return true;
+	else
+		return false;
+}
+
 static int be_mcc_compl_process(struct be_adapter *adapter,
 				struct be_mcc_compl *compl)
 {
-	u16 compl_status, extd_status;
+	enum mcc_base_status base_status;
+	enum mcc_addl_status addl_status;
 	struct be_cmd_resp_hdr *resp_hdr;
 	u8 opcode = 0, subsystem = 0;
 
@@ -130,11 +144,8 @@ static int be_mcc_compl_process(struct be_adapter *adapter,
 	 * from mcc_wrb */
 	be_dws_le_to_cpu(compl, 4);
 
-	compl_status = (compl->status >> CQE_STATUS_COMPL_SHIFT) &
-				CQE_STATUS_COMPL_MASK;
-
-	extd_status = (compl->status >> CQE_STATUS_EXTD_SHIFT) &
-				CQE_STATUS_EXTD_MASK;
+	base_status = base_status(compl->status);
+	addl_status = addl_status(compl->status);
 
 	resp_hdr = be_decode_resp_hdr(compl->tag0, compl->tag1);
 
@@ -152,11 +163,11 @@ static int be_mcc_compl_process(struct be_adapter *adapter,
 	if (((opcode == OPCODE_COMMON_WRITE_FLASHROM) ||
 	     (opcode == OPCODE_COMMON_WRITE_OBJECT)) &&
 	    (subsystem == CMD_SUBSYSTEM_COMMON)) {
-		adapter->flash_status = compl_status;
+		adapter->flash_status = compl->status;
 		complete(&adapter->et_cmd_compl);
 	}
 
-	if (compl_status == MCC_STATUS_SUCCESS) {
+	if (base_status == MCC_STATUS_SUCCESS) {
 		if (((opcode == OPCODE_ETH_GET_STATISTICS) ||
 		     (opcode == OPCODE_ETH_GET_PPORT_STATS)) &&
 		    (subsystem == CMD_SUBSYSTEM_ETH)) {
@@ -174,35 +185,20 @@ static int be_mcc_compl_process(struct be_adapter *adapter,
 		if (opcode == OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES)
 			adapter->be_get_temp_freq = 0;
 
-		if (compl_status == MCC_STATUS_NOT_SUPPORTED ||
-		    compl_status == MCC_STATUS_ILLEGAL_REQUEST)
-			return compl_status;
+		if (be_skip_err_log(opcode, base_status, addl_status))
+			return compl->status;
 
-		/* Ignore CRC mismatch error during FW download with old FW */
-		if (opcode == OPCODE_COMMON_WRITE_FLASHROM &&
-		    compl_status == MCC_STATUS_FAILED &&
-		    extd_status == MCC_ADDL_STS_FLASH_IMAGE_CRC_MISMATCH)
-			return compl_status;
-
-		/* Ignore illegal field error during FW download with old FW */
-		if (opcode == OPCODE_COMMON_WRITE_FLASHROM &&
-		    compl_status == MCC_STATUS_ILLEGAL_FIELD)
-			return compl_status;
-
-		if (compl_status == MCC_STATUS_UNAUTHORIZED_REQUEST) {
+		if (base_status == MCC_STATUS_UNAUTHORIZED_REQUEST) {
 			dev_warn(&adapter->pdev->dev,
 				 "VF is not privileged to issue opcode %d-%d\n",
 				 opcode, subsystem);
 		} else {
 			dev_err(&adapter->pdev->dev,
 				"opcode %d-%d failed:status %d-%d\n",
-				opcode, subsystem, compl_status, extd_status);
-
-			if (extd_status == MCC_ADDL_STS_INSUFFICIENT_RESOURCES)
-				return extd_status;
+				opcode, subsystem, base_status, addl_status);
 		}
 	}
-	return compl_status;
+	return compl->status;
 }
 
 /* Link state evt is a string of bytes; no need for endian swapping */
@@ -452,7 +448,9 @@ static int be_mcc_notify_wait(struct be_adapter *adapter)
 	if (status == -EIO)
 		goto out;
 
-	status = resp->status;
+	status = (resp->base_status |
+		  ((resp->addl_status & CQE_ADDL_STATUS_MASK) <<
+		   CQE_ADDL_STATUS_SHIFT));
 out:
 	return status;
 }
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h
index 070f775..af62403 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.h
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.h
@@ -50,7 +50,7 @@ struct be_mcc_wrb {
 #define CQE_FLAGS_CONSUMED_MASK 	(1 << 27)
 
 /* Completion Status */
-enum {
+enum mcc_base_status {
 	MCC_STATUS_SUCCESS = 0,
 	MCC_STATUS_FAILED = 1,
 	MCC_STATUS_ILLEGAL_REQUEST = 2,
@@ -60,13 +60,25 @@ enum {
 	MCC_STATUS_NOT_SUPPORTED = 66
 };
 
-#define MCC_ADDL_STS_INSUFFICIENT_RESOURCES	0x16
-#define MCC_ADDL_STS_FLASH_IMAGE_CRC_MISMATCH	0x4d
+/* Additional status */
+enum mcc_addl_status {
+	MCC_ADDL_STATUS_INSUFFICIENT_RESOURCES = 0x16,
+	MCC_ADDL_STATUS_FLASH_IMAGE_CRC_MISMATCH = 0x4d,
+	MCC_ADDL_STATUS_TOO_MANY_INTERFACES = 0x4a
+};
+
+#define CQE_BASE_STATUS_MASK		0xFFFF
+#define CQE_BASE_STATUS_SHIFT		0	/* bits 0 - 15 */
+#define CQE_ADDL_STATUS_MASK		0xFF
+#define CQE_ADDL_STATUS_SHIFT		16	/* bits 16 - 31 */
 
-#define CQE_STATUS_COMPL_MASK		0xFFFF
-#define CQE_STATUS_COMPL_SHIFT		0	/* bits 0 - 15 */
-#define CQE_STATUS_EXTD_MASK		0xFFFF
-#define CQE_STATUS_EXTD_SHIFT		16	/* bits 16 - 31 */
+#define base_status(status)		\
+		((enum mcc_base_status)	\
+			(status > 0 ? (status & CQE_BASE_STATUS_MASK) : 0))
+#define addl_status(status)		\
+		((enum mcc_addl_status)	\
+			(status > 0 ? (status >> CQE_ADDL_STATUS_SHIFT) & \
+					CQE_ADDL_STATUS_MASK : 0))
 
 struct be_mcc_compl {
 	u32 status;		/* dword 0 */
@@ -259,8 +271,8 @@ struct be_cmd_resp_hdr {
 	u8 opcode;		/* dword 0 */
 	u8 subsystem;		/* dword 0 */
 	u8 rsvd[2];		/* dword 0 */
-	u8 status;		/* dword 1 */
-	u8 add_status;		/* dword 1 */
+	u8 base_status;		/* dword 1 */
+	u8 addl_status;		/* dword 1 */
 	u8 rsvd1[2];		/* dword 1 */
 	u32 response_length;	/* dword 2 */
 	u32 actual_resp_len;	/* dword 3 */
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index d2b4efa..6822b3d 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -1111,7 +1111,8 @@ static int be_vid_config(struct be_adapter *adapter)
 	status = be_cmd_vlan_config(adapter, adapter->if_handle, vids, num);
 	if (status) {
 		/* Set to VLAN promisc mode as setting VLAN filter failed */
-		if (status == MCC_ADDL_STS_INSUFFICIENT_RESOURCES)
+		if (addl_status(status) ==
+				MCC_ADDL_STATUS_INSUFFICIENT_RESOURCES)
 			goto set_vlan_promisc;
 		dev_err(&adapter->pdev->dev,
 			"Setting HW VLAN filtering failed.\n");
@@ -3729,7 +3730,7 @@ static int be_flash(struct be_adapter *adapter, const u8 *img,
 		img += num_bytes;
 		status = be_cmd_write_flashrom(adapter, flash_cmd, optype,
 					       flash_op, num_bytes);
-		if (status == MCC_STATUS_ILLEGAL_REQUEST &&
+		if (base_status(status) == MCC_STATUS_ILLEGAL_REQUEST &&
 		    optype == OPTYPE_PHY_FW)
 			break;
 		else if (status)
@@ -3952,8 +3953,8 @@ static int be_flash_skyhawk(struct be_adapter *adapter,
 		 * new FLASH op_type. To complete the remaining process,
 		 * download the same FW again after the reboot.
 		 */
-		if (status == MCC_STATUS_ILLEGAL_REQUEST ||
-		    status == MCC_STATUS_ILLEGAL_FIELD) {
+		if (base_status(status) == MCC_STATUS_ILLEGAL_REQUEST ||
+		    base_status(status) == MCC_STATUS_ILLEGAL_FIELD) {
 			dev_err(dev, "Flash incomplete. Reset the server\n");
 			dev_err(dev, "Download FW image again after reset\n");
 			return -EAGAIN;
@@ -3975,9 +3976,10 @@ flash:
 		/* For old FW images ignore ILLEGAL_FIELD error or errors on
 		 * UFI_DIR region
 		 */
-		if (old_fw_img && (status == MCC_STATUS_ILLEGAL_FIELD ||
-				   (img_optype == OPTYPE_UFI_DIR &&
-				    status == MCC_STATUS_FAILED))) {
+		if (old_fw_img &&
+		    (base_status(status) == MCC_STATUS_ILLEGAL_FIELD ||
+		     (img_optype == OPTYPE_UFI_DIR &&
+		      base_status(status) == MCC_STATUS_FAILED))) {
 			continue;
 		} else if (status) {
 			dev_err(dev, "Flashing section type 0x%x failed\n",
-- 
1.7.1

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

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ