aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/mlx4/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/mlx4/main.c')
-rw-r--r--drivers/net/mlx4/main.c122
1 files changed, 118 insertions, 4 deletions
diff --git a/drivers/net/mlx4/main.c b/drivers/net/mlx4/main.c
index 2765a3ce9c24..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;
@@ -1109,6 +1204,9 @@ static int __mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
1109 } 1204 }
1110 } 1205 }
1111 1206
1207 /* Allow large DMA segments, up to the firmware limit of 1 GB */
1208 dma_set_max_seg_size(&pdev->dev, 1024 * 1024 * 1024);
1209
1112 priv = kzalloc(sizeof *priv, GFP_KERNEL); 1210 priv = kzalloc(sizeof *priv, GFP_KERNEL);
1113 if (!priv) { 1211 if (!priv) {
1114 dev_err(&pdev->dev, "Device struct alloc failed, " 1212 dev_err(&pdev->dev, "Device struct alloc failed, "
@@ -1127,6 +1225,11 @@ static int __mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
1127 INIT_LIST_HEAD(&priv->pgdir_list); 1225 INIT_LIST_HEAD(&priv->pgdir_list);
1128 mutex_init(&priv->pgdir_mutex); 1226 mutex_init(&priv->pgdir_mutex);
1129 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
1130 /* 1233 /*
1131 * Now reset the HCA before we touch the PCI capabilities or 1234 * Now reset the HCA before we touch the PCI capabilities or
1132 * attempt a firmware command, since a boot ROM may have left 1235 * attempt a firmware command, since a boot ROM may have left
@@ -1151,8 +1254,15 @@ static int __mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
1151 if (err) 1254 if (err)
1152 goto err_close; 1255 goto err_close;
1153 1256
1257 priv->msix_ctl.pool_bm = 0;
1258 spin_lock_init(&priv->msix_ctl.pool_lock);
1259
1154 mlx4_enable_msi_x(dev); 1260 mlx4_enable_msi_x(dev);
1155 1261
1262 err = mlx4_init_steering(dev);
1263 if (err)
1264 goto err_free_eq;
1265
1156 err = mlx4_setup_hca(dev); 1266 err = mlx4_setup_hca(dev);
1157 if (err == -EBUSY && (dev->flags & MLX4_FLAG_MSI_X)) { 1267 if (err == -EBUSY && (dev->flags & MLX4_FLAG_MSI_X)) {
1158 dev->flags &= ~MLX4_FLAG_MSI_X; 1268 dev->flags &= ~MLX4_FLAG_MSI_X;
@@ -1161,7 +1271,7 @@ static int __mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
1161 } 1271 }
1162 1272
1163 if (err) 1273 if (err)
1164 goto err_free_eq; 1274 goto err_steer;
1165 1275
1166 for (port = 1; port <= dev->caps.num_ports; port++) { 1276 for (port = 1; port <= dev->caps.num_ports; port++) {
1167 err = mlx4_init_port_info(dev, port); 1277 err = mlx4_init_port_info(dev, port);
@@ -1194,6 +1304,9 @@ err_port:
1194 mlx4_cleanup_pd_table(dev); 1304 mlx4_cleanup_pd_table(dev);
1195 mlx4_cleanup_uar_table(dev); 1305 mlx4_cleanup_uar_table(dev);
1196 1306
1307err_steer:
1308 mlx4_clear_steering(dev);
1309
1197err_free_eq: 1310err_free_eq:
1198 mlx4_free_eq_table(dev); 1311 mlx4_free_eq_table(dev);
1199 1312
@@ -1253,6 +1366,7 @@ static void mlx4_remove_one(struct pci_dev *pdev)
1253 iounmap(priv->kar); 1366 iounmap(priv->kar);
1254 mlx4_uar_free(dev, &priv->driver_uar); 1367 mlx4_uar_free(dev, &priv->driver_uar);
1255 mlx4_cleanup_uar_table(dev); 1368 mlx4_cleanup_uar_table(dev);
1369 mlx4_clear_steering(dev);
1256 mlx4_free_eq_table(dev); 1370 mlx4_free_eq_table(dev);
1257 mlx4_close_hca(dev); 1371 mlx4_close_hca(dev);
1258 mlx4_cmd_cleanup(dev); 1372 mlx4_cmd_cleanup(dev);