mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-10-29 09:32:34 +00:00
ucode: add multi-radio support
Signed-off-by: John Crispin <john@phrozen.org>
This commit is contained in:
612
patches/0081-ucode-multi-radio.patch
Normal file
612
patches/0081-ucode-multi-radio.patch
Normal file
@@ -0,0 +1,612 @@
|
||||
From 47728424bea22cb0dc646be2cec95fec51710e01 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <john@phrozen.org>
|
||||
Date: Fri, 22 Nov 2024 06:37:44 +0100
|
||||
Subject: [PATCH] ucode: multi radio support
|
||||
|
||||
Signed-off-by: John Crispin <john@phrozen.org>
|
||||
---
|
||||
package/utils/ucode/patches/0001-fixes.patch | 21 +-
|
||||
...ess-to-tb-array-out-of-uc_nl_convert.patch | 341 ++++++++++++++++++
|
||||
...d-support-for-multi-attribute-arrays.patch | 94 +++++
|
||||
...l80211-add-wiphy-multi-radio-support.patch | 50 +++
|
||||
...w-attributes-for-multi-radio-support.patch | 30 ++
|
||||
5 files changed, 528 insertions(+), 8 deletions(-)
|
||||
create mode 100644 package/utils/ucode/patches/110-nl80211-move-access-to-tb-array-out-of-uc_nl_convert.patch
|
||||
create mode 100644 package/utils/ucode/patches/111-nl80211-add-support-for-multi-attribute-arrays.patch
|
||||
create mode 100644 package/utils/ucode/patches/112-nl80211-add-wiphy-multi-radio-support.patch
|
||||
create mode 100644 package/utils/ucode/patches/113-nl80211-add-new-attributes-for-multi-radio-support.patch
|
||||
|
||||
diff --git a/package/utils/ucode/patches/0001-fixes.patch b/package/utils/ucode/patches/0001-fixes.patch
|
||||
index a8f96fc71d..1f60bdd656 100644
|
||||
--- a/package/utils/ucode/patches/0001-fixes.patch
|
||||
+++ b/package/utils/ucode/patches/0001-fixes.patch
|
||||
@@ -8,11 +8,9 @@ Subject: [PATCH] fixes
|
||||
lib/rtnl.c | 1 +
|
||||
2 files changed, 87 insertions(+), 6 deletions(-)
|
||||
|
||||
-Index: ucode-2023-06-06-c7d84aae/lib/nl80211.c
|
||||
-===================================================================
|
||||
---- ucode-2023-06-06-c7d84aae.orig/lib/nl80211.c
|
||||
-+++ ucode-2023-06-06-c7d84aae/lib/nl80211.c
|
||||
-@@ -56,6 +56,26 @@ limitations under the License.
|
||||
+--- a/lib/nl80211.c
|
||||
++++ b/lib/nl80211.c
|
||||
+@@ -57,6 +57,33 @@ limitations under the License.
|
||||
|
||||
#define NL80211_CMDS_BITMAP_SIZE DIV_ROUND_UP(NL80211_CMD_MAX + 1, 32)
|
||||
|
||||
@@ -33,13 +31,20 @@ Index: ucode-2023-06-06-c7d84aae/lib/nl80211.c
|
||||
+#ifndef QCA_WIFI_7
|
||||
+#define NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MAC NL80211_ATTR_NOT_IMPLEMENTED
|
||||
+#define NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PHY NL80211_ATTR_NOT_IMPLEMENTED
|
||||
++#define NL80211_WIPHY_RADIO_FREQ_ATTR_START NL80211_ATTR_NOT_IMPLEMENTED
|
||||
++#define NL80211_WIPHY_RADIO_FREQ_ATTR_END NL80211_ATTR_NOT_IMPLEMENTED
|
||||
++#define NL80211_WIPHY_RADIO_ATTR_INDEX NL80211_ATTR_NOT_IMPLEMENTED
|
||||
++#define NL80211_WIPHY_RADIO_ATTR_FREQ_RANGE NL80211_ATTR_NOT_IMPLEMENTED
|
||||
++#define NL80211_WIPHY_RADIO_ATTR_INTERFACE_COMBINATION NL80211_ATTR_NOT_IMPLEMENTED
|
||||
++#define NL80211_ATTR_WIPHY_RADIOS NL80211_ATTR_NOT_IMPLEMENTED
|
||||
++#define NL80211_ATTR_VIF_RADIO_MASK NL80211_ATTR_NOT_IMPLEMENTED
|
||||
+#endif
|
||||
+
|
||||
+
|
||||
static struct {
|
||||
int code;
|
||||
char *msg;
|
||||
-@@ -560,7 +580,7 @@ static const uc_nl_nested_spec_t nl80211
|
||||
+@@ -561,7 +588,7 @@ static const uc_nl_nested_spec_t nl80211
|
||||
|
||||
static const uc_nl_nested_spec_t nl80211_wiphy_bands_iftype_data_nla = {
|
||||
.headsize = 0,
|
||||
@@ -47,8 +52,8 @@ Index: ucode-2023-06-06-c7d84aae/lib/nl80211.c
|
||||
+ .nattrs = 9,
|
||||
.attrs = {
|
||||
{ NL80211_BAND_IFTYPE_ATTR_IFTYPES, "iftypes", DT_NESTED, 0, &nl80211_ifcomb_limit_types_nla },
|
||||
- { NL80211_BAND_IFTYPE_ATTR_HE_CAP_MAC, "he_cap_mac", DT_U16, DF_ARRAY, NULL },
|
||||
-@@ -569,6 +589,8 @@ static const uc_nl_nested_spec_t nl80211
|
||||
+ { NL80211_BAND_IFTYPE_ATTR_HE_CAP_MAC, "he_cap_mac", DT_U8, DF_ARRAY, NULL },
|
||||
+@@ -570,6 +597,8 @@ static const uc_nl_nested_spec_t nl80211
|
||||
{ NL80211_BAND_IFTYPE_ATTR_HE_CAP_PPE, "he_cap_ppe", DT_U8, DF_ARRAY, NULL },
|
||||
{ NL80211_BAND_IFTYPE_ATTR_HE_6GHZ_CAPA, "he_6ghz_capa", DT_U16, 0, NULL },
|
||||
{ NL80211_BAND_IFTYPE_ATTR_VENDOR_ELEMS, "vendor_elems", DT_STRING, DF_BINARY, NULL },
|
||||
diff --git a/package/utils/ucode/patches/110-nl80211-move-access-to-tb-array-out-of-uc_nl_convert.patch b/package/utils/ucode/patches/110-nl80211-move-access-to-tb-array-out-of-uc_nl_convert.patch
|
||||
new file mode 100644
|
||||
index 0000000000..7e9d07e01e
|
||||
--- /dev/null
|
||||
+++ b/package/utils/ucode/patches/110-nl80211-move-access-to-tb-array-out-of-uc_nl_convert.patch
|
||||
@@ -0,0 +1,341 @@
|
||||
+From: Felix Fietkau <nbd@nbd.name>
|
||||
+Date: Sat, 29 Jun 2024 12:03:21 +0200
|
||||
+Subject: [PATCH] nl80211: move access to tb array out of uc_nl_convert_attr
|
||||
+ and below
|
||||
+
|
||||
+Only one place needs access to another attribute from the tb array
|
||||
+(HE MCS rates). In order to make that access possible, add a flag to indicate
|
||||
+a second attribute dependency via auxdata.
|
||||
+
|
||||
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
+---
|
||||
+
|
||||
+--- a/lib/nl80211.c
|
||||
++++ b/lib/nl80211.c
|
||||
+@@ -197,6 +197,7 @@ enum {
|
||||
+ DF_OFFSET1 = (1 << 4),
|
||||
+ DF_ARRAY = (1 << 5),
|
||||
+ DF_BINARY = (1 << 6),
|
||||
++ DF_RELATED = (1 << 7),
|
||||
+ };
|
||||
+
|
||||
+ typedef struct uc_nl_attr_spec {
|
||||
+@@ -215,6 +216,7 @@ typedef struct uc_nl_nested_spec {
|
||||
+
|
||||
+ #define SIZE(type) (void *)(uintptr_t)sizeof(struct type)
|
||||
+ #define MEMBER(type, field) (void *)(uintptr_t)offsetof(struct type, field)
|
||||
++#define ATTRID(id) (void *)(uintptr_t)(id)
|
||||
+
|
||||
+ static const uc_nl_nested_spec_t nl80211_cqm_nla = {
|
||||
+ .headsize = 0,
|
||||
+@@ -593,7 +595,7 @@ static const uc_nl_nested_spec_t nl80211
|
||||
+ { NL80211_BAND_IFTYPE_ATTR_IFTYPES, "iftypes", DT_NESTED, 0, &nl80211_ifcomb_limit_types_nla },
|
||||
+ { NL80211_BAND_IFTYPE_ATTR_HE_CAP_MAC, "he_cap_mac", DT_U8, DF_ARRAY, NULL },
|
||||
+ { NL80211_BAND_IFTYPE_ATTR_HE_CAP_PHY, "he_cap_phy", DT_U8, DF_ARRAY, NULL },
|
||||
+- { NL80211_BAND_IFTYPE_ATTR_HE_CAP_MCS_SET, "he_cap_mcs_set", DT_HE_MCS, 0, NULL },
|
||||
++ { NL80211_BAND_IFTYPE_ATTR_HE_CAP_MCS_SET, "he_cap_mcs_set", DT_HE_MCS, DF_RELATED, ATTRID(NL80211_BAND_IFTYPE_ATTR_HE_CAP_PHY) },
|
||||
+ { NL80211_BAND_IFTYPE_ATTR_HE_CAP_PPE, "he_cap_ppe", DT_U8, DF_ARRAY, NULL },
|
||||
+ { NL80211_BAND_IFTYPE_ATTR_HE_6GHZ_CAPA, "he_6ghz_capa", DT_U16, 0, NULL },
|
||||
+ { NL80211_BAND_IFTYPE_ATTR_VENDOR_ELEMS, "vendor_elems", DT_STRING, DF_BINARY, NULL },
|
||||
+@@ -1065,12 +1067,12 @@ static bool
|
||||
+ uc_nl_parse_attr(const uc_nl_attr_spec_t *spec, struct nl_msg *msg, char *base, uc_vm_t *vm, uc_value_t *val, size_t idx);
|
||||
+
|
||||
+ static uc_value_t *
|
||||
+-uc_nl_convert_attr(const uc_nl_attr_spec_t *spec, struct nl_msg *msg, char *base, struct nlattr **tb, uc_vm_t *vm);
|
||||
++uc_nl_convert_attr(const uc_nl_attr_spec_t *spec, struct nl_msg *msg, char *base, struct nlattr *attr, struct nlattr *attr2, uc_vm_t *vm);
|
||||
+
|
||||
+ static bool
|
||||
+ uc_nl_convert_attrs(struct nl_msg *msg, void *buf, size_t buflen, size_t headsize, const uc_nl_attr_spec_t *attrs, size_t nattrs, uc_vm_t *vm, uc_value_t *obj)
|
||||
+ {
|
||||
+- struct nlattr **tb, *nla, *nla_nest;
|
||||
++ struct nlattr **tb, *nla, *nla2, *nla_nest;
|
||||
+ size_t i, type, maxattr = 0;
|
||||
+ uc_value_t *v, *arr;
|
||||
+ int rem;
|
||||
+@@ -1106,9 +1108,7 @@ uc_nl_convert_attrs(struct nl_msg *msg,
|
||||
+ attrs[i].auxdata && nla_type(nla) != (intptr_t)attrs[i].auxdata)
|
||||
+ continue;
|
||||
+
|
||||
+- tb[attrs[i].attr] = nla;
|
||||
+-
|
||||
+- v = uc_nl_convert_attr(&attrs[i], msg, (char *)buf, tb, vm);
|
||||
++ v = uc_nl_convert_attr(&attrs[i], msg, (char *)buf, nla, NULL, vm);
|
||||
+
|
||||
+ if (!v)
|
||||
+ continue;
|
||||
+@@ -1128,7 +1128,12 @@ uc_nl_convert_attrs(struct nl_msg *msg,
|
||||
+ v = arr;
|
||||
+ }
|
||||
+ else {
|
||||
+- v = uc_nl_convert_attr(&attrs[i], msg, (char *)buf, tb, vm);
|
||||
++ if (attrs[i].flags & DF_RELATED)
|
||||
++ nla2 = tb[(uintptr_t)attrs[i].auxdata];
|
||||
++ else
|
||||
++ nla2 = NULL;
|
||||
++
|
||||
++ v = uc_nl_convert_attr(&attrs[i], msg, (char *)buf, tb[attrs[i].attr], nla2, vm);
|
||||
+
|
||||
+ if (!v)
|
||||
+ continue;
|
||||
+@@ -1218,7 +1223,7 @@ uc_nl_parse_rta_nested(const uc_nl_attr_
|
||||
+ }
|
||||
+
|
||||
+ static uc_value_t *
|
||||
+-uc_nl_convert_rta_nested(const uc_nl_attr_spec_t *spec, struct nl_msg *msg, struct nlattr **tb, uc_vm_t *vm)
|
||||
++uc_nl_convert_rta_nested(const uc_nl_attr_spec_t *spec, struct nl_msg *msg, struct nlattr *attr, uc_vm_t *vm)
|
||||
+ {
|
||||
+ const uc_nl_nested_spec_t *nest = spec->auxdata;
|
||||
+ uc_value_t *nested_obj;
|
||||
+@@ -1227,13 +1232,13 @@ uc_nl_convert_rta_nested(const uc_nl_att
|
||||
+ if (!nest)
|
||||
+ return NULL;
|
||||
+
|
||||
+- if (!nla_check_len(tb[spec->attr], nest->headsize))
|
||||
++ if (!nla_check_len(attr, nest->headsize))
|
||||
+ return NULL;
|
||||
+
|
||||
+ nested_obj = ucv_object_new(vm);
|
||||
+
|
||||
+ rv = uc_nl_convert_attrs(msg,
|
||||
+- nla_data(tb[spec->attr]), nla_len(tb[spec->attr]), nest->headsize,
|
||||
++ nla_data(attr), nla_len(attr), nest->headsize,
|
||||
+ nest->attrs, nest->nattrs,
|
||||
+ vm, nested_obj);
|
||||
+
|
||||
+@@ -1247,17 +1252,17 @@ uc_nl_convert_rta_nested(const uc_nl_att
|
||||
+ }
|
||||
+
|
||||
+ static uc_value_t *
|
||||
+-uc_nl_convert_rta_ht_mcs(const uc_nl_attr_spec_t *spec, struct nl_msg *msg, struct nlattr **tb, uc_vm_t *vm)
|
||||
++uc_nl_convert_rta_ht_mcs(const uc_nl_attr_spec_t *spec, struct nl_msg *msg, struct nlattr *attr, uc_vm_t *vm)
|
||||
+ {
|
||||
+ uc_value_t *mcs_obj, *mcs_idx;
|
||||
+ uint16_t max_rate = 0;
|
||||
+ uint8_t *mcs;
|
||||
+ size_t i;
|
||||
+
|
||||
+- if (!nla_check_len(tb[spec->attr], 16))
|
||||
++ if (!nla_check_len(attr, 16))
|
||||
+ return NULL;
|
||||
+
|
||||
+- mcs = nla_data(tb[spec->attr]);
|
||||
++ mcs = nla_data(attr);
|
||||
+ mcs_obj = ucv_object_new(vm);
|
||||
+
|
||||
+ max_rate = (mcs[10] | ((mcs[11] & 0x3) << 8));
|
||||
+@@ -1282,16 +1287,16 @@ uc_nl_convert_rta_ht_mcs(const uc_nl_att
|
||||
+ }
|
||||
+
|
||||
+ static uc_value_t *
|
||||
+-uc_nl_convert_rta_ht_cap(const uc_nl_attr_spec_t *spec, struct nl_msg *msg, struct nlattr **tb, uc_vm_t *vm)
|
||||
++uc_nl_convert_rta_ht_cap(const uc_nl_attr_spec_t *spec, struct nl_msg *msg, struct nlattr *attr, uc_vm_t *vm)
|
||||
+ {
|
||||
+ uc_value_t *cap_obj, *mcs_obj, *rx_mask;
|
||||
+ struct ieee80211_ht_cap *cap;
|
||||
+ size_t i;
|
||||
+
|
||||
+- if (!nla_check_len(tb[spec->attr], sizeof(*cap)))
|
||||
++ if (!nla_check_len(attr, sizeof(*cap)))
|
||||
+ return NULL;
|
||||
+
|
||||
+- cap = nla_data(tb[spec->attr]);
|
||||
++ cap = nla_data(attr);
|
||||
+ cap_obj = ucv_object_new(vm);
|
||||
+
|
||||
+ ucv_object_add(cap_obj, "cap_info", ucv_uint64_new(le16toh(cap->cap_info)));
|
||||
+@@ -1316,17 +1321,17 @@ uc_nl_convert_rta_ht_cap(const uc_nl_att
|
||||
+ }
|
||||
+
|
||||
+ static uc_value_t *
|
||||
+-uc_nl_convert_rta_vht_mcs(const uc_nl_attr_spec_t *spec, struct nl_msg *msg, struct nlattr **tb, uc_vm_t *vm)
|
||||
++uc_nl_convert_rta_vht_mcs(const uc_nl_attr_spec_t *spec, struct nl_msg *msg, struct nlattr *attr, uc_vm_t *vm)
|
||||
+ {
|
||||
+ uc_value_t *mcs_obj, *mcs_set, *mcs_entry, *mcs_idx;
|
||||
+ size_t i, j, max_idx;
|
||||
+ uint16_t u16;
|
||||
+ uint8_t *mcs;
|
||||
+
|
||||
+- if (!nla_check_len(tb[spec->attr], 8))
|
||||
++ if (!nla_check_len(attr, 8))
|
||||
+ return NULL;
|
||||
+
|
||||
+- mcs = nla_data(tb[spec->attr]);
|
||||
++ mcs = nla_data(attr);
|
||||
+ mcs_obj = ucv_object_new(vm);
|
||||
+
|
||||
+ u16 = mcs[0] | (mcs[1] << 8);
|
||||
+@@ -1387,7 +1392,7 @@ uc_nl_convert_rta_vht_mcs(const uc_nl_at
|
||||
+ }
|
||||
+
|
||||
+ static uc_value_t *
|
||||
+-uc_nl_convert_rta_he_mcs(const uc_nl_attr_spec_t *spec, struct nl_msg *msg, struct nlattr **tb, uc_vm_t *vm)
|
||||
++uc_nl_convert_rta_he_mcs(const uc_nl_attr_spec_t *spec, struct nl_msg *msg, struct nlattr *attr, struct nlattr *phy_attr, uc_vm_t *vm)
|
||||
+ {
|
||||
+ uint8_t bw_support_mask[] = { (1 << 1) | (1 << 2), (1 << 3), (1 << 4) };
|
||||
+ uc_value_t *mcs_set, *mcs_bw, *mcs_dir, *mcs_entry, *mcs_idx;
|
||||
+@@ -1395,13 +1400,13 @@ uc_nl_convert_rta_he_mcs(const uc_nl_att
|
||||
+ uint16_t u16, phy_cap_0 = 0;
|
||||
+ size_t i, j, k, l, max_idx;
|
||||
+
|
||||
+- if (!nla_check_len(tb[spec->attr], sizeof(mcs)))
|
||||
++ if (!nla_check_len(attr, sizeof(mcs)))
|
||||
+ return NULL;
|
||||
+
|
||||
+- if (nla_check_len(tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_PHY], sizeof(phy_cap_0)))
|
||||
+- phy_cap_0 = nla_get_u16(tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_PHY]);
|
||||
++ if (nla_check_len(phy_attr, sizeof(phy_cap_0)))
|
||||
++ phy_cap_0 = nla_get_u16(phy_attr);
|
||||
+
|
||||
+- memcpy(mcs, nla_data(tb[spec->attr]), sizeof(mcs));
|
||||
++ memcpy(mcs, nla_data(attr), sizeof(mcs));
|
||||
+
|
||||
+ mcs_set = ucv_array_new_length(vm, 3);
|
||||
+
|
||||
+@@ -1458,14 +1463,14 @@ uc_nl_convert_rta_he_mcs(const uc_nl_att
|
||||
+ }
|
||||
+
|
||||
+ static uc_value_t *
|
||||
+-uc_nl_convert_rta_ie(const uc_nl_attr_spec_t *spec, struct nl_msg *msg, struct nlattr **tb, uc_vm_t *vm)
|
||||
++uc_nl_convert_rta_ie(const uc_nl_attr_spec_t *spec, struct nl_msg *msg, struct nlattr *attr, uc_vm_t *vm)
|
||||
+ {
|
||||
+ uc_value_t *ie_arr, *ie_obj;
|
||||
+ uint8_t *ie;
|
||||
+ size_t len;
|
||||
+
|
||||
+- len = nla_len(tb[spec->attr]);
|
||||
+- ie = nla_data(tb[spec->attr]);
|
||||
++ len = nla_len(attr);
|
||||
++ ie = nla_data(attr);
|
||||
+
|
||||
+ if (len < 2)
|
||||
+ return NULL;
|
||||
+@@ -1734,7 +1739,7 @@ uc_nl_convert_numval(const uc_nl_attr_sp
|
||||
+ }
|
||||
+
|
||||
+ static uc_value_t *
|
||||
+-uc_nl_convert_attr(const uc_nl_attr_spec_t *spec, struct nl_msg *msg, char *base, struct nlattr **tb, uc_vm_t *vm)
|
||||
++uc_nl_convert_attr(const uc_nl_attr_spec_t *spec, struct nl_msg *msg, char *base, struct nlattr *attr, struct nlattr *attr2, uc_vm_t *vm)
|
||||
+ {
|
||||
+ union { uint8_t u8; uint16_t u16; uint32_t u32; uint64_t u64; size_t sz; } t = { 0 };
|
||||
+ char buf[sizeof("FF:FF:FF:FF:FF:FF")];
|
||||
+@@ -1751,17 +1756,17 @@ uc_nl_convert_attr(const uc_nl_attr_spec
|
||||
+ case DT_U64:
|
||||
+ if (spec->flags & DF_ARRAY) {
|
||||
+ assert(spec->attr != 0);
|
||||
+- assert((nla_len(tb[spec->attr]) % dt_sizes[spec->type]) == 0);
|
||||
++ assert((nla_len(attr) % dt_sizes[spec->type]) == 0);
|
||||
+
|
||||
+- v = ucv_array_new_length(vm, nla_len(tb[spec->attr]) / dt_sizes[spec->type]);
|
||||
++ v = ucv_array_new_length(vm, nla_len(attr) / dt_sizes[spec->type]);
|
||||
+
|
||||
+- for (i = 0; i < nla_len(tb[spec->attr]); i += dt_sizes[spec->type])
|
||||
+- ucv_array_push(v, uc_nl_convert_numval(spec, nla_data(tb[spec->attr]) + i));
|
||||
++ for (i = 0; i < nla_len(attr); i += dt_sizes[spec->type])
|
||||
++ ucv_array_push(v, uc_nl_convert_numval(spec, nla_data(attr) + i));
|
||||
+
|
||||
+ return v;
|
||||
+ }
|
||||
+- else if (nla_check_len(tb[spec->attr], dt_sizes[spec->type])) {
|
||||
+- return uc_nl_convert_numval(spec, nla_data(tb[spec->attr]));
|
||||
++ else if (nla_check_len(attr, dt_sizes[spec->type])) {
|
||||
++ return uc_nl_convert_numval(spec, nla_data(attr));
|
||||
+ }
|
||||
+
|
||||
+ return NULL;
|
||||
+@@ -1769,15 +1774,15 @@ uc_nl_convert_attr(const uc_nl_attr_spec
|
||||
+ case DT_BOOL:
|
||||
+ if (spec->attr == 0)
|
||||
+ t.u8 = uc_nl_get_struct_member_u8(base, spec->auxdata);
|
||||
+- else if (nla_check_len(tb[spec->attr], sizeof(t.u8)))
|
||||
+- t.u8 = nla_get_u8(tb[spec->attr]);
|
||||
++ else if (nla_check_len(attr, sizeof(t.u8)))
|
||||
++ t.u8 = nla_get_u8(attr);
|
||||
+
|
||||
+ return ucv_boolean_new(t.u8 != 0);
|
||||
+
|
||||
+ case DT_FLAG:
|
||||
+ if (spec->attr == 0)
|
||||
+ t.u8 = uc_nl_get_struct_member_u8(base, spec->auxdata);
|
||||
+- else if (tb[spec->attr] != NULL)
|
||||
++ else if (attr != NULL)
|
||||
+ t.u8 = 1;
|
||||
+
|
||||
+ return ucv_boolean_new(t.u8 != 0);
|
||||
+@@ -1785,21 +1790,21 @@ uc_nl_convert_attr(const uc_nl_attr_spec
|
||||
+ case DT_STRING:
|
||||
+ assert(spec->attr != 0);
|
||||
+
|
||||
+- if (!nla_check_len(tb[spec->attr], 1))
|
||||
++ if (!nla_check_len(attr, 1))
|
||||
+ return NULL;
|
||||
+
|
||||
+- t.sz = nla_len(tb[spec->attr]);
|
||||
++ t.sz = nla_len(attr);
|
||||
+
|
||||
+ if (!(spec->flags & DF_BINARY))
|
||||
+ t.sz -= 1;
|
||||
+
|
||||
+- return ucv_string_new_length(nla_data(tb[spec->attr]), t.sz);
|
||||
++ return ucv_string_new_length(nla_data(attr), t.sz);
|
||||
+
|
||||
+ case DT_NETDEV:
|
||||
+ if (spec->attr == 0)
|
||||
+ t.u32 = uc_nl_get_struct_member_u32(base, spec->auxdata);
|
||||
+- else if (nla_check_len(tb[spec->attr], sizeof(t.u32)))
|
||||
+- t.u32 = nla_get_u32(tb[spec->attr]);
|
||||
++ else if (nla_check_len(attr, sizeof(t.u32)))
|
||||
++ t.u32 = nla_get_u32(attr);
|
||||
+
|
||||
+ if (if_indextoname(t.u32, buf))
|
||||
+ return ucv_string_new(buf);
|
||||
+@@ -1809,10 +1814,10 @@ uc_nl_convert_attr(const uc_nl_attr_spec
|
||||
+ case DT_LLADDR:
|
||||
+ assert(spec->attr != 0);
|
||||
+
|
||||
+- if (!nla_check_len(tb[spec->attr], sizeof(*ea)))
|
||||
++ if (!nla_check_len(attr, sizeof(*ea)))
|
||||
+ return NULL;
|
||||
+
|
||||
+- ea = nla_data(tb[spec->attr]);
|
||||
++ ea = nla_data(attr);
|
||||
+
|
||||
+ snprintf(buf, sizeof(buf), "%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
+ ea->ether_addr_octet[0], ea->ether_addr_octet[1],
|
||||
+@@ -1824,29 +1829,29 @@ uc_nl_convert_attr(const uc_nl_attr_spec
|
||||
+ case DT_INADDR:
|
||||
+ assert(spec->attr != 0);
|
||||
+
|
||||
+- if (!nla_check_len(tb[spec->attr], sizeof(struct in_addr)) ||
|
||||
+- !inet_ntop(AF_INET, nla_data(tb[spec->attr]), buf, sizeof(buf)))
|
||||
++ if (!nla_check_len(attr, sizeof(struct in_addr)) ||
|
||||
++ !inet_ntop(AF_INET, nla_data(attr), buf, sizeof(buf)))
|
||||
+ return NULL;
|
||||
+
|
||||
+ return ucv_string_new(buf);
|
||||
+
|
||||
+ case DT_NESTED:
|
||||
+- return uc_nl_convert_rta_nested(spec, msg, tb, vm);
|
||||
++ return uc_nl_convert_rta_nested(spec, msg, attr, vm);
|
||||
+
|
||||
+ case DT_HT_MCS:
|
||||
+- return uc_nl_convert_rta_ht_mcs(spec, msg, tb, vm);
|
||||
++ return uc_nl_convert_rta_ht_mcs(spec, msg, attr, vm);
|
||||
+
|
||||
+ case DT_HT_CAP:
|
||||
+- return uc_nl_convert_rta_ht_cap(spec, msg, tb, vm);
|
||||
++ return uc_nl_convert_rta_ht_cap(spec, msg, attr, vm);
|
||||
+
|
||||
+ case DT_VHT_MCS:
|
||||
+- return uc_nl_convert_rta_vht_mcs(spec, msg, tb, vm);
|
||||
++ return uc_nl_convert_rta_vht_mcs(spec, msg, attr, vm);
|
||||
+
|
||||
+ case DT_HE_MCS:
|
||||
+- return uc_nl_convert_rta_he_mcs(spec, msg, tb, vm);
|
||||
++ return uc_nl_convert_rta_he_mcs(spec, msg, attr, attr2, vm);
|
||||
+
|
||||
+ case DT_IE:
|
||||
+- return uc_nl_convert_rta_ie(spec, msg, tb, vm);
|
||||
++ return uc_nl_convert_rta_ie(spec, msg, attr, vm);
|
||||
+
|
||||
+ default:
|
||||
+ assert(0);
|
||||
diff --git a/package/utils/ucode/patches/111-nl80211-add-support-for-multi-attribute-arrays.patch b/package/utils/ucode/patches/111-nl80211-add-support-for-multi-attribute-arrays.patch
|
||||
new file mode 100644
|
||||
index 0000000000..517d882850
|
||||
--- /dev/null
|
||||
+++ b/package/utils/ucode/patches/111-nl80211-add-support-for-multi-attribute-arrays.patch
|
||||
@@ -0,0 +1,94 @@
|
||||
+From: Felix Fietkau <nbd@nbd.name>
|
||||
+Date: Sat, 29 Jun 2024 12:05:29 +0200
|
||||
+Subject: [PATCH] nl80211: add support for multi-attribute arrays
|
||||
+
|
||||
+For newly added attributes, the kernel prefers to no longer add a nesting
|
||||
+container attribute. Instead, an attribute with the element type is simply
|
||||
+added multiple times within the outer container.
|
||||
+Add support for this array style, which will be used in the pending wiphy
|
||||
+multi radio support.
|
||||
+
|
||||
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
+---
|
||||
+
|
||||
+--- a/lib/nl80211.c
|
||||
++++ b/lib/nl80211.c
|
||||
+@@ -198,6 +198,7 @@ enum {
|
||||
+ DF_ARRAY = (1 << 5),
|
||||
+ DF_BINARY = (1 << 6),
|
||||
+ DF_RELATED = (1 << 7),
|
||||
++ DF_REPEATED = (1 << 8),
|
||||
+ };
|
||||
+
|
||||
+ typedef struct uc_nl_attr_spec {
|
||||
+@@ -1043,26 +1044,6 @@ uc_nl_get_struct_member_u32(char *base,
|
||||
+ return u32;
|
||||
+ }
|
||||
+
|
||||
+-static void
|
||||
+-uc_nl_nla_parse(struct nlattr *tb[], int maxtype, struct nlattr *head, int len)
|
||||
+-{
|
||||
+- struct nlattr *nla;
|
||||
+- int rem;
|
||||
+-
|
||||
+- memset(tb, 0, sizeof(struct nlattr *) * (maxtype + 1));
|
||||
+-
|
||||
+- nla_for_each_attr(nla, head, len, rem) {
|
||||
+- int type = nla_type(nla);
|
||||
+-
|
||||
+- if (type <= maxtype)
|
||||
+- tb[type] = nla;
|
||||
+- }
|
||||
+-
|
||||
+- if (rem > 0)
|
||||
+- fprintf(stderr, "netlink: %d bytes leftover after parsing attributes.\n", rem);
|
||||
+-}
|
||||
+-
|
||||
+-
|
||||
+ static bool
|
||||
+ uc_nl_parse_attr(const uc_nl_attr_spec_t *spec, struct nl_msg *msg, char *base, uc_vm_t *vm, uc_value_t *val, size_t idx);
|
||||
+
|
||||
+@@ -1086,12 +1067,10 @@ uc_nl_convert_attrs(struct nl_msg *msg,
|
||||
+ if (!tb)
|
||||
+ return false;
|
||||
+
|
||||
+- uc_nl_nla_parse(tb, maxattr, buf + headsize, buflen - headsize);
|
||||
+-
|
||||
+ nla_for_each_attr(nla, buf + headsize, buflen - headsize, rem) {
|
||||
+ type = nla_type(nla);
|
||||
+
|
||||
+- if (type <= maxattr)
|
||||
++ if (type <= maxattr && !tb[type])
|
||||
+ tb[type] = nla;
|
||||
+ }
|
||||
+
|
||||
+@@ -1099,7 +1078,28 @@ uc_nl_convert_attrs(struct nl_msg *msg,
|
||||
+ if (attrs[i].attr != 0 && !tb[attrs[i].attr])
|
||||
+ continue;
|
||||
+
|
||||
+- if (attrs[i].flags & DF_MULTIPLE) {
|
||||
++ if (attrs[i].flags & DF_REPEATED) {
|
||||
++ arr = ucv_array_new(vm);
|
||||
++
|
||||
++ nla = tb[attrs[i].attr];
|
||||
++ rem = buflen - ((void *)nla - buf);
|
||||
++ for (; nla_ok(nla, rem); nla = nla_next(nla, &rem)) {
|
||||
++ if (nla_type(nla) != (int)attrs[i].attr)
|
||||
++ break;
|
||||
++ v = uc_nl_convert_attr(&attrs[i], msg, (char *)buf, nla, NULL, vm);
|
||||
++ if (!v)
|
||||
++ continue;
|
||||
++
|
||||
++ ucv_array_push(arr, v);
|
||||
++ }
|
||||
++ if (!ucv_array_length(arr)) {
|
||||
++ ucv_put(arr);
|
||||
++ continue;
|
||||
++ }
|
||||
++
|
||||
++ v = arr;
|
||||
++ }
|
||||
++ else if (attrs[i].flags & DF_MULTIPLE) {
|
||||
+ arr = ucv_array_new(vm);
|
||||
+ nla_nest = tb[attrs[i].attr];
|
||||
+
|
||||
diff --git a/package/utils/ucode/patches/112-nl80211-add-wiphy-multi-radio-support.patch b/package/utils/ucode/patches/112-nl80211-add-wiphy-multi-radio-support.patch
|
||||
new file mode 100644
|
||||
index 0000000000..588e9a5e72
|
||||
--- /dev/null
|
||||
+++ b/package/utils/ucode/patches/112-nl80211-add-wiphy-multi-radio-support.patch
|
||||
@@ -0,0 +1,50 @@
|
||||
+From: Felix Fietkau <nbd@nbd.name>
|
||||
+Date: Tue, 9 Jul 2024 17:53:30 +0200
|
||||
+Subject: [PATCH] nl80211: add wiphy multi-radio support
|
||||
+
|
||||
+Support new attributes that describe multiple radios belonging to a single
|
||||
+wiphy.
|
||||
+
|
||||
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
+---
|
||||
+
|
||||
+--- a/lib/nl80211.c
|
||||
++++ b/lib/nl80211.c
|
||||
+@@ -842,9 +842,28 @@ static const uc_nl_nested_spec_t nl80211
|
||||
+ }
|
||||
+ };
|
||||
+
|
||||
++static const uc_nl_nested_spec_t nl80211_radio_freq_range_nla = {
|
||||
++ .headsize = 0,
|
||||
++ .nattrs = 2,
|
||||
++ .attrs = {
|
||||
++ { NL80211_WIPHY_RADIO_FREQ_ATTR_START, "start", DT_U32, 0, NULL },
|
||||
++ { NL80211_WIPHY_RADIO_FREQ_ATTR_END, "end", DT_U32, 0, NULL },
|
||||
++ }
|
||||
++};
|
||||
++
|
||||
++static const uc_nl_nested_spec_t nl80211_wiphy_radio_nla = {
|
||||
++ .headsize = 0,
|
||||
++ .nattrs = 3,
|
||||
++ .attrs = {
|
||||
++ { NL80211_WIPHY_RADIO_ATTR_INDEX, "index", DT_U32, 0, NULL },
|
||||
++ { NL80211_WIPHY_RADIO_ATTR_FREQ_RANGE, "freq_ranges", DT_NESTED, DF_REPEATED, &nl80211_radio_freq_range_nla },
|
||||
++ { NL80211_WIPHY_RADIO_ATTR_INTERFACE_COMBINATION, "interface_combinations", DT_NESTED, DF_REPEATED, &nl80211_ifcomb_nla },
|
||||
++ }
|
||||
++};
|
||||
++
|
||||
+ static const uc_nl_nested_spec_t nl80211_msg = {
|
||||
+ .headsize = 0,
|
||||
+- .nattrs = 128,
|
||||
++ .nattrs = 129,
|
||||
+ .attrs = {
|
||||
+ { NL80211_ATTR_4ADDR, "4addr", DT_U8, 0, NULL },
|
||||
+ { NL80211_ATTR_AIRTIME_WEIGHT, "airtime_weight", DT_U16, 0, NULL },
|
||||
+@@ -974,6 +993,7 @@ static const uc_nl_nested_spec_t nl80211
|
||||
+ { NL80211_ATTR_SOFTWARE_IFTYPES, "software_iftypes", DT_NESTED, 0, &nl80211_ifcomb_limit_types_nla },
|
||||
+ { NL80211_ATTR_MAX_AP_ASSOC_STA, "max_ap_assoc", DT_U16, 0, NULL },
|
||||
+ { NL80211_ATTR_SURVEY_INFO, "survey_info", DT_NESTED, 0, &nl80211_survey_info_nla },
|
||||
++ { NL80211_ATTR_WIPHY_RADIOS, "radios", DT_NESTED, DF_MULTIPLE|DF_AUTOIDX, &nl80211_wiphy_radio_nla },
|
||||
+ }
|
||||
+ };
|
||||
+
|
||||
diff --git a/package/utils/ucode/patches/113-nl80211-add-new-attributes-for-multi-radio-support.patch b/package/utils/ucode/patches/113-nl80211-add-new-attributes-for-multi-radio-support.patch
|
||||
new file mode 100644
|
||||
index 0000000000..15e5047510
|
||||
--- /dev/null
|
||||
+++ b/package/utils/ucode/patches/113-nl80211-add-new-attributes-for-multi-radio-support.patch
|
||||
@@ -0,0 +1,30 @@
|
||||
+From: Felix Fietkau <nbd@nbd.name>
|
||||
+Date: Wed, 23 Oct 2024 18:50:10 +0200
|
||||
+Subject: [PATCH] nl80211: add new attributes for multi-radio support
|
||||
+
|
||||
+- vif radio mask: used to assign vifs to specific radios
|
||||
+- monitor skip_tx flag: do not pass locally transmitted packets on the monitor interface
|
||||
+- radio antenna mask: radio specific part of the phy antenna mask
|
||||
+
|
||||
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
+---
|
||||
+
|
||||
+--- a/lib/nl80211.c
|
||||
++++ b/lib/nl80211.c
|
||||
+@@ -863,7 +863,7 @@ static const uc_nl_nested_spec_t nl80211
|
||||
+
|
||||
+ static const uc_nl_nested_spec_t nl80211_msg = {
|
||||
+ .headsize = 0,
|
||||
+- .nattrs = 129,
|
||||
++ .nattrs = 130,
|
||||
+ .attrs = {
|
||||
+ { NL80211_ATTR_4ADDR, "4addr", DT_U8, 0, NULL },
|
||||
+ { NL80211_ATTR_AIRTIME_WEIGHT, "airtime_weight", DT_U16, 0, NULL },
|
||||
+@@ -994,6 +994,7 @@ static const uc_nl_nested_spec_t nl80211
|
||||
+ { NL80211_ATTR_MAX_AP_ASSOC_STA, "max_ap_assoc", DT_U16, 0, NULL },
|
||||
+ { NL80211_ATTR_SURVEY_INFO, "survey_info", DT_NESTED, 0, &nl80211_survey_info_nla },
|
||||
+ { NL80211_ATTR_WIPHY_RADIOS, "radios", DT_NESTED, DF_MULTIPLE|DF_AUTOIDX, &nl80211_wiphy_radio_nla },
|
||||
++ { NL80211_ATTR_VIF_RADIO_MASK, "vif_radio_mask", DT_U32, 0, NULL },
|
||||
+ }
|
||||
+ };
|
||||
+
|
||||
--
|
||||
2.34.1
|
||||
|
||||
Reference in New Issue
Block a user