1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2010-2018 Intel Corporation
3 */
4
5 #include <fcntl.h>
6 #include <inttypes.h>
7 #include <unistd.h>
8
9 #include "opae_hw_api.h"
10 #include "ifpga_api.h"
11
12 #include "ifpga_hw.h"
13 #include "ifpga_enumerate.h"
14 #include "ifpga_feature_dev.h"
15
16 struct dfl_fpga_enum_dfl {
17 u64 start;
18 u64 len;
19 void *addr;
20 TAILQ_ENTRY(dfl_fpga_enum_dfl) node;
21 };
22
23 TAILQ_HEAD(dfl_fpga_enum_dfls, dfl_fpga_enum_dfl);
24 struct dfl_fpga_enum_info {
25 struct ifpga_hw *hw;
26 struct dfl_fpga_enum_dfls dfls;
27 };
28
29 struct build_feature_devs_info {
30 struct opae_adapter_data_pci *pci_data;
31
32 struct ifpga_afu_info *acc_info;
33
34 void *fiu;
35 enum fpga_id_type current_type;
36 int current_port_id;
37
38 void *ioaddr;
39 void *ioend;
40 uint64_t phys_addr;
41
42 void *pfme_hdr;
43
44 struct ifpga_hw *hw;
45 };
46
feature_revision(void __iomem * start)47 static int feature_revision(void __iomem *start)
48 {
49 struct feature_header header;
50
51 header.csr = readq(start);
52
53 return header.revision;
54 }
55
feature_size(void __iomem * start)56 static u32 feature_size(void __iomem *start)
57 {
58 struct feature_header header;
59
60 header.csr = readq(start);
61
62 /*the size of private feature is 4KB aligned*/
63 return header.next_header_offset ? header.next_header_offset:4096;
64 }
65
feature_id(void __iomem * start)66 static u64 feature_id(void __iomem *start)
67 {
68 struct feature_header header;
69
70 header.csr = readq(start);
71
72 switch (header.type) {
73 case FEATURE_TYPE_FIU:
74 return FEATURE_ID_FIU_HEADER;
75 case FEATURE_TYPE_PRIVATE:
76 return header.id;
77 case FEATURE_TYPE_AFU:
78 return FEATURE_ID_AFU;
79 }
80
81 WARN_ON(1);
82 return 0;
83 }
84
85 static int
build_info_add_sub_feature(struct build_feature_devs_info * binfo,void __iomem * start,u64 fid,unsigned int size,unsigned int vec_start,unsigned int vec_cnt)86 build_info_add_sub_feature(struct build_feature_devs_info *binfo,
87 void __iomem *start, u64 fid, unsigned int size,
88 unsigned int vec_start,
89 unsigned int vec_cnt)
90 {
91 struct ifpga_hw *hw = binfo->hw;
92 struct ifpga_feature *feature = NULL;
93 struct feature_irq_ctx *ctx = NULL;
94 int port_id, ret = 0;
95 unsigned int i;
96
97 fid = fid?fid:feature_id(start);
98 size = size?size:feature_size(start);
99
100 feature = opae_malloc(sizeof(struct ifpga_feature));
101 if (!feature)
102 return -ENOMEM;
103
104 feature->state = IFPGA_FEATURE_ATTACHED;
105 feature->addr = start;
106 feature->id = fid;
107 feature->size = size;
108 feature->revision = feature_revision(start);
109 feature->phys_addr = binfo->phys_addr +
110 ((u8 *)start - (u8 *)binfo->ioaddr);
111 feature->vec_start = vec_start;
112 feature->vec_cnt = vec_cnt;
113
114 dev_debug(binfo, "%s: id=0x%llx, phys_addr=0x%llx, size=%u\n",
115 __func__, (unsigned long long)feature->id,
116 (unsigned long long)feature->phys_addr, size);
117
118 if (vec_cnt) {
119 if (vec_start + vec_cnt <= vec_start)
120 return -EINVAL;
121
122 ctx = zmalloc(sizeof(*ctx) * vec_cnt);
123 if (!ctx)
124 return -ENOMEM;
125
126 for (i = 0; i < vec_cnt; i++) {
127 ctx[i].eventfd = -1;
128 ctx[i].idx = vec_start + i;
129 }
130 }
131
132 feature->ctx = ctx;
133 feature->ctx_num = vec_cnt;
134 feature->vfio_dev_fd = binfo->pci_data->vfio_dev_fd;
135
136 if (binfo->current_type == FME_ID) {
137 feature->parent = &hw->fme;
138 feature->type = FEATURE_FME_TYPE;
139 feature->name = get_fme_feature_name(fid);
140 TAILQ_INSERT_TAIL(&hw->fme.feature_list, feature, next);
141 } else if (binfo->current_type == PORT_ID) {
142 port_id = binfo->current_port_id;
143 feature->parent = &hw->port[port_id];
144 feature->type = FEATURE_PORT_TYPE;
145 feature->name = get_port_feature_name(fid);
146 TAILQ_INSERT_TAIL(&hw->port[port_id].feature_list,
147 feature, next);
148 } else {
149 return -EFAULT;
150 }
151 return ret;
152 }
153
154 static int
create_feature_instance(struct build_feature_devs_info * binfo,void __iomem * start,u64 fid,unsigned int size,unsigned int vec_start,unsigned int vec_cnt)155 create_feature_instance(struct build_feature_devs_info *binfo,
156 void __iomem *start, u64 fid,
157 unsigned int size, unsigned int vec_start,
158 unsigned int vec_cnt)
159 {
160 if (binfo->current_type != AFU_ID)
161 return build_info_add_sub_feature(binfo, start, fid, size,
162 vec_start, vec_cnt);
163 return 0;
164 }
165
166 /*
167 * UAFU GUID is dynamic as it can be changed after FME downloads different
168 * Green Bitstream to the port, so we treat the unknown GUIDs which are
169 * attached on port's feature list as UAFU.
170 */
feature_is_UAFU(struct build_feature_devs_info * binfo)171 static bool feature_is_UAFU(struct build_feature_devs_info *binfo)
172 {
173 if ((binfo->current_type == PORT_ID) ||
174 (binfo->current_type == AFU_ID))
175 return true;
176
177 return false;
178 }
179
parse_feature_uafu(struct build_feature_devs_info * binfo,struct feature_header * hdr)180 static int parse_feature_uafu(struct build_feature_devs_info *binfo,
181 struct feature_header *hdr)
182 {
183 u64 id = PORT_FEATURE_ID_UAFU;
184 struct ifpga_afu_info *info;
185 void *start = (void *)hdr;
186 struct feature_port_header *port_hdr = binfo->ioaddr;
187 struct feature_port_capability capability;
188 int ret;
189 int size;
190
191 if (binfo->acc_info) {
192 dev_info(binfo, "Sub AFU found @ %p.\n", start);
193 return 0;
194 }
195
196 capability.csr = readq(&port_hdr->capability);
197
198 if (binfo->current_type == AFU_ID) {
199 size = AFU_REGION_SIZE;
200 } else {
201 capability.csr = readq(&port_hdr->capability);
202 size = capability.mmio_size << 10;
203 }
204
205 ret = create_feature_instance(binfo, hdr, id, size, 0, 0);
206 if (ret)
207 return ret;
208
209 info = opae_malloc(sizeof(*info));
210 if (!info)
211 return -ENOMEM;
212
213 info->region[0].addr = start;
214 info->region[0].phys_addr = binfo->phys_addr +
215 (uint8_t *)start - (uint8_t *)binfo->ioaddr;
216 info->region[0].len = size;
217 info->num_regions = AFU_MAX_REGION;
218
219 binfo->acc_info = info;
220
221 return ret;
222 }
223
224 /* create and register proper private data */
build_info_commit_dev(struct build_feature_devs_info * binfo)225 static int build_info_commit_dev(struct build_feature_devs_info *binfo)
226 {
227 struct ifpga_afu_info *info = binfo->acc_info;
228 struct ifpga_hw *hw = binfo->hw;
229 struct opae_manager *mgr;
230 struct opae_bridge *br;
231 struct opae_accelerator *acc;
232 struct ifpga_port_hw *port;
233 struct ifpga_fme_hw *fme;
234 struct ifpga_feature *feature;
235
236 if (binfo->current_type == PORT_ID) {
237 if (!binfo->fiu)
238 return 0;
239
240 br = opae_bridge_alloc(hw->adapter->name, &ifpga_br_ops,
241 binfo->fiu);
242 if (!br)
243 return -ENOMEM;
244
245 br->id = binfo->current_port_id;
246
247 /* update irq info */
248 port = &hw->port[binfo->current_port_id];
249 feature = get_feature_by_id(&port->feature_list,
250 PORT_FEATURE_ID_UINT);
251 if (feature && info)
252 info->num_irqs = feature->vec_cnt;
253
254 acc = opae_accelerator_alloc(hw->adapter->name,
255 &ifpga_acc_ops, info);
256 if (!acc) {
257 opae_bridge_free(br);
258 return -ENOMEM;
259 }
260
261 acc->adapter = hw->adapter;
262 acc->br = br;
263 if (hw->adapter->mgr)
264 acc->mgr = hw->adapter->mgr;
265 acc->index = br->id;
266
267 fme = &hw->fme;
268 fme->nums_acc_region = info ? info->num_regions : 0;
269
270 opae_adapter_add_acc(hw->adapter, acc);
271
272 } else if (binfo->current_type == FME_ID) {
273 if (!binfo->fiu)
274 return 0;
275
276 mgr = opae_manager_alloc(hw->adapter->name, &ifpga_mgr_ops,
277 &ifpga_mgr_network_ops, binfo->fiu);
278 if (!mgr)
279 return -ENOMEM;
280
281 mgr->adapter = hw->adapter;
282 hw->adapter->mgr = mgr;
283 } else if (binfo->current_type == AFU_ID) {
284 if (!info)
285 return -EFAULT;
286
287 info->num_irqs = 0;
288 acc = opae_accelerator_alloc(hw->adapter->name,
289 &ifpga_acc_ops, info);
290 if (!acc)
291 return -ENOMEM;
292
293 acc->adapter = hw->adapter;
294 acc->br = NULL;
295 acc->mgr = NULL;
296 acc->index = hw->num_afus++;
297
298 opae_adapter_add_acc(hw->adapter, acc);
299 }
300
301 binfo->fiu = NULL;
302
303 return 0;
304 }
305
306 static int
build_info_create_dev(struct build_feature_devs_info * binfo,enum fpga_id_type type,unsigned int index)307 build_info_create_dev(struct build_feature_devs_info *binfo,
308 enum fpga_id_type type, unsigned int index)
309 {
310 int ret;
311
312 if ((type == AFU_ID) && (binfo->current_type == PORT_ID))
313 return 0;
314
315 ret = build_info_commit_dev(binfo);
316 if (ret)
317 return ret;
318
319 binfo->current_type = type;
320 binfo->acc_info = NULL;
321
322 if (type == FME_ID) {
323 binfo->fiu = &binfo->hw->fme;
324 } else if (type == PORT_ID) {
325 binfo->fiu = &binfo->hw->port[index];
326 binfo->current_port_id = index;
327 }
328
329 return 0;
330 }
331
parse_feature_afus(struct build_feature_devs_info * binfo,struct feature_header * hdr)332 static int parse_feature_afus(struct build_feature_devs_info *binfo,
333 struct feature_header *hdr)
334 {
335 int ret;
336 struct feature_afu_header *afu_hdr, header;
337 u8 __iomem *start;
338 u8 __iomem *end = binfo->ioend;
339
340 ret = build_info_create_dev(binfo, AFU_ID, 0);
341 if (ret)
342 return ret;
343
344 start = (u8 __iomem *)hdr;
345 for (; start < end; start += header.next_afu) {
346 if ((unsigned int)(end - start) <
347 (unsigned int)(sizeof(*afu_hdr) + sizeof(*hdr)))
348 return -EINVAL;
349
350 hdr = (struct feature_header *)start;
351 afu_hdr = (struct feature_afu_header *)(hdr + 1);
352 header.csr = readq(&afu_hdr->csr);
353
354 if (feature_is_UAFU(binfo)) {
355 ret = parse_feature_uafu(binfo, hdr);
356 if (ret)
357 return ret;
358 }
359
360 if (!header.next_afu)
361 break;
362 }
363
364 return 0;
365 }
366
parse_feature_fme(struct build_feature_devs_info * binfo,struct feature_header * start)367 static int parse_feature_fme(struct build_feature_devs_info *binfo,
368 struct feature_header *start)
369 {
370 struct ifpga_hw *hw = binfo->hw;
371 struct ifpga_fme_hw *fme = &hw->fme;
372 int ret;
373
374 ret = build_info_create_dev(binfo, FME_ID, 0);
375 if (ret)
376 return ret;
377
378 /* Update FME states */
379 fme->state = IFPGA_FME_IMPLEMENTED;
380 fme->parent = hw;
381 TAILQ_INIT(&fme->feature_list);
382 spinlock_init(&fme->lock);
383
384 return create_feature_instance(binfo, start, 0, 0, 0, 0);
385 }
386
parse_feature_port(struct build_feature_devs_info * binfo,void __iomem * start)387 static int parse_feature_port(struct build_feature_devs_info *binfo,
388 void __iomem *start)
389 {
390 struct feature_port_header *port_hdr;
391 struct feature_port_capability capability;
392 struct ifpga_hw *hw = binfo->hw;
393 struct ifpga_port_hw *port;
394 unsigned int port_id;
395 int ret;
396
397 /* Get current port's id */
398 port_hdr = (struct feature_port_header *)start;
399 capability.csr = readq(&port_hdr->capability);
400 port_id = capability.port_number;
401
402 ret = build_info_create_dev(binfo, PORT_ID, port_id);
403 if (ret)
404 return ret;
405
406 /*found a Port device*/
407 port = &hw->port[port_id];
408 port->port_id = binfo->current_port_id;
409 port->parent = hw;
410 port->state = IFPGA_PORT_ATTACHED;
411 spinlock_init(&port->lock);
412 TAILQ_INIT(&port->feature_list);
413
414 return create_feature_instance(binfo, start, 0, 0, 0, 0);
415 }
416
enable_port_uafu(struct build_feature_devs_info * binfo,void __iomem * start)417 static void enable_port_uafu(struct build_feature_devs_info *binfo,
418 void __iomem *start)
419 {
420 struct ifpga_port_hw *port = &binfo->hw->port[binfo->current_port_id];
421
422 UNUSED(start);
423
424 fpga_port_reset(port);
425 }
426
parse_feature_fiu(struct build_feature_devs_info * binfo,struct feature_header * hdr)427 static int parse_feature_fiu(struct build_feature_devs_info *binfo,
428 struct feature_header *hdr)
429 {
430 struct feature_header header;
431 struct feature_fiu_header *fiu_hdr, fiu_header;
432 u8 __iomem *start = (u8 __iomem *)hdr;
433 int ret;
434
435 header.csr = readq(hdr);
436
437 switch (header.id) {
438 case FEATURE_FIU_ID_FME:
439 ret = parse_feature_fme(binfo, hdr);
440 binfo->pfme_hdr = hdr;
441 if (ret)
442 return ret;
443 break;
444 case FEATURE_FIU_ID_PORT:
445 ret = parse_feature_port(binfo, hdr);
446 enable_port_uafu(binfo, hdr);
447 if (ret)
448 return ret;
449
450 /* Check Port FIU's next_afu pointer to User AFU DFH */
451 fiu_hdr = (struct feature_fiu_header *)(hdr + 1);
452 fiu_header.csr = readq(&fiu_hdr->csr);
453
454 if (fiu_header.next_afu) {
455 start += fiu_header.next_afu;
456 ret = parse_feature_afus(binfo,
457 (struct feature_header *)start);
458 if (ret)
459 return ret;
460 } else {
461 dev_info(binfo, "No AFU detected on Port\n");
462 }
463
464 break;
465 default:
466 dev_info(binfo, "FIU TYPE %d is not supported yet.\n",
467 header.id);
468 }
469
470 return 0;
471 }
472
parse_feature_irqs(struct build_feature_devs_info * binfo,void __iomem * start,unsigned int * vec_start,unsigned int * vec_cnt)473 static void parse_feature_irqs(struct build_feature_devs_info *binfo,
474 void __iomem *start, unsigned int *vec_start,
475 unsigned int *vec_cnt)
476 {
477 UNUSED(binfo);
478 u64 id;
479
480 id = feature_id(start);
481
482 if ((binfo->current_type == PORT_ID) && (id == PORT_FEATURE_ID_UINT)) {
483 struct feature_port_uint *port_uint = start;
484 struct feature_port_uint_cap uint_cap;
485
486 uint_cap.csr = readq(&port_uint->capability);
487 if (uint_cap.intr_num) {
488 *vec_start = uint_cap.first_vec_num;
489 *vec_cnt = uint_cap.intr_num;
490 } else {
491 dev_debug(binfo, "UAFU doesn't support interrupt\n");
492 }
493 } else if ((binfo->current_type == PORT_ID) &&
494 (id == PORT_FEATURE_ID_ERROR)) {
495 struct feature_port_error *port_err = start;
496 struct feature_port_err_capability port_err_cap;
497
498 port_err_cap.csr = readq(&port_err->error_capability);
499 if (port_err_cap.support_intr) {
500 *vec_start = port_err_cap.intr_vector_num;
501 *vec_cnt = 1;
502 } else {
503 dev_debug(&binfo, "Port error doesn't support interrupt\n");
504 }
505
506 } else if ((binfo->current_type == FME_ID) &&
507 (id == FME_FEATURE_ID_GLOBAL_ERR)) {
508 struct feature_fme_err *fme_err = start;
509 struct feature_fme_error_capability fme_err_cap;
510
511 fme_err_cap.csr = readq(&fme_err->fme_err_capability);
512 if (fme_err_cap.support_intr) {
513 *vec_start = fme_err_cap.intr_vector_num;
514 *vec_cnt = 1;
515 } else {
516 dev_debug(&binfo, "FME error doesn't support interrupt\n");
517 }
518 }
519 }
520
parse_feature_fme_private(struct build_feature_devs_info * binfo,struct feature_header * hdr)521 static int parse_feature_fme_private(struct build_feature_devs_info *binfo,
522 struct feature_header *hdr)
523 {
524 unsigned int vec_start = 0;
525 unsigned int vec_cnt = 0;
526
527 parse_feature_irqs(binfo, hdr, &vec_start, &vec_cnt);
528
529 return create_feature_instance(binfo, hdr, 0, 0, vec_start, vec_cnt);
530 }
531
parse_feature_port_private(struct build_feature_devs_info * binfo,struct feature_header * hdr)532 static int parse_feature_port_private(struct build_feature_devs_info *binfo,
533 struct feature_header *hdr)
534 {
535 unsigned int vec_start = 0;
536 unsigned int vec_cnt = 0;
537
538 parse_feature_irqs(binfo, hdr, &vec_start, &vec_cnt);
539
540 return create_feature_instance(binfo, hdr, 0, 0, vec_start, vec_cnt);
541 }
542
parse_feature_private(struct build_feature_devs_info * binfo,struct feature_header * hdr)543 static int parse_feature_private(struct build_feature_devs_info *binfo,
544 struct feature_header *hdr)
545 {
546 struct feature_header header;
547
548 header.csr = readq(hdr);
549
550 switch (binfo->current_type) {
551 case FME_ID:
552 return parse_feature_fme_private(binfo, hdr);
553 case PORT_ID:
554 return parse_feature_port_private(binfo, hdr);
555 case AFU_ID:
556 dev_err(binfo, "private feature %x belonging to AFU "
557 "is not supported yet.\n", header.id);
558 break;
559 default:
560 dev_err(binfo, "private feature %x belonging to TYPE %d "
561 "(unknown_type) is not supported yet.\n",
562 header.id, binfo->current_type);
563 break;
564 }
565 return 0;
566 }
567
parse_feature(struct build_feature_devs_info * binfo,struct feature_header * hdr)568 static int parse_feature(struct build_feature_devs_info *binfo,
569 struct feature_header *hdr)
570 {
571 struct feature_header header;
572 int ret = 0;
573
574 header.csr = readq(hdr);
575
576 switch (header.type) {
577 case FEATURE_TYPE_AFU:
578 ret = parse_feature_afus(binfo, hdr);
579 break;
580 case FEATURE_TYPE_PRIVATE:
581 ret = parse_feature_private(binfo, hdr);
582 break;
583 case FEATURE_TYPE_FIU:
584 ret = parse_feature_fiu(binfo, hdr);
585 break;
586 default:
587 dev_err(binfo, "Feature Type %x is not supported.\n",
588 hdr->type);
589 };
590
591 return ret;
592 }
593
build_info_prepare(struct build_feature_devs_info * binfo,struct dfl_fpga_enum_dfl * dfl)594 static int build_info_prepare(struct build_feature_devs_info *binfo,
595 struct dfl_fpga_enum_dfl *dfl)
596 {
597 if (!binfo || !dfl)
598 return -EINVAL;
599
600 binfo->ioaddr = dfl->addr;
601 binfo->ioend = (u8 *)dfl->addr + dfl->len;
602 binfo->phys_addr = dfl->start;
603
604 return 0;
605 }
606
parse_feature_list(struct build_feature_devs_info * binfo,struct dfl_fpga_enum_dfl * dfl)607 static int parse_feature_list(struct build_feature_devs_info *binfo,
608 struct dfl_fpga_enum_dfl *dfl)
609 {
610 u8 *start, *end;
611 struct feature_header *hdr, header;
612 int ret = 0;
613
614 ret = build_info_prepare(binfo, dfl);
615 if (ret)
616 return ret;
617
618 start = (u8 *)binfo->ioaddr;
619 end = (u8 *)binfo->ioend;
620
621 /* walk through the device feature list via DFH's next DFH pointer. */
622 for (; start < end; start += header.next_header_offset) {
623 if ((unsigned int)(end - start) < (unsigned int)sizeof(*hdr)) {
624 dev_err(binfo, "The region is too small to "
625 "contain a feature.\n");
626 ret = -EINVAL;
627 break;
628 }
629
630 hdr = (struct feature_header *)start;
631 header.csr = opae_readq(hdr);
632
633 dev_debug(binfo, "%s: address=0x%p, val=0x%"PRIx64", "
634 "header.id=0x%x, header.next_offset=0x%x, "
635 "header.eol=0x%x, header.type=0x%x\n",
636 __func__, hdr, header.csr, header.id,
637 header.next_header_offset, header.end_of_list,
638 header.type);
639
640 ret = parse_feature(binfo, hdr);
641 if (ret)
642 return ret;
643
644 /* stop parsing if EOL(End of List) is set or offset is 0 */
645 if (header.end_of_list || !header.next_header_offset)
646 break;
647 }
648
649 return build_info_commit_dev(binfo);
650 }
651
build_info_free(struct build_feature_devs_info * binfo)652 static void build_info_free(struct build_feature_devs_info *binfo)
653 {
654 opae_free(binfo);
655 }
656
ifpga_print_device_feature_list(struct ifpga_hw * hw)657 static void ifpga_print_device_feature_list(struct ifpga_hw *hw)
658 {
659 struct ifpga_fme_hw *fme = &hw->fme;
660 struct ifpga_port_hw *port;
661 struct ifpga_feature *feature;
662 int i;
663
664 if (fme->state == IFPGA_FME_UNUSED) {
665 dev_info(hw, "FME is not present\n");
666 return;
667 }
668
669 dev_info(hw, "found fme_device, is in PF: %s\n",
670 is_ifpga_hw_pf(hw) ? "yes" : "no");
671
672 ifpga_for_each_fme_feature(fme, feature) {
673 if (feature->state != IFPGA_FEATURE_ATTACHED)
674 continue;
675
676 dev_info(hw, "%12s: %p - %p - paddr: 0x%lx\n",
677 feature->name, feature->addr,
678 feature->addr + feature->size - 1,
679 (unsigned long)feature->phys_addr);
680
681 }
682
683 for (i = 0; i < MAX_FPGA_PORT_NUM; i++) {
684 port = &hw->port[i];
685
686 if (port->state != IFPGA_PORT_ATTACHED)
687 continue;
688
689 dev_info(hw, "port device: %d\n", port->port_id);
690
691 ifpga_for_each_port_feature(port, feature) {
692 if (feature->state != IFPGA_FEATURE_ATTACHED)
693 continue;
694
695 dev_info(hw, "%12s: %p - %p - paddr:0x%lx\n",
696 feature->name,
697 feature->addr,
698 feature->addr +
699 feature->size - 1,
700 (unsigned long)feature->phys_addr);
701 }
702
703 }
704 }
705
dfl_fpga_enum_info_alloc(struct ifpga_hw * hw)706 static struct dfl_fpga_enum_info *dfl_fpga_enum_info_alloc(struct ifpga_hw *hw)
707 {
708 struct dfl_fpga_enum_info *info;
709
710 info = opae_zmalloc(sizeof(*info));
711 if (!info)
712 return NULL;
713
714 info->hw = hw;
715 TAILQ_INIT(&info->dfls);
716
717 return info;
718 }
719
dfl_fpga_enum_info_free(struct dfl_fpga_enum_info * info)720 static void dfl_fpga_enum_info_free(struct dfl_fpga_enum_info *info)
721 {
722 struct dfl_fpga_enum_dfl *tmp, *dfl;
723
724 if (!info)
725 return;
726
727 /* remove all device feature lists in the list. */
728 for (dfl = TAILQ_FIRST(&info->dfls);
729 dfl && (tmp = TAILQ_NEXT(dfl, node), 1);
730 dfl = tmp) {
731 TAILQ_REMOVE(&info->dfls, dfl, node);
732 opae_free(dfl);
733 }
734
735 opae_free(info);
736 }
737
dfl_fpga_enum_info_add_dfl(struct dfl_fpga_enum_info * info,u64 start,u64 len,void * addr)738 static int dfl_fpga_enum_info_add_dfl(struct dfl_fpga_enum_info *info,
739 u64 start, u64 len, void *addr)
740 {
741 struct dfl_fpga_enum_dfl *dfl;
742
743 dfl = opae_zmalloc(sizeof(*dfl));
744 if (!dfl)
745 return -ENOMEM;
746
747 dfl->start = start;
748 dfl->len = len;
749 dfl->addr = addr;
750
751 TAILQ_INSERT_TAIL(&info->dfls, dfl, node);
752
753 return 0;
754 }
755
756 #define PCI_CFG_SPACE_SIZE 256
757 #define PCI_CFG_SPACE_EXP_SIZE 4096
758 #define PCI_EXT_CAP_ID(header) (header & 0x0000ffff)
759 #define PCI_EXT_CAP_NEXT(header) ((header >> 20) & 0xffc)
760
761 static int
pci_find_next_ecap(int fd,int start,u32 cap)762 pci_find_next_ecap(int fd, int start, u32 cap)
763 {
764 u32 header;
765 int ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8;
766 int pos = PCI_CFG_SPACE_SIZE;
767 int ret;
768
769 if (start > 0)
770 pos = start;
771
772 ret = pread(fd, &header, sizeof(header), pos);
773 if (ret < 0)
774 return ret;
775
776 /*
777 * If we have no capabilities, this is indicated by cap ID,
778 * cap version and next pointer all being 0.
779 */
780 if (header == 0)
781 return 0;
782
783 while (ttl-- > 0) {
784 if ((PCI_EXT_CAP_ID(header) == cap) && (pos != start))
785 return pos;
786
787 pos = PCI_EXT_CAP_NEXT(header);
788 if (pos < PCI_CFG_SPACE_SIZE)
789 break;
790 ret = pread(fd, &header, sizeof(header), pos);
791 if (ret < 0)
792 return ret;
793 }
794
795 return 0;
796 }
797
798 #define PCI_EXT_CAP_ID_VNDR 0x0B
799 #define PCI_VNDR_HEADER 4
800 #define PCI_VNDR_HEADER_ID(x) ((x) & 0xffff)
801 #define PCI_VENDOR_ID_INTEL 0x8086
802 #define PCI_VSEC_ID_INTEL_DFLS 0x43
803 #define PCI_VNDR_DFLS_CNT 0x8
804 #define PCI_VNDR_DFLS_RES 0xc
805 #define PCI_VNDR_DFLS_RES_BAR_MASK GENMASK(2, 0)
806 #define PCI_VNDR_DFLS_RES_OFF_MASK GENMASK(31, 3)
807
find_dfls_by_vsec(struct dfl_fpga_enum_info * info)808 static int find_dfls_by_vsec(struct dfl_fpga_enum_info *info)
809 {
810 struct ifpga_hw *hw;
811 struct opae_adapter_data_pci *pci_data;
812 char path[64];
813 u32 bir, offset, vndr_hdr, i, dfl_cnt, dfl_res;
814 int fd, ret, dfl_res_off, voff = 0;
815 u64 start, len;
816 void *addr;
817
818 if (!info || !info->hw)
819 return -EINVAL;
820 hw = info->hw;
821
822 if (!hw->adapter || !hw->pci_data)
823 return -EINVAL;
824 pci_data = hw->pci_data;
825
826 ret = snprintf(path, sizeof(path), "/sys/bus/pci/devices/%s/config",
827 hw->adapter->name);
828 if ((unsigned int)ret >= sizeof(path))
829 return -EINVAL;
830
831 fd = open(path, O_RDWR);
832 if (fd < 0)
833 return -EIO;
834
835 while ((voff = pci_find_next_ecap(fd, voff,
836 PCI_EXT_CAP_ID_VNDR))) {
837 vndr_hdr = 0;
838 ret = pread(fd, &vndr_hdr, sizeof(vndr_hdr),
839 voff + PCI_VNDR_HEADER);
840 if (ret < 0) {
841 ret = -EIO;
842 goto free_handle;
843 }
844 if (PCI_VNDR_HEADER_ID(vndr_hdr) == PCI_VSEC_ID_INTEL_DFLS &&
845 pci_data->vendor_id == PCI_VENDOR_ID_INTEL)
846 break;
847 }
848
849 if (!voff) {
850 dev_debug(hw, "%s no DFL VSEC found\n", __func__);
851 ret = -ENODEV;
852 goto free_handle;
853 }
854
855 dfl_cnt = 0;
856 ret = pread(fd, &dfl_cnt, sizeof(dfl_cnt), voff + PCI_VNDR_DFLS_CNT);
857 if (ret < 0) {
858 ret = -EIO;
859 goto free_handle;
860 }
861
862 dfl_res_off = voff + PCI_VNDR_DFLS_RES;
863 if (dfl_res_off + (dfl_cnt * sizeof(u32)) > PCI_CFG_SPACE_EXP_SIZE) {
864 dev_err(hw, "%s DFL VSEC too big for PCIe config space\n",
865 __func__);
866 ret = -EINVAL;
867 goto free_handle;
868 }
869
870 for (i = 0; i < dfl_cnt; i++, dfl_res_off += sizeof(u32)) {
871 dfl_res = GENMASK(31, 0);
872 ret = pread(fd, &dfl_res, sizeof(dfl_res), dfl_res_off);
873 bir = dfl_res & PCI_VNDR_DFLS_RES_BAR_MASK;
874 if (bir >= PCI_MAX_RESOURCE) {
875 dev_err(hw, "%s bad bir number %d\n",
876 __func__, bir);
877 ret = -EINVAL;
878 goto free_handle;
879 }
880
881 len = pci_data->region[bir].len;
882 offset = dfl_res & PCI_VNDR_DFLS_RES_OFF_MASK;
883 if (offset >= len) {
884 dev_err(hw, "%s bad offset %u >= %"PRIu64"\n",
885 __func__, offset, len);
886 ret = -EINVAL;
887 goto free_handle;
888 }
889
890 dev_debug(hw, "%s BAR %d offset 0x%x\n", __func__, bir, offset);
891 len -= offset;
892 start = pci_data->region[bir].phys_addr + offset;
893 addr = pci_data->region[bir].addr + offset;
894 dfl_fpga_enum_info_add_dfl(info, start, len, addr);
895 }
896
897 free_handle:
898 close(fd);
899 return ret;
900 }
901
902 /* default method of finding dfls starting at offset 0 of bar 0 */
903 static int
find_dfls_by_default(struct dfl_fpga_enum_info * info)904 find_dfls_by_default(struct dfl_fpga_enum_info *info)
905 {
906 struct ifpga_hw *hw;
907 struct opae_adapter_data_pci *pci_data;
908 int port_num, bar, i, ret = 0;
909 u64 start, len;
910 void *addr;
911 u32 offset;
912 struct feature_header hdr;
913 struct feature_fme_capability cap;
914 struct feature_fme_port port;
915 struct feature_fme_header *fme_hdr;
916
917 if (!info || !info->hw)
918 return -EINVAL;
919 hw = info->hw;
920
921 if (!hw->pci_data)
922 return -EINVAL;
923 pci_data = hw->pci_data;
924
925 /* start to find Device Feature List from Bar 0 */
926 addr = pci_data->region[0].addr;
927 if (!addr)
928 return -ENOMEM;
929
930 /*
931 * PF device has FME and Ports/AFUs, and VF device only has one
932 * Port/AFU. Check them and add related "Device Feature List" info
933 * for the next step enumeration.
934 */
935 hdr.csr = opae_readq(addr);
936 if ((hdr.type == FEATURE_TYPE_FIU) && (hdr.id == FEATURE_FIU_ID_FME)) {
937 start = pci_data->region[0].phys_addr;
938 len = pci_data->region[0].len;
939 addr = pci_data->region[0].addr;
940
941 dfl_fpga_enum_info_add_dfl(info, start, len, addr);
942
943 /*
944 * find more Device Feature Lists (e.g. Ports) per information
945 * indicated by FME module.
946 */
947 fme_hdr = (struct feature_fme_header *)addr;
948 cap.csr = opae_readq(&fme_hdr->capability);
949 port_num = (int)cap.num_ports;
950
951 dev_info(hw, "port_num = %d\n", port_num);
952 if (port_num > MAX_FPGA_PORT_NUM)
953 port_num = MAX_FPGA_PORT_NUM;
954
955 for (i = 0; i < port_num; i++) {
956 port.csr = opae_readq(&fme_hdr->port[i]);
957
958 /* skip ports which are not implemented. */
959 if (!port.port_implemented)
960 continue;
961
962 /* skip port which only could be accessed via VF */
963 if (port.afu_access_control == FME_AFU_ACCESS_VF)
964 continue;
965
966 /*
967 * add Port's Device Feature List information for next
968 * step enumeration.
969 */
970 bar = (int)port.port_bar;
971 offset = port.port_offset;
972 if (bar == FME_PORT_OFST_BAR_SKIP) {
973 continue;
974 } else if (bar >= PCI_MAX_RESOURCE) {
975 dev_err(hw, "bad BAR %d for port %d\n", bar, i);
976 ret = -EINVAL;
977 break;
978 }
979 dev_info(hw, "BAR %d offset %u\n", bar, offset);
980
981 len = pci_data->region[bar].len;
982 if (offset >= len) {
983 dev_warn(hw, "bad port offset %u >= %pa\n",
984 offset, &len);
985 continue;
986 }
987
988 len -= offset;
989 start = pci_data->region[bar].phys_addr + offset;
990 addr = pci_data->region[bar].addr + offset;
991 dfl_fpga_enum_info_add_dfl(info, start, len, addr);
992 }
993 } else if ((hdr.type == FEATURE_TYPE_FIU) &&
994 (hdr.id == FEATURE_FIU_ID_PORT)) {
995 start = pci_data->region[0].phys_addr;
996 len = pci_data->region[0].len;
997 addr = pci_data->region[0].addr;
998
999 dfl_fpga_enum_info_add_dfl(info, start, len, addr);
1000 } else if (hdr.type == FEATURE_TYPE_AFU) {
1001 start = pci_data->region[0].phys_addr;
1002 len = pci_data->region[0].len;
1003 addr = pci_data->region[0].addr;
1004
1005 dfl_fpga_enum_info_add_dfl(info, start, len, addr);
1006 } else {
1007 dev_info(hw, "Unknown feature type 0x%x id 0x%x\n",
1008 hdr.type, hdr.id);
1009 ret = -ENODEV;
1010 }
1011
1012 return ret;
1013 }
1014
dfl_fpga_feature_devs_enumerate(struct dfl_fpga_enum_info * info)1015 static int dfl_fpga_feature_devs_enumerate(struct dfl_fpga_enum_info *info)
1016 {
1017 struct build_feature_devs_info *binfo;
1018 struct dfl_fpga_enum_dfl *dfl;
1019 int ret = 0;
1020
1021 if (!info || !info->hw)
1022 return -EINVAL;
1023
1024 /* create and init build info for enumeration */
1025 binfo = opae_zmalloc(sizeof(*binfo));
1026 if (!binfo)
1027 return -ENOMEM;
1028
1029 binfo->hw = info->hw;
1030 binfo->pci_data = info->hw->pci_data;
1031
1032 /*
1033 * start enumeration for all feature devices based on Device Feature
1034 * Lists.
1035 */
1036 TAILQ_FOREACH(dfl, &info->dfls, node) {
1037 ret = parse_feature_list(binfo, dfl);
1038 if (ret)
1039 break;
1040 }
1041
1042 build_info_free(binfo);
1043
1044 return ret;
1045 }
1046
ifpga_bus_enumerate(struct ifpga_hw * hw)1047 int ifpga_bus_enumerate(struct ifpga_hw *hw)
1048 {
1049 struct dfl_fpga_enum_info *info;
1050 int ret;
1051
1052 /* allocate enumeration info */
1053 info = dfl_fpga_enum_info_alloc(hw);
1054 if (!info)
1055 return -ENOMEM;
1056
1057 ret = find_dfls_by_vsec(info);
1058 if (ret < 0)
1059 ret = find_dfls_by_default(info);
1060
1061 if (ret)
1062 goto exit;
1063
1064 /* start enumeration with prepared enumeration information */
1065 ret = dfl_fpga_feature_devs_enumerate(info);
1066 if (ret < 0) {
1067 dev_err(hw, "Enumeration failure\n");
1068 goto exit;
1069 }
1070
1071 ifpga_print_device_feature_list(hw);
1072
1073 exit:
1074 dfl_fpga_enum_info_free(info);
1075
1076 return ret;
1077 }
1078
ifpga_print_acc_list(struct opae_adapter * adapter)1079 static void ifpga_print_acc_list(struct opae_adapter *adapter)
1080 {
1081 struct opae_accelerator *acc;
1082 struct ifpga_afu_info *info;
1083 struct uuid guid;
1084 char buf[48];
1085 int i;
1086
1087 opae_adapter_for_each_acc(adapter, acc) {
1088 info = acc->data;
1089 if (!info)
1090 continue;
1091 acc->ops->get_uuid(acc, &guid);
1092 i = sprintf(buf, "%02x%02x%02x%02x-",
1093 guid.b[15], guid.b[14], guid.b[13], guid.b[12]);
1094 i += sprintf(buf+i, "%02x%02x-", guid.b[11], guid.b[10]);
1095 i += sprintf(buf+i, "%02x%02x-", guid.b[9], guid.b[8]);
1096 i += sprintf(buf+i, "%02x%02x-", guid.b[7], guid.b[6]);
1097 sprintf(buf+i, "%02x%02x%02x%02x%02x%02x",
1098 guid.b[5], guid.b[4], guid.b[3],
1099 guid.b[2], guid.b[1], guid.b[0]);
1100 dev_info(hw, "AFU(%s-%d)@%p: len:0x%"PRIx64", guid:%s\n",
1101 acc->name, acc->index, info->region[0].addr,
1102 info->region[0].len, buf);
1103 }
1104 }
1105
ifpga_bus_init(struct ifpga_hw * hw)1106 int ifpga_bus_init(struct ifpga_hw *hw)
1107 {
1108 int i, ret = 0;
1109 struct ifpga_port_hw *port;
1110
1111 ret = fme_hw_init(&hw->fme);
1112 if (ret)
1113 return ret;
1114
1115 for (i = 0; i < MAX_FPGA_PORT_NUM; i++) {
1116 port = &hw->port[i];
1117 port_hw_init(port);
1118 }
1119 ifpga_print_acc_list(hw->adapter);
1120
1121 return 0;
1122 }
1123
ifpga_bus_uinit(struct ifpga_hw * hw)1124 int ifpga_bus_uinit(struct ifpga_hw *hw)
1125 {
1126 int i;
1127 struct ifpga_port_hw *port;
1128
1129 if (hw) {
1130 fme_hw_uinit(&hw->fme);
1131 for (i = 0; i < MAX_FPGA_PORT_NUM; i++) {
1132 port = &hw->port[i];
1133 port_hw_uinit(port);
1134 }
1135 }
1136
1137 return 0;
1138 }
1139