aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet
diff options
context:
space:
mode:
authorMitch Williams <mitch.a.williams@intel.com>2014-10-24 23:24:33 -0400
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2014-11-11 09:01:54 -0500
commitf8d4db35e870896dd7b2ba70a30f4dfc53c39472 (patch)
tree422102d3f8e4432f4e1ad753d0c9389951d6b04d /drivers/net/ethernet
parent79442d38b370ed7317cd82fb2b6d1dafccaf44e5 (diff)
i40evf: make early init processing more robust
In early init, if we get an unexpected message from the PF (such as link status), we just kick an error back to the init task, causing it to restart its state machine and delaying initialization. Make the early init AQ message receive code more robust by handling messages in a loop, and ignoring those that we aren't interested in. This also gets rid of some scary log messages that really didn't indicate a problem. Change-ID: I620e8c72e49c49c665ef33eeab2425dd10e721cf Signed-off-by: Mitch Williams <mitch.a.williams@intel.com> Signed-off-by: Patrick Lu <patrick.lu@intel.com> Tested-by: Jim Young <jamesx.m.young@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet')
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c59
1 files changed, 31 insertions, 28 deletions
diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c b/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c
index 66d12f5b4ca8..ff8676147c14 100644
--- a/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c
+++ b/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c
@@ -89,6 +89,7 @@ int i40evf_verify_api_ver(struct i40evf_adapter *adapter)
89 struct i40e_virtchnl_version_info *pf_vvi; 89 struct i40e_virtchnl_version_info *pf_vvi;
90 struct i40e_hw *hw = &adapter->hw; 90 struct i40e_hw *hw = &adapter->hw;
91 struct i40e_arq_event_info event; 91 struct i40e_arq_event_info event;
92 enum i40e_virtchnl_ops op;
92 i40e_status err; 93 i40e_status err;
93 94
94 event.msg_size = I40EVF_MAX_AQ_BUF_SIZE; 95 event.msg_size = I40EVF_MAX_AQ_BUF_SIZE;
@@ -98,18 +99,27 @@ int i40evf_verify_api_ver(struct i40evf_adapter *adapter)
98 goto out; 99 goto out;
99 } 100 }
100 101
101 err = i40evf_clean_arq_element(hw, &event, NULL); 102 while (1) {
102 if (err == I40E_ERR_ADMIN_QUEUE_NO_WORK) 103 err = i40evf_clean_arq_element(hw, &event, NULL);
103 goto out_alloc; 104 /* When the AQ is empty, i40evf_clean_arq_element will return
105 * nonzero and this loop will terminate.
106 */
107 if (err)
108 goto out_alloc;
109 op =
110 (enum i40e_virtchnl_ops)le32_to_cpu(event.desc.cookie_high);
111 if (op == I40E_VIRTCHNL_OP_VERSION)
112 break;
113 }
114
104 115
105 err = (i40e_status)le32_to_cpu(event.desc.cookie_low); 116 err = (i40e_status)le32_to_cpu(event.desc.cookie_low);
106 if (err) 117 if (err)
107 goto out_alloc; 118 goto out_alloc;
108 119
109 if ((enum i40e_virtchnl_ops)le32_to_cpu(event.desc.cookie_high) != 120 if (op != I40E_VIRTCHNL_OP_VERSION) {
110 I40E_VIRTCHNL_OP_VERSION) {
111 dev_info(&adapter->pdev->dev, "Invalid reply type %d from PF\n", 121 dev_info(&adapter->pdev->dev, "Invalid reply type %d from PF\n",
112 le32_to_cpu(event.desc.cookie_high)); 122 op);
113 err = -EIO; 123 err = -EIO;
114 goto out_alloc; 124 goto out_alloc;
115 } 125 }
@@ -153,8 +163,9 @@ int i40evf_get_vf_config(struct i40evf_adapter *adapter)
153{ 163{
154 struct i40e_hw *hw = &adapter->hw; 164 struct i40e_hw *hw = &adapter->hw;
155 struct i40e_arq_event_info event; 165 struct i40e_arq_event_info event;
156 u16 len; 166 enum i40e_virtchnl_ops op;
157 i40e_status err; 167 i40e_status err;
168 u16 len;
158 169
159 len = sizeof(struct i40e_virtchnl_vf_resource) + 170 len = sizeof(struct i40e_virtchnl_vf_resource) +
160 I40E_MAX_VF_VSI * sizeof(struct i40e_virtchnl_vsi_resource); 171 I40E_MAX_VF_VSI * sizeof(struct i40e_virtchnl_vsi_resource);
@@ -165,29 +176,21 @@ int i40evf_get_vf_config(struct i40evf_adapter *adapter)
165 goto out; 176 goto out;
166 } 177 }
167 178
168 err = i40evf_clean_arq_element(hw, &event, NULL); 179 while (1) {
169 if (err == I40E_ERR_ADMIN_QUEUE_NO_WORK) 180 event.msg_size = len;
170 goto out_alloc; 181 /* When the AQ is empty, i40evf_clean_arq_element will return
171 182 * nonzero and this loop will terminate.
172 err = (i40e_status)le32_to_cpu(event.desc.cookie_low); 183 */
173 if (err) { 184 err = i40evf_clean_arq_element(hw, &event, NULL);
174 dev_err(&adapter->pdev->dev, 185 if (err)
175 "%s: Error returned from PF, %d, %d\n", __func__, 186 goto out_alloc;
176 le32_to_cpu(event.desc.cookie_high), 187 op =
177 le32_to_cpu(event.desc.cookie_low)); 188 (enum i40e_virtchnl_ops)le32_to_cpu(event.desc.cookie_high);
178 err = -EIO; 189 if (op == I40E_VIRTCHNL_OP_GET_VF_RESOURCES)
179 goto out_alloc; 190 break;
180 } 191 }
181 192
182 if ((enum i40e_virtchnl_ops)le32_to_cpu(event.desc.cookie_high) != 193 err = (i40e_status)le32_to_cpu(event.desc.cookie_low);
183 I40E_VIRTCHNL_OP_GET_VF_RESOURCES) {
184 dev_err(&adapter->pdev->dev,
185 "%s: Invalid response from PF, %d, %d\n", __func__,
186 le32_to_cpu(event.desc.cookie_high),
187 le32_to_cpu(event.desc.cookie_low));
188 err = -EIO;
189 goto out_alloc;
190 }
191 memcpy(adapter->vf_res, event.msg_buf, min(event.msg_size, len)); 194 memcpy(adapter->vf_res, event.msg_buf, min(event.msg_size, len));
192 195
193 i40e_vf_parse_hw_config(hw, adapter->vf_res); 196 i40e_vf_parse_hw_config(hw, adapter->vf_res);