netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [net-next PATCH 0/8] qlcnic: bug fixes and feature updates
@ 2013-02-09 19:29 Jitendra Kalsaria
  2013-02-09 19:29 ` [net-next PATCH 1/8] qlcnic: fix initialize NIC mailbox command Jitendra Kalsaria
                   ` (8 more replies)
  0 siblings, 9 replies; 10+ messages in thread
From: Jitendra Kalsaria @ 2013-02-09 19:29 UTC (permalink / raw)
  To: davem; +Cc: netdev, sony.chacko, Dept_NX_Linux_NIC_Driver, Jitendra Kalsaria

From: Jitendra Kalsaria <jitendra.kalsaria@qlogic.com>


Please apply to net-next.

Thanks,
Jitendra

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [net-next PATCH 1/8] qlcnic: fix initialize NIC mailbox command
  2013-02-09 19:29 [net-next PATCH 0/8] qlcnic: bug fixes and feature updates Jitendra Kalsaria
@ 2013-02-09 19:29 ` Jitendra Kalsaria
  2013-02-09 19:29 ` [net-next PATCH 2/8] qlcnic: fix firmware based IDC participation Jitendra Kalsaria
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Jitendra Kalsaria @ 2013-02-09 19:29 UTC (permalink / raw)
  To: davem; +Cc: netdev, sony.chacko, Dept_NX_Linux_NIC_Driver, Himanshu Madhani

From: Himanshu Madhani <himanshu.madhani@qlogic.com>

Register for firmware based Inter Driver Communication (IDC) using initialize
NIC as the first mailbox command

Signed-off-by: Himanshu Madhani <himanshu.madhani@qlogic.com>
Signed-off-by: Jitendra Kalsaria <jitendra.kalsaria@qlogic.com>
---
 .../net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c    |    4 ++--
 .../net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c  |    9 ++++++---
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c   |    6 ++++--
 3 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
index cdcbbb0..d23372e 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
@@ -1239,10 +1239,10 @@ void qlcnic_83xx_register_nic_idc_func(struct qlcnic_adapter *adapter,
 
 	if (enable) {
 		qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_INIT_NIC_FUNC);
-		cmd.req.arg[1] = 1 | BIT_0;
+		cmd.req.arg[1] = BIT_0 | BIT_31;
 	} else {
 		qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_STOP_NIC_FUNC);
-		cmd.req.arg[1] = 0 | BIT_0;
+		cmd.req.arg[1] = BIT_0 | BIT_31;
 	}
 	status = qlcnic_issue_cmd(adapter, &cmd);
 	if (status)
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
index f647002..c53832b 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
@@ -585,6 +585,9 @@ static int qlcnic_83xx_idc_check_fan_failure(struct qlcnic_adapter *adapter)
 
 static int qlcnic_83xx_idc_reattach_driver(struct qlcnic_adapter *adapter)
 {
+	/* register for NIC IDC AEN Events */
+	qlcnic_83xx_register_nic_idc_func(adapter, 1);
+
 	qlcnic_83xx_enable_mbx_intrpt(adapter);
 	if ((adapter->flags & QLCNIC_MSIX_ENABLED)) {
 		if (qlcnic_83xx_config_intrpt(adapter, 1)) {
@@ -2025,6 +2028,9 @@ int qlcnic_83xx_init(struct qlcnic_adapter *adapter)
 	set_bit(QLC_83XX_MBX_READY, &adapter->ahw->idc.status);
 	qlcnic_83xx_clear_function_resources(adapter);
 
+	/* register for NIC IDC AEN Events */
+	qlcnic_83xx_register_nic_idc_func(adapter, 1);
+
 	if (!qlcnic_83xx_read_flash_descriptor_table(adapter))
 		qlcnic_83xx_read_flash_mfg_id(adapter);
 
@@ -2041,9 +2047,6 @@ int qlcnic_83xx_init(struct qlcnic_adapter *adapter)
 
 	INIT_DELAYED_WORK(&adapter->idc_aen_work, qlcnic_83xx_idc_aen_work);
 
-	/* register for NIC IDC AEN Events */
-	qlcnic_83xx_register_nic_idc_func(adapter, 1);
-
 	/* Periodically monitor device status */
 	qlcnic_83xx_idc_poll_dev_state(&adapter->fw_work.work);
 
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
index d0aef32..714124a 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -1174,8 +1174,6 @@ qlcnic_set_mgmt_operations(struct qlcnic_adapter *adapter)
 
 	qlcnic_dev_set_npar_ready(adapter);
 
-	if (qlcnic_83xx_check(adapter))
-		qlcnic_83xx_register_nic_idc_func(adapter, 1);
 	return err;
 }
 
@@ -3063,6 +3061,8 @@ static int qlcnic_attach_func(struct pci_dev *pdev)
 	}
 
 	if (qlcnic_83xx_check(adapter)) {
+		/* register for NIC IDC AEN Events */
+		qlcnic_83xx_register_nic_idc_func(adapter, 1);
 		err = qlcnic_83xx_setup_mbx_intr(adapter);
 		if (err) {
 			dev_err(&adapter->pdev->dev,
@@ -3224,6 +3224,8 @@ int qlcnic_set_max_rss(struct qlcnic_adapter *adapter, u8 data, size_t len)
 	}
 
 	if (qlcnic_83xx_check(adapter)) {
+		/* register for NIC IDC AEN Events */
+		qlcnic_83xx_register_nic_idc_func(adapter, 1);
 		err = qlcnic_83xx_setup_mbx_intr(adapter);
 		if (err) {
 			dev_err(&adapter->pdev->dev,
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [net-next PATCH 2/8] qlcnic: fix firmware based IDC participation
  2013-02-09 19:29 [net-next PATCH 0/8] qlcnic: bug fixes and feature updates Jitendra Kalsaria
  2013-02-09 19:29 ` [net-next PATCH 1/8] qlcnic: fix initialize NIC mailbox command Jitendra Kalsaria
@ 2013-02-09 19:29 ` Jitendra Kalsaria
  2013-02-09 19:29 ` [net-next PATCH 3/8] qlcnic: helper routine to handle async events Jitendra Kalsaria
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Jitendra Kalsaria @ 2013-02-09 19:29 UTC (permalink / raw)
  To: davem; +Cc: netdev, sony.chacko, Dept_NX_Linux_NIC_Driver, Jitendra Kalsaria

From: Jitendra Kalsaria <jitendra.kalsaria@qlogic.com>

Driver needs to stop participating in firmware based Inter Driver
Communication (IDC) while unloading driver

Signed-off-by: Jitendra Kalsaria <jitendra.kalsaria@qlogic.com>
---
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
index 714124a..dcb990d 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -2023,6 +2023,8 @@ static void qlcnic_remove(struct pci_dev *pdev)
 		if (adapter->flags & QLCNIC_MSIX_ENABLED)
 			qlcnic_83xx_config_intrpt(adapter, 0);
 		qlcnic_83xx_free_mbx_intr(adapter);
+		qlcnic_83xx_register_nic_idc_func(adapter, 0);
+		cancel_delayed_work_sync(&adapter->idc_aen_work);
 	}
 
 	qlcnic_detach(adapter);
@@ -2180,10 +2182,6 @@ static int qlcnic_close(struct net_device *netdev)
 	struct qlcnic_adapter *adapter = netdev_priv(netdev);
 
 	__qlcnic_down(adapter, netdev);
-	if (qlcnic_83xx_check(adapter)) {
-		qlcnic_83xx_register_nic_idc_func(adapter, 0);
-		cancel_delayed_work_sync(&adapter->idc_aen_work);
-	}
 
 	return 0;
 }
@@ -3117,6 +3115,8 @@ static pci_ers_result_t qlcnic_io_error_detected(struct pci_dev *pdev,
 		if (adapter->flags & QLCNIC_MSIX_ENABLED)
 			qlcnic_83xx_config_intrpt(adapter, 0);
 		qlcnic_83xx_free_mbx_intr(adapter);
+		qlcnic_83xx_register_nic_idc_func(adapter, 0);
+		cancel_delayed_work_sync(&adapter->idc_aen_work);
 	}
 
 	qlcnic_detach(adapter);
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [net-next PATCH 3/8] qlcnic: helper routine to handle async events
  2013-02-09 19:29 [net-next PATCH 0/8] qlcnic: bug fixes and feature updates Jitendra Kalsaria
  2013-02-09 19:29 ` [net-next PATCH 1/8] qlcnic: fix initialize NIC mailbox command Jitendra Kalsaria
  2013-02-09 19:29 ` [net-next PATCH 2/8] qlcnic: fix firmware based IDC participation Jitendra Kalsaria
@ 2013-02-09 19:29 ` Jitendra Kalsaria
  2013-02-09 19:29 ` [net-next PATCH 4/8] qlcnic: refactor 83xx diagnostic loopback test Jitendra Kalsaria
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Jitendra Kalsaria @ 2013-02-09 19:29 UTC (permalink / raw)
  To: davem; +Cc: netdev, sony.chacko, Dept_NX_Linux_NIC_Driver, Jitendra Kalsaria

From: Jitendra Kalsaria <jitendra.kalsaria@qlogic.com>

Create a helper routine to handle async events, as it is being called
from multiple places

Signed-off-by: Jitendra Kalsaria <jitendra.kalsaria@qlogic.com>
---
 .../net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c    |   79 +++++---------------
 .../net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h    |    9 ++-
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h     |    1 +
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c     |   20 +++++-
 4 files changed, 45 insertions(+), 64 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
index d23372e..3d628c6 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
@@ -12,13 +12,6 @@
 #include <linux/interrupt.h>
 
 #define QLCNIC_MAX_TX_QUEUES		1
-
-#define QLCNIC_MBX_RSP(reg)		LSW(reg)
-#define QLCNIC_MBX_NUM_REGS(reg)	(MSW(reg) & 0x1FF)
-#define QLCNIC_MBX_STATUS(reg)		(((reg) >> 25) & 0x7F)
-#define QLCNIC_MBX_HOST(ahw, i)	((ahw)->pci_base0 + ((i) * 4))
-#define QLCNIC_MBX_FW(ahw, i)		((ahw)->pci_base0 + 0x800 + ((i) * 4))
-
 #define RSS_HASHTYPE_IP_TCP		0x3
 
 /* status descriptor mailbox data
@@ -696,7 +689,7 @@ int qlcnic_83xx_mbx_op(struct qlcnic_adapter *adapter,
 	int i;
 	u16 opcode;
 	u8 mbx_err_code, mac_cmd_rcode;
-	u32 rsp, mbx_val, fw_data, rsp_num, mbx_cmd, temp, fw[8];
+	u32 rsp, mbx_val, fw_data, rsp_num, mbx_cmd;
 	struct qlcnic_hardware_context *ahw = adapter->ahw;
 
 	opcode = LSW(cmd->req.arg[0]);
@@ -738,42 +731,8 @@ poll:
 	opcode = QLCNIC_MBX_RSP(fw_data);
 
 	if (rsp != QLCNIC_RCODE_TIMEOUT) {
-		if (opcode == QLCNIC_MBX_LINK_EVENT) {
-			for (i = 0; i < rsp_num; i++) {
-				temp = readl(QLCNIC_MBX_FW(ahw, i));
-				fw[i] = temp;
-			}
-			qlcnic_83xx_handle_link_aen(adapter, fw);
-			/* clear fw mbx control register */
-			QLCWRX(ahw, QLCNIC_FW_MBX_CTRL, QLCNIC_CLR_OWNER);
-			mbx_val = QLCRDX(ahw, QLCNIC_HOST_MBX_CTRL);
-			if (mbx_val)
-				goto poll;
-		} else if (opcode == QLCNIC_MBX_COMP_EVENT) {
-			for (i = 0; i < rsp_num; i++) {
-				temp = readl(QLCNIC_MBX_FW(ahw, i));
-				fw[i] = temp;
-			}
-			qlcnic_83xx_handle_idc_comp_aen(adapter, fw);
-			/* clear fw mbx control register */
-			QLCWRX(ahw, QLCNIC_FW_MBX_CTRL, QLCNIC_CLR_OWNER);
-			mbx_val = QLCRDX(ahw, QLCNIC_HOST_MBX_CTRL);
-			if (mbx_val)
-				goto poll;
-		} else if (opcode == QLCNIC_MBX_REQUEST_EVENT) {
-			/* IDC Request Notification */
-			for (i = 0; i < rsp_num; i++) {
-				temp = readl(QLCNIC_MBX_FW(ahw, i));
-				fw[i] = temp;
-			}
-			for (i = 0; i < QLC_83XX_MBX_AEN_CNT; i++) {
-				temp = QLCNIC_MBX_RSP(fw[i]);
-				adapter->ahw->mbox_aen[i] = temp;
-			}
-			queue_delayed_work(adapter->qlcnic_wq,
-					   &adapter->idc_aen_work, 0);
-			/* clear fw mbx control register */
-			QLCWRX(ahw, QLCNIC_FW_MBX_CTRL, QLCNIC_CLR_OWNER);
+		if (fw_data &  QLCNIC_MBX_ASYNC_EVENT) {
+			qlcnic_83xx_process_aen(adapter);
 			mbx_val = QLCRDX(ahw, QLCNIC_HOST_MBX_CTRL);
 			if (mbx_val)
 				goto poll;
@@ -875,20 +834,10 @@ static void qlcnic_83xx_handle_idc_comp_aen(struct qlcnic_adapter *adapter,
 
 void qlcnic_83xx_process_aen(struct qlcnic_adapter *adapter)
 {
-	u32 mask, resp, event[QLC_83XX_MBX_AEN_CNT];
+	u32 event[QLC_83XX_MBX_AEN_CNT];
 	int i;
 	struct qlcnic_hardware_context *ahw = adapter->ahw;
 
-	if (!spin_trylock(&ahw->mbx_lock)) {
-		mask = QLCRDX(adapter->ahw, QLCNIC_DEF_INT_MASK);
-		writel(0, adapter->ahw->pci_base0 + mask);
-		return;
-	}
-	resp = QLCRDX(ahw, QLCNIC_FW_MBX_CTRL);
-
-	if (!(resp & QLCNIC_SET_OWNER))
-		goto out;
-
 	for (i = 0; i < QLC_83XX_MBX_AEN_CNT; i++)
 		event[i] = readl(QLCNIC_MBX_FW(ahw, i));
 
@@ -923,10 +872,6 @@ void qlcnic_83xx_process_aen(struct qlcnic_adapter *adapter)
 	}
 
 	QLCWRX(ahw, QLCNIC_FW_MBX_CTRL, QLCNIC_CLR_OWNER);
-out:
-	mask = QLCRDX(adapter->ahw, QLCNIC_DEF_INT_MASK);
-	writel(0, adapter->ahw->pci_base0 + mask);
-	spin_unlock(&ahw->mbx_lock);
 }
 
 static int qlcnic_83xx_add_rings(struct qlcnic_adapter *adapter)
@@ -1620,7 +1565,21 @@ static void qlcnic_83xx_handle_link_aen(struct qlcnic_adapter *adapter,
 irqreturn_t qlcnic_83xx_handle_aen(int irq, void *data)
 {
 	struct qlcnic_adapter *adapter = data;
-	qlcnic_83xx_process_aen(adapter);
+	unsigned long flags;
+	u32 mask, resp, event;
+
+	spin_lock_irqsave(&adapter->ahw->mbx_lock, flags);
+	resp = QLCRDX(adapter->ahw, QLCNIC_FW_MBX_CTRL);
+	if (!(resp & QLCNIC_SET_OWNER))
+		goto out;
+	event = readl(QLCNIC_MBX_FW(adapter->ahw, 0));
+	if (event &  QLCNIC_MBX_ASYNC_EVENT)
+		qlcnic_83xx_process_aen(adapter);
+out:
+	mask = QLCRDX(adapter->ahw, QLCNIC_DEF_INT_MASK);
+	writel(0, adapter->ahw->pci_base0 + mask);
+	spin_unlock_irqrestore(&adapter->ahw->mbx_lock, flags);
+
 	return IRQ_HANDLED;
 }
 
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
index b62017b..16c5df6 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
@@ -137,9 +137,6 @@ struct qlc_83xx_reset {
 #define QLC_83XX_IDC_MINOR_VERSION			0
 #define QLC_83XX_IDC_FLASH_PARAM_ADDR			0x3e8020
 
-/* Mailbox process AEN count */
-#define QLC_83XX_MBX_AEN_CNT 5
-
 struct qlcnic_adapter;
 struct qlc_83xx_idc {
 	int (*state_entry) (struct qlcnic_adapter *);
@@ -156,6 +153,12 @@ struct qlc_83xx_idc {
 	char		**name;
 };
 
+#define QLCNIC_MBX_RSP(reg)		LSW(reg)
+#define QLCNIC_MBX_NUM_REGS(reg)	(MSW(reg) & 0x1FF)
+#define QLCNIC_MBX_STATUS(reg)		(((reg) >> 25) & 0x7F)
+#define QLCNIC_MBX_HOST(ahw, i)	((ahw)->pci_base0 + ((i) * 4))
+#define QLCNIC_MBX_FW(ahw, i)		((ahw)->pci_base0 + 0x800 + ((i) * 4))
+
 /* Mailbox process AEN count */
 #define QLC_83XX_IDC_COMP_AEN			3
 #define QLC_83XX_MBX_AEN_CNT			5
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h
index ed52b9c..5b8749e 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h
@@ -135,6 +135,7 @@ struct qlcnic_mailbox_metadata {
 
 #define QLCNIC_MBX_RSP_OK	1
 #define QLCNIC_MBX_PORT_RSP_OK	0x1a
+#define QLCNIC_MBX_ASYNC_EVENT	BIT_15
 
 struct qlcnic_pci_info;
 struct qlcnic_info;
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
index bb4311e..bc38eaf 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
@@ -1553,6 +1553,24 @@ skip:
 	return count;
 }
 
+static void qlcnic_83xx_poll_process_aen(struct qlcnic_adapter *adapter)
+{
+	unsigned long flags;
+	u32 mask, resp, event;
+
+	spin_lock_irqsave(&adapter->ahw->mbx_lock, flags);
+	resp = QLCRDX(adapter->ahw, QLCNIC_FW_MBX_CTRL);
+	if (!(resp & QLCNIC_SET_OWNER))
+		goto out;
+	event = readl(QLCNIC_MBX_FW(adapter->ahw, 0));
+	if (event &  QLCNIC_MBX_ASYNC_EVENT)
+		qlcnic_83xx_process_aen(adapter);
+out:
+	mask = QLCRDX(adapter->ahw, QLCNIC_DEF_INT_MASK);
+	writel(0, adapter->ahw->pci_base0 + mask);
+	spin_unlock_irqrestore(&adapter->ahw->mbx_lock, flags);
+}
+
 static int qlcnic_83xx_poll(struct napi_struct *napi, int budget)
 {
 	int tx_complete;
@@ -1567,7 +1585,7 @@ static int qlcnic_83xx_poll(struct napi_struct *napi, int budget)
 	tx_ring = adapter->tx_ring;
 
 	if (!(adapter->flags & QLCNIC_MSIX_ENABLED))
-		qlcnic_83xx_process_aen(adapter);
+		qlcnic_83xx_poll_process_aen(adapter);
 
 	tx_complete = qlcnic_process_cmd_ring(adapter, tx_ring, budget);
 	work_done = qlcnic_83xx_process_rcv_ring(sds_ring, budget);
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [net-next PATCH 4/8] qlcnic: refactor 83xx diagnostic loopback test
  2013-02-09 19:29 [net-next PATCH 0/8] qlcnic: bug fixes and feature updates Jitendra Kalsaria
                   ` (2 preceding siblings ...)
  2013-02-09 19:29 ` [net-next PATCH 3/8] qlcnic: helper routine to handle async events Jitendra Kalsaria
@ 2013-02-09 19:29 ` Jitendra Kalsaria
  2013-02-09 19:29 ` [net-next PATCH 5/8] qlcnic: refactor 83xx diagnostic IRQ test Jitendra Kalsaria
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Jitendra Kalsaria @ 2013-02-09 19:29 UTC (permalink / raw)
  To: davem; +Cc: netdev, sony.chacko, Dept_NX_Linux_NIC_Driver, Jitendra Kalsaria

From: Jitendra Kalsaria <jitendra.kalsaria@qlogic.com>

Cleanly separate 83xx diagnostic loopback test routines from 82xx

Signed-off-by: Jitendra Kalsaria <jitendra.kalsaria@qlogic.com>
---
 drivers/net/ethernet/qlogic/qlcnic/qlcnic.h        |    4 +-
 .../net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c    |  147 +++++++++++++++++++-
 .../net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h    |    1 +
 .../net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c    |   28 +---
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c   |   10 +-
 5 files changed, 158 insertions(+), 32 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
index 3a840e7..61b594c 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
@@ -1442,7 +1442,9 @@ int qlcnic_send_lro_cleanup(struct qlcnic_adapter *adapter);
 void qlcnic_update_cmd_producer(struct qlcnic_host_tx_ring *);
 
 /* Functions from qlcnic_ethtool.c */
-int qlcnic_check_loopback_buff(unsigned char *data, u8 mac[]);
+int qlcnic_check_loopback_buff(unsigned char *, u8 []);
+int qlcnic_do_lb_test(struct qlcnic_adapter *, u8);
+int qlcnic_loopback_test(struct net_device *, u8);
 
 /* Functions from qlcnic_main.c */
 int qlcnic_reset_context(struct qlcnic_adapter *);
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
index 3d628c6..3d48131 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
@@ -257,8 +257,6 @@ static struct qlcnic_hardware_ops qlcnic_83xx_hw_ops = {
 	.config_intr_coal		= qlcnic_83xx_config_intr_coal,
 	.config_rss			= qlcnic_83xx_config_rss,
 	.config_hw_lro			= qlcnic_83xx_config_hw_lro,
-	.config_loopback		= qlcnic_83xx_set_lb_mode,
-	.clear_loopback			= qlcnic_83xx_clear_lb_mode,
 	.config_promisc_mode		= qlcnic_83xx_nic_set_promisc,
 	.change_l2_filter		= qlcnic_83xx_change_l2_filter,
 	.get_board_info			= qlcnic_83xx_get_port_info,
@@ -1118,6 +1116,100 @@ out:
 	return err;
 }
 
+static int qlcnic_83xx_diag_alloc_res(struct net_device *netdev, int test)
+{
+	struct qlcnic_adapter *adapter = netdev_priv(netdev);
+	struct qlcnic_host_sds_ring *sds_ring;
+	struct qlcnic_host_rds_ring *rds_ring;
+	u8 ring;
+	int ret;
+
+	netif_device_detach(netdev);
+
+	if (netif_running(netdev))
+		__qlcnic_down(adapter, netdev);
+
+	qlcnic_detach(adapter);
+
+	adapter->max_sds_rings = 1;
+	adapter->ahw->diag_test = test;
+	adapter->ahw->linkup = 0;
+
+	ret = qlcnic_attach(adapter);
+	if (ret) {
+		netif_device_attach(netdev);
+		return ret;
+	}
+
+	ret = qlcnic_fw_create_ctx(adapter);
+	if (ret) {
+		qlcnic_detach(adapter);
+		netif_device_attach(netdev);
+		return ret;
+	}
+
+	for (ring = 0; ring < adapter->max_rds_rings; ring++) {
+		rds_ring = &adapter->recv_ctx->rds_rings[ring];
+		qlcnic_post_rx_buffers(adapter, rds_ring, ring);
+	}
+
+	if (adapter->ahw->diag_test == QLCNIC_INTERRUPT_TEST) {
+		for (ring = 0; ring < adapter->max_sds_rings; ring++) {
+			sds_ring = &adapter->recv_ctx->sds_rings[ring];
+			qlcnic_83xx_enable_intr(adapter, sds_ring);
+		}
+	}
+
+	if (adapter->ahw->diag_test == QLCNIC_LOOPBACK_TEST) {
+		/* disable and free mailbox interrupt */
+		qlcnic_83xx_free_mbx_intr(adapter);
+		adapter->ahw->loopback_state = 0;
+		adapter->ahw->hw_ops->setup_link_event(adapter, 1);
+	}
+
+	set_bit(__QLCNIC_DEV_UP, &adapter->state);
+	return 0;
+}
+
+static void qlcnic_83xx_diag_free_res(struct net_device *netdev,
+					int max_sds_rings)
+{
+	struct qlcnic_adapter *adapter = netdev_priv(netdev);
+	struct qlcnic_host_sds_ring *sds_ring;
+	int ring, err;
+
+	clear_bit(__QLCNIC_DEV_UP, &adapter->state);
+	if (adapter->ahw->diag_test == QLCNIC_INTERRUPT_TEST) {
+		for (ring = 0; ring < adapter->max_sds_rings; ring++) {
+			sds_ring = &adapter->recv_ctx->sds_rings[ring];
+			writel(1, sds_ring->crb_intr_mask);
+		}
+	}
+
+	qlcnic_fw_destroy_ctx(adapter);
+	qlcnic_detach(adapter);
+
+	if (adapter->ahw->diag_test == QLCNIC_LOOPBACK_TEST) {
+		err = qlcnic_83xx_setup_mbx_intr(adapter);
+		if (err) {
+			dev_err(&adapter->pdev->dev,
+				"%s: failed to setup mbx interrupt\n",
+				__func__);
+			goto out;
+		}
+	}
+	adapter->ahw->diag_test = 0;
+	adapter->max_sds_rings = max_sds_rings;
+
+	if (qlcnic_attach(adapter))
+		goto out;
+
+	if (netif_running(netdev))
+		__qlcnic_up(adapter, netdev);
+out:
+	netif_device_attach(netdev);
+}
+
 int qlcnic_83xx_config_led(struct qlcnic_adapter *adapter, u32 state,
 			   u32 beacon)
 {
@@ -1265,6 +1357,57 @@ int qlcnic_83xx_nic_set_promisc(struct qlcnic_adapter *adapter, u32 mode)
 	return err;
 }
 
+int qlcnic_83xx_loopback_test(struct net_device *netdev, u8 mode)
+{
+	struct qlcnic_adapter *adapter = netdev_priv(netdev);
+	struct qlcnic_hardware_context *ahw = adapter->ahw;
+	int ret = 0, loop = 0, max_sds_rings = adapter->max_sds_rings;
+
+	QLCDB(adapter, DRV, "%s loopback test in progress\n",
+	      mode == QLCNIC_ILB_MODE ? "internal" : "external");
+	if (ahw->op_mode == QLCNIC_NON_PRIV_FUNC) {
+		dev_warn(&adapter->pdev->dev,
+			 "Loopback test not supported for non privilege function\n");
+		return ret;
+	}
+
+	if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
+		return -EBUSY;
+
+	ret = qlcnic_83xx_diag_alloc_res(netdev, QLCNIC_LOOPBACK_TEST);
+	if (ret)
+		goto fail_diag_alloc;
+
+	ret = qlcnic_83xx_set_lb_mode(adapter, mode);
+	if (ret)
+		goto free_diag_res;
+
+	/* Poll for link up event before running traffic */
+	do {
+		msleep(500);
+		qlcnic_83xx_process_aen(adapter);
+		if (loop++ > QLCNIC_ILB_MAX_RCV_LOOP) {
+			dev_info(&adapter->pdev->dev,
+				 "Firmware didn't sent link up event to loopback request\n");
+			ret = -QLCNIC_FW_NOT_RESPOND;
+			qlcnic_83xx_clear_lb_mode(adapter, mode);
+			goto free_diag_res;
+		}
+	} while ((adapter->ahw->linkup && ahw->has_link_events) != 1);
+
+	ret = qlcnic_do_lb_test(adapter, mode);
+
+	qlcnic_83xx_clear_lb_mode(adapter, mode);
+
+free_diag_res:
+	qlcnic_83xx_diag_free_res(netdev, max_sds_rings);
+
+fail_diag_alloc:
+	adapter->max_sds_rings = max_sds_rings;
+	clear_bit(__QLCNIC_RESETTING, &adapter->state);
+	return ret;
+}
+
 int qlcnic_83xx_set_lb_mode(struct qlcnic_adapter *adapter, u8 mode)
 {
 	struct qlcnic_hardware_context *ahw = adapter->ahw;
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
index 16c5df6..87f2e08 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
@@ -428,6 +428,7 @@ int qlcnic_83xx_test_link(struct qlcnic_adapter *);
 int qlcnic_83xx_reg_test(struct qlcnic_adapter *);
 int qlcnic_83xx_get_regs_len(struct qlcnic_adapter *);
 int qlcnic_83xx_get_registers(struct qlcnic_adapter *, u32 *);
+int qlcnic_83xx_loopback_test(struct net_device *, u8);
 int qlcnic_83xx_interrupt_test(struct qlcnic_adapter *,
 			       struct qlcnic_cmd_args *);
 int qlcnic_83xx_flash_test(struct qlcnic_adapter *);
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
index 6320d55..58e2554 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
@@ -883,7 +883,7 @@ int qlcnic_check_loopback_buff(unsigned char *data, u8 mac[])
 	return memcmp(data, buff, QLCNIC_ILB_PKT_SIZE);
 }
 
-static int qlcnic_do_lb_test(struct qlcnic_adapter *adapter, u8 mode)
+int qlcnic_do_lb_test(struct qlcnic_adapter *adapter, u8 mode)
 {
 	struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
 	struct qlcnic_host_sds_ring *sds_ring = &recv_ctx->sds_rings[0];
@@ -925,7 +925,7 @@ static int qlcnic_do_lb_test(struct qlcnic_adapter *adapter, u8 mode)
 	return 0;
 }
 
-static int qlcnic_loopback_test(struct net_device *netdev, u8 mode)
+int qlcnic_loopback_test(struct net_device *netdev, u8 mode)
 {
 	struct qlcnic_adapter *adapter = netdev_priv(netdev);
 	int max_sds_rings = adapter->max_sds_rings;
@@ -935,13 +935,14 @@ static int qlcnic_loopback_test(struct net_device *netdev, u8 mode)
 	int ret;
 
 	if (qlcnic_83xx_check(adapter))
-		goto skip_cap;
+		return qlcnic_83xx_loopback_test(netdev, mode);
+
 	if (!(ahw->capabilities & QLCNIC_FW_CAPABILITY_MULTI_LOOPBACK)) {
 		dev_info(&adapter->pdev->dev,
 			 "Firmware do not support loopback test\n");
 		return -EOPNOTSUPP;
 	}
-skip_cap:
+
 	dev_warn(&adapter->pdev->dev, "%s loopback test in progress\n",
 		 mode == QLCNIC_ILB_MODE ? "internal" : "external");
 	if (ahw->op_mode == QLCNIC_NON_PRIV_FUNC) {
@@ -962,9 +963,6 @@ skip_cap:
 	if (ret)
 		goto free_res;
 
-	if (qlcnic_83xx_check(adapter))
-		goto skip_fw_msg;
-
 	ahw->diag_cnt = 0;
 	do {
 		msleep(500);
@@ -979,21 +977,9 @@ skip_cap:
 			goto free_res;
 		}
 	} while (!QLCNIC_IS_LB_CONFIGURED(ahw->loopback_state));
-skip_fw_msg:
-	if (qlcnic_83xx_check(adapter)) {
-		/* wait until firmware report link up before running traffic */
-		loop = 0;
-		do {
-			msleep(500);
-			if (loop++ > QLCNIC_ILB_MAX_RCV_LOOP) {
-				dev_info(&adapter->pdev->dev,
-					 "No linkup event after LB req\n");
-				ret = -QLCNIC_FW_NOT_RESPOND;
-				goto free_res;
-			}
-		} while ((adapter->ahw->linkup && ahw->has_link_events) != 1);
-	}
+
 	ret = qlcnic_do_lb_test(adapter, mode);
+
 	qlcnic_clear_lb_mode(adapter, mode);
 
  free_res:
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
index dcb990d..30aa1f2 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -1503,10 +1503,7 @@ void qlcnic_diag_free_res(struct net_device *netdev, int max_sds_rings)
 	if (adapter->ahw->diag_test == QLCNIC_INTERRUPT_TEST) {
 		for (ring = 0; ring < adapter->max_sds_rings; ring++) {
 			sds_ring = &adapter->recv_ctx->sds_rings[ring];
-			if (qlcnic_83xx_check(adapter))
-				writel(1, sds_ring->crb_intr_mask);
-			else
-				qlcnic_disable_int(sds_ring);
+			qlcnic_disable_int(sds_ring);
 		}
 	}
 
@@ -1599,10 +1596,7 @@ int qlcnic_diag_alloc_res(struct net_device *netdev, int test)
 	if (adapter->ahw->diag_test == QLCNIC_INTERRUPT_TEST) {
 		for (ring = 0; ring < adapter->max_sds_rings; ring++) {
 			sds_ring = &adapter->recv_ctx->sds_rings[ring];
-			if (qlcnic_82xx_check(adapter))
-				qlcnic_enable_int(sds_ring);
-			else
-				qlcnic_83xx_enable_intr(adapter, sds_ring);
+			qlcnic_enable_int(sds_ring);
 		}
 	}
 
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [net-next PATCH 5/8] qlcnic: refactor 83xx diagnostic IRQ test
  2013-02-09 19:29 [net-next PATCH 0/8] qlcnic: bug fixes and feature updates Jitendra Kalsaria
                   ` (3 preceding siblings ...)
  2013-02-09 19:29 ` [net-next PATCH 4/8] qlcnic: refactor 83xx diagnostic loopback test Jitendra Kalsaria
@ 2013-02-09 19:29 ` Jitendra Kalsaria
  2013-02-09 19:29 ` [net-next PATCH 6/8] qlcnic: fix async event handling during diagnostic loopback test Jitendra Kalsaria
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Jitendra Kalsaria @ 2013-02-09 19:29 UTC (permalink / raw)
  To: davem; +Cc: netdev, sony.chacko, Dept_NX_Linux_NIC_Driver, Jitendra Kalsaria

From: Jitendra Kalsaria <jitendra.kalsaria@qlogic.com>

Cleanly separate 83xx diagnostic IRQ test from 82xx

Signed-off-by: Jitendra Kalsaria <jitendra.kalsaria@qlogic.com>
---
 .../net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c    |   48 +++++++++++++++-----
 .../net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h    |    3 +-
 .../net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c    |   24 +++++-----
 3 files changed, 48 insertions(+), 27 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
index 3d48131..36c1474 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
@@ -2744,25 +2744,37 @@ int qlcnic_83xx_get_registers(struct qlcnic_adapter *adapter, u32 *regs_buff)
 	return i;
 }
 
-int qlcnic_83xx_interrupt_test(struct qlcnic_adapter *adapter,
-			       struct qlcnic_cmd_args *cmd)
+int qlcnic_83xx_interrupt_test(struct net_device *netdev)
 {
-	u8 val;
-	int ret;
+	struct qlcnic_adapter *adapter = netdev_priv(netdev);
+	struct qlcnic_hardware_context *ahw = adapter->ahw;
+	struct qlcnic_cmd_args cmd;
 	u32 data;
 	u16 intrpt_id, id;
+	u8 val;
+	int ret, max_sds_rings = adapter->max_sds_rings;
+
+	if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
+		return -EIO;
+
+	ret = qlcnic_83xx_diag_alloc_res(netdev, QLCNIC_INTERRUPT_TEST);
+	if (ret)
+		goto fail_diag_irq;
+
+	ahw->diag_cnt = 0;
+	qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_INTRPT_TEST);
 
 	if (adapter->flags & QLCNIC_MSIX_ENABLED)
-		intrpt_id = adapter->ahw->intr_tbl[0].id;
+		intrpt_id = ahw->intr_tbl[0].id;
 	else
-		intrpt_id = QLCRDX(adapter->ahw, QLCNIC_DEF_INT_ID);
+		intrpt_id = QLCRDX(ahw, QLCNIC_DEF_INT_ID);
 
-	cmd->req.arg[1] = 1;
-	cmd->req.arg[2] = intrpt_id;
-	cmd->req.arg[3] = BIT_0;
+	cmd.req.arg[1] = 1;
+	cmd.req.arg[2] = intrpt_id;
+	cmd.req.arg[3] = BIT_0;
 
-	ret = qlcnic_issue_cmd(adapter, cmd);
-	data = cmd->rsp.arg[2];
+	ret = qlcnic_issue_cmd(adapter, &cmd);
+	data = cmd.rsp.arg[2];
 	id = LSW(data);
 	val = LSB(MSW(data));
 	if (id != intrpt_id)
@@ -2770,9 +2782,21 @@ int qlcnic_83xx_interrupt_test(struct qlcnic_adapter *adapter,
 			 "Interrupt generated: 0x%x, requested:0x%x\n",
 			 id, intrpt_id);
 	if (val)
-		dev_info(&adapter->pdev->dev,
+		dev_err(&adapter->pdev->dev,
 			 "Interrupt test error: 0x%x\n", val);
+	if (ret)
+		goto done;
+
+	msleep(20);
+	ret = !ahw->diag_cnt;
 
+done:
+	qlcnic_free_mbx_args(&cmd);
+	qlcnic_83xx_diag_free_res(netdev, max_sds_rings);
+
+fail_diag_irq:
+	adapter->max_sds_rings = max_sds_rings;
+	clear_bit(__QLCNIC_RESETTING, &adapter->state);
 	return ret;
 }
 
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
index 87f2e08..f60e28a 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
@@ -429,7 +429,6 @@ int qlcnic_83xx_reg_test(struct qlcnic_adapter *);
 int qlcnic_83xx_get_regs_len(struct qlcnic_adapter *);
 int qlcnic_83xx_get_registers(struct qlcnic_adapter *, u32 *);
 int qlcnic_83xx_loopback_test(struct net_device *, u8);
-int qlcnic_83xx_interrupt_test(struct qlcnic_adapter *,
-			       struct qlcnic_cmd_args *);
+int qlcnic_83xx_interrupt_test(struct net_device *);
 int qlcnic_83xx_flash_test(struct qlcnic_adapter *);
 #endif
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
index 58e2554..5641f8e 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
@@ -823,38 +823,36 @@ static int qlcnic_get_sset_count(struct net_device *dev, int sset)
 static int qlcnic_irq_test(struct net_device *netdev)
 {
 	struct qlcnic_adapter *adapter = netdev_priv(netdev);
-	int max_sds_rings = adapter->max_sds_rings;
-	int ret;
+	struct qlcnic_hardware_context *ahw = adapter->ahw;
 	struct qlcnic_cmd_args cmd;
+	int ret, max_sds_rings = adapter->max_sds_rings;
+
+	if (qlcnic_83xx_check(adapter))
+		return qlcnic_83xx_interrupt_test(netdev);
 
 	if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
 		return -EIO;
 
 	ret = qlcnic_diag_alloc_res(netdev, QLCNIC_INTERRUPT_TEST);
 	if (ret)
-		goto clear_it;
+		goto clear_diag_irq;
 
-	adapter->ahw->diag_cnt = 0;
+	ahw->diag_cnt = 0;
 	qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_INTRPT_TEST);
 
-	if (qlcnic_83xx_check(adapter)) {
-		ret = qlcnic_83xx_interrupt_test(adapter, &cmd);
-	} else {
-		cmd.req.arg[1] = adapter->ahw->pci_func;
-		ret = qlcnic_issue_cmd(adapter, &cmd);
-	}
-
+	cmd.req.arg[1] = ahw->pci_func;
+	ret = qlcnic_issue_cmd(adapter, &cmd);
 	if (ret)
 		goto done;
 
 	usleep_range(1000, 12000);
-	ret = !adapter->ahw->diag_cnt;
+	ret = !ahw->diag_cnt;
 
 done:
 	qlcnic_free_mbx_args(&cmd);
 	qlcnic_diag_free_res(netdev, max_sds_rings);
 
-clear_it:
+clear_diag_irq:
 	adapter->max_sds_rings = max_sds_rings;
 	clear_bit(__QLCNIC_RESETTING, &adapter->state);
 	return ret;
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [net-next PATCH 6/8] qlcnic: fix async event handling during diagnostic loopback test
  2013-02-09 19:29 [net-next PATCH 0/8] qlcnic: bug fixes and feature updates Jitendra Kalsaria
                   ` (4 preceding siblings ...)
  2013-02-09 19:29 ` [net-next PATCH 5/8] qlcnic: refactor 83xx diagnostic IRQ test Jitendra Kalsaria
@ 2013-02-09 19:29 ` Jitendra Kalsaria
  2013-02-09 19:29 ` [net-next PATCH 7/8] qlcnic: enhance MSIX allocation failure log message Jitendra Kalsaria
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Jitendra Kalsaria @ 2013-02-09 19:29 UTC (permalink / raw)
  To: davem; +Cc: netdev, sony.chacko, Dept_NX_Linux_NIC_Driver, Jitendra Kalsaria

From: Jitendra Kalsaria <jitendra.kalsaria@qlogic.com>

o Handle async events during diagnostic loopback test
o Clear loopback mode on failure to receive async events

Signed-off-by: Jitendra Kalsaria <jitendra.kalsaria@qlogic.com>
---
 .../net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c    |    7 +++++--
 1 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
index 36c1474..51b4340 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
@@ -1436,13 +1436,15 @@ int qlcnic_83xx_set_lb_mode(struct qlcnic_adapter *adapter, u8 mode)
 		return status;
 	}
 
-	/* Wait until firmware send IDC Completion AEN */
+	/* Wait for Link and IDC Completion AEN */
 	do {
 		msleep(300);
+		qlcnic_83xx_process_aen(adapter);
 		if (loop++ > QLCNIC_ILB_MAX_RCV_LOOP) {
 			dev_err(&adapter->pdev->dev,
 				"FW did not generate IDC completion AEN\n");
 			clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
+			qlcnic_83xx_clear_lb_mode(adapter, mode);
 			return -EIO;
 		}
 	} while (test_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status));
@@ -1474,9 +1476,10 @@ int qlcnic_83xx_clear_lb_mode(struct qlcnic_adapter *adapter, u8 mode)
 		return status;
 	}
 
-	/* Wait until firmware send IDC Completion AEN */
+	/* Wait for Link and IDC Completion AEN */
 	do {
 		msleep(300);
+		qlcnic_83xx_process_aen(adapter);
 		if (loop++ > QLCNIC_ILB_MAX_RCV_LOOP) {
 			dev_err(&adapter->pdev->dev,
 				"Firmware didn't sent IDC completion AEN\n");
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [net-next PATCH 7/8] qlcnic: enhance MSIX allocation failure log message
  2013-02-09 19:29 [net-next PATCH 0/8] qlcnic: bug fixes and feature updates Jitendra Kalsaria
                   ` (5 preceding siblings ...)
  2013-02-09 19:29 ` [net-next PATCH 6/8] qlcnic: fix async event handling during diagnostic loopback test Jitendra Kalsaria
@ 2013-02-09 19:29 ` Jitendra Kalsaria
  2013-02-09 19:29 ` [net-next PATCH 8/8] qlcnic: fix mailbox response handling Jitendra Kalsaria
  2013-02-11  7:05 ` [net-next PATCH 0/8] qlcnic: bug fixes and feature updates David Miller
  8 siblings, 0 replies; 10+ messages in thread
From: Jitendra Kalsaria @ 2013-02-09 19:29 UTC (permalink / raw)
  To: davem; +Cc: netdev, sony.chacko, Dept_NX_Linux_NIC_Driver, Manish Chopra

From: Manish Chopra <manish.chopra@qlogic.com>

Signed-off-by: Manish Chopra <manish.chopra@qlogic.com>
Signed-off-by: Jitendra Kalsaria <jitendra.kalsaria@qlogic.com>
---
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
index 30aa1f2..b745194 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -455,12 +455,13 @@ int qlcnic_enable_msix(struct qlcnic_adapter *adapter, u32 num_msix)
 
 			if (num_msix) {
 				dev_info(&pdev->dev,
-					 "Trying %d MSI-X interrupt vectors\n",
+					 "Trying to allocate %d MSI-X interrupt vectors\n",
 					 num_msix);
 				goto enable_msix;
 			}
 		} else {
-			dev_info(&pdev->dev, "Failed to get %d vectors\n",
+			dev_info(&pdev->dev,
+				 "Unable to allocate %d MSI-X interrupt vectors\n",
 				 num_msix);
 		}
 	}
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [net-next PATCH 8/8] qlcnic: fix mailbox response handling
  2013-02-09 19:29 [net-next PATCH 0/8] qlcnic: bug fixes and feature updates Jitendra Kalsaria
                   ` (6 preceding siblings ...)
  2013-02-09 19:29 ` [net-next PATCH 7/8] qlcnic: enhance MSIX allocation failure log message Jitendra Kalsaria
@ 2013-02-09 19:29 ` Jitendra Kalsaria
  2013-02-11  7:05 ` [net-next PATCH 0/8] qlcnic: bug fixes and feature updates David Miller
  8 siblings, 0 replies; 10+ messages in thread
From: Jitendra Kalsaria @ 2013-02-09 19:29 UTC (permalink / raw)
  To: davem; +Cc: netdev, sony.chacko, Dept_NX_Linux_NIC_Driver, Jitendra Kalsaria

From: Jitendra Kalsaria <jitendra.kalsaria@qlogic.com>

o Do not read mailbox registers on timeout
o Add a helper function to handle mailbox response

Signed-off-by: Jitendra Kalsaria <jitendra.kalsaria@qlogic.com>
---
 .../net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c    |   66 ++++++++++++--------
 1 files changed, 40 insertions(+), 26 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
index 51b4340..f7b39d1 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
@@ -664,6 +664,21 @@ static void qlcnic_dump_mbx(struct qlcnic_adapter *adapter,
 	pr_info("\n");
 }
 
+/* Mailbox response for mac rcode */
+static u32 qlcnic_83xx_mac_rcode(struct qlcnic_adapter *adapter)
+{
+	u32 fw_data;
+	u8 mac_cmd_rcode;
+
+	fw_data = readl(QLCNIC_MBX_FW(adapter->ahw, 2));
+	mac_cmd_rcode = (u8)fw_data;
+	if (mac_cmd_rcode == QLC_83XX_NO_NIC_RESOURCE ||
+	    mac_cmd_rcode == QLC_83XX_MAC_PRESENT ||
+	    mac_cmd_rcode == QLC_83XX_MAC_ABSENT)
+		return QLCNIC_RCODE_SUCCESS;
+	return 1;
+}
+
 static u32 qlcnic_83xx_mbx_poll(struct qlcnic_adapter *adapter)
 {
 	u32 data;
@@ -686,7 +701,7 @@ int qlcnic_83xx_mbx_op(struct qlcnic_adapter *adapter,
 {
 	int i;
 	u16 opcode;
-	u8 mbx_err_code, mac_cmd_rcode;
+	u8 mbx_err_code;
 	u32 rsp, mbx_val, fw_data, rsp_num, mbx_cmd;
 	struct qlcnic_hardware_context *ahw = adapter->ahw;
 
@@ -722,45 +737,44 @@ int qlcnic_83xx_mbx_op(struct qlcnic_adapter *adapter,
 	QLCWRX(ahw, QLCNIC_HOST_MBX_CTRL, QLCNIC_SET_OWNER);
 poll:
 	rsp = qlcnic_83xx_mbx_poll(adapter);
-	/* Get the FW response data */
-	fw_data = readl(QLCNIC_MBX_FW(ahw, 0));
-	mbx_err_code = QLCNIC_MBX_STATUS(fw_data);
-	rsp_num = QLCNIC_MBX_NUM_REGS(fw_data);
-	opcode = QLCNIC_MBX_RSP(fw_data);
-
 	if (rsp != QLCNIC_RCODE_TIMEOUT) {
+		/* Get the FW response data */
+		fw_data = readl(QLCNIC_MBX_FW(ahw, 0));
 		if (fw_data &  QLCNIC_MBX_ASYNC_EVENT) {
 			qlcnic_83xx_process_aen(adapter);
 			mbx_val = QLCRDX(ahw, QLCNIC_HOST_MBX_CTRL);
 			if (mbx_val)
 				goto poll;
-		} else if ((mbx_err_code == QLCNIC_MBX_RSP_OK) ||
-			   (mbx_err_code == QLCNIC_MBX_PORT_RSP_OK)) {
-			qlcnic_83xx_get_mbx_data(adapter, cmd);
+		}
+		mbx_err_code = QLCNIC_MBX_STATUS(fw_data);
+		rsp_num = QLCNIC_MBX_NUM_REGS(fw_data);
+		opcode = QLCNIC_MBX_RSP(fw_data);
+		qlcnic_83xx_get_mbx_data(adapter, cmd);
+
+		switch (mbx_err_code) {
+		case QLCNIC_MBX_RSP_OK:
+		case QLCNIC_MBX_PORT_RSP_OK:
 			rsp = QLCNIC_RCODE_SUCCESS;
-		} else {
-			qlcnic_83xx_get_mbx_data(adapter, cmd);
+			break;
+		default:
 			if (opcode == QLCNIC_CMD_CONFIG_MAC_VLAN) {
-				fw_data = readl(QLCNIC_MBX_FW(ahw, 2));
-				mac_cmd_rcode = (u8)fw_data;
-				if (mac_cmd_rcode == QLC_83XX_NO_NIC_RESOURCE ||
-				    mac_cmd_rcode == QLC_83XX_MAC_PRESENT ||
-				    mac_cmd_rcode == QLC_83XX_MAC_ABSENT) {
-					rsp = QLCNIC_RCODE_SUCCESS;
+				rsp = qlcnic_83xx_mac_rcode(adapter);
+				if (!rsp)
 					goto out;
-				}
 			}
-			dev_info(&adapter->pdev->dev,
-				 "MBX command 0x%x failed with err:0x%x\n",
-				 opcode, mbx_err_code);
+			dev_err(&adapter->pdev->dev,
+				"MBX command 0x%x failed with err:0x%x\n",
+				opcode, mbx_err_code);
 			rsp = mbx_err_code;
 			qlcnic_dump_mbx(adapter, cmd);
+			break;
 		}
-	} else {
-		dev_info(&adapter->pdev->dev,
-			 "MBX command 0x%x timed out\n", opcode);
-		qlcnic_dump_mbx(adapter, cmd);
+		goto out;
 	}
+
+	dev_err(&adapter->pdev->dev, "MBX command 0x%x timed out\n",
+		QLCNIC_MBX_RSP(mbx_cmd));
+	rsp = QLCNIC_RCODE_TIMEOUT;
 out:
 	/* clear fw mbx control register */
 	QLCWRX(ahw, QLCNIC_FW_MBX_CTRL, QLCNIC_CLR_OWNER);
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [net-next PATCH 0/8] qlcnic: bug fixes and feature updates
  2013-02-09 19:29 [net-next PATCH 0/8] qlcnic: bug fixes and feature updates Jitendra Kalsaria
                   ` (7 preceding siblings ...)
  2013-02-09 19:29 ` [net-next PATCH 8/8] qlcnic: fix mailbox response handling Jitendra Kalsaria
@ 2013-02-11  7:05 ` David Miller
  8 siblings, 0 replies; 10+ messages in thread
From: David Miller @ 2013-02-11  7:05 UTC (permalink / raw)
  To: jitendra.kalsaria; +Cc: netdev, sony.chacko, Dept_NX_Linux_NIC_Driver

From: Jitendra Kalsaria <jitendra.kalsaria@qlogic.com>
Date: Sat,  9 Feb 2013 14:29:47 -0500

> Please apply to net-next.

Series applied, thanks.

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2013-02-11  7:05 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-02-09 19:29 [net-next PATCH 0/8] qlcnic: bug fixes and feature updates Jitendra Kalsaria
2013-02-09 19:29 ` [net-next PATCH 1/8] qlcnic: fix initialize NIC mailbox command Jitendra Kalsaria
2013-02-09 19:29 ` [net-next PATCH 2/8] qlcnic: fix firmware based IDC participation Jitendra Kalsaria
2013-02-09 19:29 ` [net-next PATCH 3/8] qlcnic: helper routine to handle async events Jitendra Kalsaria
2013-02-09 19:29 ` [net-next PATCH 4/8] qlcnic: refactor 83xx diagnostic loopback test Jitendra Kalsaria
2013-02-09 19:29 ` [net-next PATCH 5/8] qlcnic: refactor 83xx diagnostic IRQ test Jitendra Kalsaria
2013-02-09 19:29 ` [net-next PATCH 6/8] qlcnic: fix async event handling during diagnostic loopback test Jitendra Kalsaria
2013-02-09 19:29 ` [net-next PATCH 7/8] qlcnic: enhance MSIX allocation failure log message Jitendra Kalsaria
2013-02-09 19:29 ` [net-next PATCH 8/8] qlcnic: fix mailbox response handling Jitendra Kalsaria
2013-02-11  7:05 ` [net-next PATCH 0/8] qlcnic: bug fixes and feature updates David Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).