GNU Linux-libre 5.19-rc6-gnu
[releases.git] / drivers / platform / x86 / intel / sdsi.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Intel Software Defined Silicon driver
4  *
5  * Copyright (c) 2022, Intel Corporation.
6  * All Rights Reserved.
7  *
8  * Author: "David E. Box" <david.e.box@linux.intel.com>
9  */
10
11 #include <linux/auxiliary_bus.h>
12 #include <linux/bits.h>
13 #include <linux/bitfield.h>
14 #include <linux/device.h>
15 #include <linux/iopoll.h>
16 #include <linux/kernel.h>
17 #include <linux/module.h>
18 #include <linux/pci.h>
19 #include <linux/slab.h>
20 #include <linux/sysfs.h>
21 #include <linux/types.h>
22 #include <linux/uaccess.h>
23
24 #include "vsec.h"
25
26 #define ACCESS_TYPE_BARID               2
27 #define ACCESS_TYPE_LOCAL               3
28
29 #define SDSI_MIN_SIZE_DWORDS            276
30 #define SDSI_SIZE_CONTROL               8
31 #define SDSI_SIZE_MAILBOX               1024
32 #define SDSI_SIZE_REGS                  72
33 #define SDSI_SIZE_CMD                   sizeof(u64)
34
35 /*
36  * Write messages are currently up to the size of the mailbox
37  * while read messages are up to 4 times the size of the
38  * mailbox, sent in packets
39  */
40 #define SDSI_SIZE_WRITE_MSG             SDSI_SIZE_MAILBOX
41 #define SDSI_SIZE_READ_MSG              (SDSI_SIZE_MAILBOX * 4)
42
43 #define SDSI_ENABLED_FEATURES_OFFSET    16
44 #define SDSI_ENABLED                    BIT(3)
45 #define SDSI_SOCKET_ID_OFFSET           64
46 #define SDSI_SOCKET_ID                  GENMASK(3, 0)
47
48 #define SDSI_MBOX_CMD_SUCCESS           0x40
49 #define SDSI_MBOX_CMD_TIMEOUT           0x80
50
51 #define MBOX_TIMEOUT_US                 2000
52 #define MBOX_TIMEOUT_ACQUIRE_US         1000
53 #define MBOX_POLLING_PERIOD_US          100
54 #define MBOX_ACQUIRE_NUM_RETRIES        5
55 #define MBOX_ACQUIRE_RETRY_DELAY_MS     500
56 #define MBOX_MAX_PACKETS                4
57
58 #define MBOX_OWNER_NONE                 0x00
59 #define MBOX_OWNER_INBAND               0x01
60
61 #define CTRL_RUN_BUSY                   BIT(0)
62 #define CTRL_READ_WRITE                 BIT(1)
63 #define CTRL_SOM                        BIT(2)
64 #define CTRL_EOM                        BIT(3)
65 #define CTRL_OWNER                      GENMASK(5, 4)
66 #define CTRL_COMPLETE                   BIT(6)
67 #define CTRL_READY                      BIT(7)
68 #define CTRL_STATUS                     GENMASK(15, 8)
69 #define CTRL_PACKET_SIZE                GENMASK(31, 16)
70 #define CTRL_MSG_SIZE                   GENMASK(63, 48)
71
72 #define DISC_TABLE_SIZE                 12
73 #define DT_ACCESS_TYPE                  GENMASK(3, 0)
74 #define DT_SIZE                         GENMASK(27, 12)
75 #define DT_TBIR                         GENMASK(2, 0)
76 #define DT_OFFSET(v)                    ((v) & GENMASK(31, 3))
77
78 enum sdsi_command {
79         SDSI_CMD_PROVISION_AKC          = 0x04,
80         SDSI_CMD_PROVISION_CAP          = 0x08,
81         SDSI_CMD_READ_STATE             = 0x10,
82 };
83
84 struct sdsi_mbox_info {
85         u64     *payload;
86         void    *buffer;
87         int     size;
88 };
89
90 struct disc_table {
91         u32     access_info;
92         u32     guid;
93         u32     offset;
94 };
95
96 struct sdsi_priv {
97         struct mutex            mb_lock;        /* Mailbox access lock */
98         struct device           *dev;
99         void __iomem            *control_addr;
100         void __iomem            *mbox_addr;
101         void __iomem            *regs_addr;
102         u32                     guid;
103         bool                    sdsi_enabled;
104 };
105
106 /* SDSi mailbox operations must be performed using 64bit mov instructions */
107 static __always_inline void
108 sdsi_memcpy64_toio(u64 __iomem *to, const u64 *from, size_t count_bytes)
109 {
110         size_t count = count_bytes / sizeof(*to);
111         int i;
112
113         for (i = 0; i < count; i++)
114                 writeq(from[i], &to[i]);
115 }
116
117 static __always_inline void
118 sdsi_memcpy64_fromio(u64 *to, const u64 __iomem *from, size_t count_bytes)
119 {
120         size_t count = count_bytes / sizeof(*to);
121         int i;
122
123         for (i = 0; i < count; i++)
124                 to[i] = readq(&from[i]);
125 }
126
127 static inline void sdsi_complete_transaction(struct sdsi_priv *priv)
128 {
129         u64 control = FIELD_PREP(CTRL_COMPLETE, 1);
130
131         lockdep_assert_held(&priv->mb_lock);
132         writeq(control, priv->control_addr);
133 }
134
135 static int sdsi_status_to_errno(u32 status)
136 {
137         switch (status) {
138         case SDSI_MBOX_CMD_SUCCESS:
139                 return 0;
140         case SDSI_MBOX_CMD_TIMEOUT:
141                 return -ETIMEDOUT;
142         default:
143                 return -EIO;
144         }
145 }
146
147 static int sdsi_mbox_cmd_read(struct sdsi_priv *priv, struct sdsi_mbox_info *info,
148                               size_t *data_size)
149 {
150         struct device *dev = priv->dev;
151         u32 total, loop, eom, status, message_size;
152         u64 control;
153         int ret;
154
155         lockdep_assert_held(&priv->mb_lock);
156
157         /* Format and send the read command */
158         control = FIELD_PREP(CTRL_EOM, 1) |
159                   FIELD_PREP(CTRL_SOM, 1) |
160                   FIELD_PREP(CTRL_RUN_BUSY, 1) |
161                   FIELD_PREP(CTRL_PACKET_SIZE, info->size);
162         writeq(control, priv->control_addr);
163
164         /* For reads, data sizes that are larger than the mailbox size are read in packets. */
165         total = 0;
166         loop = 0;
167         do {
168                 void *buf = info->buffer + (SDSI_SIZE_MAILBOX * loop);
169                 u32 packet_size;
170
171                 /* Poll on ready bit */
172                 ret = readq_poll_timeout(priv->control_addr, control, control & CTRL_READY,
173                                          MBOX_POLLING_PERIOD_US, MBOX_TIMEOUT_US);
174                 if (ret)
175                         break;
176
177                 eom = FIELD_GET(CTRL_EOM, control);
178                 status = FIELD_GET(CTRL_STATUS, control);
179                 packet_size = FIELD_GET(CTRL_PACKET_SIZE, control);
180                 message_size = FIELD_GET(CTRL_MSG_SIZE, control);
181
182                 ret = sdsi_status_to_errno(status);
183                 if (ret)
184                         break;
185
186                 /* Only the last packet can be less than the mailbox size. */
187                 if (!eom && packet_size != SDSI_SIZE_MAILBOX) {
188                         dev_err(dev, "Invalid packet size\n");
189                         ret = -EPROTO;
190                         break;
191                 }
192
193                 if (packet_size > SDSI_SIZE_MAILBOX) {
194                         dev_err(dev, "Packet size too large\n");
195                         ret = -EPROTO;
196                         break;
197                 }
198
199                 sdsi_memcpy64_fromio(buf, priv->mbox_addr, round_up(packet_size, SDSI_SIZE_CMD));
200
201                 total += packet_size;
202
203                 sdsi_complete_transaction(priv);
204         } while (!eom && ++loop < MBOX_MAX_PACKETS);
205
206         if (ret) {
207                 sdsi_complete_transaction(priv);
208                 return ret;
209         }
210
211         if (!eom) {
212                 dev_err(dev, "Exceeded read attempts\n");
213                 return -EPROTO;
214         }
215
216         /* Message size check is only valid for multi-packet transfers */
217         if (loop && total != message_size)
218                 dev_warn(dev, "Read count %u differs from expected count %u\n",
219                          total, message_size);
220
221         *data_size = total;
222
223         return 0;
224 }
225
226 static int sdsi_mbox_cmd_write(struct sdsi_priv *priv, struct sdsi_mbox_info *info)
227 {
228         u64 control;
229         u32 status;
230         int ret;
231
232         lockdep_assert_held(&priv->mb_lock);
233
234         /* Write rest of the payload */
235         sdsi_memcpy64_toio(priv->mbox_addr + SDSI_SIZE_CMD, info->payload + 1,
236                            info->size - SDSI_SIZE_CMD);
237
238         /* Format and send the write command */
239         control = FIELD_PREP(CTRL_EOM, 1) |
240                   FIELD_PREP(CTRL_SOM, 1) |
241                   FIELD_PREP(CTRL_RUN_BUSY, 1) |
242                   FIELD_PREP(CTRL_READ_WRITE, 1) |
243                   FIELD_PREP(CTRL_PACKET_SIZE, info->size);
244         writeq(control, priv->control_addr);
245
246         /* Poll on ready bit */
247         ret = readq_poll_timeout(priv->control_addr, control, control & CTRL_READY,
248                                  MBOX_POLLING_PERIOD_US, MBOX_TIMEOUT_US);
249
250         if (ret)
251                 goto release_mbox;
252
253         status = FIELD_GET(CTRL_STATUS, control);
254         ret = sdsi_status_to_errno(status);
255
256 release_mbox:
257         sdsi_complete_transaction(priv);
258
259         return ret;
260 }
261
262 static int sdsi_mbox_acquire(struct sdsi_priv *priv, struct sdsi_mbox_info *info)
263 {
264         u64 control;
265         u32 owner;
266         int ret, retries = 0;
267
268         lockdep_assert_held(&priv->mb_lock);
269
270         /* Check mailbox is available */
271         control = readq(priv->control_addr);
272         owner = FIELD_GET(CTRL_OWNER, control);
273         if (owner != MBOX_OWNER_NONE)
274                 return -EBUSY;
275
276         /*
277          * If there has been no recent transaction and no one owns the mailbox,
278          * we should acquire it in under 1ms. However, if we've accessed it
279          * recently it may take up to 2.1 seconds to acquire it again.
280          */
281         do {
282                 /* Write first qword of payload */
283                 writeq(info->payload[0], priv->mbox_addr);
284
285                 /* Check for ownership */
286                 ret = readq_poll_timeout(priv->control_addr, control,
287                         FIELD_GET(CTRL_OWNER, control) == MBOX_OWNER_INBAND,
288                         MBOX_POLLING_PERIOD_US, MBOX_TIMEOUT_ACQUIRE_US);
289
290                 if (FIELD_GET(CTRL_OWNER, control) == MBOX_OWNER_NONE &&
291                     retries++ < MBOX_ACQUIRE_NUM_RETRIES) {
292                         msleep(MBOX_ACQUIRE_RETRY_DELAY_MS);
293                         continue;
294                 }
295
296                 /* Either we got it or someone else did. */
297                 break;
298         } while (true);
299
300         return ret;
301 }
302
303 static int sdsi_mbox_write(struct sdsi_priv *priv, struct sdsi_mbox_info *info)
304 {
305         int ret;
306
307         lockdep_assert_held(&priv->mb_lock);
308
309         ret = sdsi_mbox_acquire(priv, info);
310         if (ret)
311                 return ret;
312
313         return sdsi_mbox_cmd_write(priv, info);
314 }
315
316 static int sdsi_mbox_read(struct sdsi_priv *priv, struct sdsi_mbox_info *info, size_t *data_size)
317 {
318         int ret;
319
320         lockdep_assert_held(&priv->mb_lock);
321
322         ret = sdsi_mbox_acquire(priv, info);
323         if (ret)
324                 return ret;
325
326         return sdsi_mbox_cmd_read(priv, info, data_size);
327 }
328
329 static ssize_t sdsi_provision(struct sdsi_priv *priv, char *buf, size_t count,
330                               enum sdsi_command command)
331 {
332         struct sdsi_mbox_info info;
333         int ret;
334
335         if (!priv->sdsi_enabled)
336                 return -EPERM;
337
338         if (count > (SDSI_SIZE_WRITE_MSG - SDSI_SIZE_CMD))
339                 return -EOVERFLOW;
340
341         /* Qword aligned message + command qword */
342         info.size = round_up(count, SDSI_SIZE_CMD) + SDSI_SIZE_CMD;
343
344         info.payload = kzalloc(info.size, GFP_KERNEL);
345         if (!info.payload)
346                 return -ENOMEM;
347
348         /* Copy message to payload buffer */
349         memcpy(info.payload, buf, count);
350
351         /* Command is last qword of payload buffer */
352         info.payload[(info.size - SDSI_SIZE_CMD) / SDSI_SIZE_CMD] = command;
353
354         ret = mutex_lock_interruptible(&priv->mb_lock);
355         if (ret)
356                 goto free_payload;
357         ret = sdsi_mbox_write(priv, &info);
358         mutex_unlock(&priv->mb_lock);
359
360 free_payload:
361         kfree(info.payload);
362
363         if (ret)
364                 return ret;
365
366         return count;
367 }
368
369 static ssize_t provision_akc_write(struct file *filp, struct kobject *kobj,
370                                    struct bin_attribute *attr, char *buf, loff_t off,
371                                    size_t count)
372 {
373         struct device *dev = kobj_to_dev(kobj);
374         struct sdsi_priv *priv = dev_get_drvdata(dev);
375
376         if (off)
377                 return -ESPIPE;
378
379         return sdsi_provision(priv, buf, count, SDSI_CMD_PROVISION_AKC);
380 }
381 static BIN_ATTR_WO(provision_akc, SDSI_SIZE_WRITE_MSG);
382
383 static ssize_t provision_cap_write(struct file *filp, struct kobject *kobj,
384                                    struct bin_attribute *attr, char *buf, loff_t off,
385                                    size_t count)
386 {
387         struct device *dev = kobj_to_dev(kobj);
388         struct sdsi_priv *priv = dev_get_drvdata(dev);
389
390         if (off)
391                 return -ESPIPE;
392
393         return sdsi_provision(priv, buf, count, SDSI_CMD_PROVISION_CAP);
394 }
395 static BIN_ATTR_WO(provision_cap, SDSI_SIZE_WRITE_MSG);
396
397 static long state_certificate_read(struct file *filp, struct kobject *kobj,
398                                    struct bin_attribute *attr, char *buf, loff_t off,
399                                    size_t count)
400 {
401         struct device *dev = kobj_to_dev(kobj);
402         struct sdsi_priv *priv = dev_get_drvdata(dev);
403         u64 command = SDSI_CMD_READ_STATE;
404         struct sdsi_mbox_info info;
405         size_t size;
406         int ret;
407
408         if (!priv->sdsi_enabled)
409                 return -EPERM;
410
411         if (off)
412                 return 0;
413
414         /* Buffer for return data */
415         info.buffer = kmalloc(SDSI_SIZE_READ_MSG, GFP_KERNEL);
416         if (!info.buffer)
417                 return -ENOMEM;
418
419         info.payload = &command;
420         info.size = sizeof(command);
421
422         ret = mutex_lock_interruptible(&priv->mb_lock);
423         if (ret)
424                 goto free_buffer;
425         ret = sdsi_mbox_read(priv, &info, &size);
426         mutex_unlock(&priv->mb_lock);
427         if (ret < 0)
428                 goto free_buffer;
429
430         if (size > count)
431                 size = count;
432
433         memcpy(buf, info.buffer, size);
434
435 free_buffer:
436         kfree(info.buffer);
437
438         if (ret)
439                 return ret;
440
441         return size;
442 }
443 static BIN_ATTR(state_certificate, 0400, state_certificate_read, NULL, SDSI_SIZE_READ_MSG);
444
445 static ssize_t registers_read(struct file *filp, struct kobject *kobj,
446                               struct bin_attribute *attr, char *buf, loff_t off,
447                               size_t count)
448 {
449         struct device *dev = kobj_to_dev(kobj);
450         struct sdsi_priv *priv = dev_get_drvdata(dev);
451         void __iomem *addr = priv->regs_addr;
452
453         memcpy_fromio(buf, addr + off, count);
454
455         return count;
456 }
457 static BIN_ATTR(registers, 0400, registers_read, NULL, SDSI_SIZE_REGS);
458
459 static struct bin_attribute *sdsi_bin_attrs[] = {
460         &bin_attr_registers,
461         &bin_attr_state_certificate,
462         &bin_attr_provision_akc,
463         &bin_attr_provision_cap,
464         NULL
465 };
466
467 static ssize_t guid_show(struct device *dev, struct device_attribute *attr, char *buf)
468 {
469         struct sdsi_priv *priv = dev_get_drvdata(dev);
470
471         return sysfs_emit(buf, "0x%x\n", priv->guid);
472 }
473 static DEVICE_ATTR_RO(guid);
474
475 static struct attribute *sdsi_attrs[] = {
476         &dev_attr_guid.attr,
477         NULL
478 };
479
480 static const struct attribute_group sdsi_group = {
481         .attrs = sdsi_attrs,
482         .bin_attrs = sdsi_bin_attrs,
483 };
484 __ATTRIBUTE_GROUPS(sdsi);
485
486 static int sdsi_map_mbox_registers(struct sdsi_priv *priv, struct pci_dev *parent,
487                                    struct disc_table *disc_table, struct resource *disc_res)
488 {
489         u32 access_type = FIELD_GET(DT_ACCESS_TYPE, disc_table->access_info);
490         u32 size = FIELD_GET(DT_SIZE, disc_table->access_info);
491         u32 tbir = FIELD_GET(DT_TBIR, disc_table->offset);
492         u32 offset = DT_OFFSET(disc_table->offset);
493         u32 features_offset;
494         struct resource res = {};
495
496         /* Starting location of SDSi MMIO region based on access type */
497         switch (access_type) {
498         case ACCESS_TYPE_LOCAL:
499                 if (tbir) {
500                         dev_err(priv->dev, "Unsupported BAR index %u for access type %u\n",
501                                 tbir, access_type);
502                         return -EINVAL;
503                 }
504
505                 /*
506                  * For access_type LOCAL, the base address is as follows:
507                  * base address = end of discovery region + base offset + 1
508                  */
509                 res.start = disc_res->end + offset + 1;
510                 break;
511
512         case ACCESS_TYPE_BARID:
513                 res.start = pci_resource_start(parent, tbir) + offset;
514                 break;
515
516         default:
517                 dev_err(priv->dev, "Unrecognized access_type %u\n", access_type);
518                 return -EINVAL;
519         }
520
521         res.end = res.start + size * sizeof(u32) - 1;
522         res.flags = IORESOURCE_MEM;
523
524         priv->control_addr = devm_ioremap_resource(priv->dev, &res);
525         if (IS_ERR(priv->control_addr))
526                 return PTR_ERR(priv->control_addr);
527
528         priv->mbox_addr = priv->control_addr + SDSI_SIZE_CONTROL;
529         priv->regs_addr = priv->mbox_addr + SDSI_SIZE_MAILBOX;
530
531         features_offset = readq(priv->regs_addr + SDSI_ENABLED_FEATURES_OFFSET);
532         priv->sdsi_enabled = !!(features_offset & SDSI_ENABLED);
533
534         return 0;
535 }
536
537 static int sdsi_probe(struct auxiliary_device *auxdev, const struct auxiliary_device_id *id)
538 {
539         struct intel_vsec_device *intel_cap_dev = auxdev_to_ivdev(auxdev);
540         struct disc_table disc_table;
541         struct resource *disc_res;
542         void __iomem *disc_addr;
543         struct sdsi_priv *priv;
544         int ret;
545
546         priv = devm_kzalloc(&auxdev->dev, sizeof(*priv), GFP_KERNEL);
547         if (!priv)
548                 return -ENOMEM;
549
550         priv->dev = &auxdev->dev;
551         mutex_init(&priv->mb_lock);
552         auxiliary_set_drvdata(auxdev, priv);
553
554         /* Get the SDSi discovery table */
555         disc_res = &intel_cap_dev->resource[0];
556         disc_addr = devm_ioremap_resource(&auxdev->dev, disc_res);
557         if (IS_ERR(disc_addr))
558                 return PTR_ERR(disc_addr);
559
560         memcpy_fromio(&disc_table, disc_addr, DISC_TABLE_SIZE);
561
562         priv->guid = disc_table.guid;
563
564         /* Map the SDSi mailbox registers */
565         ret = sdsi_map_mbox_registers(priv, intel_cap_dev->pcidev, &disc_table, disc_res);
566         if (ret)
567                 return ret;
568
569         return 0;
570 }
571
572 static const struct auxiliary_device_id sdsi_aux_id_table[] = {
573         { .name = "intel_vsec.sdsi" },
574         {}
575 };
576 MODULE_DEVICE_TABLE(auxiliary, sdsi_aux_id_table);
577
578 static struct auxiliary_driver sdsi_aux_driver = {
579         .driver = {
580                 .dev_groups = sdsi_groups,
581         },
582         .id_table       = sdsi_aux_id_table,
583         .probe          = sdsi_probe,
584         /* No remove. All resources are handled under devm */
585 };
586 module_auxiliary_driver(sdsi_aux_driver);
587
588 MODULE_AUTHOR("David E. Box <david.e.box@linux.intel.com>");
589 MODULE_DESCRIPTION("Intel Software Defined Silicon driver");
590 MODULE_LICENSE("GPL");