qlcnic: helper routine to handle async events
authorJitendra Kalsaria <jitendra.kalsaria@qlogic.com>
Sat, 9 Feb 2013 09:29:50 +0000 (09:29 +0000)
committerDavid S. Miller <davem@davemloft.net>
Mon, 11 Feb 2013 07:04:13 +0000 (02:04 -0500)
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>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h
drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c

index d23372e..3d628c6 100644 (file)
 #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;
 }
 
index b62017b..16c5df6 100644 (file)
@@ -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
index ed52b9c..5b8749e 100644 (file)
@@ -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;
index bb4311e..bc38eaf 100644 (file)
@@ -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);