| .. | .. |
|---|
| 30 | 30 | * SOFTWARE. |
|---|
| 31 | 31 | */ |
|---|
| 32 | 32 | |
|---|
| 33 | | -#include <linux/mlx5/cmd.h> |
|---|
| 34 | 33 | #include <linux/mlx5/vport.h> |
|---|
| 35 | 34 | #include <rdma/ib_mad.h> |
|---|
| 36 | 35 | #include <rdma/ib_smi.h> |
|---|
| 37 | 36 | #include <rdma/ib_pma.h> |
|---|
| 38 | 37 | #include "mlx5_ib.h" |
|---|
| 38 | +#include "cmd.h" |
|---|
| 39 | 39 | |
|---|
| 40 | 40 | enum { |
|---|
| 41 | 41 | MLX5_IB_VENDOR_CLASS1 = 0x9, |
|---|
| .. | .. |
|---|
| 51 | 51 | return dev->mdev->port_caps[port_num - 1].has_smi; |
|---|
| 52 | 52 | } |
|---|
| 53 | 53 | |
|---|
| 54 | | -int mlx5_MAD_IFC(struct mlx5_ib_dev *dev, int ignore_mkey, int ignore_bkey, |
|---|
| 55 | | - u8 port, const struct ib_wc *in_wc, const struct ib_grh *in_grh, |
|---|
| 56 | | - const void *in_mad, void *response_mad) |
|---|
| 54 | +static int mlx5_MAD_IFC(struct mlx5_ib_dev *dev, int ignore_mkey, |
|---|
| 55 | + int ignore_bkey, u8 port, const struct ib_wc *in_wc, |
|---|
| 56 | + const struct ib_grh *in_grh, const void *in_mad, |
|---|
| 57 | + void *response_mad) |
|---|
| 57 | 58 | { |
|---|
| 58 | 59 | u8 op_modifier = 0; |
|---|
| 59 | 60 | |
|---|
| .. | .. |
|---|
| 68 | 69 | if (ignore_bkey || !in_wc) |
|---|
| 69 | 70 | op_modifier |= 0x2; |
|---|
| 70 | 71 | |
|---|
| 71 | | - return mlx5_core_mad_ifc(dev->mdev, in_mad, response_mad, op_modifier, port); |
|---|
| 72 | | -} |
|---|
| 73 | | - |
|---|
| 74 | | -static int process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num, |
|---|
| 75 | | - const struct ib_wc *in_wc, const struct ib_grh *in_grh, |
|---|
| 76 | | - const struct ib_mad *in_mad, struct ib_mad *out_mad) |
|---|
| 77 | | -{ |
|---|
| 78 | | - u16 slid; |
|---|
| 79 | | - int err; |
|---|
| 80 | | - |
|---|
| 81 | | - slid = in_wc ? ib_lid_cpu16(in_wc->slid) : be16_to_cpu(IB_LID_PERMISSIVE); |
|---|
| 82 | | - |
|---|
| 83 | | - if (in_mad->mad_hdr.method == IB_MGMT_METHOD_TRAP && slid == 0) |
|---|
| 84 | | - return IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_CONSUMED; |
|---|
| 85 | | - |
|---|
| 86 | | - if (in_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_LID_ROUTED || |
|---|
| 87 | | - in_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) { |
|---|
| 88 | | - if (in_mad->mad_hdr.method != IB_MGMT_METHOD_GET && |
|---|
| 89 | | - in_mad->mad_hdr.method != IB_MGMT_METHOD_SET && |
|---|
| 90 | | - in_mad->mad_hdr.method != IB_MGMT_METHOD_TRAP_REPRESS) |
|---|
| 91 | | - return IB_MAD_RESULT_SUCCESS; |
|---|
| 92 | | - |
|---|
| 93 | | - /* Don't process SMInfo queries -- the SMA can't handle them. |
|---|
| 94 | | - */ |
|---|
| 95 | | - if (in_mad->mad_hdr.attr_id == IB_SMP_ATTR_SM_INFO) |
|---|
| 96 | | - return IB_MAD_RESULT_SUCCESS; |
|---|
| 97 | | - } else if (in_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_PERF_MGMT || |
|---|
| 98 | | - in_mad->mad_hdr.mgmt_class == MLX5_IB_VENDOR_CLASS1 || |
|---|
| 99 | | - in_mad->mad_hdr.mgmt_class == MLX5_IB_VENDOR_CLASS2 || |
|---|
| 100 | | - in_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_CONG_MGMT) { |
|---|
| 101 | | - if (in_mad->mad_hdr.method != IB_MGMT_METHOD_GET && |
|---|
| 102 | | - in_mad->mad_hdr.method != IB_MGMT_METHOD_SET) |
|---|
| 103 | | - return IB_MAD_RESULT_SUCCESS; |
|---|
| 104 | | - } else { |
|---|
| 105 | | - return IB_MAD_RESULT_SUCCESS; |
|---|
| 106 | | - } |
|---|
| 107 | | - |
|---|
| 108 | | - err = mlx5_MAD_IFC(to_mdev(ibdev), |
|---|
| 109 | | - mad_flags & IB_MAD_IGNORE_MKEY, |
|---|
| 110 | | - mad_flags & IB_MAD_IGNORE_BKEY, |
|---|
| 111 | | - port_num, in_wc, in_grh, in_mad, out_mad); |
|---|
| 112 | | - if (err) |
|---|
| 113 | | - return IB_MAD_RESULT_FAILURE; |
|---|
| 114 | | - |
|---|
| 115 | | - /* set return bit in status of directed route responses */ |
|---|
| 116 | | - if (in_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) |
|---|
| 117 | | - out_mad->mad_hdr.status |= cpu_to_be16(1 << 15); |
|---|
| 118 | | - |
|---|
| 119 | | - if (in_mad->mad_hdr.method == IB_MGMT_METHOD_TRAP_REPRESS) |
|---|
| 120 | | - /* no response for trap repress */ |
|---|
| 121 | | - return IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_CONSUMED; |
|---|
| 122 | | - |
|---|
| 123 | | - return IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY; |
|---|
| 72 | + return mlx5_cmd_mad_ifc(dev->mdev, in_mad, response_mad, op_modifier, |
|---|
| 73 | + port); |
|---|
| 124 | 74 | } |
|---|
| 125 | 75 | |
|---|
| 126 | 76 | static void pma_cnt_ext_assign(struct ib_pma_portcounters_ext *pma_cnt_ext, |
|---|
| .. | .. |
|---|
| 216 | 166 | mdev = dev->mdev; |
|---|
| 217 | 167 | mdev_port_num = 1; |
|---|
| 218 | 168 | } |
|---|
| 169 | + if (MLX5_CAP_GEN(dev->mdev, num_ports) == 1) { |
|---|
| 170 | + /* set local port to one for Function-Per-Port HCA. */ |
|---|
| 171 | + mdev = dev->mdev; |
|---|
| 172 | + mdev_port_num = 1; |
|---|
| 173 | + } |
|---|
| 174 | + |
|---|
| 219 | 175 | /* Declaring support of extended counters */ |
|---|
| 220 | 176 | if (in_mad->mad_hdr.attr_id == IB_PMA_CLASS_PORT_INFO) { |
|---|
| 221 | 177 | struct ib_class_port_info cpi = {}; |
|---|
| .. | .. |
|---|
| 237 | 193 | goto done; |
|---|
| 238 | 194 | } |
|---|
| 239 | 195 | |
|---|
| 240 | | - err = mlx5_core_query_vport_counter(mdev, 0, 0, |
|---|
| 241 | | - mdev_port_num, out_cnt, sz); |
|---|
| 196 | + err = mlx5_core_query_vport_counter(mdev, 0, 0, mdev_port_num, |
|---|
| 197 | + out_cnt); |
|---|
| 242 | 198 | if (!err) |
|---|
| 243 | 199 | pma_cnt_ext_assign(pma_cnt_ext, out_cnt); |
|---|
| 244 | 200 | } else { |
|---|
| .. | .. |
|---|
| 268 | 224 | |
|---|
| 269 | 225 | int mlx5_ib_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num, |
|---|
| 270 | 226 | const struct ib_wc *in_wc, const struct ib_grh *in_grh, |
|---|
| 271 | | - const struct ib_mad_hdr *in, size_t in_mad_size, |
|---|
| 272 | | - struct ib_mad_hdr *out, size_t *out_mad_size, |
|---|
| 273 | | - u16 *out_mad_pkey_index) |
|---|
| 227 | + const struct ib_mad *in, struct ib_mad *out, |
|---|
| 228 | + size_t *out_mad_size, u16 *out_mad_pkey_index) |
|---|
| 274 | 229 | { |
|---|
| 275 | 230 | struct mlx5_ib_dev *dev = to_mdev(ibdev); |
|---|
| 276 | | - const struct ib_mad *in_mad = (const struct ib_mad *)in; |
|---|
| 277 | | - struct ib_mad *out_mad = (struct ib_mad *)out; |
|---|
| 278 | | - int ret; |
|---|
| 231 | + u8 mgmt_class = in->mad_hdr.mgmt_class; |
|---|
| 232 | + u8 method = in->mad_hdr.method; |
|---|
| 233 | + u16 slid; |
|---|
| 234 | + int err; |
|---|
| 279 | 235 | |
|---|
| 280 | | - if (WARN_ON_ONCE(in_mad_size != sizeof(*in_mad) || |
|---|
| 281 | | - *out_mad_size != sizeof(*out_mad))) |
|---|
| 236 | + slid = in_wc ? ib_lid_cpu16(in_wc->slid) : |
|---|
| 237 | + be16_to_cpu(IB_LID_PERMISSIVE); |
|---|
| 238 | + |
|---|
| 239 | + if (method == IB_MGMT_METHOD_TRAP && !slid) |
|---|
| 240 | + return IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_CONSUMED; |
|---|
| 241 | + |
|---|
| 242 | + switch (mgmt_class) { |
|---|
| 243 | + case IB_MGMT_CLASS_SUBN_LID_ROUTED: |
|---|
| 244 | + case IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE: { |
|---|
| 245 | + if (method != IB_MGMT_METHOD_GET && |
|---|
| 246 | + method != IB_MGMT_METHOD_SET && |
|---|
| 247 | + method != IB_MGMT_METHOD_TRAP_REPRESS) |
|---|
| 248 | + return IB_MAD_RESULT_SUCCESS; |
|---|
| 249 | + |
|---|
| 250 | + /* Don't process SMInfo queries -- the SMA can't handle them. |
|---|
| 251 | + */ |
|---|
| 252 | + if (in->mad_hdr.attr_id == IB_SMP_ATTR_SM_INFO) |
|---|
| 253 | + return IB_MAD_RESULT_SUCCESS; |
|---|
| 254 | + } break; |
|---|
| 255 | + case IB_MGMT_CLASS_PERF_MGMT: |
|---|
| 256 | + if (MLX5_CAP_GEN(dev->mdev, vport_counters) && |
|---|
| 257 | + method == IB_MGMT_METHOD_GET) |
|---|
| 258 | + return process_pma_cmd(dev, port_num, in, out); |
|---|
| 259 | + fallthrough; |
|---|
| 260 | + case MLX5_IB_VENDOR_CLASS1: |
|---|
| 261 | + case MLX5_IB_VENDOR_CLASS2: |
|---|
| 262 | + case IB_MGMT_CLASS_CONG_MGMT: { |
|---|
| 263 | + if (method != IB_MGMT_METHOD_GET && |
|---|
| 264 | + method != IB_MGMT_METHOD_SET) |
|---|
| 265 | + return IB_MAD_RESULT_SUCCESS; |
|---|
| 266 | + } break; |
|---|
| 267 | + default: |
|---|
| 268 | + return IB_MAD_RESULT_SUCCESS; |
|---|
| 269 | + } |
|---|
| 270 | + |
|---|
| 271 | + err = mlx5_MAD_IFC(to_mdev(ibdev), mad_flags & IB_MAD_IGNORE_MKEY, |
|---|
| 272 | + mad_flags & IB_MAD_IGNORE_BKEY, port_num, in_wc, |
|---|
| 273 | + in_grh, in, out); |
|---|
| 274 | + if (err) |
|---|
| 282 | 275 | return IB_MAD_RESULT_FAILURE; |
|---|
| 283 | 276 | |
|---|
| 284 | | - memset(out_mad->data, 0, sizeof(out_mad->data)); |
|---|
| 277 | + /* set return bit in status of directed route responses */ |
|---|
| 278 | + if (mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) |
|---|
| 279 | + out->mad_hdr.status |= cpu_to_be16(1 << 15); |
|---|
| 285 | 280 | |
|---|
| 286 | | - if (MLX5_CAP_GEN(dev->mdev, vport_counters) && |
|---|
| 287 | | - in_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_PERF_MGMT && |
|---|
| 288 | | - in_mad->mad_hdr.method == IB_MGMT_METHOD_GET) { |
|---|
| 289 | | - ret = process_pma_cmd(dev, port_num, in_mad, out_mad); |
|---|
| 290 | | - } else { |
|---|
| 291 | | - ret = process_mad(ibdev, mad_flags, port_num, in_wc, in_grh, |
|---|
| 292 | | - in_mad, out_mad); |
|---|
| 293 | | - } |
|---|
| 294 | | - return ret; |
|---|
| 281 | + if (method == IB_MGMT_METHOD_TRAP_REPRESS) |
|---|
| 282 | + /* no response for trap repress */ |
|---|
| 283 | + return IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_CONSUMED; |
|---|
| 284 | + |
|---|
| 285 | + return IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY; |
|---|
| 295 | 286 | } |
|---|
| 296 | 287 | |
|---|
| 297 | 288 | int mlx5_query_ext_port_caps(struct mlx5_ib_dev *dev, u8 port) |
|---|
| .. | .. |
|---|
| 538 | 529 | int ext_active_speed; |
|---|
| 539 | 530 | int err = -ENOMEM; |
|---|
| 540 | 531 | |
|---|
| 541 | | - if (port < 1 || port > dev->num_ports) { |
|---|
| 542 | | - mlx5_ib_warn(dev, "invalid port number %d\n", port); |
|---|
| 543 | | - return -EINVAL; |
|---|
| 544 | | - } |
|---|
| 545 | | - |
|---|
| 546 | 532 | in_mad = kzalloc(sizeof(*in_mad), GFP_KERNEL); |
|---|
| 547 | 533 | out_mad = kmalloc(sizeof(*out_mad), GFP_KERNEL); |
|---|
| 548 | 534 | if (!in_mad || !out_mad) |
|---|
| .. | .. |
|---|
| 580 | 566 | props->max_vl_num = out_mad->data[37] >> 4; |
|---|
| 581 | 567 | props->init_type_reply = out_mad->data[41] >> 4; |
|---|
| 582 | 568 | |
|---|
| 569 | + if (props->port_cap_flags & IB_PORT_CAP_MASK2_SUP) { |
|---|
| 570 | + props->port_cap_flags2 = |
|---|
| 571 | + be16_to_cpup((__be16 *)(out_mad->data + 60)); |
|---|
| 572 | + |
|---|
| 573 | + if (props->port_cap_flags2 & IB_PORT_LINK_WIDTH_2X_SUP) |
|---|
| 574 | + props->active_width = out_mad->data[31] & 0x1f; |
|---|
| 575 | + } |
|---|
| 576 | + |
|---|
| 583 | 577 | /* Check if extended speeds (EDR/FDR/...) are supported */ |
|---|
| 584 | 578 | if (props->port_cap_flags & IB_PORT_EXTENDED_SPEEDS_SUP) { |
|---|
| 585 | 579 | ext_active_speed = out_mad->data[62] >> 4; |
|---|
| .. | .. |
|---|
| 591 | 585 | case 2: |
|---|
| 592 | 586 | props->active_speed = 32; /* EDR */ |
|---|
| 593 | 587 | break; |
|---|
| 588 | + case 4: |
|---|
| 589 | + if (props->port_cap_flags & IB_PORT_CAP_MASK2_SUP && |
|---|
| 590 | + props->port_cap_flags2 & IB_PORT_LINK_SPEED_HDR_SUP) |
|---|
| 591 | + props->active_speed = IB_SPEED_HDR; |
|---|
| 592 | + break; |
|---|
| 594 | 593 | } |
|---|
| 595 | 594 | } |
|---|
| 596 | 595 | |
|---|