diff options
Diffstat (limited to 'drivers/net')
| -rw-r--r-- | drivers/net/ethernet/emulex/benet/be.h | 1 | ||||
| -rw-r--r-- | drivers/net/ethernet/emulex/benet/be_main.c | 1 | ||||
| -rw-r--r-- | drivers/net/ethernet/emulex/benet/be_roce.c | 18 | ||||
| -rw-r--r-- | drivers/net/ethernet/emulex/benet/be_roce.h | 3 | ||||
| -rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/cmd.c | 9 | ||||
| -rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/fw.c | 91 | ||||
| -rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/main.c | 5 | ||||
| -rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/mlx4.h | 3 | ||||
| -rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/mr.c | 160 | ||||
| -rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/resource_tracker.c | 26 |
10 files changed, 311 insertions, 6 deletions
diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h index c2f5d2d3b932..56d4d100e024 100644 --- a/drivers/net/ethernet/emulex/benet/be.h +++ b/drivers/net/ethernet/emulex/benet/be.h | |||
| @@ -890,5 +890,6 @@ void be_roce_dev_remove(struct be_adapter *); | |||
| 890 | */ | 890 | */ |
| 891 | void be_roce_dev_open(struct be_adapter *); | 891 | void be_roce_dev_open(struct be_adapter *); |
| 892 | void be_roce_dev_close(struct be_adapter *); | 892 | void be_roce_dev_close(struct be_adapter *); |
| 893 | void be_roce_dev_shutdown(struct be_adapter *); | ||
| 893 | 894 | ||
| 894 | #endif /* BE_H */ | 895 | #endif /* BE_H */ |
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 1e187fb760f8..36ce69ae9a2f 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c | |||
| @@ -4958,6 +4958,7 @@ static void be_shutdown(struct pci_dev *pdev) | |||
| 4958 | if (!adapter) | 4958 | if (!adapter) |
| 4959 | return; | 4959 | return; |
| 4960 | 4960 | ||
| 4961 | be_roce_dev_shutdown(adapter); | ||
| 4961 | cancel_delayed_work_sync(&adapter->work); | 4962 | cancel_delayed_work_sync(&adapter->work); |
| 4962 | cancel_delayed_work_sync(&adapter->func_recovery_work); | 4963 | cancel_delayed_work_sync(&adapter->func_recovery_work); |
| 4963 | 4964 | ||
diff --git a/drivers/net/ethernet/emulex/benet/be_roce.c b/drivers/net/ethernet/emulex/benet/be_roce.c index 5bf16603a3e9..ef4672dc7357 100644 --- a/drivers/net/ethernet/emulex/benet/be_roce.c +++ b/drivers/net/ethernet/emulex/benet/be_roce.c | |||
| @@ -120,7 +120,8 @@ static void _be_roce_dev_open(struct be_adapter *adapter) | |||
| 120 | { | 120 | { |
| 121 | if (ocrdma_drv && adapter->ocrdma_dev && | 121 | if (ocrdma_drv && adapter->ocrdma_dev && |
| 122 | ocrdma_drv->state_change_handler) | 122 | ocrdma_drv->state_change_handler) |
| 123 | ocrdma_drv->state_change_handler(adapter->ocrdma_dev, 0); | 123 | ocrdma_drv->state_change_handler(adapter->ocrdma_dev, |
| 124 | BE_DEV_UP); | ||
| 124 | } | 125 | } |
| 125 | 126 | ||
| 126 | void be_roce_dev_open(struct be_adapter *adapter) | 127 | void be_roce_dev_open(struct be_adapter *adapter) |
| @@ -136,7 +137,8 @@ static void _be_roce_dev_close(struct be_adapter *adapter) | |||
| 136 | { | 137 | { |
| 137 | if (ocrdma_drv && adapter->ocrdma_dev && | 138 | if (ocrdma_drv && adapter->ocrdma_dev && |
| 138 | ocrdma_drv->state_change_handler) | 139 | ocrdma_drv->state_change_handler) |
| 139 | ocrdma_drv->state_change_handler(adapter->ocrdma_dev, 1); | 140 | ocrdma_drv->state_change_handler(adapter->ocrdma_dev, |
| 141 | BE_DEV_DOWN); | ||
| 140 | } | 142 | } |
| 141 | 143 | ||
| 142 | void be_roce_dev_close(struct be_adapter *adapter) | 144 | void be_roce_dev_close(struct be_adapter *adapter) |
| @@ -148,6 +150,18 @@ void be_roce_dev_close(struct be_adapter *adapter) | |||
| 148 | } | 150 | } |
| 149 | } | 151 | } |
| 150 | 152 | ||
| 153 | void be_roce_dev_shutdown(struct be_adapter *adapter) | ||
| 154 | { | ||
| 155 | if (be_roce_supported(adapter)) { | ||
| 156 | mutex_lock(&be_adapter_list_lock); | ||
| 157 | if (ocrdma_drv && adapter->ocrdma_dev && | ||
| 158 | ocrdma_drv->state_change_handler) | ||
| 159 | ocrdma_drv->state_change_handler(adapter->ocrdma_dev, | ||
| 160 | BE_DEV_SHUTDOWN); | ||
| 161 | mutex_unlock(&be_adapter_list_lock); | ||
| 162 | } | ||
| 163 | } | ||
| 164 | |||
| 151 | int be_roce_register_driver(struct ocrdma_driver *drv) | 165 | int be_roce_register_driver(struct ocrdma_driver *drv) |
| 152 | { | 166 | { |
| 153 | struct be_adapter *dev; | 167 | struct be_adapter *dev; |
diff --git a/drivers/net/ethernet/emulex/benet/be_roce.h b/drivers/net/ethernet/emulex/benet/be_roce.h index a3d9e96c18eb..e6f7eb1a7d87 100644 --- a/drivers/net/ethernet/emulex/benet/be_roce.h +++ b/drivers/net/ethernet/emulex/benet/be_roce.h | |||
| @@ -62,7 +62,8 @@ struct ocrdma_driver { | |||
| 62 | 62 | ||
| 63 | enum { | 63 | enum { |
| 64 | BE_DEV_UP = 0, | 64 | BE_DEV_UP = 0, |
| 65 | BE_DEV_DOWN = 1 | 65 | BE_DEV_DOWN = 1, |
| 66 | BE_DEV_SHUTDOWN = 2 | ||
| 66 | }; | 67 | }; |
| 67 | 68 | ||
| 68 | /* APIs for RoCE driver to register callback handlers, | 69 | /* APIs for RoCE driver to register callback handlers, |
diff --git a/drivers/net/ethernet/mellanox/mlx4/cmd.c b/drivers/net/ethernet/mellanox/mlx4/cmd.c index 5d940a26055c..65a4a0f88ea0 100644 --- a/drivers/net/ethernet/mellanox/mlx4/cmd.c +++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c | |||
| @@ -1311,6 +1311,15 @@ static struct mlx4_cmd_info cmd_info[] = { | |||
| 1311 | .wrapper = mlx4_MAD_IFC_wrapper | 1311 | .wrapper = mlx4_MAD_IFC_wrapper |
| 1312 | }, | 1312 | }, |
| 1313 | { | 1313 | { |
| 1314 | .opcode = MLX4_CMD_MAD_DEMUX, | ||
| 1315 | .has_inbox = false, | ||
| 1316 | .has_outbox = false, | ||
| 1317 | .out_is_imm = false, | ||
| 1318 | .encode_slave_id = false, | ||
| 1319 | .verify = NULL, | ||
| 1320 | .wrapper = mlx4_CMD_EPERM_wrapper | ||
| 1321 | }, | ||
| 1322 | { | ||
| 1314 | .opcode = MLX4_CMD_QUERY_IF_STAT, | 1323 | .opcode = MLX4_CMD_QUERY_IF_STAT, |
| 1315 | .has_inbox = false, | 1324 | .has_inbox = false, |
| 1316 | .has_outbox = true, | 1325 | .has_outbox = true, |
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c index 688e1eabab29..494753e44ae3 100644 --- a/drivers/net/ethernet/mellanox/mlx4/fw.c +++ b/drivers/net/ethernet/mellanox/mlx4/fw.c | |||
| @@ -136,7 +136,8 @@ static void dump_dev_cap_flags2(struct mlx4_dev *dev, u64 flags) | |||
| 136 | [7] = "FSM (MAC anti-spoofing) support", | 136 | [7] = "FSM (MAC anti-spoofing) support", |
| 137 | [8] = "Dynamic QP updates support", | 137 | [8] = "Dynamic QP updates support", |
| 138 | [9] = "Device managed flow steering IPoIB support", | 138 | [9] = "Device managed flow steering IPoIB support", |
| 139 | [10] = "TCP/IP offloads/flow-steering for VXLAN support" | 139 | [10] = "TCP/IP offloads/flow-steering for VXLAN support", |
| 140 | [11] = "MAD DEMUX (Secure-Host) support" | ||
| 140 | }; | 141 | }; |
| 141 | int i; | 142 | int i; |
| 142 | 143 | ||
| @@ -571,6 +572,7 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) | |||
| 571 | #define QUERY_DEV_CAP_MAX_ICM_SZ_OFFSET 0xa0 | 572 | #define QUERY_DEV_CAP_MAX_ICM_SZ_OFFSET 0xa0 |
| 572 | #define QUERY_DEV_CAP_FW_REASSIGN_MAC 0x9d | 573 | #define QUERY_DEV_CAP_FW_REASSIGN_MAC 0x9d |
| 573 | #define QUERY_DEV_CAP_VXLAN 0x9e | 574 | #define QUERY_DEV_CAP_VXLAN 0x9e |
| 575 | #define QUERY_DEV_CAP_MAD_DEMUX_OFFSET 0xb0 | ||
| 574 | 576 | ||
| 575 | dev_cap->flags2 = 0; | 577 | dev_cap->flags2 = 0; |
| 576 | mailbox = mlx4_alloc_cmd_mailbox(dev); | 578 | mailbox = mlx4_alloc_cmd_mailbox(dev); |
| @@ -748,6 +750,11 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) | |||
| 748 | MLX4_GET(dev_cap->max_counters, outbox, | 750 | MLX4_GET(dev_cap->max_counters, outbox, |
| 749 | QUERY_DEV_CAP_MAX_COUNTERS_OFFSET); | 751 | QUERY_DEV_CAP_MAX_COUNTERS_OFFSET); |
| 750 | 752 | ||
| 753 | MLX4_GET(field32, outbox, | ||
| 754 | QUERY_DEV_CAP_MAD_DEMUX_OFFSET); | ||
| 755 | if (field32 & (1 << 0)) | ||
| 756 | dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_MAD_DEMUX; | ||
| 757 | |||
| 751 | MLX4_GET(field32, outbox, QUERY_DEV_CAP_EXT_2_FLAGS_OFFSET); | 758 | MLX4_GET(field32, outbox, QUERY_DEV_CAP_EXT_2_FLAGS_OFFSET); |
| 752 | if (field32 & (1 << 16)) | 759 | if (field32 & (1 << 16)) |
| 753 | dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_UPDATE_QP; | 760 | dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_UPDATE_QP; |
| @@ -2016,3 +2023,85 @@ void mlx4_opreq_action(struct work_struct *work) | |||
| 2016 | out: | 2023 | out: |
| 2017 | mlx4_free_cmd_mailbox(dev, mailbox); | 2024 | mlx4_free_cmd_mailbox(dev, mailbox); |
| 2018 | } | 2025 | } |
| 2026 | |||
| 2027 | static int mlx4_check_smp_firewall_active(struct mlx4_dev *dev, | ||
| 2028 | struct mlx4_cmd_mailbox *mailbox) | ||
| 2029 | { | ||
| 2030 | #define MLX4_CMD_MAD_DEMUX_SET_ATTR_OFFSET 0x10 | ||
| 2031 | #define MLX4_CMD_MAD_DEMUX_GETRESP_ATTR_OFFSET 0x20 | ||
| 2032 | #define MLX4_CMD_MAD_DEMUX_TRAP_ATTR_OFFSET 0x40 | ||
| 2033 | #define MLX4_CMD_MAD_DEMUX_TRAP_REPRESS_ATTR_OFFSET 0x70 | ||
| 2034 | |||
| 2035 | u32 set_attr_mask, getresp_attr_mask; | ||
| 2036 | u32 trap_attr_mask, traprepress_attr_mask; | ||
| 2037 | |||
| 2038 | MLX4_GET(set_attr_mask, mailbox->buf, | ||
| 2039 | MLX4_CMD_MAD_DEMUX_SET_ATTR_OFFSET); | ||
| 2040 | mlx4_dbg(dev, "SMP firewall set_attribute_mask = 0x%x\n", | ||
| 2041 | set_attr_mask); | ||
| 2042 | |||
| 2043 | MLX4_GET(getresp_attr_mask, mailbox->buf, | ||
| 2044 | MLX4_CMD_MAD_DEMUX_GETRESP_ATTR_OFFSET); | ||
| 2045 | mlx4_dbg(dev, "SMP firewall getresp_attribute_mask = 0x%x\n", | ||
| 2046 | getresp_attr_mask); | ||
| 2047 | |||
| 2048 | MLX4_GET(trap_attr_mask, mailbox->buf, | ||
| 2049 | MLX4_CMD_MAD_DEMUX_TRAP_ATTR_OFFSET); | ||
| 2050 | mlx4_dbg(dev, "SMP firewall trap_attribute_mask = 0x%x\n", | ||
| 2051 | trap_attr_mask); | ||
| 2052 | |||
| 2053 | MLX4_GET(traprepress_attr_mask, mailbox->buf, | ||
| 2054 | MLX4_CMD_MAD_DEMUX_TRAP_REPRESS_ATTR_OFFSET); | ||
| 2055 | mlx4_dbg(dev, "SMP firewall traprepress_attribute_mask = 0x%x\n", | ||
| 2056 | traprepress_attr_mask); | ||
| 2057 | |||
| 2058 | if (set_attr_mask && getresp_attr_mask && trap_attr_mask && | ||
| 2059 | traprepress_attr_mask) | ||
| 2060 | return 1; | ||
| 2061 | |||
| 2062 | return 0; | ||
| 2063 | } | ||
| 2064 | |||
| 2065 | int mlx4_config_mad_demux(struct mlx4_dev *dev) | ||
| 2066 | { | ||
| 2067 | struct mlx4_cmd_mailbox *mailbox; | ||
| 2068 | int secure_host_active; | ||
| 2069 | int err; | ||
| 2070 | |||
| 2071 | /* Check if mad_demux is supported */ | ||
| 2072 | if (!(dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_MAD_DEMUX)) | ||
| 2073 | return 0; | ||
| 2074 | |||
| 2075 | mailbox = mlx4_alloc_cmd_mailbox(dev); | ||
| 2076 | if (IS_ERR(mailbox)) { | ||
| 2077 | mlx4_warn(dev, "Failed to allocate mailbox for cmd MAD_DEMUX"); | ||
| 2078 | return -ENOMEM; | ||
| 2079 | } | ||
| 2080 | |||
| 2081 | /* Query mad_demux to find out which MADs are handled by internal sma */ | ||
| 2082 | err = mlx4_cmd_box(dev, 0, mailbox->dma, 0x01 /* subn mgmt class */, | ||
| 2083 | MLX4_CMD_MAD_DEMUX_QUERY_RESTR, MLX4_CMD_MAD_DEMUX, | ||
| 2084 | MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE); | ||
| 2085 | if (err) { | ||
| 2086 | mlx4_warn(dev, "MLX4_CMD_MAD_DEMUX: query restrictions failed (%d)\n", | ||
| 2087 | err); | ||
| 2088 | goto out; | ||
| 2089 | } | ||
| 2090 | |||
| 2091 | secure_host_active = mlx4_check_smp_firewall_active(dev, mailbox); | ||
| 2092 | |||
| 2093 | /* Config mad_demux to handle all MADs returned by the query above */ | ||
| 2094 | err = mlx4_cmd(dev, mailbox->dma, 0x01 /* subn mgmt class */, | ||
| 2095 | MLX4_CMD_MAD_DEMUX_CONFIG, MLX4_CMD_MAD_DEMUX, | ||
| 2096 | MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE); | ||
| 2097 | if (err) { | ||
| 2098 | mlx4_warn(dev, "MLX4_CMD_MAD_DEMUX: configure failed (%d)\n", err); | ||
| 2099 | goto out; | ||
| 2100 | } | ||
| 2101 | |||
| 2102 | if (secure_host_active) | ||
| 2103 | mlx4_warn(dev, "HCA operating in secure-host mode. SMP firewall activated.\n"); | ||
| 2104 | out: | ||
| 2105 | mlx4_free_cmd_mailbox(dev, mailbox); | ||
| 2106 | return err; | ||
| 2107 | } | ||
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index 82ab427290c3..f2c8e8ba23fe 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c | |||
| @@ -1831,6 +1831,11 @@ static int mlx4_setup_hca(struct mlx4_dev *dev) | |||
| 1831 | mlx4_err(dev, "Failed to initialize multicast group table, aborting\n"); | 1831 | mlx4_err(dev, "Failed to initialize multicast group table, aborting\n"); |
| 1832 | goto err_mr_table_free; | 1832 | goto err_mr_table_free; |
| 1833 | } | 1833 | } |
| 1834 | err = mlx4_config_mad_demux(dev); | ||
| 1835 | if (err) { | ||
| 1836 | mlx4_err(dev, "Failed in config_mad_demux, aborting\n"); | ||
| 1837 | goto err_mcg_table_free; | ||
| 1838 | } | ||
| 1834 | } | 1839 | } |
| 1835 | 1840 | ||
| 1836 | err = mlx4_init_eq_table(dev); | 1841 | err = mlx4_init_eq_table(dev); |
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h index 1d8af7336807..3398ff7e67e9 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h | |||
| @@ -279,6 +279,8 @@ struct mlx4_icm_table { | |||
| 279 | #define MLX4_MPT_FLAG_PHYSICAL (1 << 9) | 279 | #define MLX4_MPT_FLAG_PHYSICAL (1 << 9) |
| 280 | #define MLX4_MPT_FLAG_REGION (1 << 8) | 280 | #define MLX4_MPT_FLAG_REGION (1 << 8) |
| 281 | 281 | ||
| 282 | #define MLX4_MPT_PD_MASK (0x1FFFFUL) | ||
| 283 | #define MLX4_MPT_PD_VF_MASK (0xFE0000UL) | ||
| 282 | #define MLX4_MPT_PD_FLAG_FAST_REG (1 << 27) | 284 | #define MLX4_MPT_PD_FLAG_FAST_REG (1 << 27) |
| 283 | #define MLX4_MPT_PD_FLAG_RAE (1 << 28) | 285 | #define MLX4_MPT_PD_FLAG_RAE (1 << 28) |
| 284 | #define MLX4_MPT_PD_FLAG_EN_INV (3 << 24) | 286 | #define MLX4_MPT_PD_FLAG_EN_INV (3 << 24) |
| @@ -1311,5 +1313,6 @@ void mlx4_init_quotas(struct mlx4_dev *dev); | |||
| 1311 | int mlx4_get_slave_num_gids(struct mlx4_dev *dev, int slave, int port); | 1313 | int mlx4_get_slave_num_gids(struct mlx4_dev *dev, int slave, int port); |
| 1312 | /* Returns the VF index of slave */ | 1314 | /* Returns the VF index of slave */ |
| 1313 | int mlx4_get_vf_indx(struct mlx4_dev *dev, int slave); | 1315 | int mlx4_get_vf_indx(struct mlx4_dev *dev, int slave); |
| 1316 | int mlx4_config_mad_demux(struct mlx4_dev *dev); | ||
| 1314 | 1317 | ||
| 1315 | #endif /* MLX4_H */ | 1318 | #endif /* MLX4_H */ |
diff --git a/drivers/net/ethernet/mellanox/mlx4/mr.c b/drivers/net/ethernet/mellanox/mlx4/mr.c index 2839abb878a6..7d717eccb7b0 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mr.c +++ b/drivers/net/ethernet/mellanox/mlx4/mr.c | |||
| @@ -298,6 +298,131 @@ static int mlx4_HW2SW_MPT(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox | |||
| 298 | MLX4_CMD_TIME_CLASS_B, MLX4_CMD_WRAPPED); | 298 | MLX4_CMD_TIME_CLASS_B, MLX4_CMD_WRAPPED); |
| 299 | } | 299 | } |
| 300 | 300 | ||
| 301 | int mlx4_mr_hw_get_mpt(struct mlx4_dev *dev, struct mlx4_mr *mmr, | ||
| 302 | struct mlx4_mpt_entry ***mpt_entry) | ||
| 303 | { | ||
| 304 | int err; | ||
| 305 | int key = key_to_hw_index(mmr->key) & (dev->caps.num_mpts - 1); | ||
| 306 | struct mlx4_cmd_mailbox *mailbox = NULL; | ||
| 307 | |||
| 308 | /* Make sure that at this point we have single-threaded access only */ | ||
| 309 | |||
| 310 | if (mmr->enabled != MLX4_MPT_EN_HW) | ||
| 311 | return -EINVAL; | ||
| 312 | |||
| 313 | err = mlx4_HW2SW_MPT(dev, NULL, key); | ||
| 314 | |||
| 315 | if (err) { | ||
| 316 | mlx4_warn(dev, "HW2SW_MPT failed (%d).", err); | ||
| 317 | mlx4_warn(dev, "Most likely the MR has MWs bound to it.\n"); | ||
| 318 | return err; | ||
| 319 | } | ||
| 320 | |||
| 321 | mmr->enabled = MLX4_MPT_EN_SW; | ||
| 322 | |||
| 323 | if (!mlx4_is_mfunc(dev)) { | ||
| 324 | **mpt_entry = mlx4_table_find( | ||
| 325 | &mlx4_priv(dev)->mr_table.dmpt_table, | ||
| 326 | key, NULL); | ||
| 327 | } else { | ||
| 328 | mailbox = mlx4_alloc_cmd_mailbox(dev); | ||
| 329 | if (IS_ERR_OR_NULL(mailbox)) | ||
| 330 | return PTR_ERR(mailbox); | ||
| 331 | |||
| 332 | err = mlx4_cmd_box(dev, 0, mailbox->dma, key, | ||
| 333 | 0, MLX4_CMD_QUERY_MPT, | ||
| 334 | MLX4_CMD_TIME_CLASS_B, | ||
| 335 | MLX4_CMD_WRAPPED); | ||
| 336 | |||
| 337 | if (err) | ||
| 338 | goto free_mailbox; | ||
| 339 | |||
| 340 | *mpt_entry = (struct mlx4_mpt_entry **)&mailbox->buf; | ||
| 341 | } | ||
| 342 | |||
| 343 | if (!(*mpt_entry) || !(**mpt_entry)) { | ||
| 344 | err = -ENOMEM; | ||
| 345 | goto free_mailbox; | ||
| 346 | } | ||
| 347 | |||
| 348 | return 0; | ||
| 349 | |||
| 350 | free_mailbox: | ||
| 351 | mlx4_free_cmd_mailbox(dev, mailbox); | ||
| 352 | return err; | ||
| 353 | } | ||
| 354 | EXPORT_SYMBOL_GPL(mlx4_mr_hw_get_mpt); | ||
| 355 | |||
| 356 | int mlx4_mr_hw_write_mpt(struct mlx4_dev *dev, struct mlx4_mr *mmr, | ||
| 357 | struct mlx4_mpt_entry **mpt_entry) | ||
| 358 | { | ||
| 359 | int err; | ||
| 360 | |||
| 361 | if (!mlx4_is_mfunc(dev)) { | ||
| 362 | /* Make sure any changes to this entry are flushed */ | ||
| 363 | wmb(); | ||
| 364 | |||
| 365 | *(u8 *)(*mpt_entry) = MLX4_MPT_STATUS_HW; | ||
| 366 | |||
| 367 | /* Make sure the new status is written */ | ||
| 368 | wmb(); | ||
| 369 | |||
| 370 | err = mlx4_SYNC_TPT(dev); | ||
| 371 | } else { | ||
| 372 | int key = key_to_hw_index(mmr->key) & (dev->caps.num_mpts - 1); | ||
| 373 | |||
| 374 | struct mlx4_cmd_mailbox *mailbox = | ||
| 375 | container_of((void *)mpt_entry, struct mlx4_cmd_mailbox, | ||
| 376 | buf); | ||
| 377 | |||
| 378 | err = mlx4_SW2HW_MPT(dev, mailbox, key); | ||
| 379 | } | ||
| 380 | |||
| 381 | mmr->pd = be32_to_cpu((*mpt_entry)->pd_flags) & MLX4_MPT_PD_MASK; | ||
| 382 | if (!err) | ||
| 383 | mmr->enabled = MLX4_MPT_EN_HW; | ||
| 384 | return err; | ||
| 385 | } | ||
| 386 | EXPORT_SYMBOL_GPL(mlx4_mr_hw_write_mpt); | ||
| 387 | |||
| 388 | void mlx4_mr_hw_put_mpt(struct mlx4_dev *dev, | ||
| 389 | struct mlx4_mpt_entry **mpt_entry) | ||
| 390 | { | ||
| 391 | if (mlx4_is_mfunc(dev)) { | ||
| 392 | struct mlx4_cmd_mailbox *mailbox = | ||
| 393 | container_of((void *)mpt_entry, struct mlx4_cmd_mailbox, | ||
| 394 | buf); | ||
| 395 | mlx4_free_cmd_mailbox(dev, mailbox); | ||
| 396 | } | ||
| 397 | } | ||
| 398 | EXPORT_SYMBOL_GPL(mlx4_mr_hw_put_mpt); | ||
| 399 | |||
| 400 | int mlx4_mr_hw_change_pd(struct mlx4_dev *dev, struct mlx4_mpt_entry *mpt_entry, | ||
| 401 | u32 pdn) | ||
| 402 | { | ||
| 403 | u32 pd_flags = be32_to_cpu(mpt_entry->pd_flags); | ||
| 404 | /* The wrapper function will put the slave's id here */ | ||
| 405 | if (mlx4_is_mfunc(dev)) | ||
| 406 | pd_flags &= ~MLX4_MPT_PD_VF_MASK; | ||
| 407 | mpt_entry->pd_flags = cpu_to_be32((pd_flags & ~MLX4_MPT_PD_MASK) | | ||
| 408 | (pdn & MLX4_MPT_PD_MASK) | ||
| 409 | | MLX4_MPT_PD_FLAG_EN_INV); | ||
| 410 | return 0; | ||
| 411 | } | ||
| 412 | EXPORT_SYMBOL_GPL(mlx4_mr_hw_change_pd); | ||
| 413 | |||
| 414 | int mlx4_mr_hw_change_access(struct mlx4_dev *dev, | ||
| 415 | struct mlx4_mpt_entry *mpt_entry, | ||
| 416 | u32 access) | ||
| 417 | { | ||
| 418 | u32 flags = (be32_to_cpu(mpt_entry->flags) & ~MLX4_PERM_MASK) | | ||
| 419 | (access & MLX4_PERM_MASK); | ||
| 420 | |||
| 421 | mpt_entry->flags = cpu_to_be32(flags); | ||
| 422 | return 0; | ||
| 423 | } | ||
| 424 | EXPORT_SYMBOL_GPL(mlx4_mr_hw_change_access); | ||
| 425 | |||
| 301 | static int mlx4_mr_alloc_reserved(struct mlx4_dev *dev, u32 mridx, u32 pd, | 426 | static int mlx4_mr_alloc_reserved(struct mlx4_dev *dev, u32 mridx, u32 pd, |
| 302 | u64 iova, u64 size, u32 access, int npages, | 427 | u64 iova, u64 size, u32 access, int npages, |
| 303 | int page_shift, struct mlx4_mr *mr) | 428 | int page_shift, struct mlx4_mr *mr) |
| @@ -463,6 +588,41 @@ int mlx4_mr_free(struct mlx4_dev *dev, struct mlx4_mr *mr) | |||
| 463 | } | 588 | } |
| 464 | EXPORT_SYMBOL_GPL(mlx4_mr_free); | 589 | EXPORT_SYMBOL_GPL(mlx4_mr_free); |
| 465 | 590 | ||
| 591 | void mlx4_mr_rereg_mem_cleanup(struct mlx4_dev *dev, struct mlx4_mr *mr) | ||
| 592 | { | ||
| 593 | mlx4_mtt_cleanup(dev, &mr->mtt); | ||
| 594 | } | ||
| 595 | EXPORT_SYMBOL_GPL(mlx4_mr_rereg_mem_cleanup); | ||
| 596 | |||
| 597 | int mlx4_mr_rereg_mem_write(struct mlx4_dev *dev, struct mlx4_mr *mr, | ||
| 598 | u64 iova, u64 size, int npages, | ||
| 599 | int page_shift, struct mlx4_mpt_entry *mpt_entry) | ||
| 600 | { | ||
| 601 | int err; | ||
| 602 | |||
| 603 | mpt_entry->start = cpu_to_be64(mr->iova); | ||
| 604 | mpt_entry->length = cpu_to_be64(mr->size); | ||
| 605 | mpt_entry->entity_size = cpu_to_be32(mr->mtt.page_shift); | ||
| 606 | |||
| 607 | err = mlx4_mtt_init(dev, npages, page_shift, &mr->mtt); | ||
| 608 | if (err) | ||
| 609 | return err; | ||
| 610 | |||
| 611 | if (mr->mtt.order < 0) { | ||
| 612 | mpt_entry->flags |= cpu_to_be32(MLX4_MPT_FLAG_PHYSICAL); | ||
| 613 | mpt_entry->mtt_addr = 0; | ||
| 614 | } else { | ||
| 615 | mpt_entry->mtt_addr = cpu_to_be64(mlx4_mtt_addr(dev, | ||
| 616 | &mr->mtt)); | ||
| 617 | if (mr->mtt.page_shift == 0) | ||
| 618 | mpt_entry->mtt_sz = cpu_to_be32(1 << mr->mtt.order); | ||
| 619 | } | ||
| 620 | mr->enabled = MLX4_MPT_EN_SW; | ||
| 621 | |||
| 622 | return 0; | ||
| 623 | } | ||
| 624 | EXPORT_SYMBOL_GPL(mlx4_mr_rereg_mem_write); | ||
| 625 | |||
| 466 | int mlx4_mr_enable(struct mlx4_dev *dev, struct mlx4_mr *mr) | 626 | int mlx4_mr_enable(struct mlx4_dev *dev, struct mlx4_mr *mr) |
| 467 | { | 627 | { |
| 468 | struct mlx4_cmd_mailbox *mailbox; | 628 | struct mlx4_cmd_mailbox *mailbox; |
diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c index 0efc1368e5a8..1089367fed22 100644 --- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c | |||
| @@ -2613,12 +2613,34 @@ int mlx4_QUERY_MPT_wrapper(struct mlx4_dev *dev, int slave, | |||
| 2613 | if (err) | 2613 | if (err) |
| 2614 | return err; | 2614 | return err; |
| 2615 | 2615 | ||
| 2616 | if (mpt->com.from_state != RES_MPT_HW) { | 2616 | if (mpt->com.from_state == RES_MPT_MAPPED) { |
| 2617 | /* In order to allow rereg in SRIOV, we need to alter the MPT entry. To do | ||
| 2618 | * that, the VF must read the MPT. But since the MPT entry memory is not | ||
| 2619 | * in the VF's virtual memory space, it must use QUERY_MPT to obtain the | ||
| 2620 | * entry contents. To guarantee that the MPT cannot be changed, the driver | ||
| 2621 | * must perform HW2SW_MPT before this query and return the MPT entry to HW | ||
| 2622 | * ownership fofollowing the change. The change here allows the VF to | ||
| 2623 | * perform QUERY_MPT also when the entry is in SW ownership. | ||
| 2624 | */ | ||
| 2625 | struct mlx4_mpt_entry *mpt_entry = mlx4_table_find( | ||
| 2626 | &mlx4_priv(dev)->mr_table.dmpt_table, | ||
| 2627 | mpt->key, NULL); | ||
| 2628 | |||
| 2629 | if (NULL == mpt_entry || NULL == outbox->buf) { | ||
| 2630 | err = -EINVAL; | ||
| 2631 | goto out; | ||
| 2632 | } | ||
| 2633 | |||
| 2634 | memcpy(outbox->buf, mpt_entry, sizeof(*mpt_entry)); | ||
| 2635 | |||
| 2636 | err = 0; | ||
| 2637 | } else if (mpt->com.from_state == RES_MPT_HW) { | ||
| 2638 | err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd); | ||
| 2639 | } else { | ||
| 2617 | err = -EBUSY; | 2640 | err = -EBUSY; |
| 2618 | goto out; | 2641 | goto out; |
| 2619 | } | 2642 | } |
| 2620 | 2643 | ||
| 2621 | err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd); | ||
| 2622 | 2644 | ||
| 2623 | out: | 2645 | out: |
| 2624 | put_res(dev, slave, id, RES_MPT); | 2646 | put_res(dev, slave, id, RES_MPT); |
