]> Git Repo - J-linux.git/blob - drivers/infiniband/hw/efa/efa_com_cmd.c
Merge tag 'kbuild-v6.9' of git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy...
[J-linux.git] / drivers / infiniband / hw / efa / efa_com_cmd.c
1 // SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
2 /*
3  * Copyright 2018-2024 Amazon.com, Inc. or its affiliates. All rights reserved.
4  */
5
6 #include "efa_com.h"
7 #include "efa_com_cmd.h"
8
9 int efa_com_create_qp(struct efa_com_dev *edev,
10                       struct efa_com_create_qp_params *params,
11                       struct efa_com_create_qp_result *res)
12 {
13         struct efa_admin_create_qp_cmd create_qp_cmd = {};
14         struct efa_admin_create_qp_resp cmd_completion;
15         struct efa_com_admin_queue *aq = &edev->aq;
16         int err;
17
18         create_qp_cmd.aq_common_desc.opcode = EFA_ADMIN_CREATE_QP;
19
20         create_qp_cmd.pd = params->pd;
21         create_qp_cmd.qp_type = params->qp_type;
22         create_qp_cmd.rq_base_addr = params->rq_base_addr;
23         create_qp_cmd.send_cq_idx = params->send_cq_idx;
24         create_qp_cmd.recv_cq_idx = params->recv_cq_idx;
25         create_qp_cmd.qp_alloc_size.send_queue_ring_size =
26                 params->sq_ring_size_in_bytes;
27         create_qp_cmd.qp_alloc_size.send_queue_depth =
28                         params->sq_depth;
29         create_qp_cmd.qp_alloc_size.recv_queue_ring_size =
30                         params->rq_ring_size_in_bytes;
31         create_qp_cmd.qp_alloc_size.recv_queue_depth =
32                         params->rq_depth;
33         create_qp_cmd.uar = params->uarn;
34
35         err = efa_com_cmd_exec(aq,
36                                (struct efa_admin_aq_entry *)&create_qp_cmd,
37                                sizeof(create_qp_cmd),
38                                (struct efa_admin_acq_entry *)&cmd_completion,
39                                sizeof(cmd_completion));
40         if (err) {
41                 ibdev_err_ratelimited(edev->efa_dev,
42                                       "Failed to create qp [%d]\n", err);
43                 return err;
44         }
45
46         res->qp_handle = cmd_completion.qp_handle;
47         res->qp_num = cmd_completion.qp_num;
48         res->sq_db_offset = cmd_completion.sq_db_offset;
49         res->rq_db_offset = cmd_completion.rq_db_offset;
50         res->llq_descriptors_offset = cmd_completion.llq_descriptors_offset;
51         res->send_sub_cq_idx = cmd_completion.send_sub_cq_idx;
52         res->recv_sub_cq_idx = cmd_completion.recv_sub_cq_idx;
53
54         return 0;
55 }
56
57 int efa_com_modify_qp(struct efa_com_dev *edev,
58                       struct efa_com_modify_qp_params *params)
59 {
60         struct efa_com_admin_queue *aq = &edev->aq;
61         struct efa_admin_modify_qp_cmd cmd = {};
62         struct efa_admin_modify_qp_resp resp;
63         int err;
64
65         cmd.aq_common_desc.opcode = EFA_ADMIN_MODIFY_QP;
66         cmd.modify_mask = params->modify_mask;
67         cmd.qp_handle = params->qp_handle;
68         cmd.qp_state = params->qp_state;
69         cmd.cur_qp_state = params->cur_qp_state;
70         cmd.qkey = params->qkey;
71         cmd.sq_psn = params->sq_psn;
72         cmd.sq_drained_async_notify = params->sq_drained_async_notify;
73         cmd.rnr_retry = params->rnr_retry;
74
75         err = efa_com_cmd_exec(aq,
76                                (struct efa_admin_aq_entry *)&cmd,
77                                sizeof(cmd),
78                                (struct efa_admin_acq_entry *)&resp,
79                                sizeof(resp));
80         if (err) {
81                 ibdev_err_ratelimited(
82                         edev->efa_dev,
83                         "Failed to modify qp-%u modify_mask[%#x] [%d]\n",
84                         cmd.qp_handle, cmd.modify_mask, err);
85                 return err;
86         }
87
88         return 0;
89 }
90
91 int efa_com_query_qp(struct efa_com_dev *edev,
92                      struct efa_com_query_qp_params *params,
93                      struct efa_com_query_qp_result *result)
94 {
95         struct efa_com_admin_queue *aq = &edev->aq;
96         struct efa_admin_query_qp_cmd cmd = {};
97         struct efa_admin_query_qp_resp resp;
98         int err;
99
100         cmd.aq_common_desc.opcode = EFA_ADMIN_QUERY_QP;
101         cmd.qp_handle = params->qp_handle;
102
103         err = efa_com_cmd_exec(aq,
104                                (struct efa_admin_aq_entry *)&cmd,
105                                sizeof(cmd),
106                                (struct efa_admin_acq_entry *)&resp,
107                                sizeof(resp));
108         if (err) {
109                 ibdev_err_ratelimited(edev->efa_dev,
110                                       "Failed to query qp-%u [%d]\n",
111                                       cmd.qp_handle, err);
112                 return err;
113         }
114
115         result->qp_state = resp.qp_state;
116         result->qkey = resp.qkey;
117         result->sq_draining = resp.sq_draining;
118         result->sq_psn = resp.sq_psn;
119         result->rnr_retry = resp.rnr_retry;
120
121         return 0;
122 }
123
124 int efa_com_destroy_qp(struct efa_com_dev *edev,
125                        struct efa_com_destroy_qp_params *params)
126 {
127         struct efa_admin_destroy_qp_resp cmd_completion;
128         struct efa_admin_destroy_qp_cmd qp_cmd = {};
129         struct efa_com_admin_queue *aq = &edev->aq;
130         int err;
131
132         qp_cmd.aq_common_desc.opcode = EFA_ADMIN_DESTROY_QP;
133         qp_cmd.qp_handle = params->qp_handle;
134
135         err = efa_com_cmd_exec(aq,
136                                (struct efa_admin_aq_entry *)&qp_cmd,
137                                sizeof(qp_cmd),
138                                (struct efa_admin_acq_entry *)&cmd_completion,
139                                sizeof(cmd_completion));
140         if (err) {
141                 ibdev_err_ratelimited(edev->efa_dev,
142                                       "Failed to destroy qp-%u [%d]\n",
143                                       qp_cmd.qp_handle, err);
144                 return err;
145         }
146
147         return 0;
148 }
149
150 int efa_com_create_cq(struct efa_com_dev *edev,
151                       struct efa_com_create_cq_params *params,
152                       struct efa_com_create_cq_result *result)
153 {
154         struct efa_admin_create_cq_resp cmd_completion = {};
155         struct efa_admin_create_cq_cmd create_cmd = {};
156         struct efa_com_admin_queue *aq = &edev->aq;
157         int err;
158
159         create_cmd.aq_common_desc.opcode = EFA_ADMIN_CREATE_CQ;
160         EFA_SET(&create_cmd.cq_caps_2,
161                 EFA_ADMIN_CREATE_CQ_CMD_CQ_ENTRY_SIZE_WORDS,
162                 params->entry_size_in_bytes / 4);
163         create_cmd.cq_depth = params->cq_depth;
164         create_cmd.num_sub_cqs = params->num_sub_cqs;
165         create_cmd.uar = params->uarn;
166         if (params->interrupt_mode_enabled) {
167                 EFA_SET(&create_cmd.cq_caps_1,
168                         EFA_ADMIN_CREATE_CQ_CMD_INTERRUPT_MODE_ENABLED, 1);
169                 create_cmd.eqn = params->eqn;
170         }
171         if (params->set_src_addr) {
172                 EFA_SET(&create_cmd.cq_caps_2,
173                         EFA_ADMIN_CREATE_CQ_CMD_SET_SRC_ADDR, 1);
174         }
175         efa_com_set_dma_addr(params->dma_addr,
176                              &create_cmd.cq_ba.mem_addr_high,
177                              &create_cmd.cq_ba.mem_addr_low);
178
179         err = efa_com_cmd_exec(aq,
180                                (struct efa_admin_aq_entry *)&create_cmd,
181                                sizeof(create_cmd),
182                                (struct efa_admin_acq_entry *)&cmd_completion,
183                                sizeof(cmd_completion));
184         if (err) {
185                 ibdev_err_ratelimited(edev->efa_dev,
186                                       "Failed to create cq[%d]\n", err);
187                 return err;
188         }
189
190         result->cq_idx = cmd_completion.cq_idx;
191         result->actual_depth = params->cq_depth;
192         result->db_off = cmd_completion.db_offset;
193         result->db_valid = EFA_GET(&cmd_completion.flags,
194                                    EFA_ADMIN_CREATE_CQ_RESP_DB_VALID);
195
196         return 0;
197 }
198
199 int efa_com_destroy_cq(struct efa_com_dev *edev,
200                        struct efa_com_destroy_cq_params *params)
201 {
202         struct efa_admin_destroy_cq_cmd destroy_cmd = {};
203         struct efa_admin_destroy_cq_resp destroy_resp;
204         struct efa_com_admin_queue *aq = &edev->aq;
205         int err;
206
207         destroy_cmd.cq_idx = params->cq_idx;
208         destroy_cmd.aq_common_desc.opcode = EFA_ADMIN_DESTROY_CQ;
209
210         err = efa_com_cmd_exec(aq,
211                                (struct efa_admin_aq_entry *)&destroy_cmd,
212                                sizeof(destroy_cmd),
213                                (struct efa_admin_acq_entry *)&destroy_resp,
214                                sizeof(destroy_resp));
215
216         if (err) {
217                 ibdev_err_ratelimited(edev->efa_dev,
218                                       "Failed to destroy CQ-%u [%d]\n",
219                                       params->cq_idx, err);
220                 return err;
221         }
222
223         return 0;
224 }
225
226 int efa_com_register_mr(struct efa_com_dev *edev,
227                         struct efa_com_reg_mr_params *params,
228                         struct efa_com_reg_mr_result *result)
229 {
230         struct efa_admin_reg_mr_resp cmd_completion;
231         struct efa_com_admin_queue *aq = &edev->aq;
232         struct efa_admin_reg_mr_cmd mr_cmd = {};
233         int err;
234
235         mr_cmd.aq_common_desc.opcode = EFA_ADMIN_REG_MR;
236         mr_cmd.pd = params->pd;
237         mr_cmd.mr_length = params->mr_length_in_bytes;
238         EFA_SET(&mr_cmd.flags, EFA_ADMIN_REG_MR_CMD_PHYS_PAGE_SIZE_SHIFT,
239                 params->page_shift);
240         mr_cmd.iova = params->iova;
241         mr_cmd.permissions = params->permissions;
242
243         if (params->inline_pbl) {
244                 memcpy(mr_cmd.pbl.inline_pbl_array,
245                        params->pbl.inline_pbl_array,
246                        sizeof(mr_cmd.pbl.inline_pbl_array));
247         } else {
248                 mr_cmd.pbl.pbl.length = params->pbl.pbl.length;
249                 mr_cmd.pbl.pbl.address.mem_addr_low =
250                         params->pbl.pbl.address.mem_addr_low;
251                 mr_cmd.pbl.pbl.address.mem_addr_high =
252                         params->pbl.pbl.address.mem_addr_high;
253                 EFA_SET(&mr_cmd.aq_common_desc.flags,
254                         EFA_ADMIN_AQ_COMMON_DESC_CTRL_DATA, 1);
255                 if (params->indirect)
256                         EFA_SET(&mr_cmd.aq_common_desc.flags,
257                                 EFA_ADMIN_AQ_COMMON_DESC_CTRL_DATA_INDIRECT, 1);
258         }
259
260         err = efa_com_cmd_exec(aq,
261                                (struct efa_admin_aq_entry *)&mr_cmd,
262                                sizeof(mr_cmd),
263                                (struct efa_admin_acq_entry *)&cmd_completion,
264                                sizeof(cmd_completion));
265         if (err) {
266                 ibdev_err_ratelimited(edev->efa_dev,
267                                       "Failed to register mr [%d]\n", err);
268                 return err;
269         }
270
271         result->l_key = cmd_completion.l_key;
272         result->r_key = cmd_completion.r_key;
273         result->ic_info.recv_ic_id = cmd_completion.recv_ic_id;
274         result->ic_info.rdma_read_ic_id = cmd_completion.rdma_read_ic_id;
275         result->ic_info.rdma_recv_ic_id = cmd_completion.rdma_recv_ic_id;
276         result->ic_info.recv_ic_id_valid = EFA_GET(&cmd_completion.validity,
277                                                    EFA_ADMIN_REG_MR_RESP_RECV_IC_ID);
278         result->ic_info.rdma_read_ic_id_valid = EFA_GET(&cmd_completion.validity,
279                                                         EFA_ADMIN_REG_MR_RESP_RDMA_READ_IC_ID);
280         result->ic_info.rdma_recv_ic_id_valid = EFA_GET(&cmd_completion.validity,
281                                                         EFA_ADMIN_REG_MR_RESP_RDMA_RECV_IC_ID);
282
283         return 0;
284 }
285
286 int efa_com_dereg_mr(struct efa_com_dev *edev,
287                      struct efa_com_dereg_mr_params *params)
288 {
289         struct efa_admin_dereg_mr_resp cmd_completion;
290         struct efa_com_admin_queue *aq = &edev->aq;
291         struct efa_admin_dereg_mr_cmd mr_cmd = {};
292         int err;
293
294         mr_cmd.aq_common_desc.opcode = EFA_ADMIN_DEREG_MR;
295         mr_cmd.l_key = params->l_key;
296
297         err = efa_com_cmd_exec(aq,
298                                (struct efa_admin_aq_entry *)&mr_cmd,
299                                sizeof(mr_cmd),
300                                (struct efa_admin_acq_entry *)&cmd_completion,
301                                sizeof(cmd_completion));
302         if (err) {
303                 ibdev_err_ratelimited(edev->efa_dev,
304                                       "Failed to de-register mr(lkey-%u) [%d]\n",
305                                       mr_cmd.l_key, err);
306                 return err;
307         }
308
309         return 0;
310 }
311
312 int efa_com_create_ah(struct efa_com_dev *edev,
313                       struct efa_com_create_ah_params *params,
314                       struct efa_com_create_ah_result *result)
315 {
316         struct efa_admin_create_ah_resp cmd_completion;
317         struct efa_com_admin_queue *aq = &edev->aq;
318         struct efa_admin_create_ah_cmd ah_cmd = {};
319         int err;
320
321         ah_cmd.aq_common_desc.opcode = EFA_ADMIN_CREATE_AH;
322
323         memcpy(ah_cmd.dest_addr, params->dest_addr, sizeof(ah_cmd.dest_addr));
324         ah_cmd.pd = params->pdn;
325
326         err = efa_com_cmd_exec(aq,
327                                (struct efa_admin_aq_entry *)&ah_cmd,
328                                sizeof(ah_cmd),
329                                (struct efa_admin_acq_entry *)&cmd_completion,
330                                sizeof(cmd_completion));
331         if (err) {
332                 ibdev_err_ratelimited(edev->efa_dev,
333                                       "Failed to create ah for %pI6 [%d]\n",
334                                       ah_cmd.dest_addr, err);
335                 return err;
336         }
337
338         result->ah = cmd_completion.ah;
339
340         return 0;
341 }
342
343 int efa_com_destroy_ah(struct efa_com_dev *edev,
344                        struct efa_com_destroy_ah_params *params)
345 {
346         struct efa_admin_destroy_ah_resp cmd_completion;
347         struct efa_admin_destroy_ah_cmd ah_cmd = {};
348         struct efa_com_admin_queue *aq = &edev->aq;
349         int err;
350
351         ah_cmd.aq_common_desc.opcode = EFA_ADMIN_DESTROY_AH;
352         ah_cmd.ah = params->ah;
353         ah_cmd.pd = params->pdn;
354
355         err = efa_com_cmd_exec(aq,
356                                (struct efa_admin_aq_entry *)&ah_cmd,
357                                sizeof(ah_cmd),
358                                (struct efa_admin_acq_entry *)&cmd_completion,
359                                sizeof(cmd_completion));
360         if (err) {
361                 ibdev_err_ratelimited(edev->efa_dev,
362                                       "Failed to destroy ah-%d pd-%d [%d]\n",
363                                       ah_cmd.ah, ah_cmd.pd, err);
364                 return err;
365         }
366
367         return 0;
368 }
369
370 bool
371 efa_com_check_supported_feature_id(struct efa_com_dev *edev,
372                                    enum efa_admin_aq_feature_id feature_id)
373 {
374         u32 feature_mask = 1 << feature_id;
375
376         /* Device attributes is always supported */
377         if (feature_id != EFA_ADMIN_DEVICE_ATTR &&
378             !(edev->supported_features & feature_mask))
379                 return false;
380
381         return true;
382 }
383
384 static int efa_com_get_feature_ex(struct efa_com_dev *edev,
385                                   struct efa_admin_get_feature_resp *get_resp,
386                                   enum efa_admin_aq_feature_id feature_id,
387                                   dma_addr_t control_buf_dma_addr,
388                                   u32 control_buff_size)
389 {
390         struct efa_admin_get_feature_cmd get_cmd = {};
391         struct efa_com_admin_queue *aq;
392         int err;
393
394         if (!efa_com_check_supported_feature_id(edev, feature_id)) {
395                 ibdev_err_ratelimited(edev->efa_dev,
396                                       "Feature %d isn't supported\n",
397                                       feature_id);
398                 return -EOPNOTSUPP;
399         }
400
401         aq = &edev->aq;
402
403         get_cmd.aq_common_descriptor.opcode = EFA_ADMIN_GET_FEATURE;
404
405         if (control_buff_size)
406                 EFA_SET(&get_cmd.aq_common_descriptor.flags,
407                         EFA_ADMIN_AQ_COMMON_DESC_CTRL_DATA, 1);
408
409         efa_com_set_dma_addr(control_buf_dma_addr,
410                              &get_cmd.control_buffer.address.mem_addr_high,
411                              &get_cmd.control_buffer.address.mem_addr_low);
412
413         get_cmd.control_buffer.length = control_buff_size;
414         get_cmd.feature_common.feature_id = feature_id;
415         err = efa_com_cmd_exec(aq,
416                                (struct efa_admin_aq_entry *)
417                                &get_cmd,
418                                sizeof(get_cmd),
419                                (struct efa_admin_acq_entry *)
420                                get_resp,
421                                sizeof(*get_resp));
422
423         if (err) {
424                 ibdev_err_ratelimited(
425                         edev->efa_dev,
426                         "Failed to submit get_feature command %d [%d]\n",
427                         feature_id, err);
428                 return err;
429         }
430
431         return 0;
432 }
433
434 static int efa_com_get_feature(struct efa_com_dev *edev,
435                                struct efa_admin_get_feature_resp *get_resp,
436                                enum efa_admin_aq_feature_id feature_id)
437 {
438         return efa_com_get_feature_ex(edev, get_resp, feature_id, 0, 0);
439 }
440
441 int efa_com_get_device_attr(struct efa_com_dev *edev,
442                             struct efa_com_get_device_attr_result *result)
443 {
444         struct efa_admin_get_feature_resp resp;
445         int err;
446
447         err = efa_com_get_feature(edev, &resp, EFA_ADMIN_DEVICE_ATTR);
448         if (err) {
449                 ibdev_err_ratelimited(edev->efa_dev,
450                                       "Failed to get device attributes %d\n",
451                                       err);
452                 return err;
453         }
454
455         result->page_size_cap = resp.u.device_attr.page_size_cap;
456         result->fw_version = resp.u.device_attr.fw_version;
457         result->admin_api_version = resp.u.device_attr.admin_api_version;
458         result->device_version = resp.u.device_attr.device_version;
459         result->supported_features = resp.u.device_attr.supported_features;
460         result->phys_addr_width = resp.u.device_attr.phys_addr_width;
461         result->virt_addr_width = resp.u.device_attr.virt_addr_width;
462         result->db_bar = resp.u.device_attr.db_bar;
463         result->max_rdma_size = resp.u.device_attr.max_rdma_size;
464         result->device_caps = resp.u.device_attr.device_caps;
465
466         if (result->admin_api_version < 1) {
467                 ibdev_err_ratelimited(
468                         edev->efa_dev,
469                         "Failed to get device attr api version [%u < 1]\n",
470                         result->admin_api_version);
471                 return -EINVAL;
472         }
473
474         edev->supported_features = resp.u.device_attr.supported_features;
475         err = efa_com_get_feature(edev, &resp,
476                                   EFA_ADMIN_QUEUE_ATTR);
477         if (err) {
478                 ibdev_err_ratelimited(edev->efa_dev,
479                                       "Failed to get queue attributes %d\n",
480                                       err);
481                 return err;
482         }
483
484         result->max_qp = resp.u.queue_attr.max_qp;
485         result->max_sq_depth = resp.u.queue_attr.max_sq_depth;
486         result->max_rq_depth = resp.u.queue_attr.max_rq_depth;
487         result->max_cq = resp.u.queue_attr.max_cq;
488         result->max_cq_depth = resp.u.queue_attr.max_cq_depth;
489         result->inline_buf_size = resp.u.queue_attr.inline_buf_size;
490         result->max_sq_sge = resp.u.queue_attr.max_wr_send_sges;
491         result->max_rq_sge = resp.u.queue_attr.max_wr_recv_sges;
492         result->max_mr = resp.u.queue_attr.max_mr;
493         result->max_mr_pages = resp.u.queue_attr.max_mr_pages;
494         result->max_pd = resp.u.queue_attr.max_pd;
495         result->max_ah = resp.u.queue_attr.max_ah;
496         result->max_llq_size = resp.u.queue_attr.max_llq_size;
497         result->sub_cqs_per_cq = resp.u.queue_attr.sub_cqs_per_cq;
498         result->max_wr_rdma_sge = resp.u.queue_attr.max_wr_rdma_sges;
499         result->max_tx_batch = resp.u.queue_attr.max_tx_batch;
500         result->min_sq_depth = resp.u.queue_attr.min_sq_depth;
501
502         err = efa_com_get_feature(edev, &resp, EFA_ADMIN_NETWORK_ATTR);
503         if (err) {
504                 ibdev_err_ratelimited(edev->efa_dev,
505                                       "Failed to get network attributes %d\n",
506                                       err);
507                 return err;
508         }
509
510         memcpy(result->addr, resp.u.network_attr.addr,
511                sizeof(resp.u.network_attr.addr));
512         result->mtu = resp.u.network_attr.mtu;
513
514         if (efa_com_check_supported_feature_id(edev,
515                                                EFA_ADMIN_EVENT_QUEUE_ATTR)) {
516                 err = efa_com_get_feature(edev, &resp,
517                                           EFA_ADMIN_EVENT_QUEUE_ATTR);
518                 if (err) {
519                         ibdev_err_ratelimited(
520                                 edev->efa_dev,
521                                 "Failed to get event queue attributes %d\n",
522                                 err);
523                         return err;
524                 }
525
526                 result->max_eq = resp.u.event_queue_attr.max_eq;
527                 result->max_eq_depth = resp.u.event_queue_attr.max_eq_depth;
528                 result->event_bitmask = resp.u.event_queue_attr.event_bitmask;
529         }
530
531         return 0;
532 }
533
534 int efa_com_get_hw_hints(struct efa_com_dev *edev,
535                          struct efa_com_get_hw_hints_result *result)
536 {
537         struct efa_admin_get_feature_resp resp;
538         int err;
539
540         err = efa_com_get_feature(edev, &resp, EFA_ADMIN_HW_HINTS);
541         if (err) {
542                 ibdev_err_ratelimited(edev->efa_dev,
543                                       "Failed to get hw hints %d\n", err);
544                 return err;
545         }
546
547         result->admin_completion_timeout = resp.u.hw_hints.admin_completion_timeout;
548         result->driver_watchdog_timeout = resp.u.hw_hints.driver_watchdog_timeout;
549         result->mmio_read_timeout = resp.u.hw_hints.mmio_read_timeout;
550         result->poll_interval = resp.u.hw_hints.poll_interval;
551
552         return 0;
553 }
554
555 int efa_com_set_feature_ex(struct efa_com_dev *edev,
556                            struct efa_admin_set_feature_resp *set_resp,
557                            struct efa_admin_set_feature_cmd *set_cmd,
558                            enum efa_admin_aq_feature_id feature_id,
559                            dma_addr_t control_buf_dma_addr,
560                            u32 control_buff_size)
561 {
562         struct efa_com_admin_queue *aq;
563         int err;
564
565         if (!efa_com_check_supported_feature_id(edev, feature_id)) {
566                 ibdev_err_ratelimited(edev->efa_dev,
567                                       "Feature %d isn't supported\n",
568                                       feature_id);
569                 return -EOPNOTSUPP;
570         }
571
572         aq = &edev->aq;
573
574         set_cmd->aq_common_descriptor.opcode = EFA_ADMIN_SET_FEATURE;
575         if (control_buff_size) {
576                 set_cmd->aq_common_descriptor.flags = 0;
577                 EFA_SET(&set_cmd->aq_common_descriptor.flags,
578                         EFA_ADMIN_AQ_COMMON_DESC_CTRL_DATA, 1);
579                 efa_com_set_dma_addr(control_buf_dma_addr,
580                                      &set_cmd->control_buffer.address.mem_addr_high,
581                                      &set_cmd->control_buffer.address.mem_addr_low);
582         }
583
584         set_cmd->control_buffer.length = control_buff_size;
585         set_cmd->feature_common.feature_id = feature_id;
586         err = efa_com_cmd_exec(aq,
587                                (struct efa_admin_aq_entry *)set_cmd,
588                                sizeof(*set_cmd),
589                                (struct efa_admin_acq_entry *)set_resp,
590                                sizeof(*set_resp));
591
592         if (err) {
593                 ibdev_err_ratelimited(
594                         edev->efa_dev,
595                         "Failed to submit set_feature command %d error: %d\n",
596                         feature_id, err);
597                 return err;
598         }
599
600         return 0;
601 }
602
603 static int efa_com_set_feature(struct efa_com_dev *edev,
604                                struct efa_admin_set_feature_resp *set_resp,
605                                struct efa_admin_set_feature_cmd *set_cmd,
606                                enum efa_admin_aq_feature_id feature_id)
607 {
608         return efa_com_set_feature_ex(edev, set_resp, set_cmd, feature_id,
609                                       0, 0);
610 }
611
612 int efa_com_set_aenq_config(struct efa_com_dev *edev, u32 groups)
613 {
614         struct efa_admin_get_feature_resp get_resp;
615         struct efa_admin_set_feature_resp set_resp;
616         struct efa_admin_set_feature_cmd cmd = {};
617         int err;
618
619         ibdev_dbg(edev->efa_dev, "Configuring aenq with groups[%#x]\n", groups);
620
621         err = efa_com_get_feature(edev, &get_resp, EFA_ADMIN_AENQ_CONFIG);
622         if (err) {
623                 ibdev_err_ratelimited(edev->efa_dev,
624                                       "Failed to get aenq attributes: %d\n",
625                                       err);
626                 return err;
627         }
628
629         ibdev_dbg(edev->efa_dev,
630                   "Get aenq groups: supported[%#x] enabled[%#x]\n",
631                   get_resp.u.aenq.supported_groups,
632                   get_resp.u.aenq.enabled_groups);
633
634         if ((get_resp.u.aenq.supported_groups & groups) != groups) {
635                 ibdev_err_ratelimited(
636                         edev->efa_dev,
637                         "Trying to set unsupported aenq groups[%#x] supported[%#x]\n",
638                         groups, get_resp.u.aenq.supported_groups);
639                 return -EOPNOTSUPP;
640         }
641
642         cmd.u.aenq.enabled_groups = groups;
643         err = efa_com_set_feature(edev, &set_resp, &cmd,
644                                   EFA_ADMIN_AENQ_CONFIG);
645         if (err) {
646                 ibdev_err_ratelimited(edev->efa_dev,
647                                       "Failed to set aenq attributes: %d\n",
648                                       err);
649                 return err;
650         }
651
652         return 0;
653 }
654
655 int efa_com_alloc_pd(struct efa_com_dev *edev,
656                      struct efa_com_alloc_pd_result *result)
657 {
658         struct efa_com_admin_queue *aq = &edev->aq;
659         struct efa_admin_alloc_pd_cmd cmd = {};
660         struct efa_admin_alloc_pd_resp resp;
661         int err;
662
663         cmd.aq_common_descriptor.opcode = EFA_ADMIN_ALLOC_PD;
664
665         err = efa_com_cmd_exec(aq,
666                                (struct efa_admin_aq_entry *)&cmd,
667                                sizeof(cmd),
668                                (struct efa_admin_acq_entry *)&resp,
669                                sizeof(resp));
670         if (err) {
671                 ibdev_err_ratelimited(edev->efa_dev,
672                                       "Failed to allocate pd[%d]\n", err);
673                 return err;
674         }
675
676         result->pdn = resp.pd;
677
678         return 0;
679 }
680
681 int efa_com_dealloc_pd(struct efa_com_dev *edev,
682                        struct efa_com_dealloc_pd_params *params)
683 {
684         struct efa_com_admin_queue *aq = &edev->aq;
685         struct efa_admin_dealloc_pd_cmd cmd = {};
686         struct efa_admin_dealloc_pd_resp resp;
687         int err;
688
689         cmd.aq_common_descriptor.opcode = EFA_ADMIN_DEALLOC_PD;
690         cmd.pd = params->pdn;
691
692         err = efa_com_cmd_exec(aq,
693                                (struct efa_admin_aq_entry *)&cmd,
694                                sizeof(cmd),
695                                (struct efa_admin_acq_entry *)&resp,
696                                sizeof(resp));
697         if (err) {
698                 ibdev_err_ratelimited(edev->efa_dev,
699                                       "Failed to deallocate pd-%u [%d]\n",
700                                       cmd.pd, err);
701                 return err;
702         }
703
704         return 0;
705 }
706
707 int efa_com_alloc_uar(struct efa_com_dev *edev,
708                       struct efa_com_alloc_uar_result *result)
709 {
710         struct efa_com_admin_queue *aq = &edev->aq;
711         struct efa_admin_alloc_uar_cmd cmd = {};
712         struct efa_admin_alloc_uar_resp resp;
713         int err;
714
715         cmd.aq_common_descriptor.opcode = EFA_ADMIN_ALLOC_UAR;
716
717         err = efa_com_cmd_exec(aq,
718                                (struct efa_admin_aq_entry *)&cmd,
719                                sizeof(cmd),
720                                (struct efa_admin_acq_entry *)&resp,
721                                sizeof(resp));
722         if (err) {
723                 ibdev_err_ratelimited(edev->efa_dev,
724                                       "Failed to allocate uar[%d]\n", err);
725                 return err;
726         }
727
728         result->uarn = resp.uar;
729
730         return 0;
731 }
732
733 int efa_com_dealloc_uar(struct efa_com_dev *edev,
734                         struct efa_com_dealloc_uar_params *params)
735 {
736         struct efa_com_admin_queue *aq = &edev->aq;
737         struct efa_admin_dealloc_uar_cmd cmd = {};
738         struct efa_admin_dealloc_uar_resp resp;
739         int err;
740
741         cmd.aq_common_descriptor.opcode = EFA_ADMIN_DEALLOC_UAR;
742         cmd.uar = params->uarn;
743
744         err = efa_com_cmd_exec(aq,
745                                (struct efa_admin_aq_entry *)&cmd,
746                                sizeof(cmd),
747                                (struct efa_admin_acq_entry *)&resp,
748                                sizeof(resp));
749         if (err) {
750                 ibdev_err_ratelimited(edev->efa_dev,
751                                       "Failed to deallocate uar-%u [%d]\n",
752                                       cmd.uar, err);
753                 return err;
754         }
755
756         return 0;
757 }
758
759 int efa_com_get_stats(struct efa_com_dev *edev,
760                       struct efa_com_get_stats_params *params,
761                       union efa_com_get_stats_result *result)
762 {
763         struct efa_com_admin_queue *aq = &edev->aq;
764         struct efa_admin_aq_get_stats_cmd cmd = {};
765         struct efa_admin_acq_get_stats_resp resp;
766         int err;
767
768         cmd.aq_common_descriptor.opcode = EFA_ADMIN_GET_STATS;
769         cmd.type = params->type;
770         cmd.scope = params->scope;
771         cmd.scope_modifier = params->scope_modifier;
772
773         err = efa_com_cmd_exec(aq,
774                                (struct efa_admin_aq_entry *)&cmd,
775                                sizeof(cmd),
776                                (struct efa_admin_acq_entry *)&resp,
777                                sizeof(resp));
778         if (err) {
779                 ibdev_err_ratelimited(
780                         edev->efa_dev,
781                         "Failed to get stats type-%u scope-%u.%u [%d]\n",
782                         cmd.type, cmd.scope, cmd.scope_modifier, err);
783                 return err;
784         }
785
786         switch (cmd.type) {
787         case EFA_ADMIN_GET_STATS_TYPE_BASIC:
788                 result->basic_stats.tx_bytes = resp.u.basic_stats.tx_bytes;
789                 result->basic_stats.tx_pkts = resp.u.basic_stats.tx_pkts;
790                 result->basic_stats.rx_bytes = resp.u.basic_stats.rx_bytes;
791                 result->basic_stats.rx_pkts = resp.u.basic_stats.rx_pkts;
792                 result->basic_stats.rx_drops = resp.u.basic_stats.rx_drops;
793                 break;
794         case EFA_ADMIN_GET_STATS_TYPE_MESSAGES:
795                 result->messages_stats.send_bytes = resp.u.messages_stats.send_bytes;
796                 result->messages_stats.send_wrs = resp.u.messages_stats.send_wrs;
797                 result->messages_stats.recv_bytes = resp.u.messages_stats.recv_bytes;
798                 result->messages_stats.recv_wrs = resp.u.messages_stats.recv_wrs;
799                 break;
800         case EFA_ADMIN_GET_STATS_TYPE_RDMA_READ:
801                 result->rdma_read_stats.read_wrs = resp.u.rdma_read_stats.read_wrs;
802                 result->rdma_read_stats.read_bytes = resp.u.rdma_read_stats.read_bytes;
803                 result->rdma_read_stats.read_wr_err = resp.u.rdma_read_stats.read_wr_err;
804                 result->rdma_read_stats.read_resp_bytes = resp.u.rdma_read_stats.read_resp_bytes;
805                 break;
806         case EFA_ADMIN_GET_STATS_TYPE_RDMA_WRITE:
807                 result->rdma_write_stats.write_wrs = resp.u.rdma_write_stats.write_wrs;
808                 result->rdma_write_stats.write_bytes = resp.u.rdma_write_stats.write_bytes;
809                 result->rdma_write_stats.write_wr_err = resp.u.rdma_write_stats.write_wr_err;
810                 result->rdma_write_stats.write_recv_bytes = resp.u.rdma_write_stats.write_recv_bytes;
811                 break;
812         }
813
814         return 0;
815 }
This page took 0.079955 seconds and 4 git commands to generate.