aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/intel
diff options
context:
space:
mode:
authorJeff Kirsher <jeffrey.t.kirsher@intel.com>2015-04-10 20:20:17 -0400
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2015-04-14 18:47:28 -0400
commit9de15bda37bd9b86378afd82e6fc52e82dc89ac3 (patch)
tree0a9352eb81f5ca5d3ae86b3d99dfab4c3c858809 /drivers/net/ethernet/intel
parentb382bb1b3e2d498ee7ce8976afa7737d407a4f11 (diff)
fm10k: don't handle mailbox events in iov_event path and always process mailbox
Since we already schedule the service task, we can just wait for this task to handle the mailbox events from the VF. This reduces some complex code flow, and makes it so we have a single path for handling the VF messages. There is a possibility that we have a slight delay in handling VF messages, but it should be minimal. The result of tx_complete and !rx_ready is insufficient to determine whether we need to process the mailbox. There is a possible race condition whereby the VF fills up the mbmem for us, but we have already recently processed the mailboxes in the interrupt. During this time, the interrupt is disabled. Thus, our Rx FIFO is empty, but the mbmem now has data in it. Since we continually check whether Rx FIFO is empty, we then never call process. This results in the possibility to prevent PF from handling the VF mailbox messages. Instead, just call process every time, despite the fact that we may or may not have anything to process for the VF. There should be minimal overhead for doing this, and it resolves an issue where the VF never comes up due to never getting response for its SET_LPORT_STATE message. Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Signed-off-by: Jacob Keller <jacob.e.keller@intel.com> Acked-by: Matthew Vick <matthew.vick@intel.com> Tested-by: Krishneil Singh <krishneil.k.singh@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel')
-rw-r--r--drivers/net/ethernet/intel/fm10k/fm10k_iov.c34
-rw-r--r--drivers/net/ethernet/intel/fm10k/fm10k_pci.c3
2 files changed, 5 insertions, 32 deletions
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_iov.c b/drivers/net/ethernet/intel/fm10k/fm10k_iov.c
index 69cbfde7fc09..0b37e197e300 100644
--- a/drivers/net/ethernet/intel/fm10k/fm10k_iov.c
+++ b/drivers/net/ethernet/intel/fm10k/fm10k_iov.c
@@ -47,7 +47,7 @@ s32 fm10k_iov_event(struct fm10k_intfc *interface)
47{ 47{
48 struct fm10k_hw *hw = &interface->hw; 48 struct fm10k_hw *hw = &interface->hw;
49 struct fm10k_iov_data *iov_data; 49 struct fm10k_iov_data *iov_data;
50 s64 mbicr, vflre; 50 s64 vflre;
51 int i; 51 int i;
52 52
53 /* if there is no iov_data then there is no mailboxes to process */ 53 /* if there is no iov_data then there is no mailboxes to process */
@@ -63,7 +63,7 @@ s32 fm10k_iov_event(struct fm10k_intfc *interface)
63 goto read_unlock; 63 goto read_unlock;
64 64
65 if (!(fm10k_read_reg(hw, FM10K_EICR) & FM10K_EICR_VFLR)) 65 if (!(fm10k_read_reg(hw, FM10K_EICR) & FM10K_EICR_VFLR))
66 goto process_mbx; 66 goto read_unlock;
67 67
68 /* read VFLRE to determine if any VFs have been reset */ 68 /* read VFLRE to determine if any VFs have been reset */
69 do { 69 do {
@@ -86,32 +86,6 @@ s32 fm10k_iov_event(struct fm10k_intfc *interface)
86 } 86 }
87 } while (i != iov_data->num_vfs); 87 } while (i != iov_data->num_vfs);
88 88
89process_mbx:
90 /* read MBICR to determine which VFs require attention */
91 mbicr = fm10k_read_reg(hw, FM10K_MBICR(1));
92 mbicr <<= 32;
93 mbicr |= fm10k_read_reg(hw, FM10K_MBICR(0));
94
95 i = iov_data->next_vf_mbx ? : iov_data->num_vfs;
96
97 for (mbicr <<= 64 - i; i--; mbicr += mbicr) {
98 struct fm10k_mbx_info *mbx = &iov_data->vf_info[i].mbx;
99
100 if (mbicr >= 0)
101 continue;
102
103 if (!hw->mbx.ops.tx_ready(&hw->mbx, FM10K_VFMBX_MSG_MTU))
104 break;
105
106 mbx->ops.process(hw, mbx);
107 }
108
109 if (i >= 0) {
110 iov_data->next_vf_mbx = i + 1;
111 } else if (iov_data->next_vf_mbx) {
112 iov_data->next_vf_mbx = 0;
113 goto process_mbx;
114 }
115read_unlock: 89read_unlock:
116 rcu_read_unlock(); 90 rcu_read_unlock();
117 91
@@ -155,10 +129,6 @@ process_mbx:
155 mbx->ops.connect(hw, mbx); 129 mbx->ops.connect(hw, mbx);
156 } 130 }
157 131
158 /* no work pending, then just continue */
159 if (mbx->ops.tx_complete(mbx) && !mbx->ops.rx_ready(mbx))
160 continue;
161
162 /* guarantee we have free space in the SM mailbox */ 132 /* guarantee we have free space in the SM mailbox */
163 if (!hw->mbx.ops.tx_ready(&hw->mbx, FM10K_VFMBX_MSG_MTU)) 133 if (!hw->mbx.ops.tx_ready(&hw->mbx, FM10K_VFMBX_MSG_MTU))
164 break; 134 break;
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_pci.c b/drivers/net/ethernet/intel/fm10k/fm10k_pci.c
index 514f35c31d1d..32e99ebdae66 100644
--- a/drivers/net/ethernet/intel/fm10k/fm10k_pci.c
+++ b/drivers/net/ethernet/intel/fm10k/fm10k_pci.c
@@ -1006,6 +1006,7 @@ static irqreturn_t fm10k_msix_mbx_pf(int __always_unused irq, void *data)
1006 /* service mailboxes */ 1006 /* service mailboxes */
1007 if (fm10k_mbx_trylock(interface)) { 1007 if (fm10k_mbx_trylock(interface)) {
1008 mbx->ops.process(hw, mbx); 1008 mbx->ops.process(hw, mbx);
1009 /* handle VFLRE events */
1009 fm10k_iov_event(interface); 1010 fm10k_iov_event(interface);
1010 fm10k_mbx_unlock(interface); 1011 fm10k_mbx_unlock(interface);
1011 } 1012 }
@@ -1022,6 +1023,8 @@ static irqreturn_t fm10k_msix_mbx_pf(int __always_unused irq, void *data)
1022 1023
1023 /* we should validate host state after interrupt event */ 1024 /* we should validate host state after interrupt event */
1024 hw->mac.get_host_state = 1; 1025 hw->mac.get_host_state = 1;
1026
1027 /* validate host state, and handle VF mailboxes in the service task */
1025 fm10k_service_event_schedule(interface); 1028 fm10k_service_event_schedule(interface);
1026 1029
1027 /* re-enable mailbox interrupt and indicate 20us delay */ 1030 /* re-enable mailbox interrupt and indicate 20us delay */