|
@@ -5012,24 +5012,23 @@ fwd_queue_err:
|
|
|
return err;
|
|
|
}
|
|
|
|
|
|
-static void ixgbe_configure_dfwd(struct ixgbe_adapter *adapter)
|
|
|
+static int ixgbe_upper_dev_walk(struct net_device *upper, void *data)
|
|
|
{
|
|
|
- struct net_device *upper;
|
|
|
- struct list_head *iter;
|
|
|
- int err;
|
|
|
-
|
|
|
- netdev_for_each_all_upper_dev_rcu(adapter->netdev, upper, iter) {
|
|
|
- if (netif_is_macvlan(upper)) {
|
|
|
- struct macvlan_dev *dfwd = netdev_priv(upper);
|
|
|
- struct ixgbe_fwd_adapter *vadapter = dfwd->fwd_priv;
|
|
|
+ if (netif_is_macvlan(upper)) {
|
|
|
+ struct macvlan_dev *dfwd = netdev_priv(upper);
|
|
|
+ struct ixgbe_fwd_adapter *vadapter = dfwd->fwd_priv;
|
|
|
|
|
|
- if (dfwd->fwd_priv) {
|
|
|
- err = ixgbe_fwd_ring_up(upper, vadapter);
|
|
|
- if (err)
|
|
|
- continue;
|
|
|
- }
|
|
|
- }
|
|
|
+ if (dfwd->fwd_priv)
|
|
|
+ ixgbe_fwd_ring_up(upper, vadapter);
|
|
|
}
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static void ixgbe_configure_dfwd(struct ixgbe_adapter *adapter)
|
|
|
+{
|
|
|
+ netdev_walk_all_upper_dev_rcu(adapter->netdev,
|
|
|
+ ixgbe_upper_dev_walk, NULL);
|
|
|
}
|
|
|
|
|
|
static void ixgbe_configure(struct ixgbe_adapter *adapter)
|
|
@@ -5448,12 +5447,25 @@ static void ixgbe_fdir_filter_exit(struct ixgbe_adapter *adapter)
|
|
|
spin_unlock(&adapter->fdir_perfect_lock);
|
|
|
}
|
|
|
|
|
|
+static int ixgbe_disable_macvlan(struct net_device *upper, void *data)
|
|
|
+{
|
|
|
+ if (netif_is_macvlan(upper)) {
|
|
|
+ struct macvlan_dev *vlan = netdev_priv(upper);
|
|
|
+
|
|
|
+ if (vlan->fwd_priv) {
|
|
|
+ netif_tx_stop_all_queues(upper);
|
|
|
+ netif_carrier_off(upper);
|
|
|
+ netif_tx_disable(upper);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
void ixgbe_down(struct ixgbe_adapter *adapter)
|
|
|
{
|
|
|
struct net_device *netdev = adapter->netdev;
|
|
|
struct ixgbe_hw *hw = &adapter->hw;
|
|
|
- struct net_device *upper;
|
|
|
- struct list_head *iter;
|
|
|
int i;
|
|
|
|
|
|
/* signal that we are down to the interrupt handler */
|
|
@@ -5477,17 +5489,8 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
|
|
|
netif_tx_disable(netdev);
|
|
|
|
|
|
/* disable any upper devices */
|
|
|
- netdev_for_each_all_upper_dev_rcu(adapter->netdev, upper, iter) {
|
|
|
- if (netif_is_macvlan(upper)) {
|
|
|
- struct macvlan_dev *vlan = netdev_priv(upper);
|
|
|
-
|
|
|
- if (vlan->fwd_priv) {
|
|
|
- netif_tx_stop_all_queues(upper);
|
|
|
- netif_carrier_off(upper);
|
|
|
- netif_tx_disable(upper);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
+ netdev_walk_all_upper_dev_rcu(adapter->netdev,
|
|
|
+ ixgbe_disable_macvlan, NULL);
|
|
|
|
|
|
ixgbe_irq_disable(adapter);
|
|
|
|
|
@@ -6723,6 +6726,18 @@ static void ixgbe_update_default_up(struct ixgbe_adapter *adapter)
|
|
|
#endif
|
|
|
}
|
|
|
|
|
|
+static int ixgbe_enable_macvlan(struct net_device *upper, void *data)
|
|
|
+{
|
|
|
+ if (netif_is_macvlan(upper)) {
|
|
|
+ struct macvlan_dev *vlan = netdev_priv(upper);
|
|
|
+
|
|
|
+ if (vlan->fwd_priv)
|
|
|
+ netif_tx_wake_all_queues(upper);
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* ixgbe_watchdog_link_is_up - update netif_carrier status and
|
|
|
* print link up message
|
|
@@ -6732,8 +6747,6 @@ static void ixgbe_watchdog_link_is_up(struct ixgbe_adapter *adapter)
|
|
|
{
|
|
|
struct net_device *netdev = adapter->netdev;
|
|
|
struct ixgbe_hw *hw = &adapter->hw;
|
|
|
- struct net_device *upper;
|
|
|
- struct list_head *iter;
|
|
|
u32 link_speed = adapter->link_speed;
|
|
|
const char *speed_str;
|
|
|
bool flow_rx, flow_tx;
|
|
@@ -6804,14 +6817,8 @@ static void ixgbe_watchdog_link_is_up(struct ixgbe_adapter *adapter)
|
|
|
|
|
|
/* enable any upper devices */
|
|
|
rtnl_lock();
|
|
|
- netdev_for_each_all_upper_dev_rcu(adapter->netdev, upper, iter) {
|
|
|
- if (netif_is_macvlan(upper)) {
|
|
|
- struct macvlan_dev *vlan = netdev_priv(upper);
|
|
|
-
|
|
|
- if (vlan->fwd_priv)
|
|
|
- netif_tx_wake_all_queues(upper);
|
|
|
- }
|
|
|
- }
|
|
|
+ netdev_walk_all_upper_dev_rcu(adapter->netdev,
|
|
|
+ ixgbe_enable_macvlan, NULL);
|
|
|
rtnl_unlock();
|
|
|
|
|
|
/* update the default user priority for VFs */
|
|
@@ -8345,12 +8352,38 @@ static int ixgbe_configure_clsu32_del_hnode(struct ixgbe_adapter *adapter,
|
|
|
}
|
|
|
|
|
|
#ifdef CONFIG_NET_CLS_ACT
|
|
|
+struct upper_walk_data {
|
|
|
+ struct ixgbe_adapter *adapter;
|
|
|
+ u64 action;
|
|
|
+ int ifindex;
|
|
|
+ u8 queue;
|
|
|
+};
|
|
|
+
|
|
|
+static int get_macvlan_queue(struct net_device *upper, void *_data)
|
|
|
+{
|
|
|
+ if (netif_is_macvlan(upper)) {
|
|
|
+ struct macvlan_dev *dfwd = netdev_priv(upper);
|
|
|
+ struct ixgbe_fwd_adapter *vadapter = dfwd->fwd_priv;
|
|
|
+ struct upper_walk_data *data = _data;
|
|
|
+ struct ixgbe_adapter *adapter = data->adapter;
|
|
|
+ int ifindex = data->ifindex;
|
|
|
+
|
|
|
+ if (vadapter && vadapter->netdev->ifindex == ifindex) {
|
|
|
+ data->queue = adapter->rx_ring[vadapter->rx_base_queue]->reg_idx;
|
|
|
+ data->action = data->queue;
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
static int handle_redirect_action(struct ixgbe_adapter *adapter, int ifindex,
|
|
|
u8 *queue, u64 *action)
|
|
|
{
|
|
|
unsigned int num_vfs = adapter->num_vfs, vf;
|
|
|
+ struct upper_walk_data data;
|
|
|
struct net_device *upper;
|
|
|
- struct list_head *iter;
|
|
|
|
|
|
/* redirect to a SRIOV VF */
|
|
|
for (vf = 0; vf < num_vfs; ++vf) {
|
|
@@ -8368,17 +8401,16 @@ static int handle_redirect_action(struct ixgbe_adapter *adapter, int ifindex,
|
|
|
}
|
|
|
|
|
|
/* redirect to a offloaded macvlan netdev */
|
|
|
- netdev_for_each_all_upper_dev_rcu(adapter->netdev, upper, iter) {
|
|
|
- if (netif_is_macvlan(upper)) {
|
|
|
- struct macvlan_dev *dfwd = netdev_priv(upper);
|
|
|
- struct ixgbe_fwd_adapter *vadapter = dfwd->fwd_priv;
|
|
|
-
|
|
|
- if (vadapter && vadapter->netdev->ifindex == ifindex) {
|
|
|
- *queue = adapter->rx_ring[vadapter->rx_base_queue]->reg_idx;
|
|
|
- *action = *queue;
|
|
|
- return 0;
|
|
|
- }
|
|
|
- }
|
|
|
+ data.adapter = adapter;
|
|
|
+ data.ifindex = ifindex;
|
|
|
+ data.action = 0;
|
|
|
+ data.queue = 0;
|
|
|
+ if (netdev_walk_all_upper_dev_rcu(adapter->netdev,
|
|
|
+ get_macvlan_queue, &data)) {
|
|
|
+ *action = data.action;
|
|
|
+ *queue = data.queue;
|
|
|
+
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
return -EINVAL;
|