diff options
Diffstat (limited to 'drivers/net/ethernet/intel/i40evf/i40evf_main.c')
-rw-r--r-- | drivers/net/ethernet/intel/i40evf/i40evf_main.c | 110 |
1 files changed, 47 insertions, 63 deletions
diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_main.c b/drivers/net/ethernet/intel/i40evf/i40evf_main.c index 7c53aca4b5a6..4ab4ebba07a1 100644 --- a/drivers/net/ethernet/intel/i40evf/i40evf_main.c +++ b/drivers/net/ethernet/intel/i40evf/i40evf_main.c | |||
@@ -170,7 +170,8 @@ static void i40evf_tx_timeout(struct net_device *netdev) | |||
170 | struct i40evf_adapter *adapter = netdev_priv(netdev); | 170 | struct i40evf_adapter *adapter = netdev_priv(netdev); |
171 | 171 | ||
172 | adapter->tx_timeout_count++; | 172 | adapter->tx_timeout_count++; |
173 | if (!(adapter->flags & I40EVF_FLAG_RESET_PENDING)) { | 173 | if (!(adapter->flags & (I40EVF_FLAG_RESET_PENDING | |
174 | I40EVF_FLAG_RESET_NEEDED))) { | ||
174 | adapter->flags |= I40EVF_FLAG_RESET_NEEDED; | 175 | adapter->flags |= I40EVF_FLAG_RESET_NEEDED; |
175 | schedule_work(&adapter->reset_task); | 176 | schedule_work(&adapter->reset_task); |
176 | } | 177 | } |
@@ -1460,7 +1461,7 @@ static void i40evf_configure_rss(struct i40evf_adapter *adapter) | |||
1460 | for (i = 0; i <= I40E_VFQF_HLUT_MAX_INDEX; i++) { | 1461 | for (i = 0; i <= I40E_VFQF_HLUT_MAX_INDEX; i++) { |
1461 | lut = 0; | 1462 | lut = 0; |
1462 | for (j = 0; j < 4; j++) { | 1463 | for (j = 0; j < 4; j++) { |
1463 | if (cqueue == adapter->vsi_res->num_queue_pairs) | 1464 | if (cqueue == adapter->num_active_queues) |
1464 | cqueue = 0; | 1465 | cqueue = 0; |
1465 | lut |= ((cqueue) << (8 * j)); | 1466 | lut |= ((cqueue) << (8 * j)); |
1466 | cqueue++; | 1467 | cqueue++; |
@@ -1470,8 +1471,8 @@ static void i40evf_configure_rss(struct i40evf_adapter *adapter) | |||
1470 | i40e_flush(hw); | 1471 | i40e_flush(hw); |
1471 | } | 1472 | } |
1472 | 1473 | ||
1473 | #define I40EVF_RESET_WAIT_MS 100 | 1474 | #define I40EVF_RESET_WAIT_MS 10 |
1474 | #define I40EVF_RESET_WAIT_COUNT 200 | 1475 | #define I40EVF_RESET_WAIT_COUNT 500 |
1475 | /** | 1476 | /** |
1476 | * i40evf_reset_task - Call-back task to handle hardware reset | 1477 | * i40evf_reset_task - Call-back task to handle hardware reset |
1477 | * @work: pointer to work_struct | 1478 | * @work: pointer to work_struct |
@@ -1495,10 +1496,17 @@ static void i40evf_reset_task(struct work_struct *work) | |||
1495 | &adapter->crit_section)) | 1496 | &adapter->crit_section)) |
1496 | usleep_range(500, 1000); | 1497 | usleep_range(500, 1000); |
1497 | 1498 | ||
1499 | i40evf_misc_irq_disable(adapter); | ||
1498 | if (adapter->flags & I40EVF_FLAG_RESET_NEEDED) { | 1500 | if (adapter->flags & I40EVF_FLAG_RESET_NEEDED) { |
1499 | dev_info(&adapter->pdev->dev, "Requesting reset from PF\n"); | 1501 | adapter->flags &= ~I40EVF_FLAG_RESET_NEEDED; |
1502 | /* Restart the AQ here. If we have been reset but didn't | ||
1503 | * detect it, or if the PF had to reinit, our AQ will be hosed. | ||
1504 | */ | ||
1505 | i40evf_shutdown_adminq(hw); | ||
1506 | i40evf_init_adminq(hw); | ||
1500 | i40evf_request_reset(adapter); | 1507 | i40evf_request_reset(adapter); |
1501 | } | 1508 | } |
1509 | adapter->flags |= I40EVF_FLAG_RESET_PENDING; | ||
1502 | 1510 | ||
1503 | /* poll until we see the reset actually happen */ | 1511 | /* poll until we see the reset actually happen */ |
1504 | for (i = 0; i < I40EVF_RESET_WAIT_COUNT; i++) { | 1512 | for (i = 0; i < I40EVF_RESET_WAIT_COUNT; i++) { |
@@ -1507,10 +1515,10 @@ static void i40evf_reset_task(struct work_struct *work) | |||
1507 | if ((rstat_val != I40E_VFR_VFACTIVE) && | 1515 | if ((rstat_val != I40E_VFR_VFACTIVE) && |
1508 | (rstat_val != I40E_VFR_COMPLETED)) | 1516 | (rstat_val != I40E_VFR_COMPLETED)) |
1509 | break; | 1517 | break; |
1510 | msleep(I40EVF_RESET_WAIT_MS); | 1518 | usleep_range(500, 1000); |
1511 | } | 1519 | } |
1512 | if (i == I40EVF_RESET_WAIT_COUNT) { | 1520 | if (i == I40EVF_RESET_WAIT_COUNT) { |
1513 | adapter->flags &= ~I40EVF_FLAG_RESET_PENDING; | 1521 | dev_info(&adapter->pdev->dev, "Never saw reset\n"); |
1514 | goto continue_reset; /* act like the reset happened */ | 1522 | goto continue_reset; /* act like the reset happened */ |
1515 | } | 1523 | } |
1516 | 1524 | ||
@@ -1518,11 +1526,12 @@ static void i40evf_reset_task(struct work_struct *work) | |||
1518 | for (i = 0; i < I40EVF_RESET_WAIT_COUNT; i++) { | 1526 | for (i = 0; i < I40EVF_RESET_WAIT_COUNT; i++) { |
1519 | rstat_val = rd32(hw, I40E_VFGEN_RSTAT) & | 1527 | rstat_val = rd32(hw, I40E_VFGEN_RSTAT) & |
1520 | I40E_VFGEN_RSTAT_VFR_STATE_MASK; | 1528 | I40E_VFGEN_RSTAT_VFR_STATE_MASK; |
1521 | if ((rstat_val == I40E_VFR_VFACTIVE) || | 1529 | if (rstat_val == I40E_VFR_VFACTIVE) |
1522 | (rstat_val == I40E_VFR_COMPLETED)) | ||
1523 | break; | 1530 | break; |
1524 | msleep(I40EVF_RESET_WAIT_MS); | 1531 | msleep(I40EVF_RESET_WAIT_MS); |
1525 | } | 1532 | } |
1533 | /* extra wait to make sure minimum wait is met */ | ||
1534 | msleep(I40EVF_RESET_WAIT_MS); | ||
1526 | if (i == I40EVF_RESET_WAIT_COUNT) { | 1535 | if (i == I40EVF_RESET_WAIT_COUNT) { |
1527 | struct i40evf_mac_filter *f, *ftmp; | 1536 | struct i40evf_mac_filter *f, *ftmp; |
1528 | struct i40evf_vlan_filter *fv, *fvtmp; | 1537 | struct i40evf_vlan_filter *fv, *fvtmp; |
@@ -1534,11 +1543,10 @@ static void i40evf_reset_task(struct work_struct *work) | |||
1534 | 1543 | ||
1535 | if (netif_running(adapter->netdev)) { | 1544 | if (netif_running(adapter->netdev)) { |
1536 | set_bit(__I40E_DOWN, &adapter->vsi.state); | 1545 | set_bit(__I40E_DOWN, &adapter->vsi.state); |
1537 | i40evf_irq_disable(adapter); | ||
1538 | i40evf_napi_disable_all(adapter); | ||
1539 | netif_tx_disable(netdev); | ||
1540 | netif_tx_stop_all_queues(netdev); | ||
1541 | netif_carrier_off(netdev); | 1546 | netif_carrier_off(netdev); |
1547 | netif_tx_disable(netdev); | ||
1548 | i40evf_napi_disable_all(adapter); | ||
1549 | i40evf_irq_disable(adapter); | ||
1542 | i40evf_free_traffic_irqs(adapter); | 1550 | i40evf_free_traffic_irqs(adapter); |
1543 | i40evf_free_all_tx_resources(adapter); | 1551 | i40evf_free_all_tx_resources(adapter); |
1544 | i40evf_free_all_rx_resources(adapter); | 1552 | i40evf_free_all_rx_resources(adapter); |
@@ -1550,6 +1558,7 @@ static void i40evf_reset_task(struct work_struct *work) | |||
1550 | list_del(&f->list); | 1558 | list_del(&f->list); |
1551 | kfree(f); | 1559 | kfree(f); |
1552 | } | 1560 | } |
1561 | |||
1553 | list_for_each_entry_safe(fv, fvtmp, &adapter->vlan_filter_list, | 1562 | list_for_each_entry_safe(fv, fvtmp, &adapter->vlan_filter_list, |
1554 | list) { | 1563 | list) { |
1555 | list_del(&fv->list); | 1564 | list_del(&fv->list); |
@@ -1564,22 +1573,27 @@ static void i40evf_reset_task(struct work_struct *work) | |||
1564 | i40evf_shutdown_adminq(hw); | 1573 | i40evf_shutdown_adminq(hw); |
1565 | adapter->netdev->flags &= ~IFF_UP; | 1574 | adapter->netdev->flags &= ~IFF_UP; |
1566 | clear_bit(__I40EVF_IN_CRITICAL_TASK, &adapter->crit_section); | 1575 | clear_bit(__I40EVF_IN_CRITICAL_TASK, &adapter->crit_section); |
1576 | adapter->flags &= ~I40EVF_FLAG_RESET_PENDING; | ||
1577 | dev_info(&adapter->pdev->dev, "Reset task did not complete, VF disabled\n"); | ||
1567 | return; /* Do not attempt to reinit. It's dead, Jim. */ | 1578 | return; /* Do not attempt to reinit. It's dead, Jim. */ |
1568 | } | 1579 | } |
1569 | 1580 | ||
1570 | continue_reset: | 1581 | continue_reset: |
1571 | adapter->flags &= ~I40EVF_FLAG_RESET_PENDING; | ||
1572 | |||
1573 | i40evf_irq_disable(adapter); | ||
1574 | |||
1575 | if (netif_running(adapter->netdev)) { | 1582 | if (netif_running(adapter->netdev)) { |
1576 | i40evf_napi_disable_all(adapter); | ||
1577 | netif_tx_disable(netdev); | ||
1578 | netif_tx_stop_all_queues(netdev); | ||
1579 | netif_carrier_off(netdev); | 1583 | netif_carrier_off(netdev); |
1584 | netif_tx_stop_all_queues(netdev); | ||
1585 | i40evf_napi_disable_all(adapter); | ||
1580 | } | 1586 | } |
1587 | i40evf_irq_disable(adapter); | ||
1581 | 1588 | ||
1582 | adapter->state = __I40EVF_RESETTING; | 1589 | adapter->state = __I40EVF_RESETTING; |
1590 | adapter->flags &= ~I40EVF_FLAG_RESET_PENDING; | ||
1591 | |||
1592 | /* free the Tx/Rx rings and descriptors, might be better to just | ||
1593 | * re-use them sometime in the future | ||
1594 | */ | ||
1595 | i40evf_free_all_rx_resources(adapter); | ||
1596 | i40evf_free_all_tx_resources(adapter); | ||
1583 | 1597 | ||
1584 | /* kill and reinit the admin queue */ | 1598 | /* kill and reinit the admin queue */ |
1585 | if (i40evf_shutdown_adminq(hw)) | 1599 | if (i40evf_shutdown_adminq(hw)) |
@@ -1603,6 +1617,7 @@ continue_reset: | |||
1603 | adapter->aq_required = I40EVF_FLAG_AQ_ADD_MAC_FILTER; | 1617 | adapter->aq_required = I40EVF_FLAG_AQ_ADD_MAC_FILTER; |
1604 | adapter->aq_required |= I40EVF_FLAG_AQ_ADD_VLAN_FILTER; | 1618 | adapter->aq_required |= I40EVF_FLAG_AQ_ADD_VLAN_FILTER; |
1605 | clear_bit(__I40EVF_IN_CRITICAL_TASK, &adapter->crit_section); | 1619 | clear_bit(__I40EVF_IN_CRITICAL_TASK, &adapter->crit_section); |
1620 | i40evf_misc_irq_enable(adapter); | ||
1606 | 1621 | ||
1607 | mod_timer(&adapter->watchdog_timer, jiffies + 2); | 1622 | mod_timer(&adapter->watchdog_timer, jiffies + 2); |
1608 | 1623 | ||
@@ -1624,7 +1639,10 @@ continue_reset: | |||
1624 | goto reset_err; | 1639 | goto reset_err; |
1625 | 1640 | ||
1626 | i40evf_irq_enable(adapter, true); | 1641 | i40evf_irq_enable(adapter, true); |
1642 | } else { | ||
1643 | adapter->state = __I40EVF_DOWN; | ||
1627 | } | 1644 | } |
1645 | |||
1628 | return; | 1646 | return; |
1629 | reset_err: | 1647 | reset_err: |
1630 | dev_err(&adapter->pdev->dev, "failed to allocate resources during reinit\n"); | 1648 | dev_err(&adapter->pdev->dev, "failed to allocate resources during reinit\n"); |
@@ -1667,6 +1685,11 @@ static void i40evf_adminq_task(struct work_struct *work) | |||
1667 | memset(event.msg_buf, 0, I40EVF_MAX_AQ_BUF_SIZE); | 1685 | memset(event.msg_buf, 0, I40EVF_MAX_AQ_BUF_SIZE); |
1668 | } while (pending); | 1686 | } while (pending); |
1669 | 1687 | ||
1688 | if ((adapter->flags & | ||
1689 | (I40EVF_FLAG_RESET_PENDING | I40EVF_FLAG_RESET_NEEDED)) || | ||
1690 | adapter->state == __I40EVF_RESETTING) | ||
1691 | goto freedom; | ||
1692 | |||
1670 | /* check for error indications */ | 1693 | /* check for error indications */ |
1671 | val = rd32(hw, hw->aq.arq.len); | 1694 | val = rd32(hw, hw->aq.arq.len); |
1672 | oldval = val; | 1695 | oldval = val; |
@@ -1702,6 +1725,7 @@ static void i40evf_adminq_task(struct work_struct *work) | |||
1702 | if (oldval != val) | 1725 | if (oldval != val) |
1703 | wr32(hw, hw->aq.asq.len, val); | 1726 | wr32(hw, hw->aq.asq.len, val); |
1704 | 1727 | ||
1728 | freedom: | ||
1705 | kfree(event.msg_buf); | 1729 | kfree(event.msg_buf); |
1706 | out: | 1730 | out: |
1707 | /* re-enable Admin queue interrupt cause */ | 1731 | /* re-enable Admin queue interrupt cause */ |
@@ -1897,47 +1921,6 @@ static struct net_device_stats *i40evf_get_stats(struct net_device *netdev) | |||
1897 | } | 1921 | } |
1898 | 1922 | ||
1899 | /** | 1923 | /** |
1900 | * i40evf_reinit_locked - Software reinit | ||
1901 | * @adapter: board private structure | ||
1902 | * | ||
1903 | * Reinititalizes the ring structures in response to a software configuration | ||
1904 | * change. Roughly the same as close followed by open, but skips releasing | ||
1905 | * and reallocating the interrupts. | ||
1906 | **/ | ||
1907 | void i40evf_reinit_locked(struct i40evf_adapter *adapter) | ||
1908 | { | ||
1909 | struct net_device *netdev = adapter->netdev; | ||
1910 | int err; | ||
1911 | |||
1912 | WARN_ON(in_interrupt()); | ||
1913 | |||
1914 | i40evf_down(adapter); | ||
1915 | |||
1916 | /* allocate transmit descriptors */ | ||
1917 | err = i40evf_setup_all_tx_resources(adapter); | ||
1918 | if (err) | ||
1919 | goto err_reinit; | ||
1920 | |||
1921 | /* allocate receive descriptors */ | ||
1922 | err = i40evf_setup_all_rx_resources(adapter); | ||
1923 | if (err) | ||
1924 | goto err_reinit; | ||
1925 | |||
1926 | i40evf_configure(adapter); | ||
1927 | |||
1928 | err = i40evf_up_complete(adapter); | ||
1929 | if (err) | ||
1930 | goto err_reinit; | ||
1931 | |||
1932 | i40evf_irq_enable(adapter, true); | ||
1933 | return; | ||
1934 | |||
1935 | err_reinit: | ||
1936 | dev_err(&adapter->pdev->dev, "failed to allocate resources during reinit\n"); | ||
1937 | i40evf_close(netdev); | ||
1938 | } | ||
1939 | |||
1940 | /** | ||
1941 | * i40evf_change_mtu - Change the Maximum Transfer Unit | 1924 | * i40evf_change_mtu - Change the Maximum Transfer Unit |
1942 | * @netdev: network interface device structure | 1925 | * @netdev: network interface device structure |
1943 | * @new_mtu: new value for maximum frame size | 1926 | * @new_mtu: new value for maximum frame size |
@@ -1952,9 +1935,10 @@ static int i40evf_change_mtu(struct net_device *netdev, int new_mtu) | |||
1952 | if ((new_mtu < 68) || (max_frame > I40E_MAX_RXBUFFER)) | 1935 | if ((new_mtu < 68) || (max_frame > I40E_MAX_RXBUFFER)) |
1953 | return -EINVAL; | 1936 | return -EINVAL; |
1954 | 1937 | ||
1955 | /* must set new MTU before calling down or up */ | ||
1956 | netdev->mtu = new_mtu; | 1938 | netdev->mtu = new_mtu; |
1957 | i40evf_reinit_locked(adapter); | 1939 | adapter->flags |= I40EVF_FLAG_RESET_NEEDED; |
1940 | schedule_work(&adapter->reset_task); | ||
1941 | |||
1958 | return 0; | 1942 | return 0; |
1959 | } | 1943 | } |
1960 | 1944 | ||