astlpc.c (4e8264b705d3575bea8312d6467d5fd9fb440caf) astlpc.c (3a540664c5fbf8cabeca0c1a1af27b1b979eb253)
1/* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */
2
3#if HAVE_CONFIG_H
4#include "config.h"
5#endif
6
7#if HAVE_ENDIAN_H
8#include <endian.h>

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

86 astlpc_prlog(ctx, MCTP_LOG_INFO, fmt, ##__VA_ARGS__)
87#define astlpc_prdebug(ctx, fmt, ...) \
88 astlpc_prlog(ctx, MCTP_LOG_DEBUG, fmt, ##__VA_ARGS__)
89
90/* clang-format off */
91#define ASTLPC_MCTP_MAGIC 0x4d435450
92#define ASTLPC_VER_BAD 0
93#define ASTLPC_VER_MIN 1
1/* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */
2
3#if HAVE_CONFIG_H
4#include "config.h"
5#endif
6
7#if HAVE_ENDIAN_H
8#include <endian.h>

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

86 astlpc_prlog(ctx, MCTP_LOG_INFO, fmt, ##__VA_ARGS__)
87#define astlpc_prdebug(ctx, fmt, ...) \
88 astlpc_prlog(ctx, MCTP_LOG_DEBUG, fmt, ##__VA_ARGS__)
89
90/* clang-format off */
91#define ASTLPC_MCTP_MAGIC 0x4d435450
92#define ASTLPC_VER_BAD 0
93#define ASTLPC_VER_MIN 1
94
95/* Support testing of new binding protocols */
96#ifndef ASTLPC_VER_CUR
94#define ASTLPC_VER_CUR 1
97#define ASTLPC_VER_CUR 1
98#endif
95
99
100#define ASTLPC_PACKET_SIZE(sz) (4 + (sz))
96#define ASTLPC_BODY_SIZE(sz) ((sz) - 4)
97/* clang-format on */
98
99struct mctp_lpcmap_hdr {
101#define ASTLPC_BODY_SIZE(sz) ((sz) - 4)
102/* clang-format on */
103
104struct mctp_lpcmap_hdr {
100 uint32_t magic;
105 uint32_t magic;
101
106
102 uint16_t bmc_ver_min;
103 uint16_t bmc_ver_cur;
104 uint16_t host_ver_min;
105 uint16_t host_ver_cur;
106 uint16_t negotiated_ver;
107 uint16_t pad0;
107 uint16_t bmc_ver_min;
108 uint16_t bmc_ver_cur;
109 uint16_t host_ver_min;
110 uint16_t host_ver_cur;
111 uint16_t negotiated_ver;
112 uint16_t pad0;
108
113
109 uint32_t rx_offset;
110 uint32_t rx_size;
111 uint32_t tx_offset;
112 uint32_t tx_size;
114 struct {
115 uint32_t rx_offset;
116 uint32_t rx_size;
117 uint32_t tx_offset;
118 uint32_t tx_size;
119 } layout;
113} __attribute__((packed));
114
120} __attribute__((packed));
121
115/* layout of TX/RX areas */
116static const uint32_t rx_offset = 0x100;
117static const uint32_t rx_size = 0x100;
118static const uint32_t tx_offset = 0x200;
119static const uint32_t tx_size = 0x100;
122static const uint32_t control_size = 0x100;
120
121#define LPC_WIN_SIZE (1 * 1024 * 1024)
122
123#define KCS_STATUS_BMC_READY 0x80
124#define KCS_STATUS_CHANNEL_ACTIVE 0x40
125#define KCS_STATUS_IBF 0x02
126#define KCS_STATUS_OBF 0x01
127
123
124#define LPC_WIN_SIZE (1 * 1024 * 1024)
125
126#define KCS_STATUS_BMC_READY 0x80
127#define KCS_STATUS_CHANNEL_ACTIVE 0x40
128#define KCS_STATUS_IBF 0x02
129#define KCS_STATUS_OBF 0x01
130
131#define MIN(a, b) \
132 ({ \
133 typeof(a) _a = a; \
134 typeof(b) _b = b; \
135 _a < _b ? _a : _b; \
136 })
137
138#define MAX(a, b) \
139 ({ \
140 typeof(a) _a = a; \
141 typeof(b) _b = b; \
142 _a > _b ? _a : _b; \
143 })
144
128static inline int mctp_astlpc_kcs_write(struct mctp_binding_astlpc *astlpc,
129 enum mctp_binding_astlpc_kcs_reg reg,
130 uint8_t val)
131{
132 return astlpc->ops.kcs_write(astlpc->ops_data, reg, val);
133}
134
135static inline int mctp_astlpc_kcs_read(struct mctp_binding_astlpc *astlpc,

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

208 if (rc) {
209 astlpc_prwarn(astlpc, "KCS dummy data write failed");
210 return -1;
211 }
212
213 return 0;
214}
215
145static inline int mctp_astlpc_kcs_write(struct mctp_binding_astlpc *astlpc,
146 enum mctp_binding_astlpc_kcs_reg reg,
147 uint8_t val)
148{
149 return astlpc->ops.kcs_write(astlpc->ops_data, reg, val);
150}
151
152static inline int mctp_astlpc_kcs_read(struct mctp_binding_astlpc *astlpc,

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

225 if (rc) {
226 astlpc_prwarn(astlpc, "KCS dummy data write failed");
227 return -1;
228 }
229
230 return 0;
231}
232
233static int mctp_astlpc_layout_read(struct mctp_binding_astlpc *astlpc,
234 struct mctp_astlpc_layout *layout)
235{
236 struct mctp_lpcmap_hdr hdr;
237 int rc;
238
239 rc = mctp_astlpc_lpc_read(astlpc, &hdr, 0, sizeof(hdr));
240 if (rc < 0)
241 return rc;
242
243 /* Flip the buffers as the names are defined in terms of the host */
244 if (astlpc->mode == MCTP_BINDING_ASTLPC_MODE_BMC) {
245 layout->rx.offset = be32toh(hdr.layout.tx_offset);
246 layout->rx.size = be32toh(hdr.layout.tx_size);
247 layout->tx.offset = be32toh(hdr.layout.rx_offset);
248 layout->tx.size = be32toh(hdr.layout.rx_size);
249 } else {
250 assert(astlpc->mode == MCTP_BINDING_ASTLPC_MODE_HOST);
251
252 layout->rx.offset = be32toh(hdr.layout.rx_offset);
253 layout->rx.size = be32toh(hdr.layout.rx_size);
254 layout->tx.offset = be32toh(hdr.layout.tx_offset);
255 layout->tx.size = be32toh(hdr.layout.tx_size);
256 }
257
258 return 0;
259}
260
261static int mctp_astlpc_layout_write(struct mctp_binding_astlpc *astlpc,
262 struct mctp_astlpc_layout *layout)
263{
264 uint32_t rx_size_be;
265
266 if (astlpc->mode == MCTP_BINDING_ASTLPC_MODE_BMC) {
267 struct mctp_lpcmap_hdr hdr;
268
269 /*
270 * Flip the buffers as the names are defined in terms of the
271 * host
272 */
273 hdr.layout.rx_offset = htobe32(layout->tx.offset);
274 hdr.layout.rx_size = htobe32(layout->tx.size);
275 hdr.layout.tx_offset = htobe32(layout->rx.offset);
276 hdr.layout.tx_size = htobe32(layout->rx.size);
277
278 return mctp_astlpc_lpc_write(astlpc, &hdr.layout,
279 offsetof(struct mctp_lpcmap_hdr, layout),
280 sizeof(hdr.layout));
281 }
282
283 assert(astlpc->mode == MCTP_BINDING_ASTLPC_MODE_HOST);
284
285 /*
286 * As of v2 we only need to write rx_size - the offsets are controlled
287 * by the BMC, as is the BMC's rx_size (host tx_size).
288 */
289 rx_size_be = htobe32(layout->rx.size);
290 return mctp_astlpc_lpc_write(astlpc, &rx_size_be,
291 offsetof(struct mctp_lpcmap_hdr, layout.rx_size),
292 sizeof(rx_size_be));
293}
294
295static bool mctp_astlpc_buffer_validate(struct mctp_astlpc_buffer *buf,
296 const char *name)
297{
298 /* Check for overflow */
299 if (buf->offset + buf->size < buf->offset) {
300 mctp_prerr(
301 "%s packet buffer parameters overflow: offset: 0x%" PRIx32
302 ", size: %" PRIu32,
303 name, buf->offset, buf->size);
304 return false;
305 }
306
307 /* Check that the buffers are contained within the allocated space */
308 if (buf->offset + buf->size > LPC_WIN_SIZE) {
309 mctp_prerr(
310 "%s packet buffer parameters exceed %uM window size: offset: 0x%" PRIx32
311 ", size: %" PRIu32,
312 name, (LPC_WIN_SIZE / (1024 * 1024)), buf->offset,
313 buf->size);
314 return false;
315 }
316
317 /* Check that the baseline transmission unit is supported */
318 if (buf->size < ASTLPC_PACKET_SIZE(MCTP_PACKET_SIZE(MCTP_BTU))) {
319 mctp_prerr(
320 "%s packet buffer too small: Require %zu bytes to support the %u byte baseline transmission unit, found %" PRIu32,
321 name, ASTLPC_PACKET_SIZE(MCTP_PACKET_SIZE(MCTP_BTU)),
322 MCTP_BTU, buf->size);
323 return false;
324 }
325
326 /* Check for overlap with the control space */
327 if (buf->offset < control_size) {
328 mctp_prerr(
329 "%s packet buffer overlaps control region {0x%" PRIx32
330 ", %" PRIu32 "}: Rx {0x%" PRIx32 ", %" PRIu32 "}",
331 name, 0U, control_size, buf->offset, buf->size);
332 return false;
333 }
334
335 return true;
336}
337
338static bool mctp_astlpc_layout_validate(struct mctp_astlpc_layout *layout)
339{
340 struct mctp_astlpc_buffer *rx = &layout->rx;
341 struct mctp_astlpc_buffer *tx = &layout->tx;
342 bool rx_valid, tx_valid;
343
344 rx_valid = mctp_astlpc_buffer_validate(rx, "Rx");
345 tx_valid = mctp_astlpc_buffer_validate(tx, "Tx");
346
347 if (!(rx_valid && tx_valid))
348 return false;
349
350 /* Check that the buffers are disjoint */
351 if ((rx->offset <= tx->offset && rx->offset + rx->size > tx->offset) ||
352 (tx->offset <= rx->offset && tx->offset + tx->size > rx->offset)) {
353 mctp_prerr("Rx and Tx packet buffers overlap: Rx {0x%" PRIx32
354 ", %" PRIu32 "}, Tx {0x%" PRIx32 ", %" PRIu32 "}",
355 rx->offset, rx->size, tx->offset, tx->size);
356 return false;
357 }
358
359 return true;
360}
361
216static int mctp_astlpc_init_bmc(struct mctp_binding_astlpc *astlpc)
217{
218 struct mctp_lpcmap_hdr hdr = { 0 };
219 uint8_t status;
362static int mctp_astlpc_init_bmc(struct mctp_binding_astlpc *astlpc)
363{
364 struct mctp_lpcmap_hdr hdr = { 0 };
365 uint8_t status;
366 size_t sz;
220
367
368 /*
369 * The largest buffer size is half of the allocated MCTP space
370 * excluding the control space.
371 */
372 sz = ((LPC_WIN_SIZE - control_size) / 2);
373
374 /*
375 * Trim the MTU to a multiple of 16 to meet the requirements of 12.17
376 * Query Hop in DSP0236 v1.3.0.
377 */
378 sz = MCTP_BODY_SIZE(ASTLPC_BODY_SIZE(sz));
379 sz &= ~0xfUL;
380 sz = ASTLPC_PACKET_SIZE(MCTP_PACKET_SIZE(sz));
381
221 /* Flip the buffers as the names are defined in terms of the host */
382 /* Flip the buffers as the names are defined in terms of the host */
222 astlpc->layout.rx.offset = tx_offset;
223 astlpc->layout.rx.size = tx_size;
224 astlpc->layout.tx.offset = rx_offset;
225 astlpc->layout.tx.size = rx_size;
383 astlpc->layout.tx.offset = control_size;
384 astlpc->layout.tx.size = sz;
385 astlpc->layout.rx.offset =
386 astlpc->layout.tx.offset + astlpc->layout.tx.size;
387 astlpc->layout.rx.size = sz;
226
388
389 /* Sanity check that can be eliminated if asserts are off */
390 assert(mctp_astlpc_layout_validate(&astlpc->layout));
391
227 hdr = (struct mctp_lpcmap_hdr){
228 .magic = htobe32(ASTLPC_MCTP_MAGIC),
229 .bmc_ver_min = htobe16(ASTLPC_VER_MIN),
230 .bmc_ver_cur = htobe16(ASTLPC_VER_CUR),
231
232 /* Flip the buffers back as we're now describing the host's
233 * configuration to the host */
392 hdr = (struct mctp_lpcmap_hdr){
393 .magic = htobe32(ASTLPC_MCTP_MAGIC),
394 .bmc_ver_min = htobe16(ASTLPC_VER_MIN),
395 .bmc_ver_cur = htobe16(ASTLPC_VER_CUR),
396
397 /* Flip the buffers back as we're now describing the host's
398 * configuration to the host */
234 .rx_offset = htobe32(astlpc->layout.tx.offset),
235 .rx_size = htobe32(astlpc->layout.tx.size),
236 .tx_offset = htobe32(astlpc->layout.rx.offset),
237 .tx_size = htobe32(astlpc->layout.rx.size),
399 .layout.rx_offset = htobe32(astlpc->layout.tx.offset),
400 .layout.rx_size = htobe32(astlpc->layout.tx.size),
401 .layout.tx_offset = htobe32(astlpc->layout.rx.offset),
402 .layout.tx_size = htobe32(astlpc->layout.rx.size),
238 };
239
240 mctp_astlpc_lpc_write(astlpc, &hdr, 0, sizeof(hdr));
241
242 /* set status indicating that the BMC is now active */
243 status = KCS_STATUS_BMC_READY | KCS_STATUS_OBF;
244 return mctp_astlpc_kcs_set_status(astlpc, status);
245}

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

280 ", %" PRIu16 "] and [%" PRIu16 ", %" PRIu16 "]",
281 bmc_ver_min, bmc_ver_cur, host_ver_min, host_ver_cur);
282 return false;
283 }
284
285 return true;
286}
287
403 };
404
405 mctp_astlpc_lpc_write(astlpc, &hdr, 0, sizeof(hdr));
406
407 /* set status indicating that the BMC is now active */
408 status = KCS_STATUS_BMC_READY | KCS_STATUS_OBF;
409 return mctp_astlpc_kcs_set_status(astlpc, status);
410}

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

445 ", %" PRIu16 "] and [%" PRIu16 ", %" PRIu16 "]",
446 bmc_ver_min, bmc_ver_cur, host_ver_min, host_ver_cur);
447 return false;
448 }
449
450 return true;
451}
452
453static int mctp_astlpc_negotiate_layout_host(struct mctp_binding_astlpc *astlpc)
454{
455 struct mctp_astlpc_layout layout;
456 uint32_t sz;
457 int rc;
458
459 rc = mctp_astlpc_layout_read(astlpc, &layout);
460 if (rc < 0)
461 return rc;
462
463 if (!mctp_astlpc_layout_validate(&layout)) {
464 astlpc_prerr(
465 astlpc,
466 "BMC provided invalid buffer layout: Rx {0x%" PRIx32
467 ", %" PRIu32 "}, Tx {0x%" PRIx32 ", %" PRIu32 "}",
468 layout.rx.offset, layout.rx.size, layout.tx.offset,
469 layout.tx.size);
470 return -EINVAL;
471 }
472
473 sz = ASTLPC_PACKET_SIZE(MCTP_PACKET_SIZE(MCTP_BTU));
474 layout.rx.size = sz;
475
476 if (!mctp_astlpc_layout_validate(&layout)) {
477 astlpc_prerr(
478 astlpc,
479 "Generated invalid buffer layout with size %" PRIu32
480 ": Rx {0x%" PRIx32 ", %" PRIu32 "}, Tx {0x%" PRIx32
481 ", %" PRIu32 "}",
482 sz, layout.rx.offset, layout.rx.size, layout.tx.offset,
483 layout.tx.size);
484 return -EINVAL;
485 }
486
487 astlpc_prinfo(astlpc, "Requesting MTU of %" PRIu32 " bytes", MCTP_BTU);
488
489 return mctp_astlpc_layout_write(astlpc, &layout);
490}
491
288static int mctp_astlpc_init_host(struct mctp_binding_astlpc *astlpc)
289{
290 const uint16_t ver_min_be = htobe16(ASTLPC_VER_MIN);
291 const uint16_t ver_cur_be = htobe16(ASTLPC_VER_CUR);
292 uint16_t bmc_ver_min, bmc_ver_cur;
293 struct mctp_lpcmap_hdr hdr;
294 uint8_t status;
295 int rc;

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

302
303 astlpc->kcs_status = status;
304
305 if (!(status & KCS_STATUS_BMC_READY))
306 return -EHOSTDOWN;
307
308 mctp_astlpc_lpc_read(astlpc, &hdr, 0, sizeof(hdr));
309
492static int mctp_astlpc_init_host(struct mctp_binding_astlpc *astlpc)
493{
494 const uint16_t ver_min_be = htobe16(ASTLPC_VER_MIN);
495 const uint16_t ver_cur_be = htobe16(ASTLPC_VER_CUR);
496 uint16_t bmc_ver_min, bmc_ver_cur;
497 struct mctp_lpcmap_hdr hdr;
498 uint8_t status;
499 int rc;

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

506
507 astlpc->kcs_status = status;
508
509 if (!(status & KCS_STATUS_BMC_READY))
510 return -EHOSTDOWN;
511
512 mctp_astlpc_lpc_read(astlpc, &hdr, 0, sizeof(hdr));
513
310 astlpc->layout.rx.offset = be32toh(hdr.rx_offset);
311 astlpc->layout.rx.size = be32toh(hdr.rx_size);
312 astlpc->layout.tx.offset = be32toh(hdr.tx_offset);
313 astlpc->layout.tx.size = be32toh(hdr.tx_size);
314
315 bmc_ver_min = be16toh(hdr.bmc_ver_min);
316 bmc_ver_cur = be16toh(hdr.bmc_ver_cur);
317
318 if (!mctp_astlpc_validate_version(bmc_ver_min, bmc_ver_cur,
319 ASTLPC_VER_MIN, ASTLPC_VER_CUR)) {
320 astlpc_prerr(astlpc, "Cannot negotiate with invalid versions");
321 return -EINVAL;
322 }
323
514 bmc_ver_min = be16toh(hdr.bmc_ver_min);
515 bmc_ver_cur = be16toh(hdr.bmc_ver_cur);
516
517 if (!mctp_astlpc_validate_version(bmc_ver_min, bmc_ver_cur,
518 ASTLPC_VER_MIN, ASTLPC_VER_CUR)) {
519 astlpc_prerr(astlpc, "Cannot negotiate with invalid versions");
520 return -EINVAL;
521 }
522
523 /*
524 * Negotation always chooses the highest protocol version that
525 * satisfies the version constraints. So check whether the BMC supports
526 * v2, and if so, negotiate in v2 style.
527 */
528 if (ASTLPC_VER_CUR >= 2 && bmc_ver_cur >= 2) {
529 rc = mctp_astlpc_negotiate_layout_host(astlpc);
530 if (rc < 0)
531 return rc;
532 }
533
534 /* Version negotiation */
324 mctp_astlpc_lpc_write(astlpc, &ver_min_be,
325 offsetof(struct mctp_lpcmap_hdr, host_ver_min),
326 sizeof(ver_min_be));
327
328 mctp_astlpc_lpc_write(astlpc, &ver_cur_be,
329 offsetof(struct mctp_lpcmap_hdr, host_ver_cur),
330 sizeof(ver_cur_be));
331

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

440 return ASTLPC_VER_BAD;
441
442 if (bmc_ver_cur < host_ver_cur)
443 return bmc_ver_cur;
444
445 return host_ver_cur;
446}
447
535 mctp_astlpc_lpc_write(astlpc, &ver_min_be,
536 offsetof(struct mctp_lpcmap_hdr, host_ver_min),
537 sizeof(ver_min_be));
538
539 mctp_astlpc_lpc_write(astlpc, &ver_cur_be,
540 offsetof(struct mctp_lpcmap_hdr, host_ver_cur),
541 sizeof(ver_cur_be));
542

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

651 return ASTLPC_VER_BAD;
652
653 if (bmc_ver_cur < host_ver_cur)
654 return bmc_ver_cur;
655
656 return host_ver_cur;
657}
658
659static uint32_t mctp_astlpc_calculate_mtu(struct mctp_binding_astlpc *astlpc,
660 struct mctp_astlpc_layout *layout)
661{
662 uint32_t low, high, limit;
663
664 /* Derive the largest MTU the BMC _can_ support */
665 low = MIN(astlpc->layout.rx.offset, astlpc->layout.tx.offset);
666 high = MAX(astlpc->layout.rx.offset, astlpc->layout.tx.offset);
667 limit = high - low;
668
669
670 /* Determine the accepted MTU, applied both directions by convention */
671 return MCTP_BODY_SIZE(ASTLPC_BODY_SIZE(MIN(limit, layout->tx.size)));
672}
673
674static int mctp_astlpc_negotiate_layout_bmc(struct mctp_binding_astlpc *astlpc)
675{
676 struct mctp_astlpc_layout proposed, pending;
677 uint32_t sz, mtu;
678 int rc;
679
680 /* Extract the host's proposed layout */
681 rc = mctp_astlpc_layout_read(astlpc, &proposed);
682 if (rc < 0)
683 return rc;
684
685 if (!mctp_astlpc_layout_validate(&proposed))
686 return -EINVAL;
687
688 /* Negotiate the MTU */
689 mtu = mctp_astlpc_calculate_mtu(astlpc, &proposed);
690 sz = ASTLPC_PACKET_SIZE(MCTP_PACKET_SIZE(mtu));
691
692 /*
693 * Use symmetric MTUs by convention and to pass constraints in rx/tx
694 * functions
695 */
696 pending = astlpc->layout;
697 pending.tx.size = sz;
698 pending.rx.size = sz;
699
700 if (mctp_astlpc_layout_validate(&pending)) {
701 /* We found a sensible Rx MTU, so honour it */
702 astlpc->layout = pending;
703
704 /* Enforce the negotiated MTU */
705 rc = mctp_astlpc_layout_write(astlpc, &astlpc->layout);
706 if (rc < 0)
707 return rc;
708
709 astlpc_prinfo(astlpc, "Negotiated an MTU of %" PRIu32 " bytes",
710 mtu);
711 } else {
712 astlpc_prwarn(astlpc, "MTU negotiation failed");
713 return -EINVAL;
714 }
715
716 if (astlpc->version >= 2)
717 astlpc->binding.pkt_size = MCTP_PACKET_SIZE(mtu);
718
719 return 0;
720}
721
448static void mctp_astlpc_init_channel(struct mctp_binding_astlpc *astlpc)
449{
450 uint16_t negotiated, negotiated_be;
451 struct mctp_lpcmap_hdr hdr;
452 uint8_t status;
722static void mctp_astlpc_init_channel(struct mctp_binding_astlpc *astlpc)
723{
724 uint16_t negotiated, negotiated_be;
725 struct mctp_lpcmap_hdr hdr;
726 uint8_t status;
727 int rc;
453
454 mctp_astlpc_lpc_read(astlpc, &hdr, 0, sizeof(hdr));
455
456 /* Version negotiation */
457 negotiated =
458 mctp_astlpc_negotiate_version(ASTLPC_VER_MIN, ASTLPC_VER_CUR,
459 be16toh(hdr.host_ver_min),
460 be16toh(hdr.host_ver_cur));
461
728
729 mctp_astlpc_lpc_read(astlpc, &hdr, 0, sizeof(hdr));
730
731 /* Version negotiation */
732 negotiated =
733 mctp_astlpc_negotiate_version(ASTLPC_VER_MIN, ASTLPC_VER_CUR,
734 be16toh(hdr.host_ver_min),
735 be16toh(hdr.host_ver_cur));
736
737 /* Host Rx MTU negotiation: Failure terminates channel init */
738 rc = mctp_astlpc_negotiate_layout_bmc(astlpc);
739 if (rc < 0)
740 negotiated = ASTLPC_VER_BAD;
741
462 /* Populate the negotiated version */
463 astlpc->version = negotiated;
464 negotiated_be = htobe16(negotiated);
465 mctp_astlpc_lpc_write(astlpc, &negotiated_be,
466 offsetof(struct mctp_lpcmap_hdr, negotiated_ver),
467 sizeof(negotiated_be));
468
469 /* Finalise the configuration */

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

518
519static void mctp_astlpc_tx_complete(struct mctp_binding_astlpc *astlpc)
520{
521 mctp_binding_set_tx_enabled(&astlpc->binding, true);
522}
523
524static int mctp_astlpc_finalise_channel(struct mctp_binding_astlpc *astlpc)
525{
742 /* Populate the negotiated version */
743 astlpc->version = negotiated;
744 negotiated_be = htobe16(negotiated);
745 mctp_astlpc_lpc_write(astlpc, &negotiated_be,
746 offsetof(struct mctp_lpcmap_hdr, negotiated_ver),
747 sizeof(negotiated_be));
748
749 /* Finalise the configuration */

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

798
799static void mctp_astlpc_tx_complete(struct mctp_binding_astlpc *astlpc)
800{
801 mctp_binding_set_tx_enabled(&astlpc->binding, true);
802}
803
804static int mctp_astlpc_finalise_channel(struct mctp_binding_astlpc *astlpc)
805{
806 struct mctp_astlpc_layout layout;
526 uint16_t negotiated;
527 int rc;
528
529 rc = mctp_astlpc_lpc_read(astlpc, &negotiated,
530 offsetof(struct mctp_lpcmap_hdr,
531 negotiated_ver),
532 sizeof(negotiated));
533 if (rc < 0)

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

539 negotiated > ASTLPC_VER_CUR) {
540 astlpc_prerr(astlpc, "Failed to negotiate version, got: %u\n",
541 negotiated);
542 return -EINVAL;
543 }
544
545 astlpc->version = negotiated;
546
807 uint16_t negotiated;
808 int rc;
809
810 rc = mctp_astlpc_lpc_read(astlpc, &negotiated,
811 offsetof(struct mctp_lpcmap_hdr,
812 negotiated_ver),
813 sizeof(negotiated));
814 if (rc < 0)

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

820 negotiated > ASTLPC_VER_CUR) {
821 astlpc_prerr(astlpc, "Failed to negotiate version, got: %u\n",
822 negotiated);
823 return -EINVAL;
824 }
825
826 astlpc->version = negotiated;
827
828 rc = mctp_astlpc_layout_read(astlpc, &layout);
829 if (rc < 0)
830 return rc;
831
832 if (!mctp_astlpc_layout_validate(&layout)) {
833 mctp_prerr("BMC proposed invalid buffer parameters");
834 return -EINVAL;
835 }
836
837 astlpc->layout = layout;
838
839 if (negotiated >= 2)
840 astlpc->binding.pkt_size =
841 ASTLPC_BODY_SIZE(astlpc->layout.tx.size);
842
547 return 0;
548}
549
550static int mctp_astlpc_update_channel(struct mctp_binding_astlpc *astlpc,
551 uint8_t status)
552{
553 uint8_t updated;
554 int rc = 0;

--- 299 unchanged lines hidden ---
843 return 0;
844}
845
846static int mctp_astlpc_update_channel(struct mctp_binding_astlpc *astlpc,
847 uint8_t status)
848{
849 uint8_t updated;
850 int rc = 0;

--- 299 unchanged lines hidden ---