qlcnic: Support polling for mailbox events.
authorRajesh Borundia <rajesh.borundia@qlogic.com>
Fri, 19 Apr 2013 07:01:14 +0000 (07:01 +0000)
committerDavid S. Miller <davem@davemloft.net>
Fri, 19 Apr 2013 20:14:54 +0000 (16:14 -0400)
o When mailbox interrupt is disabled PF should be
  able to process request from VF. Enable polling
  for such cases.

Signed-off-by: Rajesh Borundia <rajesh.borundia@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c

index fef2f4b..86eaa68 100644 (file)
@@ -919,6 +919,7 @@ struct qlcnic_ipaddr {
 #define __QLCNIC_ELB_INPROGRESS                8
 #define __QLCNIC_SRIOV_ENABLE          10
 #define __QLCNIC_SRIOV_CAPABLE         11
+#define __QLCNIC_MBX_POLL_ENABLE       12
 
 #define QLCNIC_INTERRUPT_TEST          1
 #define QLCNIC_LOOPBACK_TEST           2
@@ -1012,6 +1013,7 @@ struct qlcnic_adapter {
        struct workqueue_struct *qlcnic_wq;
        struct delayed_work fw_work;
        struct delayed_work idc_aen_work;
+       struct delayed_work mbx_poll_work;
 
        struct qlcnic_filter_hash fhash;
        struct qlcnic_filter_hash rx_fhash;
index f1d06d2..32a95c1 100644 (file)
@@ -926,6 +926,35 @@ static void qlcnic_83xx_process_aen(struct qlcnic_adapter *adapter)
        spin_unlock_irqrestore(&ahw->mbx_lock, flags);
 }
 
+static void qlcnic_83xx_mbx_poll_work(struct work_struct *work)
+{
+       struct qlcnic_adapter *adapter;
+
+       adapter = container_of(work, struct qlcnic_adapter, mbx_poll_work.work);
+
+       if (!test_bit(__QLCNIC_MBX_POLL_ENABLE, &adapter->state))
+               return;
+
+       qlcnic_83xx_process_aen(adapter);
+       queue_delayed_work(adapter->qlcnic_wq, &adapter->mbx_poll_work,
+                          (HZ / 10));
+}
+
+void qlcnic_83xx_enable_mbx_poll(struct qlcnic_adapter *adapter)
+{
+       if (test_and_set_bit(__QLCNIC_MBX_POLL_ENABLE, &adapter->state))
+               return;
+
+       INIT_DELAYED_WORK(&adapter->mbx_poll_work, qlcnic_83xx_mbx_poll_work);
+}
+
+void qlcnic_83xx_disable_mbx_poll(struct qlcnic_adapter *adapter)
+{
+       if (!test_and_clear_bit(__QLCNIC_MBX_POLL_ENABLE, &adapter->state))
+               return;
+       cancel_delayed_work_sync(&adapter->mbx_poll_work);
+}
+
 static int qlcnic_83xx_add_rings(struct qlcnic_adapter *adapter)
 {
        int index, i, err, sds_mbx_size;
index 73070bc..4be411c 100644 (file)
@@ -621,4 +621,6 @@ int qlcnic_83xx_enable_flash_write(struct qlcnic_adapter *);
 int qlcnic_83xx_disable_flash_write(struct qlcnic_adapter *);
 u32 qlcnic_83xx_mac_rcode(struct qlcnic_adapter *);
 u32 qlcnic_83xx_mbx_poll(struct qlcnic_adapter *);
+void qlcnic_83xx_enable_mbx_poll(struct qlcnic_adapter *);
+void qlcnic_83xx_disable_mbx_poll(struct qlcnic_adapter *);
 #endif
index a79276d..247a9f9 100644 (file)
@@ -3306,8 +3306,10 @@ int qlcnic_set_max_rss(struct qlcnic_adapter *adapter, u8 data, size_t len)
 
        qlcnic_detach(adapter);
 
-       if (qlcnic_83xx_check(adapter))
+       if (qlcnic_83xx_check(adapter)) {
                qlcnic_83xx_free_mbx_intr(adapter);
+               qlcnic_83xx_enable_mbx_poll(adapter);
+       }
 
        qlcnic_teardown_intr(adapter);
        err = qlcnic_setup_intr(adapter, data);
@@ -3321,6 +3323,7 @@ int qlcnic_set_max_rss(struct qlcnic_adapter *adapter, u8 data, size_t len)
                /* register for NIC IDC AEN Events */
                qlcnic_83xx_register_nic_idc_func(adapter, 1);
                err = qlcnic_83xx_setup_mbx_intr(adapter);
+               qlcnic_83xx_disable_mbx_poll(adapter);
                if (err) {
                        dev_err(&adapter->pdev->dev,
                                "failed to setup mbx interrupt\n");