aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/cxl/pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc/cxl/pci.c')
-rw-r--r--drivers/misc/cxl/pci.c131
1 files changed, 105 insertions, 26 deletions
diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c
index 1ef01647265f..32ad09705949 100644
--- a/drivers/misc/cxl/pci.c
+++ b/drivers/misc/cxl/pci.c
@@ -90,6 +90,7 @@
90/* This works a little different than the p1/p2 register accesses to make it 90/* This works a little different than the p1/p2 register accesses to make it
91 * easier to pull out individual fields */ 91 * easier to pull out individual fields */
92#define AFUD_READ(afu, off) in_be64(afu->afu_desc_mmio + off) 92#define AFUD_READ(afu, off) in_be64(afu->afu_desc_mmio + off)
93#define AFUD_READ_LE(afu, off) in_le64(afu->afu_desc_mmio + off)
93#define EXTRACT_PPC_BIT(val, bit) (!!(val & PPC_BIT(bit))) 94#define EXTRACT_PPC_BIT(val, bit) (!!(val & PPC_BIT(bit)))
94#define EXTRACT_PPC_BITS(val, bs, be) ((val & PPC_BITMASK(bs, be)) >> PPC_BITLSHIFT(be)) 95#define EXTRACT_PPC_BITS(val, bs, be) ((val & PPC_BITMASK(bs, be)) >> PPC_BITLSHIFT(be))
95 96
@@ -204,7 +205,7 @@ static void dump_cxl_config_space(struct pci_dev *dev)
204 dev_info(&dev->dev, "p1 regs: %#llx, len: %#llx\n", 205 dev_info(&dev->dev, "p1 regs: %#llx, len: %#llx\n",
205 p1_base(dev), p1_size(dev)); 206 p1_base(dev), p1_size(dev));
206 dev_info(&dev->dev, "p2 regs: %#llx, len: %#llx\n", 207 dev_info(&dev->dev, "p2 regs: %#llx, len: %#llx\n",
207 p1_base(dev), p2_size(dev)); 208 p2_base(dev), p2_size(dev));
208 dev_info(&dev->dev, "BAR 4/5: %#llx, len: %#llx\n", 209 dev_info(&dev->dev, "BAR 4/5: %#llx, len: %#llx\n",
209 pci_resource_start(dev, 4), pci_resource_len(dev, 4)); 210 pci_resource_start(dev, 4), pci_resource_len(dev, 4));
210 211
@@ -286,7 +287,8 @@ static void dump_cxl_config_space(struct pci_dev *dev)
286 287
287static void dump_afu_descriptor(struct cxl_afu *afu) 288static void dump_afu_descriptor(struct cxl_afu *afu)
288{ 289{
289 u64 val; 290 u64 val, afu_cr_num, afu_cr_off, afu_cr_len;
291 int i;
290 292
291#define show_reg(name, what) \ 293#define show_reg(name, what) \
292 dev_info(&afu->dev, "afu desc: %30s: %#llx\n", name, what) 294 dev_info(&afu->dev, "afu desc: %30s: %#llx\n", name, what)
@@ -296,6 +298,7 @@ static void dump_afu_descriptor(struct cxl_afu *afu)
296 show_reg("num_of_processes", AFUD_NUM_PROCS(val)); 298 show_reg("num_of_processes", AFUD_NUM_PROCS(val));
297 show_reg("num_of_afu_CRs", AFUD_NUM_CRS(val)); 299 show_reg("num_of_afu_CRs", AFUD_NUM_CRS(val));
298 show_reg("req_prog_mode", val & 0xffffULL); 300 show_reg("req_prog_mode", val & 0xffffULL);
301 afu_cr_num = AFUD_NUM_CRS(val);
299 302
300 val = AFUD_READ(afu, 0x8); 303 val = AFUD_READ(afu, 0x8);
301 show_reg("Reserved", val); 304 show_reg("Reserved", val);
@@ -307,8 +310,10 @@ static void dump_afu_descriptor(struct cxl_afu *afu)
307 val = AFUD_READ_CR(afu); 310 val = AFUD_READ_CR(afu);
308 show_reg("Reserved", (val >> (63-7)) & 0xff); 311 show_reg("Reserved", (val >> (63-7)) & 0xff);
309 show_reg("AFU_CR_len", AFUD_CR_LEN(val)); 312 show_reg("AFU_CR_len", AFUD_CR_LEN(val));
313 afu_cr_len = AFUD_CR_LEN(val) * 256;
310 314
311 val = AFUD_READ_CR_OFF(afu); 315 val = AFUD_READ_CR_OFF(afu);
316 afu_cr_off = val;
312 show_reg("AFU_CR_offset", val); 317 show_reg("AFU_CR_offset", val);
313 318
314 val = AFUD_READ_PPPSA(afu); 319 val = AFUD_READ_PPPSA(afu);
@@ -325,6 +330,11 @@ static void dump_afu_descriptor(struct cxl_afu *afu)
325 val = AFUD_READ_EB_OFF(afu); 330 val = AFUD_READ_EB_OFF(afu);
326 show_reg("AFU_EB_offset", val); 331 show_reg("AFU_EB_offset", val);
327 332
333 for (i = 0; i < afu_cr_num; i++) {
334 val = AFUD_READ_LE(afu, afu_cr_off + i * afu_cr_len);
335 show_reg("CR Vendor", val & 0xffff);
336 show_reg("CR Device", (val >> 16) & 0xffff);
337 }
328#undef show_reg 338#undef show_reg
329} 339}
330 340
@@ -529,7 +539,7 @@ err:
529 539
530static void cxl_unmap_slice_regs(struct cxl_afu *afu) 540static void cxl_unmap_slice_regs(struct cxl_afu *afu)
531{ 541{
532 if (afu->p1n_mmio) 542 if (afu->p2n_mmio)
533 iounmap(afu->p2n_mmio); 543 iounmap(afu->p2n_mmio);
534 if (afu->p1n_mmio) 544 if (afu->p1n_mmio)
535 iounmap(afu->p1n_mmio); 545 iounmap(afu->p1n_mmio);
@@ -593,6 +603,22 @@ static int cxl_read_afu_descriptor(struct cxl_afu *afu)
593 afu->crs_len = AFUD_CR_LEN(val) * 256; 603 afu->crs_len = AFUD_CR_LEN(val) * 256;
594 afu->crs_offset = AFUD_READ_CR_OFF(afu); 604 afu->crs_offset = AFUD_READ_CR_OFF(afu);
595 605
606
607 /* eb_len is in multiple of 4K */
608 afu->eb_len = AFUD_EB_LEN(AFUD_READ_EB(afu)) * 4096;
609 afu->eb_offset = AFUD_READ_EB_OFF(afu);
610
611 /* eb_off is 4K aligned so lower 12 bits are always zero */
612 if (EXTRACT_PPC_BITS(afu->eb_offset, 0, 11) != 0) {
613 dev_warn(&afu->dev,
614 "Invalid AFU error buffer offset %Lx\n",
615 afu->eb_offset);
616 dev_info(&afu->dev,
617 "Ignoring AFU error buffer in the descriptor\n");
618 /* indicate that no afu buffer exists */
619 afu->eb_len = 0;
620 }
621
596 return 0; 622 return 0;
597} 623}
598 624
@@ -631,7 +657,7 @@ static int sanitise_afu_regs(struct cxl_afu *afu)
631 reg = cxl_p2n_read(afu, CXL_AFU_Cntl_An); 657 reg = cxl_p2n_read(afu, CXL_AFU_Cntl_An);
632 if ((reg & CXL_AFU_Cntl_An_ES_MASK) != CXL_AFU_Cntl_An_ES_Disabled) { 658 if ((reg & CXL_AFU_Cntl_An_ES_MASK) != CXL_AFU_Cntl_An_ES_Disabled) {
633 dev_warn(&afu->dev, "WARNING: AFU was not disabled: %#.16llx\n", reg); 659 dev_warn(&afu->dev, "WARNING: AFU was not disabled: %#.16llx\n", reg);
634 if (cxl_afu_reset(afu)) 660 if (__cxl_afu_reset(afu))
635 return -EIO; 661 return -EIO;
636 if (cxl_afu_disable(afu)) 662 if (cxl_afu_disable(afu))
637 return -EIO; 663 return -EIO;
@@ -672,6 +698,50 @@ static int sanitise_afu_regs(struct cxl_afu *afu)
672 return 0; 698 return 0;
673} 699}
674 700
701#define ERR_BUFF_MAX_COPY_SIZE PAGE_SIZE
702/*
703 * afu_eb_read:
704 * Called from sysfs and reads the afu error info buffer. The h/w only supports
705 * 4/8 bytes aligned access. So in case the requested offset/count arent 8 byte
706 * aligned the function uses a bounce buffer which can be max PAGE_SIZE.
707 */
708ssize_t cxl_afu_read_err_buffer(struct cxl_afu *afu, char *buf,
709 loff_t off, size_t count)
710{
711 loff_t aligned_start, aligned_end;
712 size_t aligned_length;
713 void *tbuf;
714 const void __iomem *ebuf = afu->afu_desc_mmio + afu->eb_offset;
715
716 if (count == 0 || off < 0 || (size_t)off >= afu->eb_len)
717 return 0;
718
719 /* calculate aligned read window */
720 count = min((size_t)(afu->eb_len - off), count);
721 aligned_start = round_down(off, 8);
722 aligned_end = round_up(off + count, 8);
723 aligned_length = aligned_end - aligned_start;
724
725 /* max we can copy in one read is PAGE_SIZE */
726 if (aligned_length > ERR_BUFF_MAX_COPY_SIZE) {
727 aligned_length = ERR_BUFF_MAX_COPY_SIZE;
728 count = ERR_BUFF_MAX_COPY_SIZE - (off & 0x7);
729 }
730
731 /* use bounce buffer for copy */
732 tbuf = (void *)__get_free_page(GFP_TEMPORARY);
733 if (!tbuf)
734 return -ENOMEM;
735
736 /* perform aligned read from the mmio region */
737 memcpy_fromio(tbuf, ebuf + aligned_start, aligned_length);
738 memcpy(buf, tbuf + (off & 0x7), count);
739
740 free_page((unsigned long)tbuf);
741
742 return count;
743}
744
675static int cxl_init_afu(struct cxl *adapter, int slice, struct pci_dev *dev) 745static int cxl_init_afu(struct cxl *adapter, int slice, struct pci_dev *dev)
676{ 746{
677 struct cxl_afu *afu; 747 struct cxl_afu *afu;
@@ -691,7 +761,7 @@ static int cxl_init_afu(struct cxl *adapter, int slice, struct pci_dev *dev)
691 goto err2; 761 goto err2;
692 762
693 /* We need to reset the AFU before we can read the AFU descriptor */ 763 /* We need to reset the AFU before we can read the AFU descriptor */
694 if ((rc = cxl_afu_reset(afu))) 764 if ((rc = __cxl_afu_reset(afu)))
695 goto err2; 765 goto err2;
696 766
697 if (cxl_verbose) 767 if (cxl_verbose)
@@ -731,6 +801,9 @@ static int cxl_init_afu(struct cxl *adapter, int slice, struct pci_dev *dev)
731 801
732 adapter->afu[afu->slice] = afu; 802 adapter->afu[afu->slice] = afu;
733 803
804 if ((rc = cxl_pci_vphb_add(afu)))
805 dev_info(&afu->dev, "Can't register vPHB\n");
806
734 return 0; 807 return 0;
735 808
736err_put2: 809err_put2:
@@ -783,8 +856,10 @@ int cxl_reset(struct cxl *adapter)
783 856
784 dev_info(&dev->dev, "CXL reset\n"); 857 dev_info(&dev->dev, "CXL reset\n");
785 858
786 for (i = 0; i < adapter->slices; i++) 859 for (i = 0; i < adapter->slices; i++) {
860 cxl_pci_vphb_remove(adapter->afu[i]);
787 cxl_remove_afu(adapter->afu[i]); 861 cxl_remove_afu(adapter->afu[i]);
862 }
788 863
789 /* pcie_warm_reset requests a fundamental pci reset which includes a 864 /* pcie_warm_reset requests a fundamental pci reset which includes a
790 * PERST assert/deassert. PERST triggers a loading of the image 865 * PERST assert/deassert. PERST triggers a loading of the image
@@ -857,13 +932,13 @@ static int cxl_read_vsec(struct cxl *adapter, struct pci_dev *dev)
857 u8 image_state; 932 u8 image_state;
858 933
859 if (!(vsec = find_cxl_vsec(dev))) { 934 if (!(vsec = find_cxl_vsec(dev))) {
860 dev_err(&adapter->dev, "ABORTING: CXL VSEC not found!\n"); 935 dev_err(&dev->dev, "ABORTING: CXL VSEC not found!\n");
861 return -ENODEV; 936 return -ENODEV;
862 } 937 }
863 938
864 CXL_READ_VSEC_LENGTH(dev, vsec, &vseclen); 939 CXL_READ_VSEC_LENGTH(dev, vsec, &vseclen);
865 if (vseclen < CXL_VSEC_MIN_SIZE) { 940 if (vseclen < CXL_VSEC_MIN_SIZE) {
866 pr_err("ABORTING: CXL VSEC too short\n"); 941 dev_err(&dev->dev, "ABORTING: CXL VSEC too short\n");
867 return -EINVAL; 942 return -EINVAL;
868 } 943 }
869 944
@@ -902,24 +977,24 @@ static int cxl_vsec_looks_ok(struct cxl *adapter, struct pci_dev *dev)
902 return -EBUSY; 977 return -EBUSY;
903 978
904 if (adapter->vsec_status & CXL_UNSUPPORTED_FEATURES) { 979 if (adapter->vsec_status & CXL_UNSUPPORTED_FEATURES) {
905 dev_err(&adapter->dev, "ABORTING: CXL requires unsupported features\n"); 980 dev_err(&dev->dev, "ABORTING: CXL requires unsupported features\n");
906 return -EINVAL; 981 return -EINVAL;
907 } 982 }
908 983
909 if (!adapter->slices) { 984 if (!adapter->slices) {
910 /* Once we support dynamic reprogramming we can use the card if 985 /* Once we support dynamic reprogramming we can use the card if
911 * it supports loadable AFUs */ 986 * it supports loadable AFUs */
912 dev_err(&adapter->dev, "ABORTING: Device has no AFUs\n"); 987 dev_err(&dev->dev, "ABORTING: Device has no AFUs\n");
913 return -EINVAL; 988 return -EINVAL;
914 } 989 }
915 990
916 if (!adapter->afu_desc_off || !adapter->afu_desc_size) { 991 if (!adapter->afu_desc_off || !adapter->afu_desc_size) {
917 dev_err(&adapter->dev, "ABORTING: VSEC shows no AFU descriptors\n"); 992 dev_err(&dev->dev, "ABORTING: VSEC shows no AFU descriptors\n");
918 return -EINVAL; 993 return -EINVAL;
919 } 994 }
920 995
921 if (adapter->ps_size > p2_size(dev) - adapter->ps_off) { 996 if (adapter->ps_size > p2_size(dev) - adapter->ps_off) {
922 dev_err(&adapter->dev, "ABORTING: Problem state size larger than " 997 dev_err(&dev->dev, "ABORTING: Problem state size larger than "
923 "available in BAR2: 0x%llx > 0x%llx\n", 998 "available in BAR2: 0x%llx > 0x%llx\n",
924 adapter->ps_size, p2_size(dev) - adapter->ps_off); 999 adapter->ps_size, p2_size(dev) - adapter->ps_off);
925 return -EINVAL; 1000 return -EINVAL;
@@ -968,6 +1043,15 @@ static struct cxl *cxl_init_adapter(struct pci_dev *dev)
968 if (!(adapter = cxl_alloc_adapter(dev))) 1043 if (!(adapter = cxl_alloc_adapter(dev)))
969 return ERR_PTR(-ENOMEM); 1044 return ERR_PTR(-ENOMEM);
970 1045
1046 if ((rc = cxl_read_vsec(adapter, dev)))
1047 goto err1;
1048
1049 if ((rc = cxl_vsec_looks_ok(adapter, dev)))
1050 goto err1;
1051
1052 if ((rc = setup_cxl_bars(dev)))
1053 goto err1;
1054
971 if ((rc = switch_card_to_cxl(dev))) 1055 if ((rc = switch_card_to_cxl(dev)))
972 goto err1; 1056 goto err1;
973 1057
@@ -977,12 +1061,6 @@ static struct cxl *cxl_init_adapter(struct pci_dev *dev)
977 if ((rc = dev_set_name(&adapter->dev, "card%i", adapter->adapter_num))) 1061 if ((rc = dev_set_name(&adapter->dev, "card%i", adapter->adapter_num)))
978 goto err2; 1062 goto err2;
979 1063
980 if ((rc = cxl_read_vsec(adapter, dev)))
981 goto err2;
982
983 if ((rc = cxl_vsec_looks_ok(adapter, dev)))
984 goto err2;
985
986 if ((rc = cxl_update_image_control(adapter))) 1064 if ((rc = cxl_update_image_control(adapter)))
987 goto err2; 1065 goto err2;
988 1066
@@ -1067,9 +1145,6 @@ static int cxl_probe(struct pci_dev *dev, const struct pci_device_id *id)
1067 if (cxl_verbose) 1145 if (cxl_verbose)
1068 dump_cxl_config_space(dev); 1146 dump_cxl_config_space(dev);
1069 1147
1070 if ((rc = setup_cxl_bars(dev)))
1071 return rc;
1072
1073 if ((rc = pci_enable_device(dev))) { 1148 if ((rc = pci_enable_device(dev))) {
1074 dev_err(&dev->dev, "pci_enable_device failed: %i\n", rc); 1149 dev_err(&dev->dev, "pci_enable_device failed: %i\n", rc);
1075 return rc; 1150 return rc;
@@ -1078,6 +1153,7 @@ static int cxl_probe(struct pci_dev *dev, const struct pci_device_id *id)
1078 adapter = cxl_init_adapter(dev); 1153 adapter = cxl_init_adapter(dev);
1079 if (IS_ERR(adapter)) { 1154 if (IS_ERR(adapter)) {
1080 dev_err(&dev->dev, "cxl_init_adapter failed: %li\n", PTR_ERR(adapter)); 1155 dev_err(&dev->dev, "cxl_init_adapter failed: %li\n", PTR_ERR(adapter));
1156 pci_disable_device(dev);
1081 return PTR_ERR(adapter); 1157 return PTR_ERR(adapter);
1082 } 1158 }
1083 1159
@@ -1092,16 +1168,18 @@ static int cxl_probe(struct pci_dev *dev, const struct pci_device_id *id)
1092static void cxl_remove(struct pci_dev *dev) 1168static void cxl_remove(struct pci_dev *dev)
1093{ 1169{
1094 struct cxl *adapter = pci_get_drvdata(dev); 1170 struct cxl *adapter = pci_get_drvdata(dev);
1095 int afu; 1171 struct cxl_afu *afu;
1096 1172 int i;
1097 dev_warn(&dev->dev, "pci remove\n");
1098 1173
1099 /* 1174 /*
1100 * Lock to prevent someone grabbing a ref through the adapter list as 1175 * Lock to prevent someone grabbing a ref through the adapter list as
1101 * we are removing it 1176 * we are removing it
1102 */ 1177 */
1103 for (afu = 0; afu < adapter->slices; afu++) 1178 for (i = 0; i < adapter->slices; i++) {
1104 cxl_remove_afu(adapter->afu[afu]); 1179 afu = adapter->afu[i];
1180 cxl_pci_vphb_remove(afu);
1181 cxl_remove_afu(afu);
1182 }
1105 cxl_remove_adapter(adapter); 1183 cxl_remove_adapter(adapter);
1106} 1184}
1107 1185
@@ -1110,4 +1188,5 @@ struct pci_driver cxl_pci_driver = {
1110 .id_table = cxl_pci_tbl, 1188 .id_table = cxl_pci_tbl,
1111 .probe = cxl_probe, 1189 .probe = cxl_probe,
1112 .remove = cxl_remove, 1190 .remove = cxl_remove,
1191 .shutdown = cxl_remove,
1113}; 1192};