native.c (368857c16c595eb7537cc0846708ddaa57a3a25b) native.c (0b3f9c757cabad4b8101c5fcddddd029ed5506a6)
1/*
2 * Copyright 2014 IBM Corp.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 */

--- 27 unchanged lines hidden (view full) ---

36
37 AFU_Cntl = cxl_p2n_read(afu, CXL_AFU_Cntl_An);
38 while ((AFU_Cntl & mask) != result) {
39 if (time_after_eq(jiffies, timeout)) {
40 dev_warn(&afu->dev, "WARNING: AFU control timed out!\n");
41 rc = -EBUSY;
42 goto out;
43 }
1/*
2 * Copyright 2014 IBM Corp.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 */

--- 27 unchanged lines hidden (view full) ---

36
37 AFU_Cntl = cxl_p2n_read(afu, CXL_AFU_Cntl_An);
38 while ((AFU_Cntl & mask) != result) {
39 if (time_after_eq(jiffies, timeout)) {
40 dev_warn(&afu->dev, "WARNING: AFU control timed out!\n");
41 rc = -EBUSY;
42 goto out;
43 }
44
45 if (!cxl_adapter_link_ok(afu->adapter)) {
46 afu->enabled = enabled;
47 rc = -EIO;
48 goto out;
49 }
50
44 pr_devel_ratelimited("AFU control... (0x%016llx)\n",
45 AFU_Cntl | command);
46 cpu_relax();
47 AFU_Cntl = cxl_p2n_read(afu, CXL_AFU_Cntl_An);
48 };
49 pr_devel("AFU command complete: %llx\n", command);
50 afu->enabled = enabled;
51out:

--- 28 unchanged lines hidden (view full) ---

80 return afu_control(afu, CXL_AFU_Cntl_An_RA,
81 CXL_AFU_Cntl_An_RS_Complete | CXL_AFU_Cntl_An_ES_Disabled,
82 CXL_AFU_Cntl_An_RS_MASK | CXL_AFU_Cntl_An_ES_MASK,
83 false);
84}
85
86int cxl_afu_check_and_enable(struct cxl_afu *afu)
87{
51 pr_devel_ratelimited("AFU control... (0x%016llx)\n",
52 AFU_Cntl | command);
53 cpu_relax();
54 AFU_Cntl = cxl_p2n_read(afu, CXL_AFU_Cntl_An);
55 };
56 pr_devel("AFU command complete: %llx\n", command);
57 afu->enabled = enabled;
58out:

--- 28 unchanged lines hidden (view full) ---

87 return afu_control(afu, CXL_AFU_Cntl_An_RA,
88 CXL_AFU_Cntl_An_RS_Complete | CXL_AFU_Cntl_An_ES_Disabled,
89 CXL_AFU_Cntl_An_RS_MASK | CXL_AFU_Cntl_An_ES_MASK,
90 false);
91}
92
93int cxl_afu_check_and_enable(struct cxl_afu *afu)
94{
95 if (!cxl_adapter_link_ok(afu->adapter)) {
96 WARN(1, "Refusing to enable afu while link down!\n");
97 return -EIO;
98 }
88 if (afu->enabled)
89 return 0;
90 return afu_enable(afu);
91}
92
93int cxl_psl_purge(struct cxl_afu *afu)
94{
95 u64 PSL_CNTL = cxl_p1n_read(afu, CXL_PSL_SCNTL_An);
96 u64 AFU_Cntl = cxl_p2n_read(afu, CXL_AFU_Cntl_An);
97 u64 dsisr, dar;
98 u64 start, end;
99 unsigned long timeout = jiffies + (HZ * CXL_TIMEOUT);
100 int rc = 0;
101
102 trace_cxl_psl_ctrl(afu, CXL_PSL_SCNTL_An_Pc);
103
104 pr_devel("PSL purge request\n");
105
99 if (afu->enabled)
100 return 0;
101 return afu_enable(afu);
102}
103
104int cxl_psl_purge(struct cxl_afu *afu)
105{
106 u64 PSL_CNTL = cxl_p1n_read(afu, CXL_PSL_SCNTL_An);
107 u64 AFU_Cntl = cxl_p2n_read(afu, CXL_AFU_Cntl_An);
108 u64 dsisr, dar;
109 u64 start, end;
110 unsigned long timeout = jiffies + (HZ * CXL_TIMEOUT);
111 int rc = 0;
112
113 trace_cxl_psl_ctrl(afu, CXL_PSL_SCNTL_An_Pc);
114
115 pr_devel("PSL purge request\n");
116
117 if (!cxl_adapter_link_ok(afu->adapter)) {
118 dev_warn(&afu->dev, "PSL Purge called with link down, ignoring\n");
119 rc = -EIO;
120 goto out;
121 }
122
106 if ((AFU_Cntl & CXL_AFU_Cntl_An_ES_MASK) != CXL_AFU_Cntl_An_ES_Disabled) {
107 WARN(1, "psl_purge request while AFU not disabled!\n");
108 cxl_afu_disable(afu);
109 }
110
111 cxl_p1n_write(afu, CXL_PSL_SCNTL_An,
112 PSL_CNTL | CXL_PSL_SCNTL_An_Pc);
113 start = local_clock();
114 PSL_CNTL = cxl_p1n_read(afu, CXL_PSL_SCNTL_An);
115 while ((PSL_CNTL & CXL_PSL_SCNTL_An_Ps_MASK)
116 == CXL_PSL_SCNTL_An_Ps_Pending) {
117 if (time_after_eq(jiffies, timeout)) {
118 dev_warn(&afu->dev, "WARNING: PSL Purge timed out!\n");
119 rc = -EBUSY;
120 goto out;
121 }
123 if ((AFU_Cntl & CXL_AFU_Cntl_An_ES_MASK) != CXL_AFU_Cntl_An_ES_Disabled) {
124 WARN(1, "psl_purge request while AFU not disabled!\n");
125 cxl_afu_disable(afu);
126 }
127
128 cxl_p1n_write(afu, CXL_PSL_SCNTL_An,
129 PSL_CNTL | CXL_PSL_SCNTL_An_Pc);
130 start = local_clock();
131 PSL_CNTL = cxl_p1n_read(afu, CXL_PSL_SCNTL_An);
132 while ((PSL_CNTL & CXL_PSL_SCNTL_An_Ps_MASK)
133 == CXL_PSL_SCNTL_An_Ps_Pending) {
134 if (time_after_eq(jiffies, timeout)) {
135 dev_warn(&afu->dev, "WARNING: PSL Purge timed out!\n");
136 rc = -EBUSY;
137 goto out;
138 }
139 if (!cxl_adapter_link_ok(afu->adapter)) {
140 rc = -EIO;
141 goto out;
142 }
143
122 dsisr = cxl_p2n_read(afu, CXL_PSL_DSISR_An);
123 pr_devel_ratelimited("PSL purging... PSL_CNTL: 0x%016llx PSL_DSISR: 0x%016llx\n", PSL_CNTL, dsisr);
124 if (dsisr & CXL_PSL_DSISR_TRANS) {
125 dar = cxl_p2n_read(afu, CXL_PSL_DAR_An);
126 dev_notice(&afu->dev, "PSL purge terminating pending translation, DSISR: 0x%016llx, DAR: 0x%016llx\n", dsisr, dar);
127 cxl_p2n_write(afu, CXL_PSL_TFC_An, CXL_PSL_TFC_An_AE);
128 } else if (dsisr) {
129 dev_notice(&afu->dev, "PSL purge acknowledging pending non-translation fault, DSISR: 0x%016llx\n", dsisr);

--- 80 unchanged lines hidden (view full) ---

210 cxl_p1_write(adapter, CXL_PSL_AFUSEL, CXL_PSL_AFUSEL_A);
211
212 cxl_p1_write(adapter, CXL_PSL_TLBIA, CXL_TLB_SLB_IQ_ALL);
213 while (cxl_p1_read(adapter, CXL_PSL_TLBIA) & CXL_TLB_SLB_P) {
214 if (time_after_eq(jiffies, timeout)) {
215 dev_warn(&adapter->dev, "WARNING: CXL adapter wide TLBIA timed out!\n");
216 return -EBUSY;
217 }
144 dsisr = cxl_p2n_read(afu, CXL_PSL_DSISR_An);
145 pr_devel_ratelimited("PSL purging... PSL_CNTL: 0x%016llx PSL_DSISR: 0x%016llx\n", PSL_CNTL, dsisr);
146 if (dsisr & CXL_PSL_DSISR_TRANS) {
147 dar = cxl_p2n_read(afu, CXL_PSL_DAR_An);
148 dev_notice(&afu->dev, "PSL purge terminating pending translation, DSISR: 0x%016llx, DAR: 0x%016llx\n", dsisr, dar);
149 cxl_p2n_write(afu, CXL_PSL_TFC_An, CXL_PSL_TFC_An_AE);
150 } else if (dsisr) {
151 dev_notice(&afu->dev, "PSL purge acknowledging pending non-translation fault, DSISR: 0x%016llx\n", dsisr);

--- 80 unchanged lines hidden (view full) ---

232 cxl_p1_write(adapter, CXL_PSL_AFUSEL, CXL_PSL_AFUSEL_A);
233
234 cxl_p1_write(adapter, CXL_PSL_TLBIA, CXL_TLB_SLB_IQ_ALL);
235 while (cxl_p1_read(adapter, CXL_PSL_TLBIA) & CXL_TLB_SLB_P) {
236 if (time_after_eq(jiffies, timeout)) {
237 dev_warn(&adapter->dev, "WARNING: CXL adapter wide TLBIA timed out!\n");
238 return -EBUSY;
239 }
240 if (!cxl_adapter_link_ok(adapter))
241 return -EIO;
218 cpu_relax();
219 }
220
221 cxl_p1_write(adapter, CXL_PSL_SLBIA, CXL_TLB_SLB_IQ_ALL);
222 while (cxl_p1_read(adapter, CXL_PSL_SLBIA) & CXL_TLB_SLB_P) {
223 if (time_after_eq(jiffies, timeout)) {
224 dev_warn(&adapter->dev, "WARNING: CXL adapter wide SLBIA timed out!\n");
225 return -EBUSY;
226 }
242 cpu_relax();
243 }
244
245 cxl_p1_write(adapter, CXL_PSL_SLBIA, CXL_TLB_SLB_IQ_ALL);
246 while (cxl_p1_read(adapter, CXL_PSL_SLBIA) & CXL_TLB_SLB_P) {
247 if (time_after_eq(jiffies, timeout)) {
248 dev_warn(&adapter->dev, "WARNING: CXL adapter wide SLBIA timed out!\n");
249 return -EBUSY;
250 }
251 if (!cxl_adapter_link_ok(adapter))
252 return -EIO;
227 cpu_relax();
228 }
229 return 0;
230}
231
232int cxl_afu_slbia(struct cxl_afu *afu)
233{
234 unsigned long timeout = jiffies + (HZ * CXL_TIMEOUT);
235
236 pr_devel("cxl_afu_slbia issuing SLBIA command\n");
237 cxl_p2n_write(afu, CXL_SLBIA_An, CXL_TLB_SLB_IQ_ALL);
238 while (cxl_p2n_read(afu, CXL_SLBIA_An) & CXL_TLB_SLB_P) {
239 if (time_after_eq(jiffies, timeout)) {
240 dev_warn(&afu->dev, "WARNING: CXL AFU SLBIA timed out!\n");
241 return -EBUSY;
242 }
253 cpu_relax();
254 }
255 return 0;
256}
257
258int cxl_afu_slbia(struct cxl_afu *afu)
259{
260 unsigned long timeout = jiffies + (HZ * CXL_TIMEOUT);
261
262 pr_devel("cxl_afu_slbia issuing SLBIA command\n");
263 cxl_p2n_write(afu, CXL_SLBIA_An, CXL_TLB_SLB_IQ_ALL);
264 while (cxl_p2n_read(afu, CXL_SLBIA_An) & CXL_TLB_SLB_P) {
265 if (time_after_eq(jiffies, timeout)) {
266 dev_warn(&afu->dev, "WARNING: CXL AFU SLBIA timed out!\n");
267 return -EBUSY;
268 }
269 /* If the adapter has gone down, we can assume that we
270 * will PERST it and that will invalidate everything.
271 */
272 if (!cxl_adapter_link_ok(afu->adapter))
273 return -EIO;
243 cpu_relax();
244 }
245 return 0;
246}
247
248static int cxl_write_sstp(struct cxl_afu *afu, u64 sstp0, u64 sstp1)
249{
250 int rc;

--- 23 unchanged lines hidden (view full) ---

274 WARN_ON(!mutex_is_locked(&ctx->afu->spa_mutex));
275
276 cxl_p1_write(adapter, CXL_PSL_LBISEL,
277 ((u64)be32_to_cpu(ctx->elem->common.pid) << 32) |
278 be32_to_cpu(ctx->elem->lpid));
279 cxl_p1_write(adapter, CXL_PSL_SLBIA, CXL_TLB_SLB_IQ_LPIDPID);
280
281 while (1) {
274 cpu_relax();
275 }
276 return 0;
277}
278
279static int cxl_write_sstp(struct cxl_afu *afu, u64 sstp0, u64 sstp1)
280{
281 int rc;

--- 23 unchanged lines hidden (view full) ---

305 WARN_ON(!mutex_is_locked(&ctx->afu->spa_mutex));
306
307 cxl_p1_write(adapter, CXL_PSL_LBISEL,
308 ((u64)be32_to_cpu(ctx->elem->common.pid) << 32) |
309 be32_to_cpu(ctx->elem->lpid));
310 cxl_p1_write(adapter, CXL_PSL_SLBIA, CXL_TLB_SLB_IQ_LPIDPID);
311
312 while (1) {
313 if (!cxl_adapter_link_ok(adapter))
314 break;
282 slbia = cxl_p1_read(adapter, CXL_PSL_SLBIA);
283 if (!(slbia & CXL_TLB_SLB_P))
284 break;
285 cpu_relax();
286 }
287}
288
289static int do_process_element_cmd(struct cxl_context *ctx,

--- 13 unchanged lines hidden (view full) ---

303 smp_mb();
304 cxl_p1n_write(ctx->afu, CXL_PSL_LLCMD_An, cmd | ctx->pe);
305 while (1) {
306 if (time_after_eq(jiffies, timeout)) {
307 dev_warn(&ctx->afu->dev, "WARNING: Process Element Command timed out!\n");
308 rc = -EBUSY;
309 goto out;
310 }
315 slbia = cxl_p1_read(adapter, CXL_PSL_SLBIA);
316 if (!(slbia & CXL_TLB_SLB_P))
317 break;
318 cpu_relax();
319 }
320}
321
322static int do_process_element_cmd(struct cxl_context *ctx,

--- 13 unchanged lines hidden (view full) ---

336 smp_mb();
337 cxl_p1n_write(ctx->afu, CXL_PSL_LLCMD_An, cmd | ctx->pe);
338 while (1) {
339 if (time_after_eq(jiffies, timeout)) {
340 dev_warn(&ctx->afu->dev, "WARNING: Process Element Command timed out!\n");
341 rc = -EBUSY;
342 goto out;
343 }
344 if (!cxl_adapter_link_ok(ctx->afu->adapter)) {
345 dev_warn(&ctx->afu->dev, "WARNING: Device link down, aborting Process Element Command!\n");
346 rc = -EIO;
347 goto out;
348 }
311 state = be64_to_cpup(ctx->afu->sw_command_status);
312 if (state == ~0ULL) {
313 pr_err("cxl: Error adding process element to AFU\n");
314 rc = -1;
315 goto out;
316 }
317 if ((state & (CXL_SPA_SW_CMD_MASK | CXL_SPA_SW_STATE_MASK | CXL_SPA_SW_LINK_MASK)) ==
318 (cmd | (cmd >> 16) | ctx->pe))

--- 31 unchanged lines hidden (view full) ---

350 int rc = 0;
351
352 /* fast path terminate if it's already invalid */
353 if (!(ctx->elem->software_state & cpu_to_be32(CXL_PE_SOFTWARE_STATE_V)))
354 return rc;
355
356 mutex_lock(&ctx->afu->spa_mutex);
357 pr_devel("%s Terminate pe: %i started\n", __func__, ctx->pe);
349 state = be64_to_cpup(ctx->afu->sw_command_status);
350 if (state == ~0ULL) {
351 pr_err("cxl: Error adding process element to AFU\n");
352 rc = -1;
353 goto out;
354 }
355 if ((state & (CXL_SPA_SW_CMD_MASK | CXL_SPA_SW_STATE_MASK | CXL_SPA_SW_LINK_MASK)) ==
356 (cmd | (cmd >> 16) | ctx->pe))

--- 31 unchanged lines hidden (view full) ---

388 int rc = 0;
389
390 /* fast path terminate if it's already invalid */
391 if (!(ctx->elem->software_state & cpu_to_be32(CXL_PE_SOFTWARE_STATE_V)))
392 return rc;
393
394 mutex_lock(&ctx->afu->spa_mutex);
395 pr_devel("%s Terminate pe: %i started\n", __func__, ctx->pe);
358 rc = do_process_element_cmd(ctx, CXL_SPA_SW_CMD_TERMINATE,
359 CXL_PE_SOFTWARE_STATE_V | CXL_PE_SOFTWARE_STATE_T);
396 /* We could be asked to terminate when the hw is down. That
397 * should always succeed: it's not running if the hw has gone
398 * away and is being reset.
399 */
400 if (cxl_adapter_link_ok(ctx->afu->adapter))
401 rc = do_process_element_cmd(ctx, CXL_SPA_SW_CMD_TERMINATE,
402 CXL_PE_SOFTWARE_STATE_V | CXL_PE_SOFTWARE_STATE_T);
360 ctx->elem->software_state = 0; /* Remove Valid bit */
361 pr_devel("%s Terminate pe: %i finished\n", __func__, ctx->pe);
362 mutex_unlock(&ctx->afu->spa_mutex);
363 return rc;
364}
365
366static int remove_process_element(struct cxl_context *ctx)
367{
368 int rc = 0;
369
370 mutex_lock(&ctx->afu->spa_mutex);
371 pr_devel("%s Remove pe: %i started\n", __func__, ctx->pe);
403 ctx->elem->software_state = 0; /* Remove Valid bit */
404 pr_devel("%s Terminate pe: %i finished\n", __func__, ctx->pe);
405 mutex_unlock(&ctx->afu->spa_mutex);
406 return rc;
407}
408
409static int remove_process_element(struct cxl_context *ctx)
410{
411 int rc = 0;
412
413 mutex_lock(&ctx->afu->spa_mutex);
414 pr_devel("%s Remove pe: %i started\n", __func__, ctx->pe);
372 if (!(rc = do_process_element_cmd(ctx, CXL_SPA_SW_CMD_REMOVE, 0)))
415
416 /* We could be asked to remove when the hw is down. Again, if
417 * the hw is down, the PE is gone, so we succeed.
418 */
419 if (cxl_adapter_link_ok(ctx->afu->adapter))
420 rc = do_process_element_cmd(ctx, CXL_SPA_SW_CMD_REMOVE, 0);
421
422 if (!rc)
373 ctx->pe_inserted = false;
374 slb_invalid(ctx);
375 pr_devel("%s Remove pe: %i finished\n", __func__, ctx->pe);
376 mutex_unlock(&ctx->afu->spa_mutex);
377
378 return rc;
379}
380

--- 226 unchanged lines hidden (view full) ---

607
608int cxl_afu_activate_mode(struct cxl_afu *afu, int mode)
609{
610 if (!mode)
611 return 0;
612 if (!(mode & afu->modes_supported))
613 return -EINVAL;
614
423 ctx->pe_inserted = false;
424 slb_invalid(ctx);
425 pr_devel("%s Remove pe: %i finished\n", __func__, ctx->pe);
426 mutex_unlock(&ctx->afu->spa_mutex);
427
428 return rc;
429}
430

--- 226 unchanged lines hidden (view full) ---

657
658int cxl_afu_activate_mode(struct cxl_afu *afu, int mode)
659{
660 if (!mode)
661 return 0;
662 if (!(mode & afu->modes_supported))
663 return -EINVAL;
664
665 if (!cxl_adapter_link_ok(afu->adapter)) {
666 WARN(1, "Device link is down, refusing to activate!\n");
667 return -EIO;
668 }
669
615 if (mode == CXL_MODE_DIRECTED)
616 return activate_afu_directed(afu);
617 if (mode == CXL_MODE_DEDICATED)
618 return activate_dedicated_process(afu);
619
620 return -EINVAL;
621}
622
623int cxl_attach_process(struct cxl_context *ctx, bool kernel, u64 wed, u64 amr)
624{
670 if (mode == CXL_MODE_DIRECTED)
671 return activate_afu_directed(afu);
672 if (mode == CXL_MODE_DEDICATED)
673 return activate_dedicated_process(afu);
674
675 return -EINVAL;
676}
677
678int cxl_attach_process(struct cxl_context *ctx, bool kernel, u64 wed, u64 amr)
679{
680 if (!cxl_adapter_link_ok(ctx->afu->adapter)) {
681 WARN(1, "Device link is down, refusing to attach process!\n");
682 return -EIO;
683 }
684
625 ctx->kernel = kernel;
626 if (ctx->afu->current_mode == CXL_MODE_DIRECTED)
627 return attach_afu_directed(ctx, wed, amr);
628
629 if (ctx->afu->current_mode == CXL_MODE_DEDICATED)
630 return attach_dedicated(ctx, wed, amr);
631
632 return -EINVAL;

--- 28 unchanged lines hidden (view full) ---

661
662 return detach_process_native_afu_directed(ctx);
663}
664
665int cxl_get_irq(struct cxl_afu *afu, struct cxl_irq_info *info)
666{
667 u64 pidtid;
668
685 ctx->kernel = kernel;
686 if (ctx->afu->current_mode == CXL_MODE_DIRECTED)
687 return attach_afu_directed(ctx, wed, amr);
688
689 if (ctx->afu->current_mode == CXL_MODE_DEDICATED)
690 return attach_dedicated(ctx, wed, amr);
691
692 return -EINVAL;

--- 28 unchanged lines hidden (view full) ---

721
722 return detach_process_native_afu_directed(ctx);
723}
724
725int cxl_get_irq(struct cxl_afu *afu, struct cxl_irq_info *info)
726{
727 u64 pidtid;
728
729 /* If the adapter has gone away, we can't get any meaningful
730 * information.
731 */
732 if (!cxl_adapter_link_ok(afu->adapter))
733 return -EIO;
734
669 info->dsisr = cxl_p2n_read(afu, CXL_PSL_DSISR_An);
670 info->dar = cxl_p2n_read(afu, CXL_PSL_DAR_An);
671 info->dsr = cxl_p2n_read(afu, CXL_PSL_DSR_An);
672 pidtid = cxl_p2n_read(afu, CXL_PSL_PID_TID_An);
673 info->pid = pidtid >> 32;
674 info->tid = pidtid & 0xffffffff;
675 info->afu_err = cxl_p2n_read(afu, CXL_AFU_ERR_An);
676 info->errstat = cxl_p2n_read(afu, CXL_PSL_ErrStat_An);

--- 33 unchanged lines hidden ---
735 info->dsisr = cxl_p2n_read(afu, CXL_PSL_DSISR_An);
736 info->dar = cxl_p2n_read(afu, CXL_PSL_DAR_An);
737 info->dsr = cxl_p2n_read(afu, CXL_PSL_DSR_An);
738 pidtid = cxl_p2n_read(afu, CXL_PSL_PID_TID_An);
739 info->pid = pidtid >> 32;
740 info->tid = pidtid & 0xffffffff;
741 info->afu_err = cxl_p2n_read(afu, CXL_AFU_ERR_An);
742 info->errstat = cxl_p2n_read(afu, CXL_PSL_ErrStat_An);

--- 33 unchanged lines hidden ---