GNU Linux-libre 4.19.245-gnu1
[releases.git] / drivers / misc / cxl / flash.c
1 // SPDX-License-Identifier: GPL-2.0
2 #include <linux/kernel.h>
3 #include <linux/fs.h>
4 #include <linux/semaphore.h>
5 #include <linux/slab.h>
6 #include <linux/uaccess.h>
7 #include <asm/rtas.h>
8
9 #include "cxl.h"
10 #include "hcalls.h"
11
12 #define DOWNLOAD_IMAGE 1
13 #define VALIDATE_IMAGE 2
14
15 struct ai_header {
16         u16 version;
17         u8  reserved0[6];
18         u16 vendor;
19         u16 device;
20         u16 subsystem_vendor;
21         u16 subsystem;
22         u64 image_offset;
23         u64 image_length;
24         u8  reserved1[96];
25 };
26
27 static struct semaphore sem;
28 static unsigned long *buffer[CXL_AI_MAX_ENTRIES];
29 static struct sg_list *le;
30 static u64 continue_token;
31 static unsigned int transfer;
32
33 struct update_props_workarea {
34         __be32 phandle;
35         __be32 state;
36         __be64 reserved;
37         __be32 nprops;
38 } __packed;
39
40 struct update_nodes_workarea {
41         __be32 state;
42         __be64 unit_address;
43         __be32 reserved;
44 } __packed;
45
46 #define DEVICE_SCOPE 3
47 #define NODE_ACTION_MASK        0xff000000
48 #define NODE_COUNT_MASK         0x00ffffff
49 #define OPCODE_DELETE   0x01000000
50 #define OPCODE_UPDATE   0x02000000
51 #define OPCODE_ADD      0x03000000
52
53 static int rcall(int token, char *buf, s32 scope)
54 {
55         int rc;
56
57         spin_lock(&rtas_data_buf_lock);
58
59         memcpy(rtas_data_buf, buf, RTAS_DATA_BUF_SIZE);
60         rc = rtas_call(token, 2, 1, NULL, rtas_data_buf, scope);
61         memcpy(buf, rtas_data_buf, RTAS_DATA_BUF_SIZE);
62
63         spin_unlock(&rtas_data_buf_lock);
64         return rc;
65 }
66
67 static int update_property(struct device_node *dn, const char *name,
68                            u32 vd, char *value)
69 {
70         struct property *new_prop;
71         u32 *val;
72         int rc;
73
74         new_prop = kzalloc(sizeof(*new_prop), GFP_KERNEL);
75         if (!new_prop)
76                 return -ENOMEM;
77
78         new_prop->name = kstrdup(name, GFP_KERNEL);
79         if (!new_prop->name) {
80                 kfree(new_prop);
81                 return -ENOMEM;
82         }
83
84         new_prop->length = vd;
85         new_prop->value = kzalloc(new_prop->length, GFP_KERNEL);
86         if (!new_prop->value) {
87                 kfree(new_prop->name);
88                 kfree(new_prop);
89                 return -ENOMEM;
90         }
91         memcpy(new_prop->value, value, vd);
92
93         val = (u32 *)new_prop->value;
94         rc = cxl_update_properties(dn, new_prop);
95         pr_devel("%s: update property (%s, length: %i, value: %#x)\n",
96                   dn->name, name, vd, be32_to_cpu(*val));
97
98         if (rc) {
99                 kfree(new_prop->name);
100                 kfree(new_prop->value);
101                 kfree(new_prop);
102         }
103         return rc;
104 }
105
106 static int update_node(__be32 phandle, s32 scope)
107 {
108         struct update_props_workarea *upwa;
109         struct device_node *dn;
110         int i, rc, ret;
111         char *prop_data;
112         char *buf;
113         int token;
114         u32 nprops;
115         u32 vd;
116
117         token = rtas_token("ibm,update-properties");
118         if (token == RTAS_UNKNOWN_SERVICE)
119                 return -EINVAL;
120
121         buf = kzalloc(RTAS_DATA_BUF_SIZE, GFP_KERNEL);
122         if (!buf)
123                 return -ENOMEM;
124
125         dn = of_find_node_by_phandle(be32_to_cpu(phandle));
126         if (!dn) {
127                 kfree(buf);
128                 return -ENOENT;
129         }
130
131         upwa = (struct update_props_workarea *)&buf[0];
132         upwa->phandle = phandle;
133         do {
134                 rc = rcall(token, buf, scope);
135                 if (rc < 0)
136                         break;
137
138                 prop_data = buf + sizeof(*upwa);
139                 nprops = be32_to_cpu(upwa->nprops);
140
141                 if (*prop_data == 0) {
142                         prop_data++;
143                         vd = be32_to_cpu(*(__be32 *)prop_data);
144                         prop_data += vd + sizeof(vd);
145                         nprops--;
146                 }
147
148                 for (i = 0; i < nprops; i++) {
149                         char *prop_name;
150
151                         prop_name = prop_data;
152                         prop_data += strlen(prop_name) + 1;
153                         vd = be32_to_cpu(*(__be32 *)prop_data);
154                         prop_data += sizeof(vd);
155
156                         if ((vd != 0x00000000) && (vd != 0x80000000)) {
157                                 ret = update_property(dn, prop_name, vd,
158                                                 prop_data);
159                                 if (ret)
160                                         pr_err("cxl: Could not update property %s - %i\n",
161                                                prop_name, ret);
162
163                                 prop_data += vd;
164                         }
165                 }
166         } while (rc == 1);
167
168         of_node_put(dn);
169         kfree(buf);
170         return rc;
171 }
172
173 static int update_devicetree(struct cxl *adapter, s32 scope)
174 {
175         struct update_nodes_workarea *unwa;
176         u32 action, node_count;
177         int token, rc, i;
178         __be32 *data, drc_index, phandle;
179         char *buf;
180
181         token = rtas_token("ibm,update-nodes");
182         if (token == RTAS_UNKNOWN_SERVICE)
183                 return -EINVAL;
184
185         buf = kzalloc(RTAS_DATA_BUF_SIZE, GFP_KERNEL);
186         if (!buf)
187                 return -ENOMEM;
188
189         unwa = (struct update_nodes_workarea *)&buf[0];
190         unwa->unit_address = cpu_to_be64(adapter->guest->handle);
191         do {
192                 rc = rcall(token, buf, scope);
193                 if (rc && rc != 1)
194                         break;
195
196                 data = (__be32 *)buf + 4;
197                 while (be32_to_cpu(*data) & NODE_ACTION_MASK) {
198                         action = be32_to_cpu(*data) & NODE_ACTION_MASK;
199                         node_count = be32_to_cpu(*data) & NODE_COUNT_MASK;
200                         pr_devel("device reconfiguration - action: %#x, nodes: %#x\n",
201                                  action, node_count);
202                         data++;
203
204                         for (i = 0; i < node_count; i++) {
205                                 phandle = *data++;
206
207                                 switch (action) {
208                                 case OPCODE_DELETE:
209                                         /* nothing to do */
210                                         break;
211                                 case OPCODE_UPDATE:
212                                         update_node(phandle, scope);
213                                         break;
214                                 case OPCODE_ADD:
215                                         /* nothing to do, just move pointer */
216                                         drc_index = *data++;
217                                         break;
218                                 }
219                         }
220                 }
221         } while (rc == 1);
222
223         kfree(buf);
224         return 0;
225 }
226
227 static int handle_image(struct cxl *adapter, int operation,
228                         long (*fct)(u64, u64, u64, u64 *),
229                         struct cxl_adapter_image *ai)
230 {
231         size_t mod, s_copy, len_chunk = 0;
232         struct ai_header *header = NULL;
233         unsigned int entries = 0, i;
234         void *dest, *from;
235         int rc = 0, need_header;
236
237         /* base adapter image header */
238         need_header = (ai->flags & CXL_AI_NEED_HEADER);
239         if (need_header) {
240                 header = kzalloc(sizeof(struct ai_header), GFP_KERNEL);
241                 if (!header)
242                         return -ENOMEM;
243                 header->version = cpu_to_be16(1);
244                 header->vendor = cpu_to_be16(adapter->guest->vendor);
245                 header->device = cpu_to_be16(adapter->guest->device);
246                 header->subsystem_vendor = cpu_to_be16(adapter->guest->subsystem_vendor);
247                 header->subsystem = cpu_to_be16(adapter->guest->subsystem);
248                 header->image_offset = cpu_to_be64(CXL_AI_HEADER_SIZE);
249                 header->image_length = cpu_to_be64(ai->len_image);
250         }
251
252         /* number of entries in the list */
253         len_chunk = ai->len_data;
254         if (need_header)
255                 len_chunk += CXL_AI_HEADER_SIZE;
256
257         entries = len_chunk / CXL_AI_BUFFER_SIZE;
258         mod = len_chunk % CXL_AI_BUFFER_SIZE;
259         if (mod)
260                 entries++;
261
262         if (entries > CXL_AI_MAX_ENTRIES) {
263                 rc = -EINVAL;
264                 goto err;
265         }
266
267         /*          < -- MAX_CHUNK_SIZE = 4096 * 256 = 1048576 bytes -->
268          * chunk 0  ----------------------------------------------------
269          *          | header   |  data                                 |
270          *          ----------------------------------------------------
271          * chunk 1  ----------------------------------------------------
272          *          | data                                             |
273          *          ----------------------------------------------------
274          * ....
275          * chunk n  ----------------------------------------------------
276          *          | data                                             |
277          *          ----------------------------------------------------
278          */
279         from = (void *) ai->data;
280         for (i = 0; i < entries; i++) {
281                 dest = buffer[i];
282                 s_copy = CXL_AI_BUFFER_SIZE;
283
284                 if ((need_header) && (i == 0)) {
285                         /* add adapter image header */
286                         memcpy(buffer[i], header, sizeof(struct ai_header));
287                         s_copy = CXL_AI_BUFFER_SIZE - CXL_AI_HEADER_SIZE;
288                         dest += CXL_AI_HEADER_SIZE; /* image offset */
289                 }
290                 if ((i == (entries - 1)) && mod)
291                         s_copy = mod;
292
293                 /* copy data */
294                 if (copy_from_user(dest, from, s_copy))
295                         goto err;
296
297                 /* fill in the list */
298                 le[i].phys_addr = cpu_to_be64(virt_to_phys(buffer[i]));
299                 le[i].len = cpu_to_be64(CXL_AI_BUFFER_SIZE);
300                 if ((i == (entries - 1)) && mod)
301                         le[i].len = cpu_to_be64(mod);
302                 from += s_copy;
303         }
304         pr_devel("%s (op: %i, need header: %i, entries: %i, token: %#llx)\n",
305                  __func__, operation, need_header, entries, continue_token);
306
307         /*
308          * download/validate the adapter image to the coherent
309          * platform facility
310          */
311         rc = fct(adapter->guest->handle, virt_to_phys(le), entries,
312                 &continue_token);
313         if (rc == 0) /* success of download/validation operation */
314                 continue_token = 0;
315
316 err:
317         kfree(header);
318
319         return rc;
320 }
321
322 static int transfer_image(struct cxl *adapter, int operation,
323                         struct cxl_adapter_image *ai)
324 {
325         int rc = 0;
326         int afu;
327
328         switch (operation) {
329         case DOWNLOAD_IMAGE:
330                 rc = handle_image(adapter, operation,
331                                 &cxl_h_download_adapter_image, ai);
332                 if (rc < 0) {
333                         pr_devel("resetting adapter\n");
334                         cxl_h_reset_adapter(adapter->guest->handle);
335                 }
336                 return rc;
337
338         case VALIDATE_IMAGE:
339                 rc = handle_image(adapter, operation,
340                                 &cxl_h_validate_adapter_image, ai);
341                 if (rc < 0) {
342                         pr_devel("resetting adapter\n");
343                         cxl_h_reset_adapter(adapter->guest->handle);
344                         return rc;
345                 }
346                 if (rc == 0) {
347                         pr_devel("remove current afu\n");
348                         for (afu = 0; afu < adapter->slices; afu++)
349                                 cxl_guest_remove_afu(adapter->afu[afu]);
350
351                         pr_devel("resetting adapter\n");
352                         cxl_h_reset_adapter(adapter->guest->handle);
353
354                         /* The entire image has now been
355                          * downloaded and the validation has
356                          * been successfully performed.
357                          * After that, the partition should call
358                          * ibm,update-nodes and
359                          * ibm,update-properties to receive the
360                          * current configuration
361                          */
362                         rc = update_devicetree(adapter, DEVICE_SCOPE);
363                         transfer = 1;
364                 }
365                 return rc;
366         }
367
368         return -EINVAL;
369 }
370
371 static long ioctl_transfer_image(struct cxl *adapter, int operation,
372                                 struct cxl_adapter_image __user *uai)
373 {
374         struct cxl_adapter_image ai;
375
376         pr_devel("%s\n", __func__);
377
378         if (copy_from_user(&ai, uai, sizeof(struct cxl_adapter_image)))
379                 return -EFAULT;
380
381         /*
382          * Make sure reserved fields and bits are set to 0
383          */
384         if (ai.reserved1 || ai.reserved2 || ai.reserved3 || ai.reserved4 ||
385                 (ai.flags & ~CXL_AI_ALL))
386                 return -EINVAL;
387
388         return transfer_image(adapter, operation, &ai);
389 }
390
391 static int device_open(struct inode *inode, struct file *file)
392 {
393         int adapter_num = CXL_DEVT_ADAPTER(inode->i_rdev);
394         struct cxl *adapter;
395         int rc = 0, i;
396
397         pr_devel("in %s\n", __func__);
398
399         BUG_ON(sizeof(struct ai_header) != CXL_AI_HEADER_SIZE);
400
401         /* Allows one process to open the device by using a semaphore */
402         if (down_interruptible(&sem) != 0)
403                 return -EPERM;
404
405         if (!(adapter = get_cxl_adapter(adapter_num))) {
406                 rc = -ENODEV;
407                 goto err_unlock;
408         }
409
410         file->private_data = adapter;
411         continue_token = 0;
412         transfer = 0;
413
414         for (i = 0; i < CXL_AI_MAX_ENTRIES; i++)
415                 buffer[i] = NULL;
416
417         /* aligned buffer containing list entries which describes up to
418          * 1 megabyte of data (256 entries of 4096 bytes each)
419          *  Logical real address of buffer 0  -  Buffer 0 length in bytes
420          *  Logical real address of buffer 1  -  Buffer 1 length in bytes
421          *  Logical real address of buffer 2  -  Buffer 2 length in bytes
422          *  ....
423          *  ....
424          *  Logical real address of buffer N  -  Buffer N length in bytes
425          */
426         le = (struct sg_list *)get_zeroed_page(GFP_KERNEL);
427         if (!le) {
428                 rc = -ENOMEM;
429                 goto err;
430         }
431
432         for (i = 0; i < CXL_AI_MAX_ENTRIES; i++) {
433                 buffer[i] = (unsigned long *)get_zeroed_page(GFP_KERNEL);
434                 if (!buffer[i]) {
435                         rc = -ENOMEM;
436                         goto err1;
437                 }
438         }
439
440         return 0;
441
442 err1:
443         for (i = 0; i < CXL_AI_MAX_ENTRIES; i++) {
444                 if (buffer[i])
445                         free_page((unsigned long) buffer[i]);
446         }
447
448         if (le)
449                 free_page((unsigned long) le);
450 err:
451         put_device(&adapter->dev);
452 err_unlock:
453         up(&sem);
454
455         return rc;
456 }
457
458 static long device_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
459 {
460         struct cxl *adapter = file->private_data;
461
462         pr_devel("in %s\n", __func__);
463
464         if (cmd == CXL_IOCTL_DOWNLOAD_IMAGE)
465                 return ioctl_transfer_image(adapter,
466                                         DOWNLOAD_IMAGE,
467                                         (struct cxl_adapter_image __user *)arg);
468         else if (cmd == CXL_IOCTL_VALIDATE_IMAGE)
469                 return ioctl_transfer_image(adapter,
470                                         VALIDATE_IMAGE,
471                                         (struct cxl_adapter_image __user *)arg);
472         else
473                 return -EINVAL;
474 }
475
476 static long device_compat_ioctl(struct file *file, unsigned int cmd,
477                                 unsigned long arg)
478 {
479         return device_ioctl(file, cmd, arg);
480 }
481
482 static int device_close(struct inode *inode, struct file *file)
483 {
484         struct cxl *adapter = file->private_data;
485         int i;
486
487         pr_devel("in %s\n", __func__);
488
489         for (i = 0; i < CXL_AI_MAX_ENTRIES; i++) {
490                 if (buffer[i])
491                         free_page((unsigned long) buffer[i]);
492         }
493
494         if (le)
495                 free_page((unsigned long) le);
496
497         up(&sem);
498         put_device(&adapter->dev);
499         continue_token = 0;
500
501         /* reload the module */
502         if (transfer)
503                 cxl_guest_reload_module(adapter);
504         else {
505                 pr_devel("resetting adapter\n");
506                 cxl_h_reset_adapter(adapter->guest->handle);
507         }
508
509         transfer = 0;
510         return 0;
511 }
512
513 static const struct file_operations fops = {
514         .owner          = THIS_MODULE,
515         .open           = device_open,
516         .unlocked_ioctl = device_ioctl,
517         .compat_ioctl   = device_compat_ioctl,
518         .release        = device_close,
519 };
520
521 void cxl_guest_remove_chardev(struct cxl *adapter)
522 {
523         cdev_del(&adapter->guest->cdev);
524 }
525
526 int cxl_guest_add_chardev(struct cxl *adapter)
527 {
528         dev_t devt;
529         int rc;
530
531         devt = MKDEV(MAJOR(cxl_get_dev()), CXL_CARD_MINOR(adapter));
532         cdev_init(&adapter->guest->cdev, &fops);
533         if ((rc = cdev_add(&adapter->guest->cdev, devt, 1))) {
534                 dev_err(&adapter->dev,
535                         "Unable to add chardev on adapter (card%i): %i\n",
536                         adapter->adapter_num, rc);
537                 goto err;
538         }
539         adapter->dev.devt = devt;
540         sema_init(&sem, 1);
541 err:
542         return rc;
543 }