.. | .. |
---|
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 | |
---|