aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/mlx4/main.c
diff options
context:
space:
mode:
authorYevgeny Petrilin <yevgenyp@mellanox.co.il>2011-03-22 18:38:24 -0400
committerDavid S. Miller <davem@davemloft.net>2011-03-23 15:24:22 -0400
commitb12d93d63c3217f0ec923ff938b12a744e242ffa (patch)
treebecc9b94ecf1f9d664c0e137c54383786a27be45 /drivers/net/mlx4/main.c
parent0345584e0b8be3735a950d17c7e463db20c6ce27 (diff)
mlx4: Add support for promiscuous mode in the new steering model.
For Ethernet mode only, When we want to register QP as promiscuous, it must be added to all the existing steering entries and also to the default one. The promiscuous QP might also be on of "real" QPs, which means we need to monitor every entry to avoid duplicates and ensure we close an entry when all it has is promiscuous QPs. Same mechanism both for unicast and multicast. Signed-off-by: Yevgeny Petrilin <yevgenyp@mellanox.co.il> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/mlx4/main.c')
-rw-r--r--drivers/net/mlx4/main.c63
1 files changed, 62 insertions, 1 deletions
diff --git a/drivers/net/mlx4/main.c b/drivers/net/mlx4/main.c
index da0da281d830..c8e276138f81 100644
--- a/drivers/net/mlx4/main.c
+++ b/drivers/net/mlx4/main.c
@@ -1063,6 +1063,59 @@ static void mlx4_cleanup_port_info(struct mlx4_port_info *info)
1063 device_remove_file(&info->dev->pdev->dev, &info->port_attr); 1063 device_remove_file(&info->dev->pdev->dev, &info->port_attr);
1064} 1064}
1065 1065
1066static int mlx4_init_steering(struct mlx4_dev *dev)
1067{
1068 struct mlx4_priv *priv = mlx4_priv(dev);
1069 int num_entries = dev->caps.num_ports;
1070 int i, j;
1071
1072 priv->steer = kzalloc(sizeof(struct mlx4_steer) * num_entries, GFP_KERNEL);
1073 if (!priv->steer)
1074 return -ENOMEM;
1075
1076 for (i = 0; i < num_entries; i++) {
1077 for (j = 0; j < MLX4_NUM_STEERS; j++) {
1078 INIT_LIST_HEAD(&priv->steer[i].promisc_qps[j]);
1079 INIT_LIST_HEAD(&priv->steer[i].steer_entries[j]);
1080 }
1081 INIT_LIST_HEAD(&priv->steer[i].high_prios);
1082 }
1083 return 0;
1084}
1085
1086static void mlx4_clear_steering(struct mlx4_dev *dev)
1087{
1088 struct mlx4_priv *priv = mlx4_priv(dev);
1089 struct mlx4_steer_index *entry, *tmp_entry;
1090 struct mlx4_promisc_qp *pqp, *tmp_pqp;
1091 int num_entries = dev->caps.num_ports;
1092 int i, j;
1093
1094 for (i = 0; i < num_entries; i++) {
1095 for (j = 0; j < MLX4_NUM_STEERS; j++) {
1096 list_for_each_entry_safe(pqp, tmp_pqp,
1097 &priv->steer[i].promisc_qps[j],
1098 list) {
1099 list_del(&pqp->list);
1100 kfree(pqp);
1101 }
1102 list_for_each_entry_safe(entry, tmp_entry,
1103 &priv->steer[i].steer_entries[j],
1104 list) {
1105 list_del(&entry->list);
1106 list_for_each_entry_safe(pqp, tmp_pqp,
1107 &entry->duplicates,
1108 list) {
1109 list_del(&pqp->list);
1110 kfree(pqp);
1111 }
1112 kfree(entry);
1113 }
1114 }
1115 }
1116 kfree(priv->steer);
1117}
1118
1066static int __mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id) 1119static int __mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
1067{ 1120{
1068 struct mlx4_priv *priv; 1121 struct mlx4_priv *priv;
@@ -1172,6 +1225,10 @@ static int __mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
1172 1225
1173 mlx4_enable_msi_x(dev); 1226 mlx4_enable_msi_x(dev);
1174 1227
1228 err = mlx4_init_steering(dev);
1229 if (err)
1230 goto err_free_eq;
1231
1175 err = mlx4_setup_hca(dev); 1232 err = mlx4_setup_hca(dev);
1176 if (err == -EBUSY && (dev->flags & MLX4_FLAG_MSI_X)) { 1233 if (err == -EBUSY && (dev->flags & MLX4_FLAG_MSI_X)) {
1177 dev->flags &= ~MLX4_FLAG_MSI_X; 1234 dev->flags &= ~MLX4_FLAG_MSI_X;
@@ -1180,7 +1237,7 @@ static int __mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
1180 } 1237 }
1181 1238
1182 if (err) 1239 if (err)
1183 goto err_free_eq; 1240 goto err_steer;
1184 1241
1185 for (port = 1; port <= dev->caps.num_ports; port++) { 1242 for (port = 1; port <= dev->caps.num_ports; port++) {
1186 err = mlx4_init_port_info(dev, port); 1243 err = mlx4_init_port_info(dev, port);
@@ -1213,6 +1270,9 @@ err_port:
1213 mlx4_cleanup_pd_table(dev); 1270 mlx4_cleanup_pd_table(dev);
1214 mlx4_cleanup_uar_table(dev); 1271 mlx4_cleanup_uar_table(dev);
1215 1272
1273err_steer:
1274 mlx4_clear_steering(dev);
1275
1216err_free_eq: 1276err_free_eq:
1217 mlx4_free_eq_table(dev); 1277 mlx4_free_eq_table(dev);
1218 1278
@@ -1272,6 +1332,7 @@ static void mlx4_remove_one(struct pci_dev *pdev)
1272 iounmap(priv->kar); 1332 iounmap(priv->kar);
1273 mlx4_uar_free(dev, &priv->driver_uar); 1333 mlx4_uar_free(dev, &priv->driver_uar);
1274 mlx4_cleanup_uar_table(dev); 1334 mlx4_cleanup_uar_table(dev);
1335 mlx4_clear_steering(dev);
1275 mlx4_free_eq_table(dev); 1336 mlx4_free_eq_table(dev);
1276 mlx4_close_hca(dev); 1337 mlx4_close_hca(dev);
1277 mlx4_cmd_cleanup(dev); 1338 mlx4_cmd_cleanup(dev);