aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/mellanox/mlx4
diff options
context:
space:
mode:
authorHadar Hen Zion <hadarh@mellanox.com>2013-01-30 18:07:08 -0500
committerDavid S. Miller <davem@davemloft.net>2013-01-31 12:48:47 -0500
commit0d256c0e93916f416f46d2ec235ea05fca202ede (patch)
tree64c3883ddcdce138d7371e5af98d081c3a7197e6 /drivers/net/ethernet/mellanox/mlx4
parent280fce1e3ef85ff7f90a9d7e8c8a0d71bbf5a9a4 (diff)
net/mlx4_en: Fix ethtool rules leftovers after module unloaded
As part of the driver unload flow, all steering rules must be deleted, make sure to remove the rules that were set through ethtool. Signed-off-by: Hadar Hen Zion <hadarh@mellanox.com> Signed-off-by: Amir Vadai <amirv@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/mellanox/mlx4')
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_ethtool.c3
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_netdev.c15
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mlx4_en.h3
3 files changed, 21 insertions, 0 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
index 6f8044daec42..738e95d43ccb 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
@@ -915,6 +915,7 @@ static int mlx4_en_flow_replace(struct net_device *dev,
915 loc_rule->id = 0; 915 loc_rule->id = 0;
916 memset(&loc_rule->flow_spec, 0, 916 memset(&loc_rule->flow_spec, 0,
917 sizeof(struct ethtool_rx_flow_spec)); 917 sizeof(struct ethtool_rx_flow_spec));
918 list_del(&loc_rule->list);
918 } 919 }
919 err = mlx4_flow_attach(priv->mdev->dev, &rule, &reg_id); 920 err = mlx4_flow_attach(priv->mdev->dev, &rule, &reg_id);
920 if (err) { 921 if (err) {
@@ -925,6 +926,7 @@ static int mlx4_en_flow_replace(struct net_device *dev,
925 loc_rule->id = reg_id; 926 loc_rule->id = reg_id;
926 memcpy(&loc_rule->flow_spec, &cmd->fs, 927 memcpy(&loc_rule->flow_spec, &cmd->fs,
927 sizeof(struct ethtool_rx_flow_spec)); 928 sizeof(struct ethtool_rx_flow_spec));
929 list_add_tail(&loc_rule->list, &priv->ethtool_list);
928 930
929out_free_list: 931out_free_list:
930 list_for_each_entry_safe(spec, tmp_spec, &rule.list, list) { 932 list_for_each_entry_safe(spec, tmp_spec, &rule.list, list) {
@@ -958,6 +960,7 @@ static int mlx4_en_flow_detach(struct net_device *dev,
958 } 960 }
959 rule->id = 0; 961 rule->id = 0;
960 memset(&rule->flow_spec, 0, sizeof(struct ethtool_rx_flow_spec)); 962 memset(&rule->flow_spec, 0, sizeof(struct ethtool_rx_flow_spec));
963 list_del(&rule->list);
961out: 964out:
962 return err; 965 return err;
963 966
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
index 9c42812d2f6b..333a7a0b833c 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
@@ -1039,6 +1039,9 @@ int mlx4_en_start_port(struct net_device *dev)
1039 1039
1040 INIT_LIST_HEAD(&priv->mc_list); 1040 INIT_LIST_HEAD(&priv->mc_list);
1041 INIT_LIST_HEAD(&priv->curr_list); 1041 INIT_LIST_HEAD(&priv->curr_list);
1042 INIT_LIST_HEAD(&priv->ethtool_list);
1043 memset(&priv->ethtool_rules[0], 0,
1044 sizeof(struct ethtool_flow_id) * MAX_NUM_OF_FS_RULES);
1042 1045
1043 /* Calculate Rx buf size */ 1046 /* Calculate Rx buf size */
1044 dev->mtu = min(dev->mtu, priv->max_mtu); 1047 dev->mtu = min(dev->mtu, priv->max_mtu);
@@ -1202,6 +1205,7 @@ void mlx4_en_stop_port(struct net_device *dev)
1202 struct mlx4_en_priv *priv = netdev_priv(dev); 1205 struct mlx4_en_priv *priv = netdev_priv(dev);
1203 struct mlx4_en_dev *mdev = priv->mdev; 1206 struct mlx4_en_dev *mdev = priv->mdev;
1204 struct mlx4_en_mc_list *mclist, *tmp; 1207 struct mlx4_en_mc_list *mclist, *tmp;
1208 struct ethtool_flow_id *flow, *tmp_flow;
1205 int i; 1209 int i;
1206 u8 mc_list[16] = {0}; 1210 u8 mc_list[16] = {0};
1207 1211
@@ -1283,6 +1287,17 @@ void mlx4_en_stop_port(struct net_device *dev)
1283 mlx4_put_eth_qp(mdev->dev, priv->port, priv->mac, priv->base_qpn); 1287 mlx4_put_eth_qp(mdev->dev, priv->port, priv->mac, priv->base_qpn);
1284 mdev->mac_removed[priv->port] = 1; 1288 mdev->mac_removed[priv->port] = 1;
1285 1289
1290 /* Remove flow steering rules for the port*/
1291 if (mdev->dev->caps.steering_mode ==
1292 MLX4_STEERING_MODE_DEVICE_MANAGED) {
1293 ASSERT_RTNL();
1294 list_for_each_entry_safe(flow, tmp_flow,
1295 &priv->ethtool_list, list) {
1296 mlx4_flow_detach(mdev->dev, flow->id);
1297 list_del(&flow->list);
1298 }
1299 }
1300
1286 /* Free RX Rings */ 1301 /* Free RX Rings */
1287 for (i = 0; i < priv->rx_ring_num; i++) { 1302 for (i = 0; i < priv->rx_ring_num; i++) {
1288 mlx4_en_deactivate_rx_ring(priv, &priv->rx_ring[i]); 1303 mlx4_en_deactivate_rx_ring(priv, &priv->rx_ring[i]);
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
index 8d54412ada63..4fb4a3e3ae8b 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
@@ -427,6 +427,7 @@ struct mlx4_en_frag_info {
427#endif 427#endif
428 428
429struct ethtool_flow_id { 429struct ethtool_flow_id {
430 struct list_head list;
430 struct ethtool_rx_flow_spec flow_spec; 431 struct ethtool_rx_flow_spec flow_spec;
431 u64 id; 432 u64 id;
432}; 433};
@@ -441,6 +442,8 @@ struct mlx4_en_priv {
441 struct mlx4_en_port_state port_state; 442 struct mlx4_en_port_state port_state;
442 spinlock_t stats_lock; 443 spinlock_t stats_lock;
443 struct ethtool_flow_id ethtool_rules[MAX_NUM_OF_FS_RULES]; 444 struct ethtool_flow_id ethtool_rules[MAX_NUM_OF_FS_RULES];
445 /* To allow rules removal while port is going down */
446 struct list_head ethtool_list;
444 447
445 unsigned long last_moder_packets[MAX_RX_RINGS]; 448 unsigned long last_moder_packets[MAX_RX_RINGS];
446 unsigned long last_moder_tx_packets; 449 unsigned long last_moder_tx_packets;