|
@@ -1001,23 +1001,34 @@ void i40evf_virtchnl_completion(struct i40evf_adapter *adapter,
|
|
|
if (v_opcode == VIRTCHNL_OP_EVENT) {
|
|
|
struct virtchnl_pf_event *vpe =
|
|
|
(struct virtchnl_pf_event *)msg;
|
|
|
+ bool link_up = vpe->event_data.link_event.link_status;
|
|
|
switch (vpe->event) {
|
|
|
case VIRTCHNL_EVENT_LINK_CHANGE:
|
|
|
adapter->link_speed =
|
|
|
vpe->event_data.link_event.link_speed;
|
|
|
- if (adapter->link_up !=
|
|
|
- vpe->event_data.link_event.link_status) {
|
|
|
- adapter->link_up =
|
|
|
- vpe->event_data.link_event.link_status;
|
|
|
- if (adapter->link_up) {
|
|
|
- netif_tx_start_all_queues(netdev);
|
|
|
- netif_carrier_on(netdev);
|
|
|
- } else {
|
|
|
- netif_tx_stop_all_queues(netdev);
|
|
|
- netif_carrier_off(netdev);
|
|
|
- }
|
|
|
- i40evf_print_link_message(adapter);
|
|
|
+
|
|
|
+ /* we've already got the right link status, bail */
|
|
|
+ if (adapter->link_up == link_up)
|
|
|
+ break;
|
|
|
+
|
|
|
+ /* If we get link up message and start queues before
|
|
|
+ * our queues are configured it will trigger a TX hang.
|
|
|
+ * In that case, just ignore the link status message,
|
|
|
+ * we'll get another one after we enable queues and
|
|
|
+ * actually prepared to send traffic.
|
|
|
+ */
|
|
|
+ if (link_up && adapter->state != __I40EVF_RUNNING)
|
|
|
+ break;
|
|
|
+
|
|
|
+ adapter->link_up = link_up;
|
|
|
+ if (link_up) {
|
|
|
+ netif_tx_start_all_queues(netdev);
|
|
|
+ netif_carrier_on(netdev);
|
|
|
+ } else {
|
|
|
+ netif_tx_stop_all_queues(netdev);
|
|
|
+ netif_carrier_off(netdev);
|
|
|
}
|
|
|
+ i40evf_print_link_message(adapter);
|
|
|
break;
|
|
|
case VIRTCHNL_EVENT_RESET_IMPENDING:
|
|
|
dev_info(&adapter->pdev->dev, "PF reset warning received\n");
|