diff options
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/cmd.c | 170 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/fw.c | 68 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/fw.h | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/main.c | 842 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/mlx4.h | 6 | ||||
-rw-r--r-- | include/linux/mlx4/cmd.h | 2 | ||||
-rw-r--r-- | include/linux/mlx4/device.h | 1 |
7 files changed, 934 insertions, 157 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/cmd.c b/drivers/net/ethernet/mellanox/mlx4/cmd.c index 8e6e4b20b0e..c4fef839168 100644 --- a/drivers/net/ethernet/mellanox/mlx4/cmd.c +++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c | |||
@@ -257,7 +257,7 @@ out: | |||
257 | return err; | 257 | return err; |
258 | } | 258 | } |
259 | 259 | ||
260 | static int mlx4_comm_cmd(struct mlx4_dev *dev, u8 cmd, u16 param, | 260 | int mlx4_comm_cmd(struct mlx4_dev *dev, u8 cmd, u16 param, |
261 | unsigned long timeout) | 261 | unsigned long timeout) |
262 | { | 262 | { |
263 | if (mlx4_priv(dev)->cmd.use_events) | 263 | if (mlx4_priv(dev)->cmd.use_events) |
@@ -1390,6 +1390,153 @@ void mlx4_master_comm_channel(struct work_struct *work) | |||
1390 | mlx4_warn(dev, "Failed to arm comm channel events\n"); | 1390 | mlx4_warn(dev, "Failed to arm comm channel events\n"); |
1391 | } | 1391 | } |
1392 | 1392 | ||
1393 | static int sync_toggles(struct mlx4_dev *dev) | ||
1394 | { | ||
1395 | struct mlx4_priv *priv = mlx4_priv(dev); | ||
1396 | int wr_toggle; | ||
1397 | int rd_toggle; | ||
1398 | unsigned long end; | ||
1399 | |||
1400 | wr_toggle = swab32(readl(&priv->mfunc.comm->slave_write)) >> 31; | ||
1401 | end = jiffies + msecs_to_jiffies(5000); | ||
1402 | |||
1403 | while (time_before(jiffies, end)) { | ||
1404 | rd_toggle = swab32(readl(&priv->mfunc.comm->slave_read)) >> 31; | ||
1405 | if (rd_toggle == wr_toggle) { | ||
1406 | priv->cmd.comm_toggle = rd_toggle; | ||
1407 | return 0; | ||
1408 | } | ||
1409 | |||
1410 | cond_resched(); | ||
1411 | } | ||
1412 | |||
1413 | /* | ||
1414 | * we could reach here if for example the previous VM using this | ||
1415 | * function misbehaved and left the channel with unsynced state. We | ||
1416 | * should fix this here and give this VM a chance to use a properly | ||
1417 | * synced channel | ||
1418 | */ | ||
1419 | mlx4_warn(dev, "recovering from previously mis-behaved VM\n"); | ||
1420 | __raw_writel((__force u32) 0, &priv->mfunc.comm->slave_read); | ||
1421 | __raw_writel((__force u32) 0, &priv->mfunc.comm->slave_write); | ||
1422 | priv->cmd.comm_toggle = 0; | ||
1423 | |||
1424 | return 0; | ||
1425 | } | ||
1426 | |||
1427 | int mlx4_multi_func_init(struct mlx4_dev *dev) | ||
1428 | { | ||
1429 | struct mlx4_priv *priv = mlx4_priv(dev); | ||
1430 | struct mlx4_slave_state *s_state; | ||
1431 | int i, err, port; | ||
1432 | |||
1433 | priv->mfunc.vhcr = dma_alloc_coherent(&(dev->pdev->dev), PAGE_SIZE, | ||
1434 | &priv->mfunc.vhcr_dma, | ||
1435 | GFP_KERNEL); | ||
1436 | if (!priv->mfunc.vhcr) { | ||
1437 | mlx4_err(dev, "Couldn't allocate vhcr.\n"); | ||
1438 | return -ENOMEM; | ||
1439 | } | ||
1440 | |||
1441 | if (mlx4_is_master(dev)) | ||
1442 | priv->mfunc.comm = | ||
1443 | ioremap(pci_resource_start(dev->pdev, priv->fw.comm_bar) + | ||
1444 | priv->fw.comm_base, MLX4_COMM_PAGESIZE); | ||
1445 | else | ||
1446 | priv->mfunc.comm = | ||
1447 | ioremap(pci_resource_start(dev->pdev, 2) + | ||
1448 | MLX4_SLAVE_COMM_BASE, MLX4_COMM_PAGESIZE); | ||
1449 | if (!priv->mfunc.comm) { | ||
1450 | mlx4_err(dev, "Couldn't map communication vector.\n"); | ||
1451 | goto err_vhcr; | ||
1452 | } | ||
1453 | |||
1454 | if (mlx4_is_master(dev)) { | ||
1455 | priv->mfunc.master.slave_state = | ||
1456 | kzalloc(dev->num_slaves * | ||
1457 | sizeof(struct mlx4_slave_state), GFP_KERNEL); | ||
1458 | if (!priv->mfunc.master.slave_state) | ||
1459 | goto err_comm; | ||
1460 | |||
1461 | for (i = 0; i < dev->num_slaves; ++i) { | ||
1462 | s_state = &priv->mfunc.master.slave_state[i]; | ||
1463 | s_state->last_cmd = MLX4_COMM_CMD_RESET; | ||
1464 | __raw_writel((__force u32) 0, | ||
1465 | &priv->mfunc.comm[i].slave_write); | ||
1466 | __raw_writel((__force u32) 0, | ||
1467 | &priv->mfunc.comm[i].slave_read); | ||
1468 | mmiowb(); | ||
1469 | for (port = 1; port <= MLX4_MAX_PORTS; port++) { | ||
1470 | s_state->vlan_filter[port] = | ||
1471 | kzalloc(sizeof(struct mlx4_vlan_fltr), | ||
1472 | GFP_KERNEL); | ||
1473 | if (!s_state->vlan_filter[port]) { | ||
1474 | if (--port) | ||
1475 | kfree(s_state->vlan_filter[port]); | ||
1476 | goto err_slaves; | ||
1477 | } | ||
1478 | INIT_LIST_HEAD(&s_state->mcast_filters[port]); | ||
1479 | } | ||
1480 | spin_lock_init(&s_state->lock); | ||
1481 | } | ||
1482 | |||
1483 | memset(&priv->mfunc.master.cmd_eqe, 0, sizeof(struct mlx4_eqe)); | ||
1484 | priv->mfunc.master.cmd_eqe.type = MLX4_EVENT_TYPE_CMD; | ||
1485 | INIT_WORK(&priv->mfunc.master.comm_work, | ||
1486 | mlx4_master_comm_channel); | ||
1487 | INIT_WORK(&priv->mfunc.master.slave_event_work, | ||
1488 | mlx4_gen_slave_eqe); | ||
1489 | INIT_WORK(&priv->mfunc.master.slave_flr_event_work, | ||
1490 | mlx4_master_handle_slave_flr); | ||
1491 | spin_lock_init(&priv->mfunc.master.slave_state_lock); | ||
1492 | priv->mfunc.master.comm_wq = | ||
1493 | create_singlethread_workqueue("mlx4_comm"); | ||
1494 | if (!priv->mfunc.master.comm_wq) | ||
1495 | goto err_slaves; | ||
1496 | |||
1497 | if (mlx4_init_resource_tracker(dev)) | ||
1498 | goto err_thread; | ||
1499 | |||
1500 | sema_init(&priv->cmd.slave_sem, 1); | ||
1501 | err = mlx4_ARM_COMM_CHANNEL(dev); | ||
1502 | if (err) { | ||
1503 | mlx4_err(dev, " Failed to arm comm channel eq: %x\n", | ||
1504 | err); | ||
1505 | goto err_resource; | ||
1506 | } | ||
1507 | |||
1508 | } else { | ||
1509 | err = sync_toggles(dev); | ||
1510 | if (err) { | ||
1511 | mlx4_err(dev, "Couldn't sync toggles\n"); | ||
1512 | goto err_comm; | ||
1513 | } | ||
1514 | |||
1515 | sema_init(&priv->cmd.slave_sem, 1); | ||
1516 | } | ||
1517 | return 0; | ||
1518 | |||
1519 | err_resource: | ||
1520 | mlx4_free_resource_tracker(dev); | ||
1521 | err_thread: | ||
1522 | flush_workqueue(priv->mfunc.master.comm_wq); | ||
1523 | destroy_workqueue(priv->mfunc.master.comm_wq); | ||
1524 | err_slaves: | ||
1525 | while (--i) { | ||
1526 | for (port = 1; port <= MLX4_MAX_PORTS; port++) | ||
1527 | kfree(priv->mfunc.master.slave_state[i].vlan_filter[port]); | ||
1528 | } | ||
1529 | kfree(priv->mfunc.master.slave_state); | ||
1530 | err_comm: | ||
1531 | iounmap(priv->mfunc.comm); | ||
1532 | err_vhcr: | ||
1533 | dma_free_coherent(&(dev->pdev->dev), PAGE_SIZE, | ||
1534 | priv->mfunc.vhcr, | ||
1535 | priv->mfunc.vhcr_dma); | ||
1536 | priv->mfunc.vhcr = NULL; | ||
1537 | return -ENOMEM; | ||
1538 | } | ||
1539 | |||
1393 | int mlx4_cmd_init(struct mlx4_dev *dev) | 1540 | int mlx4_cmd_init(struct mlx4_dev *dev) |
1394 | { | 1541 | { |
1395 | struct mlx4_priv *priv = mlx4_priv(dev); | 1542 | struct mlx4_priv *priv = mlx4_priv(dev); |
@@ -1425,6 +1572,27 @@ err_hcr: | |||
1425 | return -ENOMEM; | 1572 | return -ENOMEM; |
1426 | } | 1573 | } |
1427 | 1574 | ||
1575 | void mlx4_multi_func_cleanup(struct mlx4_dev *dev) | ||
1576 | { | ||
1577 | struct mlx4_priv *priv = mlx4_priv(dev); | ||
1578 | int i, port; | ||
1579 | |||
1580 | if (mlx4_is_master(dev)) { | ||
1581 | flush_workqueue(priv->mfunc.master.comm_wq); | ||
1582 | destroy_workqueue(priv->mfunc.master.comm_wq); | ||
1583 | for (i = 0; i < dev->num_slaves; i++) { | ||
1584 | for (port = 1; port <= MLX4_MAX_PORTS; port++) | ||
1585 | kfree(priv->mfunc.master.slave_state[i].vlan_filter[port]); | ||
1586 | } | ||
1587 | kfree(priv->mfunc.master.slave_state); | ||
1588 | iounmap(priv->mfunc.comm); | ||
1589 | dma_free_coherent(&(dev->pdev->dev), PAGE_SIZE, | ||
1590 | priv->mfunc.vhcr, | ||
1591 | priv->mfunc.vhcr_dma); | ||
1592 | priv->mfunc.vhcr = NULL; | ||
1593 | } | ||
1594 | } | ||
1595 | |||
1428 | void mlx4_cmd_cleanup(struct mlx4_dev *dev) | 1596 | void mlx4_cmd_cleanup(struct mlx4_dev *dev) |
1429 | { | 1597 | { |
1430 | struct mlx4_priv *priv = mlx4_priv(dev); | 1598 | struct mlx4_priv *priv = mlx4_priv(dev); |
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c index 99415fec9fd..f03b54e0aa5 100644 --- a/drivers/net/ethernet/mellanox/mlx4/fw.c +++ b/drivers/net/ethernet/mellanox/mlx4/fw.c | |||
@@ -1071,7 +1071,7 @@ int mlx4_INIT_HCA(struct mlx4_dev *dev, struct mlx4_init_hca_param *param) | |||
1071 | 1071 | ||
1072 | /* UAR attributes */ | 1072 | /* UAR attributes */ |
1073 | 1073 | ||
1074 | MLX4_PUT(inbox, (u8) (PAGE_SHIFT - 12), INIT_HCA_UAR_PAGE_SZ_OFFSET); | 1074 | MLX4_PUT(inbox, param->uar_page_sz, INIT_HCA_UAR_PAGE_SZ_OFFSET); |
1075 | MLX4_PUT(inbox, param->log_uar_sz, INIT_HCA_LOG_UAR_SZ_OFFSET); | 1075 | MLX4_PUT(inbox, param->log_uar_sz, INIT_HCA_LOG_UAR_SZ_OFFSET); |
1076 | 1076 | ||
1077 | err = mlx4_cmd(dev, mailbox->dma, 0, 0, MLX4_CMD_INIT_HCA, 10000, | 1077 | err = mlx4_cmd(dev, mailbox->dma, 0, 0, MLX4_CMD_INIT_HCA, 10000, |
@@ -1084,6 +1084,72 @@ int mlx4_INIT_HCA(struct mlx4_dev *dev, struct mlx4_init_hca_param *param) | |||
1084 | return err; | 1084 | return err; |
1085 | } | 1085 | } |
1086 | 1086 | ||
1087 | int mlx4_QUERY_HCA(struct mlx4_dev *dev, | ||
1088 | struct mlx4_init_hca_param *param) | ||
1089 | { | ||
1090 | struct mlx4_cmd_mailbox *mailbox; | ||
1091 | __be32 *outbox; | ||
1092 | int err; | ||
1093 | |||
1094 | #define QUERY_HCA_GLOBAL_CAPS_OFFSET 0x04 | ||
1095 | |||
1096 | mailbox = mlx4_alloc_cmd_mailbox(dev); | ||
1097 | if (IS_ERR(mailbox)) | ||
1098 | return PTR_ERR(mailbox); | ||
1099 | outbox = mailbox->buf; | ||
1100 | |||
1101 | err = mlx4_cmd_box(dev, 0, mailbox->dma, 0, 0, | ||
1102 | MLX4_CMD_QUERY_HCA, | ||
1103 | MLX4_CMD_TIME_CLASS_B, | ||
1104 | !mlx4_is_slave(dev)); | ||
1105 | if (err) | ||
1106 | goto out; | ||
1107 | |||
1108 | MLX4_GET(param->global_caps, outbox, QUERY_HCA_GLOBAL_CAPS_OFFSET); | ||
1109 | |||
1110 | /* QPC/EEC/CQC/EQC/RDMARC attributes */ | ||
1111 | |||
1112 | MLX4_GET(param->qpc_base, outbox, INIT_HCA_QPC_BASE_OFFSET); | ||
1113 | MLX4_GET(param->log_num_qps, outbox, INIT_HCA_LOG_QP_OFFSET); | ||
1114 | MLX4_GET(param->srqc_base, outbox, INIT_HCA_SRQC_BASE_OFFSET); | ||
1115 | MLX4_GET(param->log_num_srqs, outbox, INIT_HCA_LOG_SRQ_OFFSET); | ||
1116 | MLX4_GET(param->cqc_base, outbox, INIT_HCA_CQC_BASE_OFFSET); | ||
1117 | MLX4_GET(param->log_num_cqs, outbox, INIT_HCA_LOG_CQ_OFFSET); | ||
1118 | MLX4_GET(param->altc_base, outbox, INIT_HCA_ALTC_BASE_OFFSET); | ||
1119 | MLX4_GET(param->auxc_base, outbox, INIT_HCA_AUXC_BASE_OFFSET); | ||
1120 | MLX4_GET(param->eqc_base, outbox, INIT_HCA_EQC_BASE_OFFSET); | ||
1121 | MLX4_GET(param->log_num_eqs, outbox, INIT_HCA_LOG_EQ_OFFSET); | ||
1122 | MLX4_GET(param->rdmarc_base, outbox, INIT_HCA_RDMARC_BASE_OFFSET); | ||
1123 | MLX4_GET(param->log_rd_per_qp, outbox, INIT_HCA_LOG_RD_OFFSET); | ||
1124 | |||
1125 | /* multicast attributes */ | ||
1126 | |||
1127 | MLX4_GET(param->mc_base, outbox, INIT_HCA_MC_BASE_OFFSET); | ||
1128 | MLX4_GET(param->log_mc_entry_sz, outbox, | ||
1129 | INIT_HCA_LOG_MC_ENTRY_SZ_OFFSET); | ||
1130 | MLX4_GET(param->log_mc_hash_sz, outbox, | ||
1131 | INIT_HCA_LOG_MC_HASH_SZ_OFFSET); | ||
1132 | MLX4_GET(param->log_mc_table_sz, outbox, | ||
1133 | INIT_HCA_LOG_MC_TABLE_SZ_OFFSET); | ||
1134 | |||
1135 | /* TPT attributes */ | ||
1136 | |||
1137 | MLX4_GET(param->dmpt_base, outbox, INIT_HCA_DMPT_BASE_OFFSET); | ||
1138 | MLX4_GET(param->log_mpt_sz, outbox, INIT_HCA_LOG_MPT_SZ_OFFSET); | ||
1139 | MLX4_GET(param->mtt_base, outbox, INIT_HCA_MTT_BASE_OFFSET); | ||
1140 | MLX4_GET(param->cmpt_base, outbox, INIT_HCA_CMPT_BASE_OFFSET); | ||
1141 | |||
1142 | /* UAR attributes */ | ||
1143 | |||
1144 | MLX4_GET(param->uar_page_sz, outbox, INIT_HCA_UAR_PAGE_SZ_OFFSET); | ||
1145 | MLX4_GET(param->log_uar_sz, outbox, INIT_HCA_LOG_UAR_SZ_OFFSET); | ||
1146 | |||
1147 | out: | ||
1148 | mlx4_free_cmd_mailbox(dev, mailbox); | ||
1149 | |||
1150 | return err; | ||
1151 | } | ||
1152 | |||
1087 | int mlx4_INIT_PORT_wrapper(struct mlx4_dev *dev, int slave, | 1153 | int mlx4_INIT_PORT_wrapper(struct mlx4_dev *dev, int slave, |
1088 | struct mlx4_vhcr *vhcr, | 1154 | struct mlx4_vhcr *vhcr, |
1089 | struct mlx4_cmd_mailbox *inbox, | 1155 | struct mlx4_cmd_mailbox *inbox, |
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.h b/drivers/net/ethernet/mellanox/mlx4/fw.h index 8f0f4cf7d2c..3368363a8ec 100644 --- a/drivers/net/ethernet/mellanox/mlx4/fw.h +++ b/drivers/net/ethernet/mellanox/mlx4/fw.h | |||
@@ -161,6 +161,7 @@ struct mlx4_init_hca_param { | |||
161 | u8 log_mc_table_sz; | 161 | u8 log_mc_table_sz; |
162 | u8 log_mpt_sz; | 162 | u8 log_mpt_sz; |
163 | u8 log_uar_sz; | 163 | u8 log_uar_sz; |
164 | u8 uar_page_sz; /* log pg sz in 4k chunks */ | ||
164 | }; | 165 | }; |
165 | 166 | ||
166 | struct mlx4_init_ib_param { | 167 | struct mlx4_init_ib_param { |
@@ -197,6 +198,7 @@ int mlx4_RUN_FW(struct mlx4_dev *dev); | |||
197 | int mlx4_QUERY_FW(struct mlx4_dev *dev); | 198 | int mlx4_QUERY_FW(struct mlx4_dev *dev); |
198 | int mlx4_QUERY_ADAPTER(struct mlx4_dev *dev, struct mlx4_adapter *adapter); | 199 | int mlx4_QUERY_ADAPTER(struct mlx4_dev *dev, struct mlx4_adapter *adapter); |
199 | int mlx4_INIT_HCA(struct mlx4_dev *dev, struct mlx4_init_hca_param *param); | 200 | int mlx4_INIT_HCA(struct mlx4_dev *dev, struct mlx4_init_hca_param *param); |
201 | int mlx4_QUERY_HCA(struct mlx4_dev *dev, struct mlx4_init_hca_param *param); | ||
200 | int mlx4_CLOSE_HCA(struct mlx4_dev *dev, int panic); | 202 | int mlx4_CLOSE_HCA(struct mlx4_dev *dev, int panic); |
201 | int mlx4_map_cmd(struct mlx4_dev *dev, u16 op, struct mlx4_icm *icm, u64 virt); | 203 | int mlx4_map_cmd(struct mlx4_dev *dev, u16 op, struct mlx4_icm *icm, u64 virt); |
202 | int mlx4_SET_ICM_SIZE(struct mlx4_dev *dev, u64 icm_size, u64 *aux_pages); | 204 | int mlx4_SET_ICM_SIZE(struct mlx4_dev *dev, u64 icm_size, u64 *aux_pages); |
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index 19363b61829..b969bfb569e 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c | |||
@@ -40,6 +40,7 @@ | |||
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 | #include <linux/io-mapping.h> |
43 | #include <linux/delay.h> | ||
43 | 44 | ||
44 | #include <linux/mlx4/device.h> | 45 | #include <linux/mlx4/device.h> |
45 | #include <linux/mlx4/doorbell.h> | 46 | #include <linux/mlx4/doorbell.h> |
@@ -75,6 +76,14 @@ MODULE_PARM_DESC(msi_x, "attempt to use MSI-X if nonzero"); | |||
75 | 76 | ||
76 | #endif /* CONFIG_PCI_MSI */ | 77 | #endif /* CONFIG_PCI_MSI */ |
77 | 78 | ||
79 | static int num_vfs; | ||
80 | module_param(num_vfs, int, 0444); | ||
81 | MODULE_PARM_DESC(num_vfs, "enable #num_vfs functions if num_vfs > 0"); | ||
82 | |||
83 | static int probe_vf; | ||
84 | module_param(probe_vf, int, 0644); | ||
85 | MODULE_PARM_DESC(probe_vf, "number of vfs to probe by pf driver (num_vfs > 0)"); | ||
86 | |||
78 | int mlx4_log_num_mgm_entry_size = 10; | 87 | int mlx4_log_num_mgm_entry_size = 10; |
79 | module_param_named(log_num_mgm_entry_size, | 88 | module_param_named(log_num_mgm_entry_size, |
80 | mlx4_log_num_mgm_entry_size, int, 0444); | 89 | mlx4_log_num_mgm_entry_size, int, 0444); |
@@ -83,21 +92,26 @@ MODULE_PARM_DESC(log_num_mgm_entry_size, "log mgm size, that defines the num" | |||
83 | " 10 gives 248.range: 9<=" | 92 | " 10 gives 248.range: 9<=" |
84 | " log_num_mgm_entry_size <= 12"); | 93 | " log_num_mgm_entry_size <= 12"); |
85 | 94 | ||
95 | #define MLX4_VF (1 << 0) | ||
96 | |||
97 | #define HCA_GLOBAL_CAP_MASK 0 | ||
98 | #define PF_CONTEXT_BEHAVIOUR_MASK 0 | ||
99 | |||
86 | static char mlx4_version[] __devinitdata = | 100 | static char mlx4_version[] __devinitdata = |
87 | DRV_NAME ": Mellanox ConnectX core driver v" | 101 | DRV_NAME ": Mellanox ConnectX core driver v" |
88 | DRV_VERSION " (" DRV_RELDATE ")\n"; | 102 | DRV_VERSION " (" DRV_RELDATE ")\n"; |
89 | 103 | ||
90 | static struct mlx4_profile default_profile = { | 104 | static struct mlx4_profile default_profile = { |
91 | .num_qp = 1 << 17, | 105 | .num_qp = 1 << 18, |
92 | .num_srq = 1 << 16, | 106 | .num_srq = 1 << 16, |
93 | .rdmarc_per_qp = 1 << 4, | 107 | .rdmarc_per_qp = 1 << 4, |
94 | .num_cq = 1 << 16, | 108 | .num_cq = 1 << 16, |
95 | .num_mcg = 1 << 13, | 109 | .num_mcg = 1 << 13, |
96 | .num_mpt = 1 << 17, | 110 | .num_mpt = 1 << 19, |
97 | .num_mtt = 1 << 20, | 111 | .num_mtt = 1 << 20, |
98 | }; | 112 | }; |
99 | 113 | ||
100 | static int log_num_mac = 2; | 114 | static int log_num_mac = 7; |
101 | module_param_named(log_num_mac, log_num_mac, int, 0444); | 115 | module_param_named(log_num_mac, log_num_mac, int, 0444); |
102 | MODULE_PARM_DESC(log_num_mac, "Log2 max number of MACs per ETH port (1-7)"); | 116 | MODULE_PARM_DESC(log_num_mac, "Log2 max number of MACs per ETH port (1-7)"); |
103 | 117 | ||
@@ -116,6 +130,23 @@ int log_mtts_per_seg = ilog2(MLX4_MTT_ENTRY_PER_SEG); | |||
116 | module_param_named(log_mtts_per_seg, log_mtts_per_seg, int, 0444); | 130 | module_param_named(log_mtts_per_seg, log_mtts_per_seg, int, 0444); |
117 | MODULE_PARM_DESC(log_mtts_per_seg, "Log2 number of MTT entries per segment (1-7)"); | 131 | MODULE_PARM_DESC(log_mtts_per_seg, "Log2 number of MTT entries per segment (1-7)"); |
118 | 132 | ||
133 | static int port_type_array[2] = {1, 1}; | ||
134 | static int arr_argc = 2; | ||
135 | module_param_array(port_type_array, int, &arr_argc, 0444); | ||
136 | MODULE_PARM_DESC(port_type_array, "Array of port types: IB by default"); | ||
137 | |||
138 | struct mlx4_port_config { | ||
139 | struct list_head list; | ||
140 | enum mlx4_port_type port_type[MLX4_MAX_PORTS + 1]; | ||
141 | struct pci_dev *pdev; | ||
142 | }; | ||
143 | |||
144 | static inline int mlx4_master_get_num_eqs(struct mlx4_dev *dev) | ||
145 | { | ||
146 | return dev->caps.reserved_eqs + | ||
147 | MLX4_MFUNC_EQ_NUM * (dev->num_slaves + 1); | ||
148 | } | ||
149 | |||
119 | int mlx4_check_port_params(struct mlx4_dev *dev, | 150 | int mlx4_check_port_params(struct mlx4_dev *dev, |
120 | enum mlx4_port_type *port_type) | 151 | enum mlx4_port_type *port_type) |
121 | { | 152 | { |
@@ -200,6 +231,7 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) | |||
200 | dev->caps.trans_code[i] = dev_cap->trans_code[i]; | 231 | dev->caps.trans_code[i] = dev_cap->trans_code[i]; |
201 | } | 232 | } |
202 | 233 | ||
234 | dev->caps.uar_page_size = PAGE_SIZE; | ||
203 | dev->caps.num_uars = dev_cap->uar_size / PAGE_SIZE; | 235 | dev->caps.num_uars = dev_cap->uar_size / PAGE_SIZE; |
204 | dev->caps.local_ca_ack_delay = dev_cap->local_ca_ack_delay; | 236 | dev->caps.local_ca_ack_delay = dev_cap->local_ca_ack_delay; |
205 | dev->caps.bf_reg_size = dev_cap->bf_reg_size; | 237 | dev->caps.bf_reg_size = dev_cap->bf_reg_size; |
@@ -224,7 +256,9 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) | |||
224 | dev->caps.reserved_eqs = dev_cap->reserved_eqs; | 256 | dev->caps.reserved_eqs = dev_cap->reserved_eqs; |
225 | dev->caps.reserved_mtts = dev_cap->reserved_mtts; | 257 | dev->caps.reserved_mtts = dev_cap->reserved_mtts; |
226 | dev->caps.reserved_mrws = dev_cap->reserved_mrws; | 258 | dev->caps.reserved_mrws = dev_cap->reserved_mrws; |
227 | dev->caps.reserved_uars = dev_cap->reserved_uars; | 259 | |
260 | /* The first 128 UARs are used for EQ doorbells */ | ||
261 | dev->caps.reserved_uars = max_t(int, 128, dev_cap->reserved_uars); | ||
228 | dev->caps.reserved_pds = dev_cap->reserved_pds; | 262 | dev->caps.reserved_pds = dev_cap->reserved_pds; |
229 | dev->caps.reserved_xrcds = (dev->caps.flags & MLX4_DEV_CAP_FLAG_XRC) ? | 263 | dev->caps.reserved_xrcds = (dev->caps.flags & MLX4_DEV_CAP_FLAG_XRC) ? |
230 | dev_cap->reserved_xrcds : 0; | 264 | dev_cap->reserved_xrcds : 0; |
@@ -245,10 +279,36 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) | |||
245 | dev->caps.log_num_prios = use_prio ? 3 : 0; | 279 | dev->caps.log_num_prios = use_prio ? 3 : 0; |
246 | 280 | ||
247 | for (i = 1; i <= dev->caps.num_ports; ++i) { | 281 | for (i = 1; i <= dev->caps.num_ports; ++i) { |
248 | if (dev->caps.supported_type[i] != MLX4_PORT_TYPE_ETH) | 282 | dev->caps.port_type[i] = MLX4_PORT_TYPE_NONE; |
249 | dev->caps.port_type[i] = MLX4_PORT_TYPE_IB; | 283 | if (dev->caps.supported_type[i]) { |
250 | else | 284 | /* if only ETH is supported - assign ETH */ |
251 | dev->caps.port_type[i] = MLX4_PORT_TYPE_ETH; | 285 | if (dev->caps.supported_type[i] == MLX4_PORT_TYPE_ETH) |
286 | dev->caps.port_type[i] = MLX4_PORT_TYPE_ETH; | ||
287 | /* if only IB is supported, | ||
288 | * assign IB only if SRIOV is off*/ | ||
289 | else if (dev->caps.supported_type[i] == | ||
290 | MLX4_PORT_TYPE_IB) { | ||
291 | if (dev->flags & MLX4_FLAG_SRIOV) | ||
292 | dev->caps.port_type[i] = | ||
293 | MLX4_PORT_TYPE_NONE; | ||
294 | else | ||
295 | dev->caps.port_type[i] = | ||
296 | MLX4_PORT_TYPE_IB; | ||
297 | /* if IB and ETH are supported, | ||
298 | * first of all check if SRIOV is on */ | ||
299 | } else if (dev->flags & MLX4_FLAG_SRIOV) | ||
300 | dev->caps.port_type[i] = MLX4_PORT_TYPE_ETH; | ||
301 | /* if IB and ETH are supported and SRIOV is off | ||
302 | * use module parameters */ | ||
303 | else { | ||
304 | if (port_type_array[i-1]) | ||
305 | dev->caps.port_type[i] = | ||
306 | MLX4_PORT_TYPE_IB; | ||
307 | else | ||
308 | dev->caps.port_type[i] = | ||
309 | MLX4_PORT_TYPE_ETH; | ||
310 | } | ||
311 | } | ||
252 | dev->caps.possible_type[i] = dev->caps.port_type[i]; | 312 | dev->caps.possible_type[i] = dev->caps.port_type[i]; |
253 | mlx4_priv(dev)->sense.sense_allowed[i] = | 313 | mlx4_priv(dev)->sense.sense_allowed[i] = |
254 | dev->caps.supported_type[i] == MLX4_PORT_TYPE_AUTO; | 314 | dev->caps.supported_type[i] == MLX4_PORT_TYPE_AUTO; |
@@ -267,8 +327,6 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) | |||
267 | } | 327 | } |
268 | } | 328 | } |
269 | 329 | ||
270 | mlx4_set_port_mask(dev); | ||
271 | |||
272 | dev->caps.max_counters = 1 << ilog2(dev_cap->max_counters); | 330 | dev->caps.max_counters = 1 << ilog2(dev_cap->max_counters); |
273 | 331 | ||
274 | dev->caps.reserved_qps_cnt[MLX4_QP_REGION_FW] = dev_cap->reserved_qps; | 332 | dev->caps.reserved_qps_cnt[MLX4_QP_REGION_FW] = dev_cap->reserved_qps; |
@@ -287,6 +345,149 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) | |||
287 | 345 | ||
288 | return 0; | 346 | return 0; |
289 | } | 347 | } |
348 | /*The function checks if there are live vf, return the num of them*/ | ||
349 | static int mlx4_how_many_lives_vf(struct mlx4_dev *dev) | ||
350 | { | ||
351 | struct mlx4_priv *priv = mlx4_priv(dev); | ||
352 | struct mlx4_slave_state *s_state; | ||
353 | int i; | ||
354 | int ret = 0; | ||
355 | |||
356 | for (i = 1/*the ppf is 0*/; i < dev->num_slaves; ++i) { | ||
357 | s_state = &priv->mfunc.master.slave_state[i]; | ||
358 | if (s_state->active && s_state->last_cmd != | ||
359 | MLX4_COMM_CMD_RESET) { | ||
360 | mlx4_warn(dev, "%s: slave: %d is still active\n", | ||
361 | __func__, i); | ||
362 | ret++; | ||
363 | } | ||
364 | } | ||
365 | return ret; | ||
366 | } | ||
367 | |||
368 | static int mlx4_is_slave_active(struct mlx4_dev *dev, int slave) | ||
369 | { | ||
370 | struct mlx4_priv *priv = mlx4_priv(dev); | ||
371 | struct mlx4_slave_state *s_slave; | ||
372 | |||
373 | if (!mlx4_is_master(dev)) | ||
374 | return 0; | ||
375 | |||
376 | s_slave = &priv->mfunc.master.slave_state[slave]; | ||
377 | return !!s_slave->active; | ||
378 | } | ||
379 | EXPORT_SYMBOL(mlx4_is_slave_active); | ||
380 | |||
381 | static int mlx4_slave_cap(struct mlx4_dev *dev) | ||
382 | { | ||
383 | int err; | ||
384 | u32 page_size; | ||
385 | struct mlx4_dev_cap dev_cap; | ||
386 | struct mlx4_func_cap func_cap; | ||
387 | struct mlx4_init_hca_param hca_param; | ||
388 | int i; | ||
389 | |||
390 | memset(&hca_param, 0, sizeof(hca_param)); | ||
391 | err = mlx4_QUERY_HCA(dev, &hca_param); | ||
392 | if (err) { | ||
393 | mlx4_err(dev, "QUERY_HCA command failed, aborting.\n"); | ||
394 | return err; | ||
395 | } | ||
396 | |||
397 | /*fail if the hca has an unknown capability */ | ||
398 | if ((hca_param.global_caps | HCA_GLOBAL_CAP_MASK) != | ||
399 | HCA_GLOBAL_CAP_MASK) { | ||
400 | mlx4_err(dev, "Unknown hca global capabilities\n"); | ||
401 | return -ENOSYS; | ||
402 | } | ||
403 | |||
404 | mlx4_log_num_mgm_entry_size = hca_param.log_mc_entry_sz; | ||
405 | |||
406 | memset(&dev_cap, 0, sizeof(dev_cap)); | ||
407 | err = mlx4_dev_cap(dev, &dev_cap); | ||
408 | if (err) { | ||
409 | mlx4_err(dev, "QUERY_DEV_CAP command failed, aborting.\n"); | ||
410 | return err; | ||
411 | } | ||
412 | |||
413 | page_size = ~dev->caps.page_size_cap + 1; | ||
414 | mlx4_warn(dev, "HCA minimum page size:%d\n", page_size); | ||
415 | if (page_size > PAGE_SIZE) { | ||
416 | mlx4_err(dev, "HCA minimum page size of %d bigger than " | ||
417 | "kernel PAGE_SIZE of %ld, aborting.\n", | ||
418 | page_size, PAGE_SIZE); | ||
419 | return -ENODEV; | ||
420 | } | ||
421 | |||
422 | /* slave gets uar page size from QUERY_HCA fw command */ | ||
423 | dev->caps.uar_page_size = 1 << (hca_param.uar_page_sz + 12); | ||
424 | |||
425 | /* TODO: relax this assumption */ | ||
426 | if (dev->caps.uar_page_size != PAGE_SIZE) { | ||
427 | mlx4_err(dev, "UAR size:%d != kernel PAGE_SIZE of %ld\n", | ||
428 | dev->caps.uar_page_size, PAGE_SIZE); | ||
429 | return -ENODEV; | ||
430 | } | ||
431 | |||
432 | memset(&func_cap, 0, sizeof(func_cap)); | ||
433 | err = mlx4_QUERY_FUNC_CAP(dev, &func_cap); | ||
434 | if (err) { | ||
435 | mlx4_err(dev, "QUERY_FUNC_CAP command failed, aborting.\n"); | ||
436 | return err; | ||
437 | } | ||
438 | |||
439 | if ((func_cap.pf_context_behaviour | PF_CONTEXT_BEHAVIOUR_MASK) != | ||
440 | PF_CONTEXT_BEHAVIOUR_MASK) { | ||
441 | mlx4_err(dev, "Unknown pf context behaviour\n"); | ||
442 | return -ENOSYS; | ||
443 | } | ||
444 | |||
445 | dev->caps.function = func_cap.function; | ||
446 | dev->caps.num_ports = func_cap.num_ports; | ||
447 | dev->caps.num_qps = func_cap.qp_quota; | ||
448 | dev->caps.num_srqs = func_cap.srq_quota; | ||
449 | dev->caps.num_cqs = func_cap.cq_quota; | ||
450 | dev->caps.num_eqs = func_cap.max_eq; | ||
451 | dev->caps.reserved_eqs = func_cap.reserved_eq; | ||
452 | dev->caps.num_mpts = func_cap.mpt_quota; | ||
453 | dev->caps.num_mtts = func_cap.mtt_quota; | ||
454 | dev->caps.num_pds = MLX4_NUM_PDS; | ||
455 | dev->caps.num_mgms = 0; | ||
456 | dev->caps.num_amgms = 0; | ||
457 | |||
458 | for (i = 1; i <= dev->caps.num_ports; ++i) | ||
459 | dev->caps.port_mask[i] = dev->caps.port_type[i]; | ||
460 | |||
461 | if (dev->caps.num_ports > MLX4_MAX_PORTS) { | ||
462 | mlx4_err(dev, "HCA has %d ports, but we only support %d, " | ||
463 | "aborting.\n", dev->caps.num_ports, MLX4_MAX_PORTS); | ||
464 | return -ENODEV; | ||
465 | } | ||
466 | |||
467 | if (dev->caps.uar_page_size * (dev->caps.num_uars - | ||
468 | dev->caps.reserved_uars) > | ||
469 | pci_resource_len(dev->pdev, 2)) { | ||
470 | mlx4_err(dev, "HCA reported UAR region size of 0x%x bigger than " | ||
471 | "PCI resource 2 size of 0x%llx, aborting.\n", | ||
472 | dev->caps.uar_page_size * dev->caps.num_uars, | ||
473 | (unsigned long long) pci_resource_len(dev->pdev, 2)); | ||
474 | return -ENODEV; | ||
475 | } | ||
476 | |||
477 | #if 0 | ||
478 | mlx4_warn(dev, "sqp_demux:%d\n", dev->caps.sqp_demux); | ||
479 | mlx4_warn(dev, "num_uars:%d reserved_uars:%d uar region:0x%x bar2:0x%llx\n", | ||
480 | dev->caps.num_uars, dev->caps.reserved_uars, | ||
481 | dev->caps.uar_page_size * dev->caps.num_uars, | ||
482 | pci_resource_len(dev->pdev, 2)); | ||
483 | mlx4_warn(dev, "num_eqs:%d reserved_eqs:%d\n", dev->caps.num_eqs, | ||
484 | dev->caps.reserved_eqs); | ||
485 | mlx4_warn(dev, "num_pds:%d reserved_pds:%d slave_pd_shift:%d pd_base:%d\n", | ||
486 | dev->caps.num_pds, dev->caps.reserved_pds, | ||
487 | dev->caps.slave_pd_shift, dev->caps.pd_base); | ||
488 | #endif | ||
489 | return 0; | ||
490 | } | ||
290 | 491 | ||
291 | /* | 492 | /* |
292 | * Change the port configuration of the device. | 493 | * Change the port configuration of the device. |
@@ -456,6 +657,7 @@ static int mlx4_init_cmpt_table(struct mlx4_dev *dev, u64 cmpt_base, | |||
456 | { | 657 | { |
457 | struct mlx4_priv *priv = mlx4_priv(dev); | 658 | struct mlx4_priv *priv = mlx4_priv(dev); |
458 | int err; | 659 | int err; |
660 | int num_eqs; | ||
459 | 661 | ||
460 | err = mlx4_init_icm_table(dev, &priv->qp_table.cmpt_table, | 662 | err = mlx4_init_icm_table(dev, &priv->qp_table.cmpt_table, |
461 | cmpt_base + | 663 | cmpt_base + |
@@ -485,12 +687,14 @@ static int mlx4_init_cmpt_table(struct mlx4_dev *dev, u64 cmpt_base, | |||
485 | if (err) | 687 | if (err) |
486 | goto err_srq; | 688 | goto err_srq; |
487 | 689 | ||
690 | num_eqs = (mlx4_is_master(dev)) ? | ||
691 | roundup_pow_of_two(mlx4_master_get_num_eqs(dev)) : | ||
692 | dev->caps.num_eqs; | ||
488 | err = mlx4_init_icm_table(dev, &priv->eq_table.cmpt_table, | 693 | err = mlx4_init_icm_table(dev, &priv->eq_table.cmpt_table, |
489 | cmpt_base + | 694 | cmpt_base + |
490 | ((u64) (MLX4_CMPT_TYPE_EQ * | 695 | ((u64) (MLX4_CMPT_TYPE_EQ * |
491 | cmpt_entry_sz) << MLX4_CMPT_SHIFT), | 696 | cmpt_entry_sz) << MLX4_CMPT_SHIFT), |
492 | cmpt_entry_sz, | 697 | cmpt_entry_sz, num_eqs, num_eqs, 0, 0); |
493 | dev->caps.num_eqs, dev->caps.num_eqs, 0, 0); | ||
494 | if (err) | 698 | if (err) |
495 | goto err_cq; | 699 | goto err_cq; |
496 | 700 | ||
@@ -514,6 +718,7 @@ static int mlx4_init_icm(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap, | |||
514 | { | 718 | { |
515 | struct mlx4_priv *priv = mlx4_priv(dev); | 719 | struct mlx4_priv *priv = mlx4_priv(dev); |
516 | u64 aux_pages; | 720 | u64 aux_pages; |
721 | int num_eqs; | ||
517 | int err; | 722 | int err; |
518 | 723 | ||
519 | err = mlx4_SET_ICM_SIZE(dev, icm_size, &aux_pages); | 724 | err = mlx4_SET_ICM_SIZE(dev, icm_size, &aux_pages); |
@@ -545,10 +750,13 @@ static int mlx4_init_icm(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap, | |||
545 | goto err_unmap_aux; | 750 | goto err_unmap_aux; |
546 | } | 751 | } |
547 | 752 | ||
753 | |||
754 | num_eqs = (mlx4_is_master(dev)) ? | ||
755 | roundup_pow_of_two(mlx4_master_get_num_eqs(dev)) : | ||
756 | dev->caps.num_eqs; | ||
548 | err = mlx4_init_icm_table(dev, &priv->eq_table.table, | 757 | err = mlx4_init_icm_table(dev, &priv->eq_table.table, |
549 | init_hca->eqc_base, dev_cap->eqc_entry_sz, | 758 | init_hca->eqc_base, dev_cap->eqc_entry_sz, |
550 | dev->caps.num_eqs, dev->caps.num_eqs, | 759 | num_eqs, num_eqs, 0, 0); |
551 | 0, 0); | ||
552 | if (err) { | 760 | if (err) { |
553 | mlx4_err(dev, "Failed to map EQ context memory, aborting.\n"); | 761 | mlx4_err(dev, "Failed to map EQ context memory, aborting.\n"); |
554 | goto err_unmap_cmpt; | 762 | goto err_unmap_cmpt; |
@@ -732,6 +940,16 @@ static void mlx4_free_icms(struct mlx4_dev *dev) | |||
732 | mlx4_free_icm(dev, priv->fw.aux_icm, 0); | 940 | mlx4_free_icm(dev, priv->fw.aux_icm, 0); |
733 | } | 941 | } |
734 | 942 | ||
943 | static void mlx4_slave_exit(struct mlx4_dev *dev) | ||
944 | { | ||
945 | struct mlx4_priv *priv = mlx4_priv(dev); | ||
946 | |||
947 | down(&priv->cmd.slave_sem); | ||
948 | if (mlx4_comm_cmd(dev, MLX4_COMM_CMD_RESET, 0, MLX4_COMM_TIME)) | ||
949 | mlx4_warn(dev, "Failed to close slave function.\n"); | ||
950 | up(&priv->cmd.slave_sem); | ||
951 | } | ||
952 | |||
735 | static int map_bf_area(struct mlx4_dev *dev) | 953 | static int map_bf_area(struct mlx4_dev *dev) |
736 | { | 954 | { |
737 | struct mlx4_priv *priv = mlx4_priv(dev); | 955 | struct mlx4_priv *priv = mlx4_priv(dev); |
@@ -739,8 +957,10 @@ static int map_bf_area(struct mlx4_dev *dev) | |||
739 | resource_size_t bf_len; | 957 | resource_size_t bf_len; |
740 | int err = 0; | 958 | int err = 0; |
741 | 959 | ||
742 | bf_start = pci_resource_start(dev->pdev, 2) + (dev->caps.num_uars << PAGE_SHIFT); | 960 | bf_start = pci_resource_start(dev->pdev, 2) + |
743 | bf_len = pci_resource_len(dev->pdev, 2) - (dev->caps.num_uars << PAGE_SHIFT); | 961 | (dev->caps.num_uars << PAGE_SHIFT); |
962 | bf_len = pci_resource_len(dev->pdev, 2) - | ||
963 | (dev->caps.num_uars << PAGE_SHIFT); | ||
744 | priv->bf_mapping = io_mapping_create_wc(bf_start, bf_len); | 964 | priv->bf_mapping = io_mapping_create_wc(bf_start, bf_len); |
745 | if (!priv->bf_mapping) | 965 | if (!priv->bf_mapping) |
746 | err = -ENOMEM; | 966 | err = -ENOMEM; |
@@ -757,10 +977,81 @@ static void unmap_bf_area(struct mlx4_dev *dev) | |||
757 | static void mlx4_close_hca(struct mlx4_dev *dev) | 977 | static void mlx4_close_hca(struct mlx4_dev *dev) |
758 | { | 978 | { |
759 | unmap_bf_area(dev); | 979 | unmap_bf_area(dev); |
760 | mlx4_CLOSE_HCA(dev, 0); | 980 | if (mlx4_is_slave(dev)) |
761 | mlx4_free_icms(dev); | 981 | mlx4_slave_exit(dev); |
762 | mlx4_UNMAP_FA(dev); | 982 | else { |
763 | mlx4_free_icm(dev, mlx4_priv(dev)->fw.fw_icm, 0); | 983 | mlx4_CLOSE_HCA(dev, 0); |
984 | mlx4_free_icms(dev); | ||
985 | mlx4_UNMAP_FA(dev); | ||
986 | mlx4_free_icm(dev, mlx4_priv(dev)->fw.fw_icm, 0); | ||
987 | } | ||
988 | } | ||
989 | |||
990 | static int mlx4_init_slave(struct mlx4_dev *dev) | ||
991 | { | ||
992 | struct mlx4_priv *priv = mlx4_priv(dev); | ||
993 | u64 dma = (u64) priv->mfunc.vhcr_dma; | ||
994 | int num_of_reset_retries = NUM_OF_RESET_RETRIES; | ||
995 | int ret_from_reset = 0; | ||
996 | u32 slave_read; | ||
997 | u32 cmd_channel_ver; | ||
998 | |||
999 | down(&priv->cmd.slave_sem); | ||
1000 | priv->cmd.max_cmds = 1; | ||
1001 | mlx4_warn(dev, "Sending reset\n"); | ||
1002 | ret_from_reset = mlx4_comm_cmd(dev, MLX4_COMM_CMD_RESET, 0, | ||
1003 | MLX4_COMM_TIME); | ||
1004 | /* if we are in the middle of flr the slave will try | ||
1005 | * NUM_OF_RESET_RETRIES times before leaving.*/ | ||
1006 | if (ret_from_reset) { | ||
1007 | if (MLX4_DELAY_RESET_SLAVE == ret_from_reset) { | ||
1008 | msleep(SLEEP_TIME_IN_RESET); | ||
1009 | while (ret_from_reset && num_of_reset_retries) { | ||
1010 | mlx4_warn(dev, "slave is currently in the" | ||
1011 | "middle of FLR. retrying..." | ||
1012 | "(try num:%d)\n", | ||
1013 | (NUM_OF_RESET_RETRIES - | ||
1014 | num_of_reset_retries + 1)); | ||
1015 | ret_from_reset = | ||
1016 | mlx4_comm_cmd(dev, MLX4_COMM_CMD_RESET, | ||
1017 | 0, MLX4_COMM_TIME); | ||
1018 | num_of_reset_retries = num_of_reset_retries - 1; | ||
1019 | } | ||
1020 | } else | ||
1021 | goto err; | ||
1022 | } | ||
1023 | |||
1024 | /* check the driver version - the slave I/F revision | ||
1025 | * must match the master's */ | ||
1026 | slave_read = swab32(readl(&priv->mfunc.comm->slave_read)); | ||
1027 | cmd_channel_ver = mlx4_comm_get_version(); | ||
1028 | |||
1029 | if (MLX4_COMM_GET_IF_REV(cmd_channel_ver) != | ||
1030 | MLX4_COMM_GET_IF_REV(slave_read)) { | ||
1031 | mlx4_err(dev, "slave driver version is not supported" | ||
1032 | " by the master\n"); | ||
1033 | goto err; | ||
1034 | } | ||
1035 | |||
1036 | mlx4_warn(dev, "Sending vhcr0\n"); | ||
1037 | if (mlx4_comm_cmd(dev, MLX4_COMM_CMD_VHCR0, dma >> 48, | ||
1038 | MLX4_COMM_TIME)) | ||
1039 | goto err; | ||
1040 | if (mlx4_comm_cmd(dev, MLX4_COMM_CMD_VHCR1, dma >> 32, | ||
1041 | MLX4_COMM_TIME)) | ||
1042 | goto err; | ||
1043 | if (mlx4_comm_cmd(dev, MLX4_COMM_CMD_VHCR2, dma >> 16, | ||
1044 | MLX4_COMM_TIME)) | ||
1045 | goto err; | ||
1046 | if (mlx4_comm_cmd(dev, MLX4_COMM_CMD_VHCR_EN, dma, MLX4_COMM_TIME)) | ||
1047 | goto err; | ||
1048 | up(&priv->cmd.slave_sem); | ||
1049 | return 0; | ||
1050 | |||
1051 | err: | ||
1052 | mlx4_comm_cmd(dev, MLX4_COMM_CMD_RESET, 0, 0); | ||
1053 | up(&priv->cmd.slave_sem); | ||
1054 | return -EIO; | ||
764 | } | 1055 | } |
765 | 1056 | ||
766 | static int mlx4_init_hca(struct mlx4_dev *dev) | 1057 | static int mlx4_init_hca(struct mlx4_dev *dev) |
@@ -774,56 +1065,76 @@ static int mlx4_init_hca(struct mlx4_dev *dev) | |||
774 | u64 icm_size; | 1065 | u64 icm_size; |
775 | int err; | 1066 | int err; |
776 | 1067 | ||
777 | err = mlx4_QUERY_FW(dev); | 1068 | if (!mlx4_is_slave(dev)) { |
778 | if (err) { | 1069 | err = mlx4_QUERY_FW(dev); |
779 | if (err == -EACCES) | 1070 | if (err) { |
780 | mlx4_info(dev, "non-primary physical function, skipping.\n"); | 1071 | if (err == -EACCES) |
781 | else | 1072 | mlx4_info(dev, "non-primary physical function, skipping.\n"); |
782 | mlx4_err(dev, "QUERY_FW command failed, aborting.\n"); | 1073 | else |
783 | return err; | 1074 | mlx4_err(dev, "QUERY_FW command failed, aborting.\n"); |
784 | } | 1075 | goto unmap_bf; |
1076 | } | ||
785 | 1077 | ||
786 | err = mlx4_load_fw(dev); | 1078 | err = mlx4_load_fw(dev); |
787 | if (err) { | 1079 | if (err) { |
788 | mlx4_err(dev, "Failed to start FW, aborting.\n"); | 1080 | mlx4_err(dev, "Failed to start FW, aborting.\n"); |
789 | return err; | 1081 | goto unmap_bf; |
790 | } | 1082 | } |
791 | 1083 | ||
792 | mlx4_cfg.log_pg_sz_m = 1; | 1084 | mlx4_cfg.log_pg_sz_m = 1; |
793 | mlx4_cfg.log_pg_sz = 0; | 1085 | mlx4_cfg.log_pg_sz = 0; |
794 | err = mlx4_MOD_STAT_CFG(dev, &mlx4_cfg); | 1086 | err = mlx4_MOD_STAT_CFG(dev, &mlx4_cfg); |
795 | if (err) | 1087 | if (err) |
796 | mlx4_warn(dev, "Failed to override log_pg_sz parameter\n"); | 1088 | mlx4_warn(dev, "Failed to override log_pg_sz parameter\n"); |
797 | 1089 | ||
798 | err = mlx4_dev_cap(dev, &dev_cap); | 1090 | err = mlx4_dev_cap(dev, &dev_cap); |
799 | if (err) { | 1091 | if (err) { |
800 | mlx4_err(dev, "QUERY_DEV_CAP command failed, aborting.\n"); | 1092 | mlx4_err(dev, "QUERY_DEV_CAP command failed, aborting.\n"); |
801 | goto err_stop_fw; | 1093 | goto err_stop_fw; |
802 | } | 1094 | } |
803 | 1095 | ||
804 | profile = default_profile; | 1096 | profile = default_profile; |
805 | 1097 | ||
806 | icm_size = mlx4_make_profile(dev, &profile, &dev_cap, &init_hca); | 1098 | icm_size = mlx4_make_profile(dev, &profile, &dev_cap, |
807 | if ((long long) icm_size < 0) { | 1099 | &init_hca); |
808 | err = icm_size; | 1100 | if ((long long) icm_size < 0) { |
809 | goto err_stop_fw; | 1101 | err = icm_size; |
810 | } | 1102 | goto err_stop_fw; |
1103 | } | ||
811 | 1104 | ||
812 | if (map_bf_area(dev)) | 1105 | init_hca.log_uar_sz = ilog2(dev->caps.num_uars); |
813 | mlx4_dbg(dev, "Failed to map blue flame area\n"); | 1106 | init_hca.uar_page_sz = PAGE_SHIFT - 12; |
814 | 1107 | ||
815 | init_hca.log_uar_sz = ilog2(dev->caps.num_uars); | 1108 | err = mlx4_init_icm(dev, &dev_cap, &init_hca, icm_size); |
1109 | if (err) | ||
1110 | goto err_stop_fw; | ||
816 | 1111 | ||
817 | err = mlx4_init_icm(dev, &dev_cap, &init_hca, icm_size); | 1112 | err = mlx4_INIT_HCA(dev, &init_hca); |
818 | if (err) | 1113 | if (err) { |
819 | goto err_stop_fw; | 1114 | mlx4_err(dev, "INIT_HCA command failed, aborting.\n"); |
1115 | goto err_free_icm; | ||
1116 | } | ||
1117 | } else { | ||
1118 | err = mlx4_init_slave(dev); | ||
1119 | if (err) { | ||
1120 | mlx4_err(dev, "Failed to initialize slave\n"); | ||
1121 | goto unmap_bf; | ||
1122 | } | ||
820 | 1123 | ||
821 | err = mlx4_INIT_HCA(dev, &init_hca); | 1124 | err = mlx4_slave_cap(dev); |
822 | if (err) { | 1125 | if (err) { |
823 | mlx4_err(dev, "INIT_HCA command failed, aborting.\n"); | 1126 | mlx4_err(dev, "Failed to obtain slave caps\n"); |
824 | goto err_free_icm; | 1127 | goto err_close; |
1128 | } | ||
825 | } | 1129 | } |
826 | 1130 | ||
1131 | if (map_bf_area(dev)) | ||
1132 | mlx4_dbg(dev, "Failed to map blue flame area\n"); | ||
1133 | |||
1134 | /*Only the master set the ports, all the rest got it from it.*/ | ||
1135 | if (!mlx4_is_slave(dev)) | ||
1136 | mlx4_set_port_mask(dev); | ||
1137 | |||
827 | err = mlx4_QUERY_ADAPTER(dev, &adapter); | 1138 | err = mlx4_QUERY_ADAPTER(dev, &adapter); |
828 | if (err) { | 1139 | if (err) { |
829 | mlx4_err(dev, "QUERY_ADAPTER command failed, aborting.\n"); | 1140 | mlx4_err(dev, "QUERY_ADAPTER command failed, aborting.\n"); |
@@ -836,16 +1147,19 @@ static int mlx4_init_hca(struct mlx4_dev *dev) | |||
836 | return 0; | 1147 | return 0; |
837 | 1148 | ||
838 | err_close: | 1149 | err_close: |
839 | mlx4_CLOSE_HCA(dev, 0); | 1150 | mlx4_close_hca(dev); |
840 | 1151 | ||
841 | err_free_icm: | 1152 | err_free_icm: |
842 | mlx4_free_icms(dev); | 1153 | if (!mlx4_is_slave(dev)) |
1154 | mlx4_free_icms(dev); | ||
843 | 1155 | ||
844 | err_stop_fw: | 1156 | err_stop_fw: |
1157 | if (!mlx4_is_slave(dev)) { | ||
1158 | mlx4_UNMAP_FA(dev); | ||
1159 | mlx4_free_icm(dev, priv->fw.fw_icm, 0); | ||
1160 | } | ||
1161 | unmap_bf: | ||
845 | unmap_bf_area(dev); | 1162 | unmap_bf_area(dev); |
846 | mlx4_UNMAP_FA(dev); | ||
847 | mlx4_free_icm(dev, priv->fw.fw_icm, 0); | ||
848 | |||
849 | return err; | 1163 | return err; |
850 | } | 1164 | } |
851 | 1165 | ||
@@ -992,55 +1306,62 @@ static int mlx4_setup_hca(struct mlx4_dev *dev) | |||
992 | goto err_srq_table_free; | 1306 | goto err_srq_table_free; |
993 | } | 1307 | } |
994 | 1308 | ||
995 | err = mlx4_init_mcg_table(dev); | 1309 | if (!mlx4_is_slave(dev)) { |
996 | if (err) { | 1310 | err = mlx4_init_mcg_table(dev); |
997 | mlx4_err(dev, "Failed to initialize " | 1311 | if (err) { |
998 | "multicast group table, aborting.\n"); | 1312 | mlx4_err(dev, "Failed to initialize " |
999 | goto err_qp_table_free; | 1313 | "multicast group table, aborting.\n"); |
1314 | goto err_qp_table_free; | ||
1315 | } | ||
1000 | } | 1316 | } |
1001 | 1317 | ||
1002 | err = mlx4_init_counters_table(dev); | 1318 | err = mlx4_init_counters_table(dev); |
1003 | if (err && err != -ENOENT) { | 1319 | if (err && err != -ENOENT) { |
1004 | mlx4_err(dev, "Failed to initialize counters table, aborting.\n"); | 1320 | mlx4_err(dev, "Failed to initialize counters table, aborting.\n"); |
1005 | goto err_counters_table_free; | 1321 | goto err_mcg_table_free; |
1006 | } | 1322 | } |
1007 | 1323 | ||
1008 | for (port = 1; port <= dev->caps.num_ports; port++) { | 1324 | if (!mlx4_is_slave(dev)) { |
1009 | enum mlx4_port_type port_type = 0; | 1325 | for (port = 1; port <= dev->caps.num_ports; port++) { |
1010 | mlx4_SENSE_PORT(dev, port, &port_type); | 1326 | if (!mlx4_is_mfunc(dev)) { |
1011 | if (port_type) | 1327 | enum mlx4_port_type port_type = 0; |
1012 | dev->caps.port_type[port] = port_type; | 1328 | mlx4_SENSE_PORT(dev, port, &port_type); |
1013 | ib_port_default_caps = 0; | 1329 | if (port_type) |
1014 | err = mlx4_get_port_ib_caps(dev, port, &ib_port_default_caps); | 1330 | dev->caps.port_type[port] = port_type; |
1015 | if (err) | 1331 | } |
1016 | mlx4_warn(dev, "failed to get port %d default " | 1332 | ib_port_default_caps = 0; |
1017 | "ib capabilities (%d). Continuing with " | 1333 | err = mlx4_get_port_ib_caps(dev, port, |
1018 | "caps = 0\n", port, err); | 1334 | &ib_port_default_caps); |
1019 | dev->caps.ib_port_def_cap[port] = ib_port_default_caps; | 1335 | if (err) |
1020 | 1336 | mlx4_warn(dev, "failed to get port %d default " | |
1021 | err = mlx4_check_ext_port_caps(dev, port); | 1337 | "ib capabilities (%d). Continuing " |
1022 | if (err) | 1338 | "with caps = 0\n", port, err); |
1023 | mlx4_warn(dev, "failed to get port %d extended " | 1339 | dev->caps.ib_port_def_cap[port] = ib_port_default_caps; |
1024 | "port capabilities support info (%d)." | 1340 | |
1025 | " Assuming not supported\n", port, err); | 1341 | err = mlx4_check_ext_port_caps(dev, port); |
1342 | if (err) | ||
1343 | mlx4_warn(dev, "failed to get port %d extended " | ||
1344 | "port capabilities support info (%d)." | ||
1345 | " Assuming not supported\n", | ||
1346 | port, err); | ||
1026 | 1347 | ||
1027 | err = mlx4_SET_PORT(dev, port); | 1348 | err = mlx4_SET_PORT(dev, port); |
1028 | if (err) { | 1349 | if (err) { |
1029 | mlx4_err(dev, "Failed to set port %d, aborting\n", | 1350 | mlx4_err(dev, "Failed to set port %d, aborting\n", |
1030 | port); | 1351 | port); |
1031 | goto err_mcg_table_free; | 1352 | goto err_counters_table_free; |
1353 | } | ||
1032 | } | 1354 | } |
1033 | } | 1355 | } |
1034 | mlx4_set_port_mask(dev); | ||
1035 | 1356 | ||
1036 | return 0; | 1357 | return 0; |
1037 | 1358 | ||
1038 | err_mcg_table_free: | ||
1039 | mlx4_cleanup_mcg_table(dev); | ||
1040 | |||
1041 | err_counters_table_free: | 1359 | err_counters_table_free: |
1042 | mlx4_cleanup_counters_table(dev); | 1360 | mlx4_cleanup_counters_table(dev); |
1043 | 1361 | ||
1362 | err_mcg_table_free: | ||
1363 | mlx4_cleanup_mcg_table(dev); | ||
1364 | |||
1044 | err_qp_table_free: | 1365 | err_qp_table_free: |
1045 | mlx4_cleanup_qp_table(dev); | 1366 | mlx4_cleanup_qp_table(dev); |
1046 | 1367 | ||
@@ -1087,8 +1408,16 @@ static void mlx4_enable_msi_x(struct mlx4_dev *dev) | |||
1087 | int i; | 1408 | int i; |
1088 | 1409 | ||
1089 | if (msi_x) { | 1410 | if (msi_x) { |
1090 | nreq = min_t(int, dev->caps.num_eqs - dev->caps.reserved_eqs, | 1411 | /* In multifunction mode each function gets 2 msi-X vectors |
1091 | nreq); | 1412 | * one for data path completions anf the other for asynch events |
1413 | * or command completions */ | ||
1414 | if (mlx4_is_mfunc(dev)) { | ||
1415 | nreq = 2; | ||
1416 | } else { | ||
1417 | nreq = min_t(int, dev->caps.num_eqs - | ||
1418 | dev->caps.reserved_eqs, nreq); | ||
1419 | } | ||
1420 | |||
1092 | entries = kcalloc(nreq, sizeof *entries, GFP_KERNEL); | 1421 | entries = kcalloc(nreq, sizeof *entries, GFP_KERNEL); |
1093 | if (!entries) | 1422 | if (!entries) |
1094 | goto no_msi; | 1423 | goto no_msi; |
@@ -1144,16 +1473,24 @@ static int mlx4_init_port_info(struct mlx4_dev *dev, int port) | |||
1144 | 1473 | ||
1145 | info->dev = dev; | 1474 | info->dev = dev; |
1146 | info->port = port; | 1475 | info->port = port; |
1147 | mlx4_init_mac_table(dev, &info->mac_table); | 1476 | if (!mlx4_is_slave(dev)) { |
1148 | mlx4_init_vlan_table(dev, &info->vlan_table); | 1477 | INIT_RADIX_TREE(&info->mac_tree, GFP_KERNEL); |
1149 | info->base_qpn = dev->caps.reserved_qps_base[MLX4_QP_REGION_ETH_ADDR] + | 1478 | mlx4_init_mac_table(dev, &info->mac_table); |
1479 | mlx4_init_vlan_table(dev, &info->vlan_table); | ||
1480 | info->base_qpn = | ||
1481 | dev->caps.reserved_qps_base[MLX4_QP_REGION_ETH_ADDR] + | ||
1150 | (port - 1) * (1 << log_num_mac); | 1482 | (port - 1) * (1 << log_num_mac); |
1483 | } | ||
1151 | 1484 | ||
1152 | sprintf(info->dev_name, "mlx4_port%d", port); | 1485 | sprintf(info->dev_name, "mlx4_port%d", port); |
1153 | info->port_attr.attr.name = info->dev_name; | 1486 | info->port_attr.attr.name = info->dev_name; |
1154 | info->port_attr.attr.mode = S_IRUGO | S_IWUSR; | 1487 | if (mlx4_is_mfunc(dev)) |
1488 | info->port_attr.attr.mode = S_IRUGO; | ||
1489 | else { | ||
1490 | info->port_attr.attr.mode = S_IRUGO | S_IWUSR; | ||
1491 | info->port_attr.store = set_port_type; | ||
1492 | } | ||
1155 | info->port_attr.show = show_port_type; | 1493 | info->port_attr.show = show_port_type; |
1156 | info->port_attr.store = set_port_type; | ||
1157 | sysfs_attr_init(&info->port_attr.attr); | 1494 | sysfs_attr_init(&info->port_attr.attr); |
1158 | 1495 | ||
1159 | err = device_create_file(&dev->pdev->dev, &info->port_attr); | 1496 | err = device_create_file(&dev->pdev->dev, &info->port_attr); |
@@ -1226,6 +1563,46 @@ static void mlx4_clear_steering(struct mlx4_dev *dev) | |||
1226 | kfree(priv->steer); | 1563 | kfree(priv->steer); |
1227 | } | 1564 | } |
1228 | 1565 | ||
1566 | static int extended_func_num(struct pci_dev *pdev) | ||
1567 | { | ||
1568 | return PCI_SLOT(pdev->devfn) * 8 + PCI_FUNC(pdev->devfn); | ||
1569 | } | ||
1570 | |||
1571 | #define MLX4_OWNER_BASE 0x8069c | ||
1572 | #define MLX4_OWNER_SIZE 4 | ||
1573 | |||
1574 | static int mlx4_get_ownership(struct mlx4_dev *dev) | ||
1575 | { | ||
1576 | void __iomem *owner; | ||
1577 | u32 ret; | ||
1578 | |||
1579 | owner = ioremap(pci_resource_start(dev->pdev, 0) + MLX4_OWNER_BASE, | ||
1580 | MLX4_OWNER_SIZE); | ||
1581 | if (!owner) { | ||
1582 | mlx4_err(dev, "Failed to obtain ownership bit\n"); | ||
1583 | return -ENOMEM; | ||
1584 | } | ||
1585 | |||
1586 | ret = readl(owner); | ||
1587 | iounmap(owner); | ||
1588 | return (int) !!ret; | ||
1589 | } | ||
1590 | |||
1591 | static void mlx4_free_ownership(struct mlx4_dev *dev) | ||
1592 | { | ||
1593 | void __iomem *owner; | ||
1594 | |||
1595 | owner = ioremap(pci_resource_start(dev->pdev, 0) + MLX4_OWNER_BASE, | ||
1596 | MLX4_OWNER_SIZE); | ||
1597 | if (!owner) { | ||
1598 | mlx4_err(dev, "Failed to obtain ownership bit\n"); | ||
1599 | return; | ||
1600 | } | ||
1601 | writel(0, owner); | ||
1602 | msleep(1000); | ||
1603 | iounmap(owner); | ||
1604 | } | ||
1605 | |||
1229 | static int __mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | 1606 | static int __mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id) |
1230 | { | 1607 | { |
1231 | struct mlx4_priv *priv; | 1608 | struct mlx4_priv *priv; |
@@ -1241,13 +1618,20 @@ static int __mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1241 | "aborting.\n"); | 1618 | "aborting.\n"); |
1242 | return err; | 1619 | return err; |
1243 | } | 1620 | } |
1244 | 1621 | if (num_vfs > MLX4_MAX_NUM_VF) { | |
1622 | printk(KERN_ERR "There are more VF's (%d) than allowed(%d)\n", | ||
1623 | num_vfs, MLX4_MAX_NUM_VF); | ||
1624 | return -EINVAL; | ||
1625 | } | ||
1245 | /* | 1626 | /* |
1246 | * Check for BARs. We expect 0: 1MB | 1627 | * Check for BARs. |
1247 | */ | 1628 | */ |
1248 | if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM) || | 1629 | if (((id == NULL) || !(id->driver_data & MLX4_VF)) && |
1249 | pci_resource_len(pdev, 0) != 1 << 20) { | 1630 | !(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) { |
1250 | dev_err(&pdev->dev, "Missing DCS, aborting.\n"); | 1631 | dev_err(&pdev->dev, "Missing DCS, aborting." |
1632 | "(id == 0X%p, id->driver_data: 0x%lx," | ||
1633 | " pci_resource_flags(pdev, 0):0x%lx)\n", id, | ||
1634 | id ? id->driver_data : 0, pci_resource_flags(pdev, 0)); | ||
1251 | err = -ENODEV; | 1635 | err = -ENODEV; |
1252 | goto err_disable_pdev; | 1636 | goto err_disable_pdev; |
1253 | } | 1637 | } |
@@ -1311,42 +1695,132 @@ static int __mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1311 | mutex_init(&priv->bf_mutex); | 1695 | mutex_init(&priv->bf_mutex); |
1312 | 1696 | ||
1313 | dev->rev_id = pdev->revision; | 1697 | dev->rev_id = pdev->revision; |
1698 | /* Detect if this device is a virtual function */ | ||
1699 | if (id && id->driver_data & MLX4_VF) { | ||
1700 | /* When acting as pf, we normally skip vfs unless explicitly | ||
1701 | * requested to probe them. */ | ||
1702 | if (num_vfs && extended_func_num(pdev) > probe_vf) { | ||
1703 | mlx4_warn(dev, "Skipping virtual function:%d\n", | ||
1704 | extended_func_num(pdev)); | ||
1705 | err = -ENODEV; | ||
1706 | goto err_free_dev; | ||
1707 | } | ||
1708 | mlx4_warn(dev, "Detected virtual function - running in slave mode\n"); | ||
1709 | dev->flags |= MLX4_FLAG_SLAVE; | ||
1710 | } else { | ||
1711 | /* We reset the device and enable SRIOV only for physical | ||
1712 | * devices. Try to claim ownership on the device; | ||
1713 | * if already taken, skip -- do not allow multiple PFs */ | ||
1714 | err = mlx4_get_ownership(dev); | ||
1715 | if (err) { | ||
1716 | if (err < 0) | ||
1717 | goto err_free_dev; | ||
1718 | else { | ||
1719 | mlx4_warn(dev, "Multiple PFs not yet supported." | ||
1720 | " Skipping PF.\n"); | ||
1721 | err = -EINVAL; | ||
1722 | goto err_free_dev; | ||
1723 | } | ||
1724 | } | ||
1314 | 1725 | ||
1315 | /* | 1726 | if (num_vfs) { |
1316 | * Now reset the HCA before we touch the PCI capabilities or | 1727 | mlx4_warn(dev, "Enabling sriov with:%d vfs\n", num_vfs); |
1317 | * attempt a firmware command, since a boot ROM may have left | 1728 | err = pci_enable_sriov(pdev, num_vfs); |
1318 | * the HCA in an undefined state. | 1729 | if (err) { |
1319 | */ | 1730 | mlx4_err(dev, "Failed to enable sriov," |
1320 | err = mlx4_reset(dev); | 1731 | "continuing without sriov enabled" |
1321 | if (err) { | 1732 | " (err = %d).\n", err); |
1322 | mlx4_err(dev, "Failed to reset HCA, aborting.\n"); | 1733 | num_vfs = 0; |
1323 | goto err_free_dev; | 1734 | err = 0; |
1735 | } else { | ||
1736 | mlx4_warn(dev, "Running in master mode\n"); | ||
1737 | dev->flags |= MLX4_FLAG_SRIOV | | ||
1738 | MLX4_FLAG_MASTER; | ||
1739 | dev->num_vfs = num_vfs; | ||
1740 | } | ||
1741 | } | ||
1742 | |||
1743 | /* | ||
1744 | * Now reset the HCA before we touch the PCI capabilities or | ||
1745 | * attempt a firmware command, since a boot ROM may have left | ||
1746 | * the HCA in an undefined state. | ||
1747 | */ | ||
1748 | err = mlx4_reset(dev); | ||
1749 | if (err) { | ||
1750 | mlx4_err(dev, "Failed to reset HCA, aborting.\n"); | ||
1751 | goto err_rel_own; | ||
1752 | } | ||
1324 | } | 1753 | } |
1325 | 1754 | ||
1755 | slave_start: | ||
1326 | if (mlx4_cmd_init(dev)) { | 1756 | if (mlx4_cmd_init(dev)) { |
1327 | mlx4_err(dev, "Failed to init command interface, aborting.\n"); | 1757 | mlx4_err(dev, "Failed to init command interface, aborting.\n"); |
1328 | goto err_free_dev; | 1758 | goto err_sriov; |
1759 | } | ||
1760 | |||
1761 | /* In slave functions, the communication channel must be initialized | ||
1762 | * before posting commands. Also, init num_slaves before calling | ||
1763 | * mlx4_init_hca */ | ||
1764 | if (mlx4_is_mfunc(dev)) { | ||
1765 | if (mlx4_is_master(dev)) | ||
1766 | dev->num_slaves = MLX4_MAX_NUM_SLAVES; | ||
1767 | else { | ||
1768 | dev->num_slaves = 0; | ||
1769 | if (mlx4_multi_func_init(dev)) { | ||
1770 | mlx4_err(dev, "Failed to init slave mfunc" | ||
1771 | " interface, aborting.\n"); | ||
1772 | goto err_cmd; | ||
1773 | } | ||
1774 | } | ||
1329 | } | 1775 | } |
1330 | 1776 | ||
1331 | err = mlx4_init_hca(dev); | 1777 | err = mlx4_init_hca(dev); |
1332 | if (err) | 1778 | if (err) { |
1333 | goto err_cmd; | 1779 | if (err == -EACCES) { |
1780 | /* Not primary Physical function | ||
1781 | * Running in slave mode */ | ||
1782 | mlx4_cmd_cleanup(dev); | ||
1783 | dev->flags |= MLX4_FLAG_SLAVE; | ||
1784 | dev->flags &= ~MLX4_FLAG_MASTER; | ||
1785 | goto slave_start; | ||
1786 | } else | ||
1787 | goto err_mfunc; | ||
1788 | } | ||
1789 | |||
1790 | /* In master functions, the communication channel must be initialized | ||
1791 | * after obtaining its address from fw */ | ||
1792 | if (mlx4_is_master(dev)) { | ||
1793 | if (mlx4_multi_func_init(dev)) { | ||
1794 | mlx4_err(dev, "Failed to init master mfunc" | ||
1795 | "interface, aborting.\n"); | ||
1796 | goto err_close; | ||
1797 | } | ||
1798 | } | ||
1334 | 1799 | ||
1335 | err = mlx4_alloc_eq_table(dev); | 1800 | err = mlx4_alloc_eq_table(dev); |
1336 | if (err) | 1801 | if (err) |
1337 | goto err_close; | 1802 | goto err_master_mfunc; |
1338 | 1803 | ||
1339 | priv->msix_ctl.pool_bm = 0; | 1804 | priv->msix_ctl.pool_bm = 0; |
1340 | spin_lock_init(&priv->msix_ctl.pool_lock); | 1805 | spin_lock_init(&priv->msix_ctl.pool_lock); |
1341 | 1806 | ||
1342 | mlx4_enable_msi_x(dev); | 1807 | mlx4_enable_msi_x(dev); |
1343 | 1808 | if ((mlx4_is_mfunc(dev)) && | |
1344 | err = mlx4_init_steering(dev); | 1809 | !(dev->flags & MLX4_FLAG_MSI_X)) { |
1345 | if (err) | 1810 | mlx4_err(dev, "INTx is not supported in multi-function mode." |
1811 | " aborting.\n"); | ||
1346 | goto err_free_eq; | 1812 | goto err_free_eq; |
1813 | } | ||
1814 | |||
1815 | if (!mlx4_is_slave(dev)) { | ||
1816 | err = mlx4_init_steering(dev); | ||
1817 | if (err) | ||
1818 | goto err_free_eq; | ||
1819 | } | ||
1347 | 1820 | ||
1348 | err = mlx4_setup_hca(dev); | 1821 | err = mlx4_setup_hca(dev); |
1349 | if (err == -EBUSY && (dev->flags & MLX4_FLAG_MSI_X)) { | 1822 | if (err == -EBUSY && (dev->flags & MLX4_FLAG_MSI_X) && |
1823 | !mlx4_is_mfunc(dev)) { | ||
1350 | dev->flags &= ~MLX4_FLAG_MSI_X; | 1824 | dev->flags &= ~MLX4_FLAG_MSI_X; |
1351 | pci_disable_msix(pdev); | 1825 | pci_disable_msix(pdev); |
1352 | err = mlx4_setup_hca(dev); | 1826 | err = mlx4_setup_hca(dev); |
@@ -1389,20 +1863,37 @@ err_port: | |||
1389 | mlx4_cleanup_uar_table(dev); | 1863 | mlx4_cleanup_uar_table(dev); |
1390 | 1864 | ||
1391 | err_steer: | 1865 | err_steer: |
1392 | mlx4_clear_steering(dev); | 1866 | if (!mlx4_is_slave(dev)) |
1867 | mlx4_clear_steering(dev); | ||
1393 | 1868 | ||
1394 | err_free_eq: | 1869 | err_free_eq: |
1395 | mlx4_free_eq_table(dev); | 1870 | mlx4_free_eq_table(dev); |
1396 | 1871 | ||
1872 | err_master_mfunc: | ||
1873 | if (mlx4_is_master(dev)) | ||
1874 | mlx4_multi_func_cleanup(dev); | ||
1875 | |||
1397 | err_close: | 1876 | err_close: |
1398 | if (dev->flags & MLX4_FLAG_MSI_X) | 1877 | if (dev->flags & MLX4_FLAG_MSI_X) |
1399 | pci_disable_msix(pdev); | 1878 | pci_disable_msix(pdev); |
1400 | 1879 | ||
1401 | mlx4_close_hca(dev); | 1880 | mlx4_close_hca(dev); |
1402 | 1881 | ||
1882 | err_mfunc: | ||
1883 | if (mlx4_is_slave(dev)) | ||
1884 | mlx4_multi_func_cleanup(dev); | ||
1885 | |||
1403 | err_cmd: | 1886 | err_cmd: |
1404 | mlx4_cmd_cleanup(dev); | 1887 | mlx4_cmd_cleanup(dev); |
1405 | 1888 | ||
1889 | err_sriov: | ||
1890 | if (num_vfs && (dev->flags & MLX4_FLAG_SRIOV)) | ||
1891 | pci_disable_sriov(pdev); | ||
1892 | |||
1893 | err_rel_own: | ||
1894 | if (!mlx4_is_slave(dev)) | ||
1895 | mlx4_free_ownership(dev); | ||
1896 | |||
1406 | err_free_dev: | 1897 | err_free_dev: |
1407 | kfree(priv); | 1898 | kfree(priv); |
1408 | 1899 | ||
@@ -1430,6 +1921,12 @@ static void mlx4_remove_one(struct pci_dev *pdev) | |||
1430 | int p; | 1921 | int p; |
1431 | 1922 | ||
1432 | if (dev) { | 1923 | if (dev) { |
1924 | /* in SRIOV it is not allowed to unload the pf's | ||
1925 | * driver while there are alive vf's */ | ||
1926 | if (mlx4_is_master(dev)) { | ||
1927 | if (mlx4_how_many_lives_vf(dev)) | ||
1928 | printk(KERN_ERR "Removing PF when there are assigned VF's !!!\n"); | ||
1929 | } | ||
1433 | mlx4_stop_sense(dev); | 1930 | mlx4_stop_sense(dev); |
1434 | mlx4_unregister_device(dev); | 1931 | mlx4_unregister_device(dev); |
1435 | 1932 | ||
@@ -1449,17 +1946,31 @@ static void mlx4_remove_one(struct pci_dev *pdev) | |||
1449 | mlx4_cleanup_xrcd_table(dev); | 1946 | mlx4_cleanup_xrcd_table(dev); |
1450 | mlx4_cleanup_pd_table(dev); | 1947 | mlx4_cleanup_pd_table(dev); |
1451 | 1948 | ||
1949 | if (mlx4_is_master(dev)) | ||
1950 | mlx4_free_resource_tracker(dev); | ||
1951 | |||
1452 | iounmap(priv->kar); | 1952 | iounmap(priv->kar); |
1453 | mlx4_uar_free(dev, &priv->driver_uar); | 1953 | mlx4_uar_free(dev, &priv->driver_uar); |
1454 | mlx4_cleanup_uar_table(dev); | 1954 | mlx4_cleanup_uar_table(dev); |
1455 | mlx4_clear_steering(dev); | 1955 | if (!mlx4_is_slave(dev)) |
1956 | mlx4_clear_steering(dev); | ||
1456 | mlx4_free_eq_table(dev); | 1957 | mlx4_free_eq_table(dev); |
1958 | if (mlx4_is_master(dev)) | ||
1959 | mlx4_multi_func_cleanup(dev); | ||
1457 | mlx4_close_hca(dev); | 1960 | mlx4_close_hca(dev); |
1961 | if (mlx4_is_slave(dev)) | ||
1962 | mlx4_multi_func_cleanup(dev); | ||
1458 | mlx4_cmd_cleanup(dev); | 1963 | mlx4_cmd_cleanup(dev); |
1459 | 1964 | ||
1460 | if (dev->flags & MLX4_FLAG_MSI_X) | 1965 | if (dev->flags & MLX4_FLAG_MSI_X) |
1461 | pci_disable_msix(pdev); | 1966 | pci_disable_msix(pdev); |
1967 | if (num_vfs && (dev->flags & MLX4_FLAG_SRIOV)) { | ||
1968 | mlx4_warn(dev, "Disabling sriov\n"); | ||
1969 | pci_disable_sriov(pdev); | ||
1970 | } | ||
1462 | 1971 | ||
1972 | if (!mlx4_is_slave(dev)) | ||
1973 | mlx4_free_ownership(dev); | ||
1463 | kfree(priv); | 1974 | kfree(priv); |
1464 | pci_release_regions(pdev); | 1975 | pci_release_regions(pdev); |
1465 | pci_disable_device(pdev); | 1976 | pci_disable_device(pdev); |
@@ -1474,33 +1985,48 @@ int mlx4_restart_one(struct pci_dev *pdev) | |||
1474 | } | 1985 | } |
1475 | 1986 | ||
1476 | static DEFINE_PCI_DEVICE_TABLE(mlx4_pci_table) = { | 1987 | static DEFINE_PCI_DEVICE_TABLE(mlx4_pci_table) = { |
1477 | { PCI_VDEVICE(MELLANOX, 0x6340) }, /* MT25408 "Hermon" SDR */ | 1988 | /* MT25408 "Hermon" SDR */ |
1478 | { PCI_VDEVICE(MELLANOX, 0x634a) }, /* MT25408 "Hermon" DDR */ | 1989 | { PCI_VDEVICE(MELLANOX, 0x6340), 0 }, |
1479 | { PCI_VDEVICE(MELLANOX, 0x6354) }, /* MT25408 "Hermon" QDR */ | 1990 | /* MT25408 "Hermon" DDR */ |
1480 | { PCI_VDEVICE(MELLANOX, 0x6732) }, /* MT25408 "Hermon" DDR PCIe gen2 */ | 1991 | { PCI_VDEVICE(MELLANOX, 0x634a), 0 }, |
1481 | { PCI_VDEVICE(MELLANOX, 0x673c) }, /* MT25408 "Hermon" QDR PCIe gen2 */ | 1992 | /* MT25408 "Hermon" QDR */ |
1482 | { PCI_VDEVICE(MELLANOX, 0x6368) }, /* MT25408 "Hermon" EN 10GigE */ | 1993 | { PCI_VDEVICE(MELLANOX, 0x6354), 0 }, |
1483 | { PCI_VDEVICE(MELLANOX, 0x6750) }, /* MT25408 "Hermon" EN 10GigE PCIe gen2 */ | 1994 | /* MT25408 "Hermon" DDR PCIe gen2 */ |
1484 | { PCI_VDEVICE(MELLANOX, 0x6372) }, /* MT25458 ConnectX EN 10GBASE-T 10GigE */ | 1995 | { PCI_VDEVICE(MELLANOX, 0x6732), 0 }, |
1485 | { PCI_VDEVICE(MELLANOX, 0x675a) }, /* MT25458 ConnectX EN 10GBASE-T+Gen2 10GigE */ | 1996 | /* MT25408 "Hermon" QDR PCIe gen2 */ |
1486 | { PCI_VDEVICE(MELLANOX, 0x6764) }, /* MT26468 ConnectX EN 10GigE PCIe gen2*/ | 1997 | { PCI_VDEVICE(MELLANOX, 0x673c), 0 }, |
1487 | { PCI_VDEVICE(MELLANOX, 0x6746) }, /* MT26438 ConnectX EN 40GigE PCIe gen2 5GT/s */ | 1998 | /* MT25408 "Hermon" EN 10GigE */ |
1488 | { PCI_VDEVICE(MELLANOX, 0x676e) }, /* MT26478 ConnectX2 40GigE PCIe gen2 */ | 1999 | { PCI_VDEVICE(MELLANOX, 0x6368), 0 }, |
1489 | { PCI_VDEVICE(MELLANOX, 0x1002) }, /* MT25400 Family [ConnectX-2 Virtual Function] */ | 2000 | /* MT25408 "Hermon" EN 10GigE PCIe gen2 */ |
1490 | { PCI_VDEVICE(MELLANOX, 0x1003) }, /* MT27500 Family [ConnectX-3] */ | 2001 | { PCI_VDEVICE(MELLANOX, 0x6750), 0 }, |
1491 | { PCI_VDEVICE(MELLANOX, 0x1004) }, /* MT27500 Family [ConnectX-3 Virtual Function] */ | 2002 | /* MT25458 ConnectX EN 10GBASE-T 10GigE */ |
1492 | { PCI_VDEVICE(MELLANOX, 0x1005) }, /* MT27510 Family */ | 2003 | { PCI_VDEVICE(MELLANOX, 0x6372), 0 }, |
1493 | { PCI_VDEVICE(MELLANOX, 0x1006) }, /* MT27511 Family */ | 2004 | /* MT25458 ConnectX EN 10GBASE-T+Gen2 10GigE */ |
1494 | { PCI_VDEVICE(MELLANOX, 0x1007) }, /* MT27520 Family */ | 2005 | { PCI_VDEVICE(MELLANOX, 0x675a), 0 }, |
1495 | { PCI_VDEVICE(MELLANOX, 0x1008) }, /* MT27521 Family */ | 2006 | /* MT26468 ConnectX EN 10GigE PCIe gen2*/ |
1496 | { PCI_VDEVICE(MELLANOX, 0x1009) }, /* MT27530 Family */ | 2007 | { PCI_VDEVICE(MELLANOX, 0x6764), 0 }, |
1497 | { PCI_VDEVICE(MELLANOX, 0x100a) }, /* MT27531 Family */ | 2008 | /* MT26438 ConnectX EN 40GigE PCIe gen2 5GT/s */ |
1498 | { PCI_VDEVICE(MELLANOX, 0x100b) }, /* MT27540 Family */ | 2009 | { PCI_VDEVICE(MELLANOX, 0x6746), 0 }, |
1499 | { PCI_VDEVICE(MELLANOX, 0x100c) }, /* MT27541 Family */ | 2010 | /* MT26478 ConnectX2 40GigE PCIe gen2 */ |
1500 | { PCI_VDEVICE(MELLANOX, 0x100d) }, /* MT27550 Family */ | 2011 | { PCI_VDEVICE(MELLANOX, 0x676e), 0 }, |
1501 | { PCI_VDEVICE(MELLANOX, 0x100e) }, /* MT27551 Family */ | 2012 | /* MT25400 Family [ConnectX-2 Virtual Function] */ |
1502 | { PCI_VDEVICE(MELLANOX, 0x100f) }, /* MT27560 Family */ | 2013 | { PCI_VDEVICE(MELLANOX, 0x1002), MLX4_VF }, |
1503 | { PCI_VDEVICE(MELLANOX, 0x1010) }, /* MT27561 Family */ | 2014 | /* MT27500 Family [ConnectX-3] */ |
2015 | { PCI_VDEVICE(MELLANOX, 0x1003), 0 }, | ||
2016 | /* MT27500 Family [ConnectX-3 Virtual Function] */ | ||
2017 | { PCI_VDEVICE(MELLANOX, 0x1004), MLX4_VF }, | ||
2018 | { PCI_VDEVICE(MELLANOX, 0x1005), 0 }, /* MT27510 Family */ | ||
2019 | { PCI_VDEVICE(MELLANOX, 0x1006), 0 }, /* MT27511 Family */ | ||
2020 | { PCI_VDEVICE(MELLANOX, 0x1007), 0 }, /* MT27520 Family */ | ||
2021 | { PCI_VDEVICE(MELLANOX, 0x1008), 0 }, /* MT27521 Family */ | ||
2022 | { PCI_VDEVICE(MELLANOX, 0x1009), 0 }, /* MT27530 Family */ | ||
2023 | { PCI_VDEVICE(MELLANOX, 0x100a), 0 }, /* MT27531 Family */ | ||
2024 | { PCI_VDEVICE(MELLANOX, 0x100b), 0 }, /* MT27540 Family */ | ||
2025 | { PCI_VDEVICE(MELLANOX, 0x100c), 0 }, /* MT27541 Family */ | ||
2026 | { PCI_VDEVICE(MELLANOX, 0x100d), 0 }, /* MT27550 Family */ | ||
2027 | { PCI_VDEVICE(MELLANOX, 0x100e), 0 }, /* MT27551 Family */ | ||
2028 | { PCI_VDEVICE(MELLANOX, 0x100f), 0 }, /* MT27560 Family */ | ||
2029 | { PCI_VDEVICE(MELLANOX, 0x1010), 0 }, /* MT27561 Family */ | ||
1504 | { 0, } | 2030 | { 0, } |
1505 | }; | 2031 | }; |
1506 | 2032 | ||
@@ -1529,6 +2055,12 @@ static int __init mlx4_verify_params(void) | |||
1529 | return -1; | 2055 | return -1; |
1530 | } | 2056 | } |
1531 | 2057 | ||
2058 | /* Check if module param for ports type has legal combination */ | ||
2059 | if (port_type_array[0] == false && port_type_array[1] == true) { | ||
2060 | printk(KERN_WARNING "Module parameter configuration ETH/IB is not supported. Switching to default configuration IB/IB\n"); | ||
2061 | port_type_array[0] = true; | ||
2062 | } | ||
2063 | |||
1532 | return 0; | 2064 | return 0; |
1533 | } | 2065 | } |
1534 | 2066 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h index 879f825c6f6..3921dbf01da 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h | |||
@@ -49,6 +49,7 @@ | |||
49 | #include <linux/mlx4/cmd.h> | 49 | #include <linux/mlx4/cmd.h> |
50 | 50 | ||
51 | #define DRV_NAME "mlx4_core" | 51 | #define DRV_NAME "mlx4_core" |
52 | #define PFX DRV_NAME ": " | ||
52 | #define DRV_VERSION "1.0" | 53 | #define DRV_VERSION "1.0" |
53 | #define DRV_RELDATE "July 14, 2011" | 54 | #define DRV_RELDATE "July 14, 2011" |
54 | 55 | ||
@@ -957,10 +958,15 @@ int mlx4_GEN_EQE(struct mlx4_dev *dev, int slave, struct mlx4_eqe *eqe); | |||
957 | 958 | ||
958 | int mlx4_cmd_init(struct mlx4_dev *dev); | 959 | int mlx4_cmd_init(struct mlx4_dev *dev); |
959 | void mlx4_cmd_cleanup(struct mlx4_dev *dev); | 960 | void mlx4_cmd_cleanup(struct mlx4_dev *dev); |
961 | int mlx4_multi_func_init(struct mlx4_dev *dev); | ||
962 | void mlx4_multi_func_cleanup(struct mlx4_dev *dev); | ||
960 | void mlx4_cmd_event(struct mlx4_dev *dev, u16 token, u8 status, u64 out_param); | 963 | void mlx4_cmd_event(struct mlx4_dev *dev, u16 token, u8 status, u64 out_param); |
961 | int mlx4_cmd_use_events(struct mlx4_dev *dev); | 964 | int mlx4_cmd_use_events(struct mlx4_dev *dev); |
962 | void mlx4_cmd_use_polling(struct mlx4_dev *dev); | 965 | void mlx4_cmd_use_polling(struct mlx4_dev *dev); |
963 | 966 | ||
967 | int mlx4_comm_cmd(struct mlx4_dev *dev, u8 cmd, u16 param, | ||
968 | unsigned long timeout); | ||
969 | |||
964 | void mlx4_cq_completion(struct mlx4_dev *dev, u32 cqn); | 970 | void mlx4_cq_completion(struct mlx4_dev *dev, u32 cqn); |
965 | void mlx4_cq_event(struct mlx4_dev *dev, u32 cqn, int event_type); | 971 | void mlx4_cq_event(struct mlx4_dev *dev, u32 cqn, int event_type); |
966 | 972 | ||
diff --git a/include/linux/mlx4/cmd.h b/include/linux/mlx4/cmd.h index ae62630a665..9958ff2cad3 100644 --- a/include/linux/mlx4/cmd.h +++ b/include/linux/mlx4/cmd.h | |||
@@ -225,4 +225,6 @@ void mlx4_free_cmd_mailbox(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbo | |||
225 | 225 | ||
226 | u32 mlx4_comm_get_version(void); | 226 | u32 mlx4_comm_get_version(void); |
227 | 227 | ||
228 | #define MLX4_COMM_GET_IF_REV(cmd_chan_ver) (u8)((cmd_chan_ver) >> 8) | ||
229 | |||
228 | #endif /* MLX4_CMD_H */ | 230 | #endif /* MLX4_CMD_H */ |
diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h index 65bb466c575..5f784ff6a36 100644 --- a/include/linux/mlx4/device.h +++ b/include/linux/mlx4/device.h | |||
@@ -489,6 +489,7 @@ struct mlx4_dev { | |||
489 | struct radix_tree_root qp_table_tree; | 489 | struct radix_tree_root qp_table_tree; |
490 | u8 rev_id; | 490 | u8 rev_id; |
491 | char board_id[MLX4_BOARD_ID_LEN]; | 491 | char board_id[MLX4_BOARD_ID_LEN]; |
492 | int num_vfs; | ||
492 | }; | 493 | }; |
493 | 494 | ||
494 | struct mlx4_init_port_param { | 495 | struct mlx4_init_port_param { |