aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/mlx4/main.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-03-26 00:02:22 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-03-26 00:02:22 -0400
commit00a2470546dd8427325636a711a42c934135dbf5 (patch)
tree9567002c1ae07a918ccf11ec2a72c6e4831cb535 /drivers/net/mlx4/main.c
parent5aafdea448fb86412a6f8e46df518c1545d32436 (diff)
parent6df59a84eccd4cad7fcefda3e0c5e55239a3b2dd (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (56 commits) route: Take the right src and dst addresses in ip_route_newports ipv4: Fix nexthop caching wrt. scoping. ipv4: Invalidate nexthop cache nh_saddr more correctly. net: fix pch_gbe section mismatch warning ipv4: fix fib metrics mlx4_en: Removing HW info from ethtool -i report. net_sched: fix THROTTLED/RUNNING race drivers/net/a2065.c: Convert release_resource to release_region/release_mem_region drivers/net/ariadne.c: Convert release_resource to release_region/release_mem_region bonding: fix rx_handler locking myri10ge: fix rmmod crash mlx4_en: updated driver version to 1.5.4.1 mlx4_en: Using blue flame support mlx4_core: reserve UARs for userspace consumers mlx4_core: maintain available field in bitmap allocator mlx4: Add blue flame support for kernel consumers mlx4_en: Enabling new steering mlx4: Add support for promiscuous mode in the new steering model. mlx4: generalization of multicast steering. mlx4_en: Reporting HW revision in ethtool -i ...
Diffstat (limited to 'drivers/net/mlx4/main.c')
-rw-r--r--drivers/net/mlx4/main.c119
1 files changed, 115 insertions, 4 deletions
diff --git a/drivers/net/mlx4/main.c b/drivers/net/mlx4/main.c
index c83501122d77..62fa7eec5f0c 100644
--- a/drivers/net/mlx4/main.c
+++ b/drivers/net/mlx4/main.c
@@ -39,6 +39,7 @@
39#include <linux/pci.h> 39#include <linux/pci.h>
40#include <linux/dma-mapping.h> 40#include <linux/dma-mapping.h>
41#include <linux/slab.h> 41#include <linux/slab.h>
42#include <linux/io-mapping.h>
42 43
43#include <linux/mlx4/device.h> 44#include <linux/mlx4/device.h>
44#include <linux/mlx4/doorbell.h> 45#include <linux/mlx4/doorbell.h>
@@ -227,6 +228,9 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
227 dev->caps.stat_rate_support = dev_cap->stat_rate_support; 228 dev->caps.stat_rate_support = dev_cap->stat_rate_support;
228 dev->caps.udp_rss = dev_cap->udp_rss; 229 dev->caps.udp_rss = dev_cap->udp_rss;
229 dev->caps.loopback_support = dev_cap->loopback_support; 230 dev->caps.loopback_support = dev_cap->loopback_support;
231 dev->caps.vep_uc_steering = dev_cap->vep_uc_steering;
232 dev->caps.vep_mc_steering = dev_cap->vep_mc_steering;
233 dev->caps.wol = dev_cap->wol;
230 dev->caps.max_gso_sz = dev_cap->max_gso_sz; 234 dev->caps.max_gso_sz = dev_cap->max_gso_sz;
231 235
232 dev->caps.log_num_macs = log_num_mac; 236 dev->caps.log_num_macs = log_num_mac;
@@ -718,8 +722,31 @@ static void mlx4_free_icms(struct mlx4_dev *dev)
718 mlx4_free_icm(dev, priv->fw.aux_icm, 0); 722 mlx4_free_icm(dev, priv->fw.aux_icm, 0);
719} 723}
720 724
725static int map_bf_area(struct mlx4_dev *dev)
726{
727 struct mlx4_priv *priv = mlx4_priv(dev);
728 resource_size_t bf_start;
729 resource_size_t bf_len;
730 int err = 0;
731
732 bf_start = pci_resource_start(dev->pdev, 2) + (dev->caps.num_uars << PAGE_SHIFT);
733 bf_len = pci_resource_len(dev->pdev, 2) - (dev->caps.num_uars << PAGE_SHIFT);
734 priv->bf_mapping = io_mapping_create_wc(bf_start, bf_len);
735 if (!priv->bf_mapping)
736 err = -ENOMEM;
737
738 return err;
739}
740
741static void unmap_bf_area(struct mlx4_dev *dev)
742{
743 if (mlx4_priv(dev)->bf_mapping)
744 io_mapping_free(mlx4_priv(dev)->bf_mapping);
745}
746
721static void mlx4_close_hca(struct mlx4_dev *dev) 747static void mlx4_close_hca(struct mlx4_dev *dev)
722{ 748{
749 unmap_bf_area(dev);
723 mlx4_CLOSE_HCA(dev, 0); 750 mlx4_CLOSE_HCA(dev, 0);
724 mlx4_free_icms(dev); 751 mlx4_free_icms(dev);
725 mlx4_UNMAP_FA(dev); 752 mlx4_UNMAP_FA(dev);
@@ -772,6 +799,9 @@ static int mlx4_init_hca(struct mlx4_dev *dev)
772 goto err_stop_fw; 799 goto err_stop_fw;
773 } 800 }
774 801
802 if (map_bf_area(dev))
803 mlx4_dbg(dev, "Failed to map blue flame area\n");
804
775 init_hca.log_uar_sz = ilog2(dev->caps.num_uars); 805 init_hca.log_uar_sz = ilog2(dev->caps.num_uars);
776 806
777 err = mlx4_init_icm(dev, &dev_cap, &init_hca, icm_size); 807 err = mlx4_init_icm(dev, &dev_cap, &init_hca, icm_size);
@@ -802,6 +832,7 @@ err_free_icm:
802 mlx4_free_icms(dev); 832 mlx4_free_icms(dev);
803 833
804err_stop_fw: 834err_stop_fw:
835 unmap_bf_area(dev);
805 mlx4_UNMAP_FA(dev); 836 mlx4_UNMAP_FA(dev);
806 mlx4_free_icm(dev, priv->fw.fw_icm, 0); 837 mlx4_free_icm(dev, priv->fw.fw_icm, 0);
807 838
@@ -969,13 +1000,15 @@ static void mlx4_enable_msi_x(struct mlx4_dev *dev)
969{ 1000{
970 struct mlx4_priv *priv = mlx4_priv(dev); 1001 struct mlx4_priv *priv = mlx4_priv(dev);
971 struct msix_entry *entries; 1002 struct msix_entry *entries;
972 int nreq; 1003 int nreq = min_t(int, dev->caps.num_ports *
1004 min_t(int, num_online_cpus() + 1, MAX_MSIX_P_PORT)
1005 + MSIX_LEGACY_SZ, MAX_MSIX);
973 int err; 1006 int err;
974 int i; 1007 int i;
975 1008
976 if (msi_x) { 1009 if (msi_x) {
977 nreq = min_t(int, dev->caps.num_eqs - dev->caps.reserved_eqs, 1010 nreq = min_t(int, dev->caps.num_eqs - dev->caps.reserved_eqs,
978 num_possible_cpus() + 1); 1011 nreq);
979 entries = kcalloc(nreq, sizeof *entries, GFP_KERNEL); 1012 entries = kcalloc(nreq, sizeof *entries, GFP_KERNEL);
980 if (!entries) 1013 if (!entries)
981 goto no_msi; 1014 goto no_msi;
@@ -998,7 +1031,15 @@ static void mlx4_enable_msi_x(struct mlx4_dev *dev)
998 goto no_msi; 1031 goto no_msi;
999 } 1032 }
1000 1033
1001 dev->caps.num_comp_vectors = nreq - 1; 1034 if (nreq <
1035 MSIX_LEGACY_SZ + dev->caps.num_ports * MIN_MSIX_P_PORT) {
1036 /*Working in legacy mode , all EQ's shared*/
1037 dev->caps.comp_pool = 0;
1038 dev->caps.num_comp_vectors = nreq - 1;
1039 } else {
1040 dev->caps.comp_pool = nreq - MSIX_LEGACY_SZ;
1041 dev->caps.num_comp_vectors = MSIX_LEGACY_SZ - 1;
1042 }
1002 for (i = 0; i < nreq; ++i) 1043 for (i = 0; i < nreq; ++i)
1003 priv->eq_table.eq[i].irq = entries[i].vector; 1044 priv->eq_table.eq[i].irq = entries[i].vector;
1004 1045
@@ -1010,6 +1051,7 @@ static void mlx4_enable_msi_x(struct mlx4_dev *dev)
1010 1051
1011no_msi: 1052no_msi:
1012 dev->caps.num_comp_vectors = 1; 1053 dev->caps.num_comp_vectors = 1;
1054 dev->caps.comp_pool = 0;
1013 1055
1014 for (i = 0; i < 2; ++i) 1056 for (i = 0; i < 2; ++i)
1015 priv->eq_table.eq[i].irq = dev->pdev->irq; 1057 priv->eq_table.eq[i].irq = dev->pdev->irq;
@@ -1049,6 +1091,59 @@ static void mlx4_cleanup_port_info(struct mlx4_port_info *info)
1049 device_remove_file(&info->dev->pdev->dev, &info->port_attr); 1091 device_remove_file(&info->dev->pdev->dev, &info->port_attr);
1050} 1092}
1051 1093
1094static int mlx4_init_steering(struct mlx4_dev *dev)
1095{
1096 struct mlx4_priv *priv = mlx4_priv(dev);
1097 int num_entries = dev->caps.num_ports;
1098 int i, j;
1099
1100 priv->steer = kzalloc(sizeof(struct mlx4_steer) * num_entries, GFP_KERNEL);
1101 if (!priv->steer)
1102 return -ENOMEM;
1103
1104 for (i = 0; i < num_entries; i++) {
1105 for (j = 0; j < MLX4_NUM_STEERS; j++) {
1106 INIT_LIST_HEAD(&priv->steer[i].promisc_qps[j]);
1107 INIT_LIST_HEAD(&priv->steer[i].steer_entries[j]);
1108 }
1109 INIT_LIST_HEAD(&priv->steer[i].high_prios);
1110 }
1111 return 0;
1112}
1113
1114static void mlx4_clear_steering(struct mlx4_dev *dev)
1115{
1116 struct mlx4_priv *priv = mlx4_priv(dev);
1117 struct mlx4_steer_index *entry, *tmp_entry;
1118 struct mlx4_promisc_qp *pqp, *tmp_pqp;
1119 int num_entries = dev->caps.num_ports;
1120 int i, j;
1121
1122 for (i = 0; i < num_entries; i++) {
1123 for (j = 0; j < MLX4_NUM_STEERS; j++) {
1124 list_for_each_entry_safe(pqp, tmp_pqp,
1125 &priv->steer[i].promisc_qps[j],
1126 list) {
1127 list_del(&pqp->list);
1128 kfree(pqp);
1129 }
1130 list_for_each_entry_safe(entry, tmp_entry,
1131 &priv->steer[i].steer_entries[j],
1132 list) {
1133 list_del(&entry->list);
1134 list_for_each_entry_safe(pqp, tmp_pqp,
1135 &entry->duplicates,
1136 list) {
1137 list_del(&pqp->list);
1138 kfree(pqp);
1139 }
1140 kfree(entry);
1141 }
1142 }
1143 }
1144 kfree(priv->steer);
1145}
1146
1052static int __mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id) 1147static int __mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
1053{ 1148{
1054 struct mlx4_priv *priv; 1149 struct mlx4_priv *priv;
@@ -1130,6 +1225,11 @@ static int __mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
1130 INIT_LIST_HEAD(&priv->pgdir_list); 1225 INIT_LIST_HEAD(&priv->pgdir_list);
1131 mutex_init(&priv->pgdir_mutex); 1226 mutex_init(&priv->pgdir_mutex);
1132 1227
1228 pci_read_config_byte(pdev, PCI_REVISION_ID, &dev->rev_id);
1229
1230 INIT_LIST_HEAD(&priv->bf_list);
1231 mutex_init(&priv->bf_mutex);
1232
1133 /* 1233 /*
1134 * Now reset the HCA before we touch the PCI capabilities or 1234 * Now reset the HCA before we touch the PCI capabilities or
1135 * attempt a firmware command, since a boot ROM may have left 1235 * attempt a firmware command, since a boot ROM may have left
@@ -1154,8 +1254,15 @@ static int __mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
1154 if (err) 1254 if (err)
1155 goto err_close; 1255 goto err_close;
1156 1256
1257 priv->msix_ctl.pool_bm = 0;
1258 spin_lock_init(&priv->msix_ctl.pool_lock);
1259
1157 mlx4_enable_msi_x(dev); 1260 mlx4_enable_msi_x(dev);
1158 1261
1262 err = mlx4_init_steering(dev);
1263 if (err)
1264 goto err_free_eq;
1265
1159 err = mlx4_setup_hca(dev); 1266 err = mlx4_setup_hca(dev);
1160 if (err == -EBUSY && (dev->flags & MLX4_FLAG_MSI_X)) { 1267 if (err == -EBUSY && (dev->flags & MLX4_FLAG_MSI_X)) {
1161 dev->flags &= ~MLX4_FLAG_MSI_X; 1268 dev->flags &= ~MLX4_FLAG_MSI_X;
@@ -1164,7 +1271,7 @@ static int __mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
1164 } 1271 }
1165 1272
1166 if (err) 1273 if (err)
1167 goto err_free_eq; 1274 goto err_steer;
1168 1275
1169 for (port = 1; port <= dev->caps.num_ports; port++) { 1276 for (port = 1; port <= dev->caps.num_ports; port++) {
1170 err = mlx4_init_port_info(dev, port); 1277 err = mlx4_init_port_info(dev, port);
@@ -1197,6 +1304,9 @@ err_port:
1197 mlx4_cleanup_pd_table(dev); 1304 mlx4_cleanup_pd_table(dev);
1198 mlx4_cleanup_uar_table(dev); 1305 mlx4_cleanup_uar_table(dev);
1199 1306
1307err_steer:
1308 mlx4_clear_steering(dev);
1309
1200err_free_eq: 1310err_free_eq:
1201 mlx4_free_eq_table(dev); 1311 mlx4_free_eq_table(dev);
1202 1312
@@ -1256,6 +1366,7 @@ static void mlx4_remove_one(struct pci_dev *pdev)
1256 iounmap(priv->kar); 1366 iounmap(priv->kar);
1257 mlx4_uar_free(dev, &priv->driver_uar); 1367 mlx4_uar_free(dev, &priv->driver_uar);
1258 mlx4_cleanup_uar_table(dev); 1368 mlx4_cleanup_uar_table(dev);
1369 mlx4_clear_steering(dev);
1259 mlx4_free_eq_table(dev); 1370 mlx4_free_eq_table(dev);
1260 mlx4_close_hca(dev); 1371 mlx4_close_hca(dev);
1261 mlx4_cmd_cleanup(dev); 1372 mlx4_cmd_cleanup(dev);