1
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
15struct 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
27static struct semaphore sem;
28static unsigned long *buffer[CXL_AI_MAX_ENTRIES];
29static struct sg_list *le;
30static u64 continue_token;
31static unsigned int transfer;
32
33struct update_props_workarea {
34 __be32 phandle;
35 __be32 state;
36 __be64 reserved;
37 __be32 nprops;
38} __packed;
39
40struct 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
53static 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
67static 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("%pOFn: update property (%s, length: %i, value: %#x)\n",
96 dn, 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
106static 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
173static 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
210 break;
211 case OPCODE_UPDATE:
212 update_node(phandle, scope);
213 break;
214 case OPCODE_ADD:
215
216 drc_index = *data++;
217 break;
218 }
219 }
220 }
221 } while (rc == 1);
222
223 kfree(buf);
224 return 0;
225}
226
227static 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
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
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
268
269
270
271
272
273
274
275
276
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
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;
289 }
290 if ((i == (entries - 1)) && mod)
291 s_copy = mod;
292
293
294 if (copy_from_user(dest, from, s_copy))
295 goto err;
296
297
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
309
310
311 rc = fct(adapter->guest->handle, virt_to_phys(le), entries,
312 &continue_token);
313 if (rc == 0)
314 continue_token = 0;
315
316err:
317 kfree(header);
318
319 return rc;
320}
321
322static 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
355
356
357
358
359
360
361
362 rc = update_devicetree(adapter, DEVICE_SCOPE);
363 transfer = 1;
364 }
365 return rc;
366 }
367
368 return -EINVAL;
369}
370
371static 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
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
391static 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
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
418
419
420
421
422
423
424
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
442err1:
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);
450err:
451 put_device(&adapter->dev);
452err_unlock:
453 up(&sem);
454
455 return rc;
456}
457
458static 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
476static long device_compat_ioctl(struct file *file, unsigned int cmd,
477 unsigned long arg)
478{
479 return device_ioctl(file, cmd, arg);
480}
481
482static 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
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
513static 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
521void cxl_guest_remove_chardev(struct cxl *adapter)
522{
523 cdev_del(&adapter->guest->cdev);
524}
525
526int 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);
541err:
542 return rc;
543}
544