switchtec-user: upgrade 4.3 -> 4.4

Adds Gen6 support across the CLI and library (new OSA sub-commands,
status query and capture-control variants) and reworks
switchtec_osa_capture_data() to fill in a caller supplied
switchtec_osa_capture_data structure rather than printing directly.

That rework replaced the run-time sized reply buffer, which 4.3 built
from a flexible array member plus alloca(), with a variable length array
declared as a struct member. That is a GCC-only extension which clang
rejects outright ('variable length array in structure' extension will
never be supported), so add a patch restoring the portable flexible
array member form and passing the computed reply size to switchtec_cmd().

AI-Generated: Uses Claude Code
Signed-off-by: Khem Raj <khem.raj@oss.qualcomm.com>
This commit is contained in:
Khem Raj
2026-08-04 07:15:14 +00:00
parent e838bf4dcf
commit c902c57f89
2 changed files with 127 additions and 2 deletions
@@ -0,0 +1,123 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Khem Raj <raj.khem@gmail.com>
Date: Tue, 4 Aug 2026 00:00:00 -0700
Subject: [PATCH] lib/diag: do not use a variable length array in a struct
switchtec_osa_capture_data() declares the MRPC reply buffer as a struct
whose last member is a VLA:
uint32_t entry_dwords[osa_data_entries_out.entries_remaining * 6];
A variably-modified type as a struct member is a GCC extension that
clang has never implemented, so the build fails with:
lib/diag.c:2454:12: error: fields must have a constant size:
'variable length array in structure' extension will never be supported
v4.3 expressed the same buffer as a flexible array member sized at run
time with alloca(), which is portable; that idiom was lost when this
function was reworked to fill in a switchtec_osa_capture_data structure.
Restore it: declare entry_dwords[] as a flexible array member, allocate
the struct with alloca(), and pass the computed size to switchtec_cmd()
instead of sizeof() so the reply length is unchanged.
Upstream-Status: Pending
Signed-off-by: Khem Raj <raj.khem@gmail.com>
---
diff --git a/lib/diag.c b/lib/diag.c
index 62b2b7d..63769ee 100644
--- a/lib/diag.c
+++ b/lib/diag.c
@@ -36,6 +36,7 @@
#include "switchtec/switchtec.h"
#include "switchtec/utils.h"
+#include <alloca.h>
#include <errno.h>
#include <math.h>
#include <string.h>
@@ -2442,7 +2443,7 @@ int switchtec_osa_capture_data(struct switchtec_dev *dev, int stack_id,
return ret;
}
- struct {
+ struct osa_data_read_out {
uint8_t entries_read;
uint8_t stack_id;
uint8_t lane;
@@ -2451,11 +2452,17 @@ int switchtec_osa_capture_data(struct switchtec_dev *dev, int stack_id,
uint16_t entries_remaining;
uint16_t wrap;
uint16_t reserved;
- uint32_t entry_dwords[osa_data_entries_out.entries_remaining * 6];
- } osa_data_read_out;
+ uint32_t entry_dwords[];
+ } *osa_data_read_out;
+ size_t osa_data_read_out_size;
+
+ osa_data_read_out_size = sizeof(*osa_data_read_out) +
+ osa_data_entries_out.entries_remaining * 6 *
+ sizeof(uint32_t);
+ osa_data_read_out = alloca(osa_data_read_out_size);
- osa_data_read_out.entries_remaining = osa_data_entries_out.entries_remaining;
- osa_data_read_out.next_entry = osa_data_entries_out.next_entry;
+ osa_data_read_out->entries_remaining = osa_data_entries_out.entries_remaining;
+ osa_data_read_out->next_entry = osa_data_entries_out.next_entry;
if (data) {
data->stack_id = stack_id;
@@ -2475,31 +2482,31 @@ int switchtec_osa_capture_data(struct switchtec_dev *dev, int stack_id,
uint32_t osa_data_dwords[4];
int osa_data_idx = 0;
- while (osa_data_read_out.entries_remaining != 0) {
+ while (osa_data_read_out->entries_remaining != 0) {
if (data && total_entries >= SWITCHTEC_OSA_MAX_ENTRIES)
break;
- osa_data_read_in.num_entries = osa_data_read_out.entries_remaining;
- osa_data_read_in.start_entry = osa_data_read_out.next_entry;
+ osa_data_read_in.num_entries = osa_data_read_out->entries_remaining;
+ osa_data_read_in.start_entry = osa_data_read_out->next_entry;
ret = switchtec_cmd(dev, MRPC_ORDERED_SET_ANALYZER,
&osa_data_read_in, sizeof(osa_data_read_in),
- &osa_data_read_out, sizeof(osa_data_read_out));
+ osa_data_read_out, osa_data_read_out_size);
if (ret)
return -1;
- for (int i = total_dword; i < total_dword + (osa_data_read_out.entries_read * 6); i++) {
+ for (int i = total_dword; i < total_dword + (osa_data_read_out->entries_read * 6); i++) {
if (curr_entry_dword < 4) {
- osa_data_dwords[osa_data_idx++] = osa_data_read_out.entry_dwords[i];
+ osa_data_dwords[osa_data_idx++] = osa_data_read_out->entry_dwords[i];
} else if (curr_entry_dword == 4) {
- timestamp_lower = (osa_data_read_out.entry_dwords[i] >> 22) & 0x3FF;
- timestamp_upper = (osa_data_read_out.entry_dwords[i+1] & 0x1A);
+ timestamp_lower = (osa_data_read_out->entry_dwords[i] >> 22) & 0x3FF;
+ timestamp_upper = (osa_data_read_out->entry_dwords[i+1] & 0x1A);
timestamp = timestamp_upper | timestamp_lower;
- link_rate = osa_data_read_out.entry_dwords[i] & 0x3;
- counter = (osa_data_read_out.entry_dwords[i] >> 3) & 0x12;
- trigger = (osa_data_read_out.entry_dwords[i+1] >> 28) & 0x1;
- os_droppped = (osa_data_read_out.entry_dwords[i+1] >> 29) & 0x1;
+ link_rate = osa_data_read_out->entry_dwords[i] & 0x3;
+ counter = (osa_data_read_out->entry_dwords[i] >> 3) & 0x12;
+ trigger = (osa_data_read_out->entry_dwords[i+1] >> 28) & 0x1;
+ os_droppped = (osa_data_read_out->entry_dwords[i+1] >> 29) & 0x1;
if (data && total_entries < SWITCHTEC_OSA_MAX_ENTRIES) {
data->entries[total_entries].timestamp = timestamp;
@@ -2522,7 +2529,7 @@ int switchtec_osa_capture_data(struct switchtec_dev *dev, int stack_id,
curr_entry_dword = 0;
}
}
- total_dword += osa_data_read_out.entries_read;
+ total_dword += osa_data_read_out->entries_read;
}
return ret;
@@ -6,8 +6,10 @@ LIC_FILES_CHKSUM = "file://LICENSE;md5=3d6b07c89629cff2990d2e8e1f4c2382"
DEPENDS = "ncurses openssl"
SRC_URI = "git://github.com/Microsemi/switchtec-user.git;protocol=https;branch=master;tag=v${PV}"
SRCREV = "abe2a1d2367a118469a7b94bc4dd856aaf856eec"
SRC_URI = "git://github.com/Microsemi/switchtec-user.git;protocol=https;branch=master;tag=v${PV} \
file://0001-lib-diag-do-not-use-a-variable-length-array-in-a-str.patch \
"
SRCREV = "d995512f3bf1ceb98eefada813642d5ba5d62cd1"
inherit autotools-brokensep pkgconfig