Commit 262ae1f9 authored by David S. Miller's avatar David S. Miller

Merge branch '40GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/net-

queue

Tony Nguyen says:

====================
Intel Wired LAN Driver Updates 2021-11-19

This series contains updates to iavf driver only.

Nitesh prevents user from changing interrupt settings when adaptive
interrupt moderation is on.

Jedrzej resolves a hang that occurred when interface was closed while a
reset was occurring and fixes statistics to be updated when requested to
prevent stale values.

Brett adjusts driver to accommodate changes in supported VLAN features
that could occur during reset and cause various errors to be reported.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 0f296e78 5951a2b9
...@@ -305,6 +305,7 @@ struct iavf_adapter { ...@@ -305,6 +305,7 @@ struct iavf_adapter {
#define IAVF_FLAG_AQ_DEL_FDIR_FILTER BIT(26) #define IAVF_FLAG_AQ_DEL_FDIR_FILTER BIT(26)
#define IAVF_FLAG_AQ_ADD_ADV_RSS_CFG BIT(27) #define IAVF_FLAG_AQ_ADD_ADV_RSS_CFG BIT(27)
#define IAVF_FLAG_AQ_DEL_ADV_RSS_CFG BIT(28) #define IAVF_FLAG_AQ_DEL_ADV_RSS_CFG BIT(28)
#define IAVF_FLAG_AQ_REQUEST_STATS BIT(29)
/* OS defined structs */ /* OS defined structs */
struct net_device *netdev; struct net_device *netdev;
...@@ -444,6 +445,7 @@ int iavf_up(struct iavf_adapter *adapter); ...@@ -444,6 +445,7 @@ int iavf_up(struct iavf_adapter *adapter);
void iavf_down(struct iavf_adapter *adapter); void iavf_down(struct iavf_adapter *adapter);
int iavf_process_config(struct iavf_adapter *adapter); int iavf_process_config(struct iavf_adapter *adapter);
void iavf_schedule_reset(struct iavf_adapter *adapter); void iavf_schedule_reset(struct iavf_adapter *adapter);
void iavf_schedule_request_stats(struct iavf_adapter *adapter);
void iavf_reset(struct iavf_adapter *adapter); void iavf_reset(struct iavf_adapter *adapter);
void iavf_set_ethtool_ops(struct net_device *netdev); void iavf_set_ethtool_ops(struct net_device *netdev);
void iavf_update_stats(struct iavf_adapter *adapter); void iavf_update_stats(struct iavf_adapter *adapter);
...@@ -501,4 +503,5 @@ void iavf_add_adv_rss_cfg(struct iavf_adapter *adapter); ...@@ -501,4 +503,5 @@ void iavf_add_adv_rss_cfg(struct iavf_adapter *adapter);
void iavf_del_adv_rss_cfg(struct iavf_adapter *adapter); void iavf_del_adv_rss_cfg(struct iavf_adapter *adapter);
struct iavf_mac_filter *iavf_add_filter(struct iavf_adapter *adapter, struct iavf_mac_filter *iavf_add_filter(struct iavf_adapter *adapter,
const u8 *macaddr); const u8 *macaddr);
int iavf_lock_timeout(struct mutex *lock, unsigned int msecs);
#endif /* _IAVF_H_ */ #endif /* _IAVF_H_ */
...@@ -354,6 +354,9 @@ static void iavf_get_ethtool_stats(struct net_device *netdev, ...@@ -354,6 +354,9 @@ static void iavf_get_ethtool_stats(struct net_device *netdev,
struct iavf_adapter *adapter = netdev_priv(netdev); struct iavf_adapter *adapter = netdev_priv(netdev);
unsigned int i; unsigned int i;
/* Explicitly request stats refresh */
iavf_schedule_request_stats(adapter);
iavf_add_ethtool_stats(&data, adapter, iavf_gstrings_stats); iavf_add_ethtool_stats(&data, adapter, iavf_gstrings_stats);
rcu_read_lock(); rcu_read_lock();
...@@ -723,12 +726,31 @@ static int iavf_get_per_queue_coalesce(struct net_device *netdev, u32 queue, ...@@ -723,12 +726,31 @@ static int iavf_get_per_queue_coalesce(struct net_device *netdev, u32 queue,
* *
* Change the ITR settings for a specific queue. * Change the ITR settings for a specific queue.
**/ **/
static void iavf_set_itr_per_queue(struct iavf_adapter *adapter, static int iavf_set_itr_per_queue(struct iavf_adapter *adapter,
struct ethtool_coalesce *ec, int queue) struct ethtool_coalesce *ec, int queue)
{ {
struct iavf_ring *rx_ring = &adapter->rx_rings[queue]; struct iavf_ring *rx_ring = &adapter->rx_rings[queue];
struct iavf_ring *tx_ring = &adapter->tx_rings[queue]; struct iavf_ring *tx_ring = &adapter->tx_rings[queue];
struct iavf_q_vector *q_vector; struct iavf_q_vector *q_vector;
u16 itr_setting;
itr_setting = rx_ring->itr_setting & ~IAVF_ITR_DYNAMIC;
if (ec->rx_coalesce_usecs != itr_setting &&
ec->use_adaptive_rx_coalesce) {
netif_info(adapter, drv, adapter->netdev,
"Rx interrupt throttling cannot be changed if adaptive-rx is enabled\n");
return -EINVAL;
}
itr_setting = tx_ring->itr_setting & ~IAVF_ITR_DYNAMIC;
if (ec->tx_coalesce_usecs != itr_setting &&
ec->use_adaptive_tx_coalesce) {
netif_info(adapter, drv, adapter->netdev,
"Tx interrupt throttling cannot be changed if adaptive-tx is enabled\n");
return -EINVAL;
}
rx_ring->itr_setting = ITR_REG_ALIGN(ec->rx_coalesce_usecs); rx_ring->itr_setting = ITR_REG_ALIGN(ec->rx_coalesce_usecs);
tx_ring->itr_setting = ITR_REG_ALIGN(ec->tx_coalesce_usecs); tx_ring->itr_setting = ITR_REG_ALIGN(ec->tx_coalesce_usecs);
...@@ -751,6 +773,7 @@ static void iavf_set_itr_per_queue(struct iavf_adapter *adapter, ...@@ -751,6 +773,7 @@ static void iavf_set_itr_per_queue(struct iavf_adapter *adapter,
* the Tx and Rx ITR values based on the values we have entered * the Tx and Rx ITR values based on the values we have entered
* into the q_vector, no need to write the values now. * into the q_vector, no need to write the values now.
*/ */
return 0;
} }
/** /**
...@@ -792,9 +815,11 @@ static int __iavf_set_coalesce(struct net_device *netdev, ...@@ -792,9 +815,11 @@ static int __iavf_set_coalesce(struct net_device *netdev,
*/ */
if (queue < 0) { if (queue < 0) {
for (i = 0; i < adapter->num_active_queues; i++) for (i = 0; i < adapter->num_active_queues; i++)
iavf_set_itr_per_queue(adapter, ec, i); if (iavf_set_itr_per_queue(adapter, ec, i))
return -EINVAL;
} else if (queue < adapter->num_active_queues) { } else if (queue < adapter->num_active_queues) {
iavf_set_itr_per_queue(adapter, ec, queue); if (iavf_set_itr_per_queue(adapter, ec, queue))
return -EINVAL;
} else { } else {
netif_info(adapter, drv, netdev, "Invalid queue value, queue range is 0 - %d\n", netif_info(adapter, drv, netdev, "Invalid queue value, queue range is 0 - %d\n",
adapter->num_active_queues - 1); adapter->num_active_queues - 1);
......
...@@ -147,7 +147,7 @@ enum iavf_status iavf_free_virt_mem_d(struct iavf_hw *hw, ...@@ -147,7 +147,7 @@ enum iavf_status iavf_free_virt_mem_d(struct iavf_hw *hw,
* *
* Returns 0 on success, negative on failure * Returns 0 on success, negative on failure
**/ **/
static int iavf_lock_timeout(struct mutex *lock, unsigned int msecs) int iavf_lock_timeout(struct mutex *lock, unsigned int msecs)
{ {
unsigned int wait, delay = 10; unsigned int wait, delay = 10;
...@@ -174,6 +174,19 @@ void iavf_schedule_reset(struct iavf_adapter *adapter) ...@@ -174,6 +174,19 @@ void iavf_schedule_reset(struct iavf_adapter *adapter)
} }
} }
/**
* iavf_schedule_request_stats - Set the flags and schedule statistics request
* @adapter: board private structure
*
* Sets IAVF_FLAG_AQ_REQUEST_STATS flag so iavf_watchdog_task() will explicitly
* request and refresh ethtool stats
**/
void iavf_schedule_request_stats(struct iavf_adapter *adapter)
{
adapter->aq_required |= IAVF_FLAG_AQ_REQUEST_STATS;
mod_delayed_work(iavf_wq, &adapter->watchdog_task, 0);
}
/** /**
* iavf_tx_timeout - Respond to a Tx Hang * iavf_tx_timeout - Respond to a Tx Hang
* @netdev: network interface device structure * @netdev: network interface device structure
...@@ -704,13 +717,11 @@ static void iavf_del_vlan(struct iavf_adapter *adapter, u16 vlan) ...@@ -704,13 +717,11 @@ static void iavf_del_vlan(struct iavf_adapter *adapter, u16 vlan)
**/ **/
static void iavf_restore_filters(struct iavf_adapter *adapter) static void iavf_restore_filters(struct iavf_adapter *adapter)
{ {
/* re-add all VLAN filters */ u16 vid;
if (VLAN_ALLOWED(adapter)) {
u16 vid;
for_each_set_bit(vid, adapter->vsi.active_vlans, VLAN_N_VID) /* re-add all VLAN filters */
iavf_add_vlan(adapter, vid); for_each_set_bit(vid, adapter->vsi.active_vlans, VLAN_N_VID)
} iavf_add_vlan(adapter, vid);
} }
/** /**
...@@ -745,9 +756,6 @@ static int iavf_vlan_rx_kill_vid(struct net_device *netdev, ...@@ -745,9 +756,6 @@ static int iavf_vlan_rx_kill_vid(struct net_device *netdev,
{ {
struct iavf_adapter *adapter = netdev_priv(netdev); struct iavf_adapter *adapter = netdev_priv(netdev);
if (!VLAN_ALLOWED(adapter))
return -EIO;
iavf_del_vlan(adapter, vid); iavf_del_vlan(adapter, vid);
clear_bit(vid, adapter->vsi.active_vlans); clear_bit(vid, adapter->vsi.active_vlans);
...@@ -1709,6 +1717,11 @@ static int iavf_process_aq_command(struct iavf_adapter *adapter) ...@@ -1709,6 +1717,11 @@ static int iavf_process_aq_command(struct iavf_adapter *adapter)
iavf_del_adv_rss_cfg(adapter); iavf_del_adv_rss_cfg(adapter);
return 0; return 0;
} }
if (adapter->aq_required & IAVF_FLAG_AQ_REQUEST_STATS) {
iavf_request_stats(adapter);
return 0;
}
return -EAGAIN; return -EAGAIN;
} }
...@@ -2173,7 +2186,6 @@ static void iavf_reset_task(struct work_struct *work) ...@@ -2173,7 +2186,6 @@ static void iavf_reset_task(struct work_struct *work)
struct net_device *netdev = adapter->netdev; struct net_device *netdev = adapter->netdev;
struct iavf_hw *hw = &adapter->hw; struct iavf_hw *hw = &adapter->hw;
struct iavf_mac_filter *f, *ftmp; struct iavf_mac_filter *f, *ftmp;
struct iavf_vlan_filter *vlf;
struct iavf_cloud_filter *cf; struct iavf_cloud_filter *cf;
u32 reg_val; u32 reg_val;
int i = 0, err; int i = 0, err;
...@@ -2254,6 +2266,7 @@ static void iavf_reset_task(struct work_struct *work) ...@@ -2254,6 +2266,7 @@ static void iavf_reset_task(struct work_struct *work)
(adapter->state == __IAVF_RESETTING)); (adapter->state == __IAVF_RESETTING));
if (running) { if (running) {
netdev->flags &= ~IFF_UP;
netif_carrier_off(netdev); netif_carrier_off(netdev);
netif_tx_stop_all_queues(netdev); netif_tx_stop_all_queues(netdev);
adapter->link_up = false; adapter->link_up = false;
...@@ -2313,11 +2326,6 @@ static void iavf_reset_task(struct work_struct *work) ...@@ -2313,11 +2326,6 @@ static void iavf_reset_task(struct work_struct *work)
list_for_each_entry(f, &adapter->mac_filter_list, list) { list_for_each_entry(f, &adapter->mac_filter_list, list) {
f->add = true; f->add = true;
} }
/* re-add all VLAN filters */
list_for_each_entry(vlf, &adapter->vlan_filter_list, list) {
vlf->add = true;
}
spin_unlock_bh(&adapter->mac_vlan_list_lock); spin_unlock_bh(&adapter->mac_vlan_list_lock);
/* check if TCs are running and re-add all cloud filters */ /* check if TCs are running and re-add all cloud filters */
...@@ -2331,7 +2339,6 @@ static void iavf_reset_task(struct work_struct *work) ...@@ -2331,7 +2339,6 @@ static void iavf_reset_task(struct work_struct *work)
spin_unlock_bh(&adapter->cloud_filter_list_lock); spin_unlock_bh(&adapter->cloud_filter_list_lock);
adapter->aq_required |= IAVF_FLAG_AQ_ADD_MAC_FILTER; adapter->aq_required |= IAVF_FLAG_AQ_ADD_MAC_FILTER;
adapter->aq_required |= IAVF_FLAG_AQ_ADD_VLAN_FILTER;
adapter->aq_required |= IAVF_FLAG_AQ_ADD_CLOUD_FILTER; adapter->aq_required |= IAVF_FLAG_AQ_ADD_CLOUD_FILTER;
iavf_misc_irq_enable(adapter); iavf_misc_irq_enable(adapter);
...@@ -2365,7 +2372,7 @@ static void iavf_reset_task(struct work_struct *work) ...@@ -2365,7 +2372,7 @@ static void iavf_reset_task(struct work_struct *work)
* to __IAVF_RUNNING * to __IAVF_RUNNING
*/ */
iavf_up_complete(adapter); iavf_up_complete(adapter);
netdev->flags |= IFF_UP;
iavf_irq_enable(adapter, true); iavf_irq_enable(adapter, true);
} else { } else {
iavf_change_state(adapter, __IAVF_DOWN); iavf_change_state(adapter, __IAVF_DOWN);
...@@ -2378,8 +2385,10 @@ static void iavf_reset_task(struct work_struct *work) ...@@ -2378,8 +2385,10 @@ static void iavf_reset_task(struct work_struct *work)
reset_err: reset_err:
mutex_unlock(&adapter->client_lock); mutex_unlock(&adapter->client_lock);
mutex_unlock(&adapter->crit_lock); mutex_unlock(&adapter->crit_lock);
if (running) if (running) {
iavf_change_state(adapter, __IAVF_RUNNING); iavf_change_state(adapter, __IAVF_RUNNING);
netdev->flags |= IFF_UP;
}
dev_err(&adapter->pdev->dev, "failed to allocate resources during reinit\n"); dev_err(&adapter->pdev->dev, "failed to allocate resources during reinit\n");
iavf_close(netdev); iavf_close(netdev);
} }
...@@ -3441,11 +3450,16 @@ static int iavf_set_features(struct net_device *netdev, ...@@ -3441,11 +3450,16 @@ static int iavf_set_features(struct net_device *netdev,
{ {
struct iavf_adapter *adapter = netdev_priv(netdev); struct iavf_adapter *adapter = netdev_priv(netdev);
/* Don't allow changing VLAN_RX flag when adapter is not capable /* Don't allow enabling VLAN features when adapter is not capable
* of VLAN offload * of VLAN offload/filtering
*/ */
if (!VLAN_ALLOWED(adapter)) { if (!VLAN_ALLOWED(adapter)) {
if ((netdev->features ^ features) & NETIF_F_HW_VLAN_CTAG_RX) netdev->hw_features &= ~(NETIF_F_HW_VLAN_CTAG_RX |
NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_HW_VLAN_CTAG_FILTER);
if (features & (NETIF_F_HW_VLAN_CTAG_RX |
NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_HW_VLAN_CTAG_FILTER))
return -EINVAL; return -EINVAL;
} else if ((netdev->features ^ features) & NETIF_F_HW_VLAN_CTAG_RX) { } else if ((netdev->features ^ features) & NETIF_F_HW_VLAN_CTAG_RX) {
if (features & NETIF_F_HW_VLAN_CTAG_RX) if (features & NETIF_F_HW_VLAN_CTAG_RX)
......
...@@ -607,7 +607,7 @@ void iavf_add_vlans(struct iavf_adapter *adapter) ...@@ -607,7 +607,7 @@ void iavf_add_vlans(struct iavf_adapter *adapter)
if (f->add) if (f->add)
count++; count++;
} }
if (!count) { if (!count || !VLAN_ALLOWED(adapter)) {
adapter->aq_required &= ~IAVF_FLAG_AQ_ADD_VLAN_FILTER; adapter->aq_required &= ~IAVF_FLAG_AQ_ADD_VLAN_FILTER;
spin_unlock_bh(&adapter->mac_vlan_list_lock); spin_unlock_bh(&adapter->mac_vlan_list_lock);
return; return;
...@@ -673,9 +673,19 @@ void iavf_del_vlans(struct iavf_adapter *adapter) ...@@ -673,9 +673,19 @@ void iavf_del_vlans(struct iavf_adapter *adapter)
spin_lock_bh(&adapter->mac_vlan_list_lock); spin_lock_bh(&adapter->mac_vlan_list_lock);
list_for_each_entry(f, &adapter->vlan_filter_list, list) { list_for_each_entry_safe(f, ftmp, &adapter->vlan_filter_list, list) {
if (f->remove) /* since VLAN capabilities are not allowed, we dont want to send
* a VLAN delete request because it will most likely fail and
* create unnecessary errors/noise, so just free the VLAN
* filters marked for removal to enable bailing out before
* sending a virtchnl message
*/
if (f->remove && !VLAN_ALLOWED(adapter)) {
list_del(&f->list);
kfree(f);
} else if (f->remove) {
count++; count++;
}
} }
if (!count) { if (!count) {
adapter->aq_required &= ~IAVF_FLAG_AQ_DEL_VLAN_FILTER; adapter->aq_required &= ~IAVF_FLAG_AQ_DEL_VLAN_FILTER;
...@@ -784,6 +794,8 @@ void iavf_request_stats(struct iavf_adapter *adapter) ...@@ -784,6 +794,8 @@ void iavf_request_stats(struct iavf_adapter *adapter)
/* no error message, this isn't crucial */ /* no error message, this isn't crucial */
return; return;
} }
adapter->aq_required &= ~IAVF_FLAG_AQ_REQUEST_STATS;
adapter->current_op = VIRTCHNL_OP_GET_STATS; adapter->current_op = VIRTCHNL_OP_GET_STATS;
vqs.vsi_id = adapter->vsi_res->vsi_id; vqs.vsi_id = adapter->vsi_res->vsi_id;
/* queue maps are ignored for this message - only the vsi is used */ /* queue maps are ignored for this message - only the vsi is used */
...@@ -1722,8 +1734,37 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter, ...@@ -1722,8 +1734,37 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter,
} }
spin_lock_bh(&adapter->mac_vlan_list_lock); spin_lock_bh(&adapter->mac_vlan_list_lock);
iavf_add_filter(adapter, adapter->hw.mac.addr); iavf_add_filter(adapter, adapter->hw.mac.addr);
if (VLAN_ALLOWED(adapter)) {
if (!list_empty(&adapter->vlan_filter_list)) {
struct iavf_vlan_filter *vlf;
/* re-add all VLAN filters over virtchnl */
list_for_each_entry(vlf,
&adapter->vlan_filter_list,
list)
vlf->add = true;
adapter->aq_required |=
IAVF_FLAG_AQ_ADD_VLAN_FILTER;
}
}
spin_unlock_bh(&adapter->mac_vlan_list_lock); spin_unlock_bh(&adapter->mac_vlan_list_lock);
iavf_process_config(adapter); iavf_process_config(adapter);
/* unlock crit_lock before acquiring rtnl_lock as other
* processes holding rtnl_lock could be waiting for the same
* crit_lock
*/
mutex_unlock(&adapter->crit_lock);
rtnl_lock();
netdev_update_features(adapter->netdev);
rtnl_unlock();
if (iavf_lock_timeout(&adapter->crit_lock, 10000))
dev_warn(&adapter->pdev->dev, "failed to acquire crit_lock in %s\n",
__FUNCTION__);
} }
break; break;
case VIRTCHNL_OP_ENABLE_QUEUES: case VIRTCHNL_OP_ENABLE_QUEUES:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment