Merge Official Source
Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
This commit is contained in:
commit
cb3b41ef89
@ -77,7 +77,7 @@ SQUASHFSOPT := -b $(SQUASHFS_BLOCKSIZE)
|
||||
SQUASHFSOPT += -p '/dev d 755 0 0' -p '/dev/console c 600 0 0 5 1'
|
||||
SQUASHFSOPT += $(if $(CONFIG_SELINUX),-xattrs,-no-xattrs)
|
||||
SQUASHFSCOMP := gzip
|
||||
LZMA_XZ_OPTIONS := -Xpreset 9 -Xe -Xlc 0 -Xlp 2 -Xpb 2
|
||||
LZMA_XZ_OPTIONS := -Xpreset extreme -Xlc 0 -Xlp 2 -Xpb 2
|
||||
ifeq ($(CONFIG_SQUASHFS_XZ),y)
|
||||
ifneq ($(filter arm x86 powerpc sparc,$(LINUX_KARCH)),)
|
||||
BCJ_FILTER:=-Xbcj $(LINUX_KARCH)
|
||||
|
@ -1,8 +1,8 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
#
|
||||
# Copyright (C) 2022 Enéas Ulir de Queiroz
|
||||
# Copyright (C) 2022-2023 Enéas Ulir de Queiroz
|
||||
|
||||
ENGINES_DIR=engines-1.1
|
||||
ENGINES_DIR=engines-3
|
||||
|
||||
define Package/openssl/engine/Default
|
||||
SECTION:=libs
|
||||
|
@ -8,23 +8,33 @@ RTC_DEV=/dev/rtc0
|
||||
HWCLOCK=/sbin/hwclock
|
||||
|
||||
boot() {
|
||||
start && exit 0
|
||||
|
||||
local maxtime="$(maxtime)"
|
||||
hwclock_load
|
||||
local maxtime="$(find_max_time)"
|
||||
local curtime="$(date +%s)"
|
||||
[ $curtime -lt $maxtime ] && date -s @$maxtime
|
||||
if [ $curtime -lt $maxtime ]; then
|
||||
date -s @$maxtime
|
||||
hwclock_save
|
||||
fi
|
||||
}
|
||||
|
||||
start() {
|
||||
[ -e "$RTC_DEV" ] && [ -e "$HWCLOCK" ] && $HWCLOCK -s -u -f $RTC_DEV
|
||||
hwclock_load
|
||||
}
|
||||
|
||||
stop() {
|
||||
hwclock_save
|
||||
}
|
||||
|
||||
hwclock_load() {
|
||||
[ -e "$RTC_DEV" ] && [ -e "$HWCLOCK" ] && $HWCLOCK -s -u -f $RTC_DEV
|
||||
}
|
||||
|
||||
hwclock_save(){
|
||||
[ -e "$RTC_DEV" ] && [ -e "$HWCLOCK" ] && $HWCLOCK -w -u -f $RTC_DEV && \
|
||||
logger -t sysfixtime "saved '$(date)' to $RTC_DEV"
|
||||
}
|
||||
|
||||
maxtime() {
|
||||
find_max_time() {
|
||||
local file newest
|
||||
|
||||
for file in $( find /etc -type f ) ; do
|
||||
|
@ -0,0 +1,35 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Wed, 15 Feb 2023 15:11:54 +0100
|
||||
Subject: [PATCH] wifi: mac80211: fix qos on mesh interfaces
|
||||
|
||||
When ieee80211_select_queue is called for mesh, the sta pointer is usually
|
||||
NULL, since the nexthop is looked up much later in the tx path.
|
||||
Explicitly check for unicast address in that case in order to make qos work
|
||||
again.
|
||||
|
||||
Fixes: 50e2ab392919 ("wifi: mac80211: fix queue selection for mesh/OCB interfaces")
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/wme.c
|
||||
+++ b/net/mac80211/wme.c
|
||||
@@ -147,6 +147,7 @@ u16 ieee80211_select_queue_80211(struct
|
||||
u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
|
||||
struct sta_info *sta, struct sk_buff *skb)
|
||||
{
|
||||
+ const struct ethhdr *eth = (void *)skb->data;
|
||||
struct mac80211_qos_map *qos_map;
|
||||
bool qos;
|
||||
|
||||
@@ -154,8 +155,9 @@ u16 ieee80211_select_queue(struct ieee80
|
||||
skb_get_hash(skb);
|
||||
|
||||
/* all mesh/ocb stations are required to support WME */
|
||||
- if (sta && (sdata->vif.type == NL80211_IFTYPE_MESH_POINT ||
|
||||
- sdata->vif.type == NL80211_IFTYPE_OCB))
|
||||
+ if ((sdata->vif.type == NL80211_IFTYPE_MESH_POINT &&
|
||||
+ !is_multicast_ether_addr(eth->h_dest)) ||
|
||||
+ (sdata->vif.type == NL80211_IFTYPE_OCB && sta))
|
||||
qos = true;
|
||||
else if (sta)
|
||||
qos = sta->sta.wme;
|
@ -0,0 +1,37 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Wed, 15 Feb 2023 15:21:37 +0100
|
||||
Subject: [PATCH] wifi: mac80211: fix race in mesh sequence number
|
||||
assignment
|
||||
|
||||
Since the sequence number is shared across different tx queues, it needs
|
||||
to be atomic in order to avoid accidental duplicate assignment
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/ieee80211_i.h
|
||||
+++ b/net/mac80211/ieee80211_i.h
|
||||
@@ -695,7 +695,7 @@ struct ieee80211_if_mesh {
|
||||
struct mesh_stats mshstats;
|
||||
struct mesh_config mshcfg;
|
||||
atomic_t estab_plinks;
|
||||
- u32 mesh_seqnum;
|
||||
+ atomic_t mesh_seqnum;
|
||||
bool accepting_plinks;
|
||||
int num_gates;
|
||||
struct beacon_data __rcu *beacon;
|
||||
--- a/net/mac80211/mesh.c
|
||||
+++ b/net/mac80211/mesh.c
|
||||
@@ -752,10 +752,8 @@ unsigned int ieee80211_new_mesh_header(s
|
||||
|
||||
meshhdr->ttl = sdata->u.mesh.mshcfg.dot11MeshTTL;
|
||||
|
||||
- /* FIXME: racy -- TX on multiple queues can be concurrent */
|
||||
- put_unaligned(cpu_to_le32(sdata->u.mesh.mesh_seqnum), &meshhdr->seqnum);
|
||||
- sdata->u.mesh.mesh_seqnum++;
|
||||
-
|
||||
+ put_unaligned_le32(atomic_inc_return(&sdata->u.mesh.mesh_seqnum),
|
||||
+ &meshhdr->seqnum);
|
||||
if (addr4or5 && !addr6) {
|
||||
meshhdr->flags |= MESH_FLAGS_AE_A4;
|
||||
memcpy(meshhdr->eaddr1, addr4or5, ETH_ALEN);
|
@ -0,0 +1,764 @@
|
||||
From: Sriram R <quic_srirrama@quicinc.com>
|
||||
Date: Thu, 18 Aug 2022 12:35:42 +0530
|
||||
Subject: [PATCH] wifi: mac80211: mesh fast xmit support
|
||||
|
||||
Currently fast xmit is supported in AP, STA and other device types where
|
||||
the destination doesn't change for the lifetime of its association by
|
||||
caching the static parts of the header that can be reused directly for
|
||||
every Tx such as addresses and updates only mutable header fields such as
|
||||
PN.
|
||||
This technique is not directly applicable for a Mesh device type due
|
||||
to the dynamic nature of the topology and protocol. The header is built
|
||||
based on the destination mesh device which is proxying a certain external
|
||||
device and based on the Mesh destination the next hop changes.
|
||||
And the RA/A1 which is the next hop for reaching the destination can
|
||||
vary during runtime as per the best route based on airtime. To accommodate
|
||||
these changes and to come up with a solution to avoid overhead during header
|
||||
generation, the headers comprising the MAC, Mesh and LLC part are cached
|
||||
whenever data for a certain external destination is sent.
|
||||
This cached header is reused every time a data is sent to that external
|
||||
destination.
|
||||
|
||||
To ensure the changes in network are reflected in these cached headers,
|
||||
flush affected cached entries on path changes, as well as other conditions
|
||||
that currently trigger a fast xmit check in other modes (key changes etc.)
|
||||
|
||||
In order to keep the cache small, use a short timeout for expiring cache
|
||||
entries.
|
||||
|
||||
Co-developed-by: Felix Fietkau <nbd@nbd.name>
|
||||
Signed-off-by: Sriram R <quic_srirrama@quicinc.com>
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/ieee80211_i.h
|
||||
+++ b/net/mac80211/ieee80211_i.h
|
||||
@@ -37,6 +37,7 @@
|
||||
extern const struct cfg80211_ops mac80211_config_ops;
|
||||
|
||||
struct ieee80211_local;
|
||||
+struct mhdr_cache_entry;
|
||||
|
||||
/* Maximum number of broadcast/multicast frames to buffer when some of the
|
||||
* associated stations are using power saving. */
|
||||
@@ -655,6 +656,20 @@ struct mesh_table {
|
||||
atomic_t entries; /* Up to MAX_MESH_NEIGHBOURS */
|
||||
};
|
||||
|
||||
+/**
|
||||
+ * struct mesh_hdr_cache - mesh fast xmit header cache
|
||||
+ *
|
||||
+ * @rhead: hash table containing struct mhdr_cache_entry, using skb DA as key
|
||||
+ * @walk_head: linked list containing all mhdr_cache_entry objects
|
||||
+ * @walk_lock: lock protecting walk_head and rhead
|
||||
+ * @enabled: indicates if header cache is initialized
|
||||
+ */
|
||||
+struct mesh_hdr_cache {
|
||||
+ struct rhashtable rhead;
|
||||
+ struct hlist_head walk_head;
|
||||
+ spinlock_t walk_lock;
|
||||
+};
|
||||
+
|
||||
struct ieee80211_if_mesh {
|
||||
struct timer_list housekeeping_timer;
|
||||
struct timer_list mesh_path_timer;
|
||||
@@ -733,6 +748,7 @@ struct ieee80211_if_mesh {
|
||||
struct mesh_table mpp_paths; /* Store paths for MPP&MAP */
|
||||
int mesh_paths_generation;
|
||||
int mpp_paths_generation;
|
||||
+ struct mesh_hdr_cache hdr_cache;
|
||||
};
|
||||
|
||||
#ifdef CPTCFG_MAC80211_MESH
|
||||
@@ -1998,6 +2014,9 @@ int ieee80211_tx_control_port(struct wip
|
||||
int link_id, u64 *cookie);
|
||||
int ieee80211_probe_mesh_link(struct wiphy *wiphy, struct net_device *dev,
|
||||
const u8 *buf, size_t len);
|
||||
+void __ieee80211_mesh_xmit_fast(struct ieee80211_sub_if_data *sdata,
|
||||
+ struct mhdr_cache_entry *entry,
|
||||
+ struct sk_buff *skb);
|
||||
|
||||
/* HT */
|
||||
void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata,
|
||||
--- a/net/mac80211/mesh.c
|
||||
+++ b/net/mac80211/mesh.c
|
||||
@@ -780,6 +780,8 @@ static void ieee80211_mesh_housekeeping(
|
||||
changed = mesh_accept_plinks_update(sdata);
|
||||
ieee80211_mbss_info_change_notify(sdata, changed);
|
||||
|
||||
+ mesh_hdr_cache_gc(sdata);
|
||||
+
|
||||
mod_timer(&ifmsh->housekeeping_timer,
|
||||
round_jiffies(jiffies +
|
||||
IEEE80211_MESH_HOUSEKEEPING_INTERVAL));
|
||||
--- a/net/mac80211/mesh.h
|
||||
+++ b/net/mac80211/mesh.h
|
||||
@@ -122,11 +122,49 @@ struct mesh_path {
|
||||
u8 rann_snd_addr[ETH_ALEN];
|
||||
u32 rann_metric;
|
||||
unsigned long last_preq_to_root;
|
||||
+ unsigned long fast_xmit_check;
|
||||
bool is_root;
|
||||
bool is_gate;
|
||||
u32 path_change_count;
|
||||
};
|
||||
|
||||
+#define MESH_HEADER_CACHE_MAX_SIZE 512
|
||||
+#define MESH_HEADER_CACHE_THRESHOLD_SIZE 384
|
||||
+#define MESH_HEADER_CACHE_TIMEOUT 8000 /* msecs */
|
||||
+#define MESH_HEADER_MAX_LEN 68 /* mac+mesh+rfc1042 hdr */
|
||||
+
|
||||
+/**
|
||||
+ * struct mhdr_cache_entry - Cached Mesh header entry
|
||||
+ * @addr_key: The Ethernet DA which is the key for this entry
|
||||
+ * @hdr: The cached header
|
||||
+ * @machdr_len: Total length of the mac header
|
||||
+ * @hdrlen: Length of this header entry
|
||||
+ * @key: Key corresponding to the nexthop stored in the header
|
||||
+ * @pn_offs: Offset to PN which is updated for every xmit
|
||||
+ * @band: band used for tx
|
||||
+ * @walk_list: list containing all the cached header entries
|
||||
+ * @rhash: rhashtable pointer
|
||||
+ * @mpath: The Mesh path corresponding to the Mesh DA
|
||||
+ * @mppath: The MPP entry corresponding to this DA
|
||||
+ * @timestamp: Last used time of this entry
|
||||
+ * @rcu: rcu to free this entry
|
||||
+ * @path_change_count: Stored path change value corresponding to the mpath
|
||||
+ */
|
||||
+struct mhdr_cache_entry {
|
||||
+ u8 addr_key[ETH_ALEN] __aligned(2);
|
||||
+ u8 hdr[MESH_HEADER_MAX_LEN];
|
||||
+ u16 machdr_len;
|
||||
+ u16 hdrlen;
|
||||
+ u8 pn_offs;
|
||||
+ u8 band;
|
||||
+ struct ieee80211_key __rcu *key;
|
||||
+ struct hlist_node walk_list;
|
||||
+ struct rhash_head rhash;
|
||||
+ struct mesh_path *mpath, *mppath;
|
||||
+ unsigned long timestamp;
|
||||
+ struct rcu_head rcu;
|
||||
+};
|
||||
+
|
||||
/* Recent multicast cache */
|
||||
/* RMC_BUCKETS must be a power of 2, maximum 256 */
|
||||
#define RMC_BUCKETS 256
|
||||
@@ -298,6 +336,15 @@ void mesh_path_discard_frame(struct ieee
|
||||
void mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata);
|
||||
|
||||
bool mesh_action_is_path_sel(struct ieee80211_mgmt *mgmt);
|
||||
+struct mhdr_cache_entry *
|
||||
+mesh_get_cached_hdr(struct ieee80211_sub_if_data *sdata, const u8 *addr);
|
||||
+void mesh_cache_hdr(struct ieee80211_sub_if_data *sdata,
|
||||
+ struct sk_buff *skb, struct mesh_path *mpath);
|
||||
+void mesh_hdr_cache_gc(struct ieee80211_sub_if_data *sdata);
|
||||
+void mesh_hdr_cache_flush(struct ieee80211_sub_if_data *sdata, const u8 *addr,
|
||||
+ bool is_mpp);
|
||||
+void mesh_refresh_path(struct ieee80211_sub_if_data *sdata,
|
||||
+ struct mesh_path *mpath, const u8 *addr);
|
||||
|
||||
#ifdef CPTCFG_MAC80211_MESH
|
||||
static inline
|
||||
--- a/net/mac80211/mesh_hwmp.c
|
||||
+++ b/net/mac80211/mesh_hwmp.c
|
||||
@@ -491,8 +491,11 @@ static u32 hwmp_route_info_get(struct ie
|
||||
}
|
||||
|
||||
if (fresh_info) {
|
||||
- if (rcu_access_pointer(mpath->next_hop) != sta)
|
||||
+ if (rcu_access_pointer(mpath->next_hop) != sta) {
|
||||
mpath->path_change_count++;
|
||||
+ mesh_hdr_cache_flush(mpath->sdata, mpath->dst,
|
||||
+ false);
|
||||
+ }
|
||||
mesh_path_assign_nexthop(mpath, sta);
|
||||
mpath->flags |= MESH_PATH_SN_VALID;
|
||||
mpath->metric = new_metric;
|
||||
@@ -539,8 +542,11 @@ static u32 hwmp_route_info_get(struct ie
|
||||
}
|
||||
|
||||
if (fresh_info) {
|
||||
- if (rcu_access_pointer(mpath->next_hop) != sta)
|
||||
+ if (rcu_access_pointer(mpath->next_hop) != sta) {
|
||||
mpath->path_change_count++;
|
||||
+ mesh_hdr_cache_flush(mpath->sdata, mpath->dst,
|
||||
+ false);
|
||||
+ }
|
||||
mesh_path_assign_nexthop(mpath, sta);
|
||||
mpath->metric = last_hop_metric;
|
||||
mpath->exp_time = time_after(mpath->exp_time, exp_time)
|
||||
@@ -977,7 +983,7 @@ free:
|
||||
* Locking: the function must be called from within a rcu read lock block.
|
||||
*
|
||||
*/
|
||||
-static void mesh_queue_preq(struct mesh_path *mpath, u8 flags)
|
||||
+void mesh_queue_preq(struct mesh_path *mpath, u8 flags)
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata = mpath->sdata;
|
||||
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
|
||||
@@ -1215,6 +1221,20 @@ static int mesh_nexthop_lookup_nolearn(s
|
||||
return 0;
|
||||
}
|
||||
|
||||
+void mesh_refresh_path(struct ieee80211_sub_if_data *sdata,
|
||||
+ struct mesh_path *mpath, const u8 *addr)
|
||||
+{
|
||||
+ if (mpath->flags & (MESH_PATH_REQ_QUEUED | MESH_PATH_FIXED |
|
||||
+ MESH_PATH_RESOLVING))
|
||||
+ return;
|
||||
+
|
||||
+ if (time_after(jiffies,
|
||||
+ mpath->exp_time -
|
||||
+ msecs_to_jiffies(sdata->u.mesh.mshcfg.path_refresh_time)) &&
|
||||
+ (!addr || ether_addr_equal(sdata->vif.addr, addr)))
|
||||
+ mesh_queue_preq(mpath, PREQ_Q_F_START | PREQ_Q_F_REFRESH);
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* mesh_nexthop_lookup - put the appropriate next hop on a mesh frame. Calling
|
||||
* this function is considered "using" the associated mpath, so preempt a path
|
||||
@@ -1242,19 +1262,18 @@ int mesh_nexthop_lookup(struct ieee80211
|
||||
if (!mpath || !(mpath->flags & MESH_PATH_ACTIVE))
|
||||
return -ENOENT;
|
||||
|
||||
- if (time_after(jiffies,
|
||||
- mpath->exp_time -
|
||||
- msecs_to_jiffies(sdata->u.mesh.mshcfg.path_refresh_time)) &&
|
||||
- ether_addr_equal(sdata->vif.addr, hdr->addr4) &&
|
||||
- !(mpath->flags & MESH_PATH_RESOLVING) &&
|
||||
- !(mpath->flags & MESH_PATH_FIXED))
|
||||
- mesh_queue_preq(mpath, PREQ_Q_F_START | PREQ_Q_F_REFRESH);
|
||||
+ mesh_refresh_path(sdata, mpath, hdr->addr4);
|
||||
|
||||
next_hop = rcu_dereference(mpath->next_hop);
|
||||
if (next_hop) {
|
||||
memcpy(hdr->addr1, next_hop->sta.addr, ETH_ALEN);
|
||||
memcpy(hdr->addr2, sdata->vif.addr, ETH_ALEN);
|
||||
ieee80211_mps_set_frame_flags(sdata, next_hop, hdr);
|
||||
+ /* Cache the whole header so as to use next time rather than resolving
|
||||
+ * and building it every time
|
||||
+ */
|
||||
+ if (ieee80211_hw_check(&sdata->local->hw, SUPPORT_FAST_XMIT))
|
||||
+ mesh_cache_hdr(sdata, skb, mpath);
|
||||
return 0;
|
||||
}
|
||||
|
||||
--- a/net/mac80211/mesh_pathtbl.c
|
||||
+++ b/net/mac80211/mesh_pathtbl.c
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "wme.h"
|
||||
#include "ieee80211_i.h"
|
||||
#include "mesh.h"
|
||||
+#include <linux/rhashtable.h>
|
||||
|
||||
static void mesh_path_free_rcu(struct mesh_table *tbl, struct mesh_path *mpath);
|
||||
|
||||
@@ -32,6 +33,41 @@ static const struct rhashtable_params me
|
||||
.hashfn = mesh_table_hash,
|
||||
};
|
||||
|
||||
+static const struct rhashtable_params mesh_hdr_rht_params = {
|
||||
+ .nelem_hint = 10,
|
||||
+ .automatic_shrinking = true,
|
||||
+ .key_len = ETH_ALEN,
|
||||
+ .key_offset = offsetof(struct mhdr_cache_entry, addr_key),
|
||||
+ .head_offset = offsetof(struct mhdr_cache_entry, rhash),
|
||||
+ .hashfn = mesh_table_hash,
|
||||
+};
|
||||
+
|
||||
+static void __mesh_hdr_cache_entry_free(void *ptr, void *tblptr)
|
||||
+{
|
||||
+ struct mhdr_cache_entry *mhdr = ptr;
|
||||
+
|
||||
+ kfree_rcu(mhdr, rcu);
|
||||
+}
|
||||
+
|
||||
+static void mesh_hdr_cache_deinit(struct ieee80211_sub_if_data *sdata)
|
||||
+{
|
||||
+ struct mesh_hdr_cache *cache;
|
||||
+
|
||||
+ cache = &sdata->u.mesh.hdr_cache;
|
||||
+ rhashtable_free_and_destroy(&cache->rhead,
|
||||
+ __mesh_hdr_cache_entry_free, NULL);
|
||||
+}
|
||||
+
|
||||
+static void mesh_hdr_cache_init(struct ieee80211_sub_if_data *sdata)
|
||||
+{
|
||||
+ struct mesh_hdr_cache *cache;
|
||||
+
|
||||
+ cache = &sdata->u.mesh.hdr_cache;
|
||||
+ rhashtable_init(&cache->rhead, &mesh_hdr_rht_params);
|
||||
+ INIT_HLIST_HEAD(&cache->walk_head);
|
||||
+ spin_lock_init(&cache->walk_lock);
|
||||
+}
|
||||
+
|
||||
static inline bool mpath_expired(struct mesh_path *mpath)
|
||||
{
|
||||
return (mpath->flags & MESH_PATH_ACTIVE) &&
|
||||
@@ -381,6 +417,211 @@ struct mesh_path *mesh_path_new(struct i
|
||||
return new_mpath;
|
||||
}
|
||||
|
||||
+struct mhdr_cache_entry *
|
||||
+mesh_get_cached_hdr(struct ieee80211_sub_if_data *sdata, const u8 *addr)
|
||||
+{
|
||||
+ struct mesh_path *mpath, *mppath;
|
||||
+ struct mhdr_cache_entry *entry;
|
||||
+ struct mesh_hdr_cache *cache;
|
||||
+
|
||||
+ cache = &sdata->u.mesh.hdr_cache;
|
||||
+ entry = rhashtable_lookup(&cache->rhead, addr, mesh_hdr_rht_params);
|
||||
+ if (!entry)
|
||||
+ return NULL;
|
||||
+
|
||||
+ mpath = rcu_dereference(entry->mpath);
|
||||
+ mppath = rcu_dereference(entry->mppath);
|
||||
+ if (!(mpath->flags & MESH_PATH_ACTIVE) || mpath_expired(mpath))
|
||||
+ return NULL;
|
||||
+
|
||||
+ mesh_refresh_path(sdata, mpath, NULL);
|
||||
+ if (mppath)
|
||||
+ mppath->exp_time = jiffies;
|
||||
+ entry->timestamp = jiffies;
|
||||
+
|
||||
+ return entry;
|
||||
+}
|
||||
+
|
||||
+void mesh_cache_hdr(struct ieee80211_sub_if_data *sdata,
|
||||
+ struct sk_buff *skb, struct mesh_path *mpath)
|
||||
+{
|
||||
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
|
||||
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||
+ struct mesh_hdr_cache *cache;
|
||||
+ struct mhdr_cache_entry *mhdr, *old_mhdr;
|
||||
+ struct ieee80211s_hdr *meshhdr;
|
||||
+ struct sta_info *next_hop;
|
||||
+ struct ieee80211_key *key;
|
||||
+ struct mesh_path *mppath;
|
||||
+ u16 meshhdr_len;
|
||||
+ u8 pn_offs = 0;
|
||||
+ int hdrlen;
|
||||
+
|
||||
+ if (sdata->noack_map)
|
||||
+ return;
|
||||
+
|
||||
+ if (!ieee80211_is_data_qos(hdr->frame_control))
|
||||
+ return;
|
||||
+
|
||||
+ hdrlen = ieee80211_hdrlen(hdr->frame_control);
|
||||
+ meshhdr = (struct ieee80211s_hdr *)(skb->data + hdrlen);
|
||||
+ meshhdr_len = ieee80211_get_mesh_hdrlen(meshhdr);
|
||||
+
|
||||
+ cache = &sdata->u.mesh.hdr_cache;
|
||||
+ if (atomic_read(&cache->rhead.nelems) >= MESH_HEADER_CACHE_MAX_SIZE)
|
||||
+ return;
|
||||
+
|
||||
+ next_hop = rcu_dereference(mpath->next_hop);
|
||||
+ if (!next_hop)
|
||||
+ return;
|
||||
+
|
||||
+ if ((meshhdr->flags & MESH_FLAGS_AE) == MESH_FLAGS_AE_A5_A6) {
|
||||
+ /* This is required to keep the mppath alive */
|
||||
+ mppath = mpp_path_lookup(sdata, meshhdr->eaddr1);
|
||||
+ if (!mppath)
|
||||
+ return;
|
||||
+ } else if (ieee80211_has_a4(hdr->frame_control)) {
|
||||
+ mppath = mpath;
|
||||
+ } else {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /* rate limit, in case fast xmit can't be enabled */
|
||||
+ if (mppath->fast_xmit_check == jiffies)
|
||||
+ return;
|
||||
+
|
||||
+ mppath->fast_xmit_check = jiffies;
|
||||
+
|
||||
+ key = rcu_access_pointer(next_hop->ptk[next_hop->ptk_idx]);
|
||||
+ if (!key)
|
||||
+ key = rcu_access_pointer(sdata->default_unicast_key);
|
||||
+
|
||||
+ if (key) {
|
||||
+ bool gen_iv, iv_spc;
|
||||
+
|
||||
+ gen_iv = key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV;
|
||||
+ iv_spc = key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE;
|
||||
+
|
||||
+ if (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) ||
|
||||
+ (key->flags & KEY_FLAG_TAINTED))
|
||||
+ return;
|
||||
+
|
||||
+ switch (key->conf.cipher) {
|
||||
+ case WLAN_CIPHER_SUITE_CCMP:
|
||||
+ case WLAN_CIPHER_SUITE_CCMP_256:
|
||||
+ if (gen_iv)
|
||||
+ pn_offs = hdrlen;
|
||||
+ if (gen_iv || iv_spc)
|
||||
+ hdrlen += IEEE80211_CCMP_HDR_LEN;
|
||||
+ break;
|
||||
+ case WLAN_CIPHER_SUITE_GCMP:
|
||||
+ case WLAN_CIPHER_SUITE_GCMP_256:
|
||||
+ if (gen_iv)
|
||||
+ pn_offs = hdrlen;
|
||||
+ if (gen_iv || iv_spc)
|
||||
+ hdrlen += IEEE80211_GCMP_HDR_LEN;
|
||||
+ break;
|
||||
+ default:
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (WARN_ON_ONCE(hdrlen + meshhdr_len + sizeof(rfc1042_header) >
|
||||
+ MESH_HEADER_MAX_LEN))
|
||||
+ return;
|
||||
+
|
||||
+ mhdr = kzalloc(sizeof(*mhdr), GFP_ATOMIC);
|
||||
+ if (!mhdr)
|
||||
+ return;
|
||||
+
|
||||
+ memcpy(mhdr->addr_key, mppath->dst, ETH_ALEN);
|
||||
+ mhdr->machdr_len = hdrlen;
|
||||
+ mhdr->hdrlen = mhdr->machdr_len + meshhdr_len + sizeof(rfc1042_header);
|
||||
+ rcu_assign_pointer(mhdr->mpath, mpath);
|
||||
+ if (meshhdr->flags & MESH_FLAGS_AE)
|
||||
+ rcu_assign_pointer(mhdr->mppath, mppath);
|
||||
+ rcu_assign_pointer(mhdr->key, key);
|
||||
+ mhdr->timestamp = jiffies;
|
||||
+ mhdr->band = info->band;
|
||||
+ mhdr->pn_offs = pn_offs;
|
||||
+
|
||||
+ if (pn_offs) {
|
||||
+ memcpy(mhdr->hdr, skb->data, pn_offs);
|
||||
+ memcpy(mhdr->hdr + mhdr->machdr_len, skb->data + pn_offs,
|
||||
+ mhdr->hdrlen - mhdr->machdr_len);
|
||||
+ } else {
|
||||
+ memcpy(mhdr->hdr, skb->data, mhdr->hdrlen);
|
||||
+ }
|
||||
+
|
||||
+ if (key) {
|
||||
+ hdr = (struct ieee80211_hdr *)mhdr->hdr;
|
||||
+ hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
|
||||
+ }
|
||||
+
|
||||
+ spin_lock_bh(&cache->walk_lock);
|
||||
+ old_mhdr = rhashtable_lookup_get_insert_fast(&cache->rhead,
|
||||
+ &mhdr->rhash,
|
||||
+ mesh_hdr_rht_params);
|
||||
+ if (likely(!old_mhdr))
|
||||
+ hlist_add_head(&mhdr->walk_list, &cache->walk_head);
|
||||
+ else
|
||||
+ kfree(mhdr);
|
||||
+ spin_unlock_bh(&cache->walk_lock);
|
||||
+}
|
||||
+
|
||||
+static void mesh_hdr_cache_entry_free(struct mesh_hdr_cache *cache,
|
||||
+ struct mhdr_cache_entry *entry)
|
||||
+{
|
||||
+ hlist_del_rcu(&entry->walk_list);
|
||||
+ rhashtable_remove_fast(&cache->rhead, &entry->rhash, mesh_hdr_rht_params);
|
||||
+ kfree_rcu(entry, rcu);
|
||||
+}
|
||||
+
|
||||
+void mesh_hdr_cache_gc(struct ieee80211_sub_if_data *sdata)
|
||||
+{
|
||||
+ unsigned long timeout = msecs_to_jiffies(MESH_HEADER_CACHE_TIMEOUT);
|
||||
+ struct mesh_hdr_cache *cache;
|
||||
+ struct mhdr_cache_entry *entry;
|
||||
+ struct hlist_node *n;
|
||||
+
|
||||
+ cache = &sdata->u.mesh.hdr_cache;
|
||||
+ if (atomic_read(&cache->rhead.nelems) < MESH_HEADER_CACHE_THRESHOLD_SIZE)
|
||||
+ return;
|
||||
+
|
||||
+ spin_lock_bh(&cache->walk_lock);
|
||||
+ hlist_for_each_entry_safe(entry, n, &cache->walk_head, walk_list)
|
||||
+ if (!time_is_after_jiffies(entry->timestamp + timeout))
|
||||
+ mesh_hdr_cache_entry_free(cache, entry);
|
||||
+ spin_unlock_bh(&cache->walk_lock);
|
||||
+}
|
||||
+
|
||||
+void mesh_hdr_cache_flush(struct ieee80211_sub_if_data *sdata, const u8 *addr,
|
||||
+ bool is_mpp)
|
||||
+{
|
||||
+ struct mesh_hdr_cache *cache = &sdata->u.mesh.hdr_cache;
|
||||
+ struct mhdr_cache_entry *entry;
|
||||
+ struct hlist_node *n;
|
||||
+
|
||||
+ cache = &sdata->u.mesh.hdr_cache;
|
||||
+ spin_lock_bh(&cache->walk_lock);
|
||||
+
|
||||
+ /* Only one header per mpp address is expected in the header cache */
|
||||
+ if (is_mpp) {
|
||||
+ entry = rhashtable_lookup(&cache->rhead, addr,
|
||||
+ mesh_hdr_rht_params);
|
||||
+ if (entry)
|
||||
+ mesh_hdr_cache_entry_free(cache, entry);
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ hlist_for_each_entry_safe(entry, n, &cache->walk_head, walk_list)
|
||||
+ if (ether_addr_equal(entry->mpath->dst, addr))
|
||||
+ mesh_hdr_cache_entry_free(cache, entry);
|
||||
+
|
||||
+out:
|
||||
+ spin_unlock_bh(&cache->walk_lock);
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* mesh_path_add - allocate and add a new path to the mesh path table
|
||||
* @dst: destination address of the path (ETH_ALEN length)
|
||||
@@ -521,6 +762,8 @@ static void mesh_path_free_rcu(struct me
|
||||
|
||||
static void __mesh_path_del(struct mesh_table *tbl, struct mesh_path *mpath)
|
||||
{
|
||||
+ mesh_hdr_cache_flush(mpath->sdata, mpath->dst,
|
||||
+ tbl == &mpath->sdata->u.mesh.mpp_paths);
|
||||
hlist_del_rcu(&mpath->walk_list);
|
||||
rhashtable_remove_fast(&tbl->rhead, &mpath->rhash, mesh_rht_params);
|
||||
mesh_path_free_rcu(tbl, mpath);
|
||||
@@ -747,6 +990,7 @@ void mesh_path_fix_nexthop(struct mesh_p
|
||||
mpath->exp_time = 0;
|
||||
mpath->flags = MESH_PATH_FIXED | MESH_PATH_SN_VALID;
|
||||
mesh_path_activate(mpath);
|
||||
+ mesh_hdr_cache_flush(mpath->sdata, mpath->dst, false);
|
||||
spin_unlock_bh(&mpath->state_lock);
|
||||
ewma_mesh_fail_avg_init(&next_hop->mesh->fail_avg);
|
||||
/* init it at a low value - 0 start is tricky */
|
||||
@@ -758,6 +1002,7 @@ void mesh_pathtbl_init(struct ieee80211_
|
||||
{
|
||||
mesh_table_init(&sdata->u.mesh.mesh_paths);
|
||||
mesh_table_init(&sdata->u.mesh.mpp_paths);
|
||||
+ mesh_hdr_cache_init(sdata);
|
||||
}
|
||||
|
||||
static
|
||||
@@ -785,6 +1030,7 @@ void mesh_path_expire(struct ieee80211_s
|
||||
|
||||
void mesh_pathtbl_unregister(struct ieee80211_sub_if_data *sdata)
|
||||
{
|
||||
+ mesh_hdr_cache_deinit(sdata);
|
||||
mesh_table_free(&sdata->u.mesh.mesh_paths);
|
||||
mesh_table_free(&sdata->u.mesh.mpp_paths);
|
||||
}
|
||||
--- a/net/mac80211/rx.c
|
||||
+++ b/net/mac80211/rx.c
|
||||
@@ -2791,6 +2791,7 @@ ieee80211_rx_mesh_data(struct ieee80211_
|
||||
if (mesh_hdr->flags & MESH_FLAGS_AE) {
|
||||
struct mesh_path *mppath;
|
||||
char *proxied_addr;
|
||||
+ bool update = false;
|
||||
|
||||
if (multicast)
|
||||
proxied_addr = mesh_hdr->eaddr1;
|
||||
@@ -2806,11 +2807,18 @@ ieee80211_rx_mesh_data(struct ieee80211_
|
||||
mpp_path_add(sdata, proxied_addr, eth->h_source);
|
||||
} else {
|
||||
spin_lock_bh(&mppath->state_lock);
|
||||
- if (!ether_addr_equal(mppath->mpp, eth->h_source))
|
||||
+ if (!ether_addr_equal(mppath->mpp, eth->h_source)) {
|
||||
memcpy(mppath->mpp, eth->h_source, ETH_ALEN);
|
||||
+ update = true;
|
||||
+ }
|
||||
mppath->exp_time = jiffies;
|
||||
spin_unlock_bh(&mppath->state_lock);
|
||||
}
|
||||
+
|
||||
+ /* flush fast xmit cache if the address path changed */
|
||||
+ if (update)
|
||||
+ mesh_hdr_cache_flush(sdata, proxied_addr, true);
|
||||
+
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
--- a/net/mac80211/tx.c
|
||||
+++ b/net/mac80211/tx.c
|
||||
@@ -3021,6 +3021,9 @@ void ieee80211_check_fast_xmit(struct st
|
||||
if (!ieee80211_hw_check(&local->hw, SUPPORT_FAST_XMIT))
|
||||
return;
|
||||
|
||||
+ if (ieee80211_vif_is_mesh(&sdata->vif))
|
||||
+ mesh_hdr_cache_flush(sdata, sta->addr, false);
|
||||
+
|
||||
/* Locking here protects both the pointer itself, and against concurrent
|
||||
* invocations winning data access races to, e.g., the key pointer that
|
||||
* is used.
|
||||
@@ -3723,6 +3726,155 @@ free:
|
||||
kfree_skb(skb);
|
||||
}
|
||||
|
||||
+void __ieee80211_mesh_xmit_fast(struct ieee80211_sub_if_data *sdata,
|
||||
+ struct mhdr_cache_entry *entry,
|
||||
+ struct sk_buff *skb)
|
||||
+{
|
||||
+ struct ieee80211_local *local = sdata->local;
|
||||
+ struct ieee80211_tx_data tx = {};
|
||||
+ struct ieee80211_tx_info *info;
|
||||
+ struct ieee80211_key *key;
|
||||
+ struct ieee80211_hdr *hdr;
|
||||
+ struct mesh_path *mpath;
|
||||
+ ieee80211_tx_result r;
|
||||
+ struct sta_info *sta;
|
||||
+ u8 tid;
|
||||
+
|
||||
+ if (!IS_ENABLED(CPTCFG_MAC80211_MESH))
|
||||
+ return;
|
||||
+
|
||||
+ info = IEEE80211_SKB_CB(skb);
|
||||
+ memset(info, 0, sizeof(*info));
|
||||
+ info->band = entry->band;
|
||||
+ info->control.vif = &sdata->vif;
|
||||
+ info->flags = IEEE80211_TX_CTL_FIRST_FRAGMENT |
|
||||
+ IEEE80211_TX_CTL_DONTFRAG;
|
||||
+
|
||||
+ info->control.flags = IEEE80211_TX_CTRL_FAST_XMIT;
|
||||
+
|
||||
+#ifdef CONFIG_MAC80211_DEBUGFS
|
||||
+ if (local->force_tx_status)
|
||||
+ info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS;
|
||||
+#endif
|
||||
+
|
||||
+ mpath = entry->mpath;
|
||||
+ key = entry->key;
|
||||
+ sta = rcu_dereference(mpath->next_hop);
|
||||
+
|
||||
+ __skb_queue_head_init(&tx.skbs);
|
||||
+
|
||||
+ tx.flags = IEEE80211_TX_UNICAST;
|
||||
+ tx.local = local;
|
||||
+ tx.sdata = sdata;
|
||||
+ tx.sta = sta;
|
||||
+ tx.key = key;
|
||||
+ tx.skb = skb;
|
||||
+
|
||||
+ hdr = (struct ieee80211_hdr *)skb->data;
|
||||
+ tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK;
|
||||
+ *ieee80211_get_qos_ctl(hdr) = tid;
|
||||
+
|
||||
+ ieee80211_aggr_check(sdata, sta, skb);
|
||||
+
|
||||
+ if (ieee80211_queue_skb(local, sdata, sta, skb))
|
||||
+ return;
|
||||
+
|
||||
+ r = ieee80211_xmit_fast_finish(sdata, sta, entry->pn_offs, key, &tx);
|
||||
+ if (r == TX_DROP) {
|
||||
+ kfree_skb(skb);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ __skb_queue_tail(&tx.skbs, skb);
|
||||
+ ieee80211_tx_frags(local, &sdata->vif, sta, &tx.skbs, false);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static bool ieee80211_mesh_xmit_fast(struct ieee80211_sub_if_data *sdata,
|
||||
+ struct sk_buff *skb, u32 ctrl_flags)
|
||||
+{
|
||||
+ struct ieee80211_local *local = sdata->local;
|
||||
+ struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
|
||||
+ struct mhdr_cache_entry *entry;
|
||||
+ struct ieee80211s_hdr *meshhdr;
|
||||
+ u8 sa[ETH_ALEN] __aligned(2);
|
||||
+ struct sta_info *sta;
|
||||
+ bool copy_sa = false;
|
||||
+ u16 ethertype;
|
||||
+
|
||||
+ if (ctrl_flags & IEEE80211_TX_CTRL_SKIP_MPATH_LOOKUP)
|
||||
+ return false;
|
||||
+
|
||||
+ if (ifmsh->mshcfg.dot11MeshNolearn)
|
||||
+ return false;
|
||||
+
|
||||
+ if (!ieee80211_hw_check(&local->hw, SUPPORT_FAST_XMIT))
|
||||
+ return false;
|
||||
+
|
||||
+ /* Add support for these cases later */
|
||||
+ if (ifmsh->ps_peers_light_sleep || ifmsh->ps_peers_deep_sleep)
|
||||
+ return false;
|
||||
+
|
||||
+ if (is_multicast_ether_addr(skb->data))
|
||||
+ return false;
|
||||
+
|
||||
+ ethertype = (skb->data[12] << 8) | skb->data[13];
|
||||
+ if (ethertype < ETH_P_802_3_MIN)
|
||||
+ return false;
|
||||
+
|
||||
+ if (skb->sk && skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS)
|
||||
+ return false;
|
||||
+
|
||||
+ if (skb->ip_summed == CHECKSUM_PARTIAL) {
|
||||
+ skb_set_transport_header(skb, skb_checksum_start_offset(skb));
|
||||
+ if (skb_checksum_help(skb))
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ entry = mesh_get_cached_hdr(sdata, skb->data);
|
||||
+ if (!entry)
|
||||
+ return false;
|
||||
+
|
||||
+ /* Avoid extra work in this path */
|
||||
+ if (skb_headroom(skb) < (entry->hdrlen - ETH_HLEN + 2))
|
||||
+ return false;
|
||||
+
|
||||
+ /* If the skb is shared we need to obtain our own copy */
|
||||
+ if (skb_shared(skb)) {
|
||||
+ struct sk_buff *oskb = skb;
|
||||
+
|
||||
+ skb = skb_clone(skb, GFP_ATOMIC);
|
||||
+ if (!skb)
|
||||
+ return false;
|
||||
+
|
||||
+ kfree_skb(oskb);
|
||||
+ }
|
||||
+
|
||||
+ sta = rcu_dereference(entry->mpath->next_hop);
|
||||
+ skb_set_queue_mapping(skb, ieee80211_select_queue(sdata, sta, skb));
|
||||
+
|
||||
+ meshhdr = (struct ieee80211s_hdr *)(entry->hdr + entry->machdr_len);
|
||||
+ if ((meshhdr->flags & MESH_FLAGS_AE) == MESH_FLAGS_AE_A5_A6) {
|
||||
+ /* preserve SA from eth header for 6-addr frames */
|
||||
+ ether_addr_copy(sa, skb->data + ETH_ALEN);
|
||||
+ copy_sa = true;
|
||||
+ }
|
||||
+
|
||||
+ memcpy(skb_push(skb, entry->hdrlen - 2 * ETH_ALEN), entry->hdr,
|
||||
+ entry->hdrlen);
|
||||
+
|
||||
+ meshhdr = (struct ieee80211s_hdr *)(skb->data + entry->machdr_len);
|
||||
+ put_unaligned_le32(atomic_inc_return(&sdata->u.mesh.mesh_seqnum),
|
||||
+ &meshhdr->seqnum);
|
||||
+ meshhdr->ttl = sdata->u.mesh.mshcfg.dot11MeshTTL;
|
||||
+ if (copy_sa)
|
||||
+ ether_addr_copy(meshhdr->eaddr2, sa);
|
||||
+
|
||||
+ __ieee80211_mesh_xmit_fast(sdata, entry, skb);
|
||||
+
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
static bool ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata,
|
||||
struct sta_info *sta,
|
||||
struct ieee80211_fast_tx *fast_tx,
|
||||
@@ -4244,8 +4396,14 @@ void __ieee80211_subif_start_xmit(struct
|
||||
return;
|
||||
}
|
||||
|
||||
+ sk_pacing_shift_update(skb->sk, sdata->local->hw.tx_sk_pacing_shift);
|
||||
+
|
||||
rcu_read_lock();
|
||||
|
||||
+ if (ieee80211_vif_is_mesh(&sdata->vif) &&
|
||||
+ ieee80211_mesh_xmit_fast(sdata, skb, ctrl_flags))
|
||||
+ goto out;
|
||||
+
|
||||
if (ieee80211_lookup_ra_sta(sdata, skb, &sta))
|
||||
goto out_free;
|
||||
|
||||
@@ -4255,8 +4413,6 @@ void __ieee80211_subif_start_xmit(struct
|
||||
skb_set_queue_mapping(skb, ieee80211_select_queue(sdata, sta, skb));
|
||||
ieee80211_aggr_check(sdata, sta, skb);
|
||||
|
||||
- sk_pacing_shift_update(skb->sk, sdata->local->hw.tx_sk_pacing_shift);
|
||||
-
|
||||
if (sta) {
|
||||
struct ieee80211_fast_tx *fast_tx;
|
||||
|
@ -0,0 +1,70 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Thu, 16 Feb 2023 11:07:30 +0100
|
||||
Subject: [PATCH] wifi: mac80211: use mesh header cache to speed up mesh
|
||||
forwarding
|
||||
|
||||
Use it to look up the next hop address + sta pointer + key and call
|
||||
__ieee80211_mesh_xmit_fast to queue the tx frame.
|
||||
|
||||
Significantly reduces mesh forwarding path CPU usage and enables the
|
||||
use of iTXQ.
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/rx.c
|
||||
+++ b/net/mac80211/rx.c
|
||||
@@ -2731,6 +2731,7 @@ ieee80211_rx_mesh_data(struct ieee80211_
|
||||
struct ieee80211_hdr hdr = {
|
||||
.frame_control = cpu_to_le16(fc)
|
||||
};
|
||||
+ struct mhdr_cache_entry *entry = NULL;
|
||||
struct ieee80211_hdr *fwd_hdr;
|
||||
struct ieee80211s_hdr *mesh_hdr;
|
||||
struct ieee80211_tx_info *info;
|
||||
@@ -2788,7 +2789,12 @@ ieee80211_rx_mesh_data(struct ieee80211_
|
||||
return RX_DROP_MONITOR;
|
||||
}
|
||||
|
||||
- if (mesh_hdr->flags & MESH_FLAGS_AE) {
|
||||
+ if ((mesh_hdr->flags & MESH_FLAGS_AE) == MESH_FLAGS_AE_A5_A6)
|
||||
+ entry = mesh_get_cached_hdr(sdata, mesh_hdr->eaddr1);
|
||||
+ else if (!(mesh_hdr->flags & MESH_FLAGS_AE))
|
||||
+ entry = mesh_get_cached_hdr(sdata, eth->h_dest);
|
||||
+
|
||||
+ if (!entry && (mesh_hdr->flags & MESH_FLAGS_AE)) {
|
||||
struct mesh_path *mppath;
|
||||
char *proxied_addr;
|
||||
bool update = false;
|
||||
@@ -2862,11 +2868,23 @@ ieee80211_rx_mesh_data(struct ieee80211_
|
||||
info->control.flags |= IEEE80211_TX_INTCFL_NEED_TXPROCESSING;
|
||||
info->control.vif = &sdata->vif;
|
||||
info->control.jiffies = jiffies;
|
||||
+ fwd_skb->dev = sdata->dev;
|
||||
if (multicast) {
|
||||
IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_mcast);
|
||||
memcpy(fwd_hdr->addr2, sdata->vif.addr, ETH_ALEN);
|
||||
/* update power mode indication when forwarding */
|
||||
ieee80211_mps_set_frame_flags(sdata, NULL, fwd_hdr);
|
||||
+ } else if (entry) {
|
||||
+ struct ieee80211_hdr *ehdr = (struct ieee80211_hdr *)entry->hdr;
|
||||
+
|
||||
+ ether_addr_copy(fwd_hdr->addr1, ehdr->addr1);
|
||||
+ ether_addr_copy(fwd_hdr->addr2, sdata->vif.addr);
|
||||
+ IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_unicast);
|
||||
+ IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_frames);
|
||||
+ qos[0] = fwd_skb->priority;
|
||||
+ qos[1] = ieee80211_get_qos_ctl(ehdr)[1];
|
||||
+ __ieee80211_mesh_xmit_fast(sdata, entry, fwd_skb);
|
||||
+ return RX_QUEUED;
|
||||
} else if (!mesh_nexthop_lookup(sdata, fwd_skb)) {
|
||||
/* mesh power mode flags updated in mesh_nexthop_lookup */
|
||||
IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_unicast);
|
||||
@@ -2883,7 +2901,6 @@ ieee80211_rx_mesh_data(struct ieee80211_
|
||||
}
|
||||
|
||||
IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_frames);
|
||||
- fwd_skb->dev = sdata->dev;
|
||||
ieee80211_add_pending_skb(local, fwd_skb);
|
||||
|
||||
rx_accept:
|
@ -0,0 +1,32 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Mon, 20 Feb 2023 12:50:50 +0100
|
||||
Subject: [PATCH] mac80211: fix mesh forwarding
|
||||
|
||||
Linearize packets (needed for forwarding A-MSDU subframes).
|
||||
Fix network header offset to fix flow dissector (and fair queueing).
|
||||
|
||||
Fixes: 986e43b19ae9 ("wifi: mac80211: fix receiving A-MSDU frames on mesh interfaces")
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/rx.c
|
||||
+++ b/net/mac80211/rx.c
|
||||
@@ -2847,6 +2847,9 @@ ieee80211_rx_mesh_data(struct ieee80211_
|
||||
|
||||
if (skb_cow_head(fwd_skb, hdrlen - sizeof(struct ethhdr)))
|
||||
return RX_DROP_UNUSABLE;
|
||||
+
|
||||
+ if (skb_linearize(fwd_skb))
|
||||
+ return RX_DROP_UNUSABLE;
|
||||
}
|
||||
|
||||
fwd_hdr = skb_push(fwd_skb, hdrlen - sizeof(struct ethhdr));
|
||||
@@ -2861,7 +2864,7 @@ ieee80211_rx_mesh_data(struct ieee80211_
|
||||
hdrlen += ETH_ALEN;
|
||||
else
|
||||
fwd_skb->protocol = htons(fwd_skb->len - hdrlen);
|
||||
- skb_set_network_header(fwd_skb, hdrlen);
|
||||
+ skb_set_network_header(fwd_skb, hdrlen + 2);
|
||||
|
||||
info = IEEE80211_SKB_CB(fwd_skb);
|
||||
memset(info, 0, sizeof(*info));
|
@ -87,7 +87,7 @@
|
||||
CFG80211_TESTMODE_DUMP(ieee80211_testmode_dump)
|
||||
--- a/net/mac80211/ieee80211_i.h
|
||||
+++ b/net/mac80211/ieee80211_i.h
|
||||
@@ -1520,6 +1520,7 @@ struct ieee80211_local {
|
||||
@@ -1536,6 +1536,7 @@ struct ieee80211_local {
|
||||
int dynamic_ps_forced_timeout;
|
||||
|
||||
int user_power_level; /* in dBm, for all interfaces */
|
||||
|
@ -8,11 +8,9 @@ config OPENSSL_OPTIMIZE_SPEED
|
||||
prompt "Enable optimization for speed instead of size"
|
||||
select OPENSSL_WITH_ASM
|
||||
help
|
||||
Enabling this option increases code size (around 20%) and
|
||||
performance. The increase in performance and size depends on the
|
||||
target CPU. EC and AES seem to benefit the most, with EC speed
|
||||
increased by 20%-50% (mipsel & x86).
|
||||
AES-GCM is supposed to be 3x faster on x86. YMMV.
|
||||
Enabling this option increases code size and performance.
|
||||
The increase in performance and size depends on the
|
||||
target CPU. EC and AES seem to benefit the most.
|
||||
|
||||
config OPENSSL_WITH_ASM
|
||||
bool
|
||||
@ -22,19 +20,7 @@ config OPENSSL_WITH_ASM
|
||||
help
|
||||
Disabling this option will reduce code size and performance.
|
||||
The increase in performance and size depends on the target
|
||||
CPU and on the algorithms being optimized. As of 1.1.0i*:
|
||||
|
||||
Platform Pkg Inc. Algorithms where assembly is used - ~% Speed Increase
|
||||
aarch64 174K BN, aes, sha1, sha256, sha512, nist256, poly1305
|
||||
arm 152K BN, aes, sha1, sha256, sha512, nist256, poly1305
|
||||
i386 183K BN+147%, aes+300%, rc4+55%, sha1+160%, sha256+114%, sha512+270%, nist256+282%, poly1305+292%
|
||||
mipsel 1.5K BN+97%, aes+4%, sha1+94%, sha256+60%
|
||||
mips64 3.7K BN, aes, sha1, sha256, sha512, poly1305
|
||||
powerpc 20K BN, aes, sha1, sha256, sha512, poly1305
|
||||
x86_64 228K BN+220%, aes+173%, rc4+38%, sha1+40%, sha256+64%, sha512+31%, nist256+354%, poly1305+228%
|
||||
|
||||
* Only most common algorithms shown. Your mileage may vary.
|
||||
BN (bignum) performance was measured using RSA sign/verify.
|
||||
CPU and on the algorithms being optimized.
|
||||
|
||||
config OPENSSL_WITH_SSE2
|
||||
bool
|
||||
@ -42,21 +28,17 @@ config OPENSSL_WITH_SSE2
|
||||
prompt "Enable use of x86 SSE2 instructions"
|
||||
depends on OPENSSL_WITH_ASM && x86_64 || i386
|
||||
help
|
||||
Use of SSE2 instructions greatly increase performance (up to
|
||||
3x faster) with a minimum (~0.2%, or 23KB) increase in package
|
||||
size, but it will bring no benefit if your hardware does not
|
||||
support them, such as Geode GX and LX. In this case you may
|
||||
save 23KB by saying yes here. AMD Geode NX, and Intel
|
||||
Pentium 4 and above support SSE2.
|
||||
Use of SSE2 instructions greatly increase performance with a
|
||||
minimum increase in package size, but it will bring no benefit
|
||||
if your hardware does not support them, such as Geode GX and LX.
|
||||
AMD Geode NX, and Intel Pentium 4 and above support SSE2.
|
||||
|
||||
config OPENSSL_WITH_DEPRECATED
|
||||
bool
|
||||
default y
|
||||
prompt "Include deprecated APIs (See help for a list of packages that need this)"
|
||||
prompt "Include deprecated APIs"
|
||||
help
|
||||
Since openssl 1.1.x is still new to openwrt, some packages
|
||||
requiring this option do not list it as a requirement yet:
|
||||
* freeswitch-stable, freeswitch, python, python3, squid.
|
||||
This drops all deprecated API, including engine support.
|
||||
|
||||
config OPENSSL_NO_DEPRECATED
|
||||
bool
|
||||
@ -84,7 +66,6 @@ config OPENSSL_WITH_TLS13
|
||||
protocol;
|
||||
* to increase performance by reducing the number of round-trips
|
||||
when performing a full handshake.
|
||||
It increases package size by ~4KB.
|
||||
|
||||
config OPENSSL_WITH_DTLS
|
||||
bool
|
||||
@ -233,6 +214,7 @@ comment "Engine/Hardware Support"
|
||||
|
||||
config OPENSSL_ENGINE
|
||||
bool "Enable engine support"
|
||||
select OPENSSL_WITH_DEPRECATED
|
||||
default y
|
||||
select PACKAGE_libopenssl-devcrypto
|
||||
help
|
||||
|
@ -8,14 +8,13 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=openssl
|
||||
PKG_BASE:=1.1.1
|
||||
PKG_BUGFIX:=t
|
||||
PKG_VERSION:=$(PKG_BASE)$(PKG_BUGFIX)
|
||||
PKG_VERSION:=3.0.8
|
||||
PKG_RELEASE:=1
|
||||
PKG_USE_MIPS16:=0
|
||||
|
||||
PKG_BUILD_PARALLEL:=1
|
||||
|
||||
PKG_BASE:=$(subst $(space),.,$(wordlist 1,2,$(subst .,$(space),$(PKG_VERSION))))
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:= \
|
||||
https://mirrors.tencent.com/openssl/source/ \
|
||||
@ -27,9 +26,9 @@ PKG_SOURCE_URL:= \
|
||||
ftp://ftp.pca.dfn.de/pub/tools/net/openssl/source/ \
|
||||
ftp://ftp.pca.dfn.de/pub/tools/net/openssl/source/old/$(PKG_BASE)/
|
||||
|
||||
PKG_HASH:=8dee9b24bdb1dcbf0c3d1e9b02fb8f6bf22165e807f45adeb7c9677536859d3b
|
||||
PKG_HASH:=6c13d2bf38fdf31eac3ce2a347073673f5d63263398f1f69d0df4a41253e4b3e
|
||||
|
||||
PKG_LICENSE:=OpenSSL
|
||||
PKG_LICENSE:=Apache-2.0
|
||||
PKG_LICENSE_FILES:=LICENSE
|
||||
PKG_MAINTAINER:=Eneas U de Queiroz <cotequeiroz@gmail.com>
|
||||
PKG_CPE_ID:=cpe:/a:openssl:openssl
|
||||
@ -97,9 +96,10 @@ $(call Package/openssl/Default)
|
||||
DEPENDS:=+OPENSSL_WITH_COMPRESSION:zlib \
|
||||
+OPENSSL_ENGINE_BUILTIN_AFALG:kmod-crypto-user \
|
||||
+OPENSSL_ENGINE_BUILTIN_DEVCRYPTO:kmod-cryptodev \
|
||||
+OPENSSL_ENGINE_BUILTIN_PADLOCK:kmod-crypto-hw-padlock
|
||||
+OPENSSL_ENGINE_BUILTIN_PADLOCK:kmod-crypto-hw-padlock \
|
||||
+(arm||armeb||mips||mipsel||ppc):libatomic
|
||||
TITLE+= (libraries)
|
||||
ABI_VERSION:=1.1
|
||||
ABI_VERSION:=$(firstword $(subst .,$(space),$(PKG_VERSION)))
|
||||
MENU:=1
|
||||
endef
|
||||
|
||||
@ -188,7 +188,7 @@ and https://openwrt.org/docs/techref/hardware/cryptographic.hardware.accelerator
|
||||
The engine_id is "padlock"
|
||||
endef
|
||||
|
||||
OPENSSL_OPTIONS:= shared
|
||||
OPENSSL_OPTIONS:= shared no-tests
|
||||
|
||||
ifndef CONFIG_OPENSSL_WITH_BLAKE2
|
||||
OPENSSL_OPTIONS += no-blake2
|
||||
@ -274,7 +274,7 @@ ifdef CONFIG_OPENSSL_ENGINE
|
||||
OPENSSL_OPTIONS += enable-devcryptoeng
|
||||
endif
|
||||
ifndef CONFIG_OPENSSL_ENGINE_BUILTIN_PADLOCK
|
||||
OPENSSL_OPTIONS += no-hw-padlock
|
||||
OPENSSL_OPTIONS += no-padlockeng
|
||||
endif
|
||||
else
|
||||
ifdef CONFIG_PACKAGE_libopenssl-devcrypto
|
||||
@ -284,7 +284,7 @@ ifdef CONFIG_OPENSSL_ENGINE
|
||||
OPENSSL_OPTIONS += no-afalgeng
|
||||
endif
|
||||
ifndef CONFIG_PACKAGE_libopenssl-padlock
|
||||
OPENSSL_OPTIONS += no-hw-padlock
|
||||
OPENSSL_OPTIONS += no-padlockeng
|
||||
endif
|
||||
endif
|
||||
else
|
||||
|
@ -1,55 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Andy Polyakov <appro@openssl.org>
|
||||
Date: Sun, 5 May 2019 18:25:50 +0200
|
||||
Subject: crypto/perlasm/ppc-xlate.pl: add linux64v2 flavour
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This is a big endian ELFv2 configuration. ELFv2 was already being
|
||||
used for little endian, and big endian was traditionally ELFv1
|
||||
but there are practical configurations that use ELFv2 with big
|
||||
endian nowadays (Adélie Linux, Void Linux, possibly Gentoo, etc.)
|
||||
|
||||
Reviewed-by: Paul Dale <paul.dale@oracle.com>
|
||||
Reviewed-by: Richard Levitte <levitte@openssl.org>
|
||||
(Merged from https://github.com/openssl/openssl/pull/8883)
|
||||
|
||||
--- a/crypto/perlasm/ppc-xlate.pl
|
||||
+++ b/crypto/perlasm/ppc-xlate.pl
|
||||
@@ -49,7 +49,7 @@ my $globl = sub {
|
||||
/osx/ && do { $name = "_$name";
|
||||
last;
|
||||
};
|
||||
- /linux.*(32|64le)/
|
||||
+ /linux.*(32|64(le|v2))/
|
||||
&& do { $ret .= ".globl $name";
|
||||
if (!$$type) {
|
||||
$ret .= "\n.type $name,\@function";
|
||||
@@ -80,7 +80,7 @@ my $globl = sub {
|
||||
};
|
||||
my $text = sub {
|
||||
my $ret = ($flavour =~ /aix/) ? ".csect\t.text[PR],7" : ".text";
|
||||
- $ret = ".abiversion 2\n".$ret if ($flavour =~ /linux.*64le/);
|
||||
+ $ret = ".abiversion 2\n".$ret if ($flavour =~ /linux.*64(le|v2)/);
|
||||
$ret;
|
||||
};
|
||||
my $machine = sub {
|
||||
@@ -186,7 +186,7 @@ my $vmr = sub {
|
||||
|
||||
# Some ABIs specify vrsave, special-purpose register #256, as reserved
|
||||
# for system use.
|
||||
-my $no_vrsave = ($flavour =~ /aix|linux64le/);
|
||||
+my $no_vrsave = ($flavour =~ /aix|linux64(le|v2)/);
|
||||
my $mtspr = sub {
|
||||
my ($f,$idx,$ra) = @_;
|
||||
if ($idx == 256 && $no_vrsave) {
|
||||
@@ -318,7 +318,7 @@ while($line=<>) {
|
||||
if ($label) {
|
||||
my $xlated = ($GLOBALS{$label} or $label);
|
||||
print "$xlated:";
|
||||
- if ($flavour =~ /linux.*64le/) {
|
||||
+ if ($flavour =~ /linux.*64(le|v2)/) {
|
||||
if ($TYPES{$label} =~ /function/) {
|
||||
printf "\n.localentry %s,0\n",$xlated;
|
||||
}
|
@ -10,7 +10,7 @@ Signed-off-by: Eneas U de Queiroz <cote2004-github@yahoo.com>
|
||||
|
||||
--- a/Configure
|
||||
+++ b/Configure
|
||||
@@ -1548,7 +1548,9 @@ unless ($disabled{"crypto-mdebug-backtra
|
||||
@@ -1677,7 +1677,9 @@ $config{CFLAGS} = [ map { $_ eq '--ossl-
|
||||
|
||||
unless ($disabled{afalgeng}) {
|
||||
$config{afalgeng}="";
|
||||
|
@ -10,12 +10,12 @@ Signed-off-by: Eneas U de Queiroz <cote2004-github@yahoo.com>
|
||||
|
||||
--- a/crypto/build.info
|
||||
+++ b/crypto/build.info
|
||||
@@ -10,7 +10,7 @@ EXTRA= ../ms/uplink-x86.pl ../ms/uplink
|
||||
ppccpuid.pl pariscid.pl alphacpuid.pl arm64cpuid.pl armv4cpuid.pl
|
||||
@@ -113,7 +113,7 @@ DEFINE[../libcrypto]=$UPLINKDEF
|
||||
|
||||
DEPEND[info.o]=buildinf.h
|
||||
DEPEND[cversion.o]=buildinf.h
|
||||
-GENERATE[buildinf.h]=../util/mkbuildinf.pl "$(CC) $(LIB_CFLAGS) $(CPPFLAGS_Q)" "$(PLATFORM)"
|
||||
+GENERATE[buildinf.h]=../util/mkbuildinf.pl "$(filter-out -I% -iremap% -fmacro-prefix-map% -ffile-prefix-map%,$(CC) $(LIB_CFLAGS) $(CPPFLAGS_Q))" "$(PLATFORM)"
|
||||
DEPEND[buildinf.h]=../configdata.pm
|
||||
|
||||
GENERATE[uplink-x86.s]=../ms/uplink-x86.pl $(PERLASM_SCHEME)
|
||||
GENERATE[uplink-x86.S]=../ms/uplink-x86.pl
|
||||
GENERATE[uplink-x86_64.s]=../ms/uplink-x86_64.pl
|
||||
|
20
package/libs/openssl/patches/130-dont-build-fuzz-docs.patch
Normal file
20
package/libs/openssl/patches/130-dont-build-fuzz-docs.patch
Normal file
@ -0,0 +1,20 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Eneas U de Queiroz <cote2004-github@yahoo.com>
|
||||
Date: Thu, 27 Sep 2018 08:34:38 -0300
|
||||
Subject: Do not build tests and fuzz directories
|
||||
|
||||
This shortens build time.
|
||||
|
||||
Signed-off-by: Eneas U de Queiroz <cote2004-github@yahoo.com>
|
||||
|
||||
--- a/build.info
|
||||
+++ b/build.info
|
||||
@@ -1,7 +1,7 @@
|
||||
# Note that some of these directories are filtered in Configure. Look for
|
||||
# %skipdir there for further explanations.
|
||||
|
||||
-SUBDIRS=crypto ssl apps util tools fuzz providers doc
|
||||
+SUBDIRS=crypto ssl apps util tools providers
|
||||
IF[{- !$disabled{tests} -}]
|
||||
SUBDIRS=test
|
||||
ENDIF
|
@ -1,29 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Eneas U de Queiroz <cote2004-github@yahoo.com>
|
||||
Date: Thu, 27 Sep 2018 08:34:38 -0300
|
||||
Subject: Do not build tests and fuzz directories
|
||||
|
||||
This shortens build time.
|
||||
|
||||
Signed-off-by: Eneas U de Queiroz <cote2004-github@yahoo.com>
|
||||
|
||||
--- a/Configure
|
||||
+++ b/Configure
|
||||
@@ -318,7 +318,7 @@ my $auto_threads=1; # enable threads
|
||||
my $default_ranlib;
|
||||
|
||||
# Top level directories to build
|
||||
-$config{dirs} = [ "crypto", "ssl", "engines", "apps", "test", "util", "tools", "fuzz" ];
|
||||
+$config{dirs} = [ "crypto", "ssl", "engines", "apps", "util", "tools" ];
|
||||
# crypto/ subdirectories to build
|
||||
$config{sdirs} = [
|
||||
"objects",
|
||||
@@ -330,7 +330,7 @@ $config{sdirs} = [
|
||||
"cms", "ts", "srp", "cmac", "ct", "async", "kdf", "store"
|
||||
];
|
||||
# test/ subdirectories to build
|
||||
-$config{tdirs} = [ "ossl_shim" ];
|
||||
+$config{tdirs} = [];
|
||||
|
||||
# Known TLS and DTLS protocols
|
||||
my @tls = qw(ssl3 tls1 tls1_1 tls1_2 tls1_3);
|
@ -14,30 +14,9 @@ when the client has it on top of its ciphersuite preference.
|
||||
|
||||
Signed-off-by: Eneas U de Queiroz <cote2004-github@yahoo.com>
|
||||
|
||||
--- a/include/openssl/ssl.h
|
||||
+++ b/include/openssl/ssl.h
|
||||
@@ -173,9 +173,15 @@ extern "C" {
|
||||
# define SSL_DEFAULT_CIPHER_LIST "ALL:!COMPLEMENTOFDEFAULT:!eNULL"
|
||||
/* This is the default set of TLSv1.3 ciphersuites */
|
||||
# if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305)
|
||||
-# define TLS_DEFAULT_CIPHERSUITES "TLS_AES_256_GCM_SHA384:" \
|
||||
- "TLS_CHACHA20_POLY1305_SHA256:" \
|
||||
- "TLS_AES_128_GCM_SHA256"
|
||||
+# ifdef OPENSSL_PREFER_CHACHA_OVER_GCM
|
||||
+# define TLS_DEFAULT_CIPHERSUITES "TLS_CHACHA20_POLY1305_SHA256:" \
|
||||
+ "TLS_AES_256_GCM_SHA384:" \
|
||||
+ "TLS_AES_128_GCM_SHA256"
|
||||
+# else
|
||||
+# define TLS_DEFAULT_CIPHERSUITES "TLS_AES_256_GCM_SHA384:" \
|
||||
+ "TLS_CHACHA20_POLY1305_SHA256:" \
|
||||
+ "TLS_AES_128_GCM_SHA256"
|
||||
+# endif
|
||||
# else
|
||||
# define TLS_DEFAULT_CIPHERSUITES "TLS_AES_256_GCM_SHA384:" \
|
||||
"TLS_AES_128_GCM_SHA256"
|
||||
--- a/ssl/ssl_ciph.c
|
||||
+++ b/ssl/ssl_ciph.c
|
||||
@@ -1465,11 +1465,29 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_
|
||||
@@ -1505,11 +1505,29 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_
|
||||
ssl_cipher_apply_rule(0, SSL_kECDHE, 0, 0, 0, 0, 0, CIPHER_DEL, -1, &head,
|
||||
&tail);
|
||||
|
||||
@ -67,7 +46,7 @@ Signed-off-by: Eneas U de Queiroz <cote2004-github@yahoo.com>
|
||||
|
||||
/*
|
||||
* ...and generally, our preferred cipher is AES.
|
||||
@@ -1525,7 +1543,7 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_
|
||||
@@ -1564,7 +1582,7 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_
|
||||
* Within each group, ciphers remain sorted by strength and previous
|
||||
* preference, i.e.,
|
||||
* 1) ECDHE > DHE
|
||||
@ -76,3 +55,38 @@ Signed-off-by: Eneas U de Queiroz <cote2004-github@yahoo.com>
|
||||
* 3) AES > rest
|
||||
* 4) TLS 1.2 > legacy
|
||||
*
|
||||
@@ -2235,7 +2253,13 @@ const char *OSSL_default_cipher_list(voi
|
||||
*/
|
||||
const char *OSSL_default_ciphersuites(void)
|
||||
{
|
||||
+#ifdef OPENSSL_PREFER_CHACHA_OVER_GCM
|
||||
+ return "TLS_CHACHA20_POLY1305_SHA256:"
|
||||
+ "TLS_AES_256_GCM_SHA384:"
|
||||
+ "TLS_AES_128_GCM_SHA256";
|
||||
+#else
|
||||
return "TLS_AES_256_GCM_SHA384:"
|
||||
"TLS_CHACHA20_POLY1305_SHA256:"
|
||||
"TLS_AES_128_GCM_SHA256";
|
||||
+#endif
|
||||
}
|
||||
--- a/include/openssl/ssl.h.in
|
||||
+++ b/include/openssl/ssl.h.in
|
||||
@@ -195,9 +195,15 @@ extern "C" {
|
||||
* DEPRECATED IN 3.0.0, in favor of OSSL_default_ciphersuites()
|
||||
* Update both macro and function simultaneously
|
||||
*/
|
||||
-# define TLS_DEFAULT_CIPHERSUITES "TLS_AES_256_GCM_SHA384:" \
|
||||
- "TLS_CHACHA20_POLY1305_SHA256:" \
|
||||
- "TLS_AES_128_GCM_SHA256"
|
||||
+# ifdef OPENSSL_PREFER_CHACHA_OVER_GCM
|
||||
+# define TLS_DEFAULT_CIPHERSUITES "TLS_CHACHA20_POLY1305_SHA256:" \
|
||||
+ "TLS_AES_256_GCM_SHA384:" \
|
||||
+ "TLS_AES_128_GCM_SHA256"
|
||||
+# else
|
||||
+# define TLS_DEFAULT_CIPHERSUITES "TLS_AES_256_GCM_SHA384:" \
|
||||
+ "TLS_CHACHA20_POLY1305_SHA256:" \
|
||||
+ "TLS_AES_128_GCM_SHA256"
|
||||
+# endif
|
||||
# endif
|
||||
/*
|
||||
* As of OpenSSL 1.0.0, ssl_create_cipher_list() in ssl/ssl_ciph.c always
|
||||
|
@ -10,7 +10,7 @@ Signed-off-by: Eneas U de Queiroz <cotequeiroz@gmail.com>
|
||||
|
||||
--- a/apps/openssl.cnf
|
||||
+++ b/apps/openssl.cnf
|
||||
@@ -22,6 +22,16 @@ oid_section = new_oids
|
||||
@@ -30,6 +30,16 @@ oid_section = new_oids
|
||||
# (Alternatively, use a configuration file that has only
|
||||
# X.509v3 extensions in its main [= default] section.)
|
||||
|
||||
@ -25,5 +25,5 @@ Signed-off-by: Eneas U de Queiroz <cotequeiroz@gmail.com>
|
||||
+.include /etc/ssl/engines.cnf.d
|
||||
+
|
||||
[ new_oids ]
|
||||
|
||||
# We can add new OIDs in here for use by 'ca', 'req' and 'ts'.
|
||||
# Add a simple OID like this:
|
||||
|
@ -1,58 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Eneas U de Queiroz <cote2004-github@yahoo.com>
|
||||
Date: Mon, 5 Nov 2018 15:54:17 -0200
|
||||
Subject: eng_devcrypto: save ioctl if EVP_MD_..FLAG_ONESHOT
|
||||
|
||||
Since each ioctl causes a context switch, slowing things down, if
|
||||
EVP_MD_CTX_FLAG_ONESHOT is set, then:
|
||||
- call the ioctl in digest_update, saving the result; and
|
||||
- just copy the result in digest_final, instead of using another ioctl.
|
||||
|
||||
Signed-off-by: Eneas U de Queiroz <cote2004-github@yahoo.com>
|
||||
|
||||
Reviewed-by: Matthias St. Pierre <Matthias.St.Pierre@ncp-e.com>
|
||||
Reviewed-by: Richard Levitte <levitte@openssl.org>
|
||||
(Merged from https://github.com/openssl/openssl/pull/7585)
|
||||
|
||||
--- a/crypto/engine/eng_devcrypto.c
|
||||
+++ b/crypto/engine/eng_devcrypto.c
|
||||
@@ -461,6 +461,7 @@ struct digest_ctx {
|
||||
struct session_op sess;
|
||||
/* This signals that the init function was called, not that it succeeded. */
|
||||
int init_called;
|
||||
+ unsigned char digest_res[HASH_MAX_LEN];
|
||||
};
|
||||
|
||||
static const struct digest_data_st {
|
||||
@@ -564,12 +565,15 @@ static int digest_update(EVP_MD_CTX *ctx
|
||||
if (digest_ctx == NULL)
|
||||
return 0;
|
||||
|
||||
- if (digest_op(digest_ctx, data, count, NULL, COP_FLAG_UPDATE) < 0) {
|
||||
- SYSerr(SYS_F_IOCTL, errno);
|
||||
- return 0;
|
||||
+ if (EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_ONESHOT)) {
|
||||
+ if (digest_op(digest_ctx, data, count, digest_ctx->digest_res, 0) >= 0)
|
||||
+ return 1;
|
||||
+ } else if (digest_op(digest_ctx, data, count, NULL, COP_FLAG_UPDATE) >= 0) {
|
||||
+ return 1;
|
||||
}
|
||||
|
||||
- return 1;
|
||||
+ SYSerr(SYS_F_IOCTL, errno);
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
static int digest_final(EVP_MD_CTX *ctx, unsigned char *md)
|
||||
@@ -579,7 +583,10 @@ static int digest_final(EVP_MD_CTX *ctx,
|
||||
|
||||
if (md == NULL || digest_ctx == NULL)
|
||||
return 0;
|
||||
- if (digest_op(digest_ctx, NULL, 0, md, COP_FLAG_FINAL) < 0) {
|
||||
+
|
||||
+ if (EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_ONESHOT)) {
|
||||
+ memcpy(md, digest_ctx->digest_res, EVP_MD_CTX_size(ctx));
|
||||
+ } else if (digest_op(digest_ctx, NULL, 0, md, COP_FLAG_FINAL) < 0) {
|
||||
SYSerr(SYS_F_IOCTL, errno);
|
||||
return 0;
|
||||
}
|
@ -1,566 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Eneas U de Queiroz <cote2004-github@yahoo.com>
|
||||
Date: Sat, 3 Nov 2018 15:41:10 -0300
|
||||
Subject: eng_devcrypto: add configuration options
|
||||
|
||||
USE_SOFTDRIVERS: whether to use software (not accelerated) drivers
|
||||
CIPHERS: list of ciphers to enable
|
||||
DIGESTS: list of digests to enable
|
||||
|
||||
Signed-off-by: Eneas U de Queiroz <cote2004-github@yahoo.com>
|
||||
|
||||
Reviewed-by: Matthias St. Pierre <Matthias.St.Pierre@ncp-e.com>
|
||||
Reviewed-by: Richard Levitte <levitte@openssl.org>
|
||||
(Merged from https://github.com/openssl/openssl/pull/7585)
|
||||
|
||||
--- a/crypto/engine/eng_devcrypto.c
|
||||
+++ b/crypto/engine/eng_devcrypto.c
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <unistd.h>
|
||||
#include <assert.h>
|
||||
|
||||
+#include <openssl/conf.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/engine.h>
|
||||
@@ -36,6 +37,30 @@
|
||||
* saner... why re-open /dev/crypto for every session?
|
||||
*/
|
||||
static int cfd;
|
||||
+#define DEVCRYPTO_REQUIRE_ACCELERATED 0 /* require confirmation of acceleration */
|
||||
+#define DEVCRYPTO_USE_SOFTWARE 1 /* allow software drivers */
|
||||
+#define DEVCRYPTO_REJECT_SOFTWARE 2 /* only disallow confirmed software drivers */
|
||||
+
|
||||
+#define DEVCRYPTO_DEFAULT_USE_SOFDTRIVERS DEVCRYPTO_REJECT_SOFTWARE
|
||||
+static int use_softdrivers = DEVCRYPTO_DEFAULT_USE_SOFDTRIVERS;
|
||||
+
|
||||
+/*
|
||||
+ * cipher/digest status & acceleration definitions
|
||||
+ * Make sure the defaults are set to 0
|
||||
+ */
|
||||
+struct driver_info_st {
|
||||
+ enum devcrypto_status_t {
|
||||
+ DEVCRYPTO_STATUS_UNUSABLE = -1, /* session open failed */
|
||||
+ DEVCRYPTO_STATUS_UNKNOWN = 0, /* not tested yet */
|
||||
+ DEVCRYPTO_STATUS_USABLE = 1 /* algo can be used */
|
||||
+ } status;
|
||||
+
|
||||
+ enum devcrypto_accelerated_t {
|
||||
+ DEVCRYPTO_NOT_ACCELERATED = -1, /* software implemented */
|
||||
+ DEVCRYPTO_ACCELERATION_UNKNOWN = 0, /* acceleration support unkown */
|
||||
+ DEVCRYPTO_ACCELERATED = 1 /* hardware accelerated */
|
||||
+ } accelerated;
|
||||
+};
|
||||
|
||||
static int clean_devcrypto_session(struct session_op *sess) {
|
||||
if (ioctl(cfd, CIOCFSESSION, &sess->ses) < 0) {
|
||||
@@ -119,13 +144,22 @@ static const struct cipher_data_st {
|
||||
#endif
|
||||
};
|
||||
|
||||
-static size_t get_cipher_data_index(int nid)
|
||||
+static size_t find_cipher_data_index(int nid)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < OSSL_NELEM(cipher_data); i++)
|
||||
if (nid == cipher_data[i].nid)
|
||||
return i;
|
||||
+ return (size_t)-1;
|
||||
+}
|
||||
+
|
||||
+static size_t get_cipher_data_index(int nid)
|
||||
+{
|
||||
+ size_t i = find_cipher_data_index(nid);
|
||||
+
|
||||
+ if (i != (size_t)-1)
|
||||
+ return i;
|
||||
|
||||
/*
|
||||
* Code further down must make sure that only NIDs in the table above
|
||||
@@ -333,19 +367,40 @@ static int cipher_cleanup(EVP_CIPHER_CTX
|
||||
}
|
||||
|
||||
/*
|
||||
- * Keep a table of known nids and associated methods.
|
||||
+ * Keep tables of known nids, associated methods, selected ciphers, and driver
|
||||
+ * info.
|
||||
* Note that known_cipher_nids[] isn't necessarily indexed the same way as
|
||||
- * cipher_data[] above, which known_cipher_methods[] is.
|
||||
+ * cipher_data[] above, which the other tables are.
|
||||
*/
|
||||
static int known_cipher_nids[OSSL_NELEM(cipher_data)];
|
||||
static int known_cipher_nids_amount = -1; /* -1 indicates not yet initialised */
|
||||
static EVP_CIPHER *known_cipher_methods[OSSL_NELEM(cipher_data)] = { NULL, };
|
||||
+static int selected_ciphers[OSSL_NELEM(cipher_data)];
|
||||
+static struct driver_info_st cipher_driver_info[OSSL_NELEM(cipher_data)];
|
||||
+
|
||||
+
|
||||
+static int devcrypto_test_cipher(size_t cipher_data_index)
|
||||
+{
|
||||
+ return (cipher_driver_info[cipher_data_index].status == DEVCRYPTO_STATUS_USABLE
|
||||
+ && selected_ciphers[cipher_data_index] == 1
|
||||
+ && (cipher_driver_info[cipher_data_index].accelerated
|
||||
+ == DEVCRYPTO_ACCELERATED
|
||||
+ || use_softdrivers == DEVCRYPTO_USE_SOFTWARE
|
||||
+ || (cipher_driver_info[cipher_data_index].accelerated
|
||||
+ != DEVCRYPTO_NOT_ACCELERATED
|
||||
+ && use_softdrivers == DEVCRYPTO_REJECT_SOFTWARE)));
|
||||
+}
|
||||
|
||||
static void prepare_cipher_methods(void)
|
||||
{
|
||||
size_t i;
|
||||
struct session_op sess;
|
||||
unsigned long cipher_mode;
|
||||
+#ifdef CIOCGSESSINFO
|
||||
+ struct session_info_op siop;
|
||||
+#endif
|
||||
+
|
||||
+ memset(&cipher_driver_info, 0, sizeof(cipher_driver_info));
|
||||
|
||||
memset(&sess, 0, sizeof(sess));
|
||||
sess.key = (void *)"01234567890123456789012345678901234567890123456789";
|
||||
@@ -353,15 +408,16 @@ static void prepare_cipher_methods(void)
|
||||
for (i = 0, known_cipher_nids_amount = 0;
|
||||
i < OSSL_NELEM(cipher_data); i++) {
|
||||
|
||||
+ selected_ciphers[i] = 1;
|
||||
/*
|
||||
- * Check that the algo is really availably by trying to open and close
|
||||
- * a session.
|
||||
+ * Check that the cipher is usable
|
||||
*/
|
||||
sess.cipher = cipher_data[i].devcryptoid;
|
||||
sess.keylen = cipher_data[i].keylen;
|
||||
- if (ioctl(cfd, CIOCGSESSION, &sess) < 0
|
||||
- || ioctl(cfd, CIOCFSESSION, &sess.ses) < 0)
|
||||
+ if (ioctl(cfd, CIOCGSESSION, &sess) < 0) {
|
||||
+ cipher_driver_info[i].status = DEVCRYPTO_STATUS_UNUSABLE;
|
||||
continue;
|
||||
+ }
|
||||
|
||||
cipher_mode = cipher_data[i].flags & EVP_CIPH_MODE;
|
||||
|
||||
@@ -387,15 +443,41 @@ static void prepare_cipher_methods(void)
|
||||
cipher_cleanup)
|
||||
|| !EVP_CIPHER_meth_set_impl_ctx_size(known_cipher_methods[i],
|
||||
sizeof(struct cipher_ctx))) {
|
||||
+ cipher_driver_info[i].status = DEVCRYPTO_STATUS_UNUSABLE;
|
||||
EVP_CIPHER_meth_free(known_cipher_methods[i]);
|
||||
known_cipher_methods[i] = NULL;
|
||||
} else {
|
||||
+ cipher_driver_info[i].status = DEVCRYPTO_STATUS_USABLE;
|
||||
+#ifdef CIOCGSESSINFO
|
||||
+ siop.ses = sess.ses;
|
||||
+ if (ioctl(cfd, CIOCGSESSINFO, &siop) < 0)
|
||||
+ cipher_driver_info[i].accelerated = DEVCRYPTO_ACCELERATION_UNKNOWN;
|
||||
+ else if (!(siop.flags & SIOP_FLAG_KERNEL_DRIVER_ONLY))
|
||||
+ cipher_driver_info[i].accelerated = DEVCRYPTO_NOT_ACCELERATED;
|
||||
+ else
|
||||
+ cipher_driver_info[i].accelerated = DEVCRYPTO_ACCELERATED;
|
||||
+#endif /* CIOCGSESSINFO */
|
||||
+ }
|
||||
+ ioctl(cfd, CIOCFSESSION, &sess.ses);
|
||||
+ if (devcrypto_test_cipher(i)) {
|
||||
known_cipher_nids[known_cipher_nids_amount++] =
|
||||
cipher_data[i].nid;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+static void rebuild_known_cipher_nids(ENGINE *e)
|
||||
+{
|
||||
+ size_t i;
|
||||
+
|
||||
+ for (i = 0, known_cipher_nids_amount = 0; i < OSSL_NELEM(cipher_data); i++) {
|
||||
+ if (devcrypto_test_cipher(i))
|
||||
+ known_cipher_nids[known_cipher_nids_amount++] = cipher_data[i].nid;
|
||||
+ }
|
||||
+ ENGINE_unregister_ciphers(e);
|
||||
+ ENGINE_register_ciphers(e);
|
||||
+}
|
||||
+
|
||||
static const EVP_CIPHER *get_cipher_method(int nid)
|
||||
{
|
||||
size_t i = get_cipher_data_index(nid);
|
||||
@@ -438,6 +520,36 @@ static int devcrypto_ciphers(ENGINE *e,
|
||||
return *cipher != NULL;
|
||||
}
|
||||
|
||||
+static void devcrypto_select_all_ciphers(int *cipher_list)
|
||||
+{
|
||||
+ size_t i;
|
||||
+
|
||||
+ for (i = 0; i < OSSL_NELEM(cipher_data); i++)
|
||||
+ cipher_list[i] = 1;
|
||||
+}
|
||||
+
|
||||
+static int cryptodev_select_cipher_cb(const char *str, int len, void *usr)
|
||||
+{
|
||||
+ int *cipher_list = (int *)usr;
|
||||
+ char *name;
|
||||
+ const EVP_CIPHER *EVP;
|
||||
+ size_t i;
|
||||
+
|
||||
+ if (len == 0)
|
||||
+ return 1;
|
||||
+ if (usr == NULL || (name = OPENSSL_strndup(str, len)) == NULL)
|
||||
+ return 0;
|
||||
+ EVP = EVP_get_cipherbyname(name);
|
||||
+ if (EVP == NULL)
|
||||
+ fprintf(stderr, "devcrypto: unknown cipher %s\n", name);
|
||||
+ else if ((i = find_cipher_data_index(EVP_CIPHER_nid(EVP))) != (size_t)-1)
|
||||
+ cipher_list[i] = 1;
|
||||
+ else
|
||||
+ fprintf(stderr, "devcrypto: cipher %s not available\n", name);
|
||||
+ OPENSSL_free(name);
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* We only support digests if the cryptodev implementation supports multiple
|
||||
* data updates and session copying. Otherwise, we would be forced to maintain
|
||||
@@ -493,13 +605,22 @@ static const struct digest_data_st {
|
||||
#endif
|
||||
};
|
||||
|
||||
-static size_t get_digest_data_index(int nid)
|
||||
+static size_t find_digest_data_index(int nid)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < OSSL_NELEM(digest_data); i++)
|
||||
if (nid == digest_data[i].nid)
|
||||
return i;
|
||||
+ return (size_t)-1;
|
||||
+}
|
||||
+
|
||||
+static size_t get_digest_data_index(int nid)
|
||||
+{
|
||||
+ size_t i = find_digest_data_index(nid);
|
||||
+
|
||||
+ if (i != (size_t)-1)
|
||||
+ return i;
|
||||
|
||||
/*
|
||||
* Code further down must make sure that only NIDs in the table above
|
||||
@@ -516,8 +637,8 @@ static const struct digest_data_st *get_
|
||||
}
|
||||
|
||||
/*
|
||||
- * Following are the four necessary functions to map OpenSSL functionality
|
||||
- * with cryptodev.
|
||||
+ * Following are the five necessary functions to map OpenSSL functionality
|
||||
+ * with cryptodev: init, update, final, cleanup, and copy.
|
||||
*/
|
||||
|
||||
static int digest_init(EVP_MD_CTX *ctx)
|
||||
@@ -630,52 +751,94 @@ static int digest_cleanup(EVP_MD_CTX *ct
|
||||
return clean_devcrypto_session(&digest_ctx->sess);
|
||||
}
|
||||
|
||||
-static int devcrypto_test_digest(size_t digest_data_index)
|
||||
-{
|
||||
- struct session_op sess1, sess2;
|
||||
- struct cphash_op cphash;
|
||||
- int ret=0;
|
||||
-
|
||||
- memset(&sess1, 0, sizeof(sess1));
|
||||
- memset(&sess2, 0, sizeof(sess2));
|
||||
- sess1.mac = digest_data[digest_data_index].devcryptoid;
|
||||
- if (ioctl(cfd, CIOCGSESSION, &sess1) < 0)
|
||||
- return 0;
|
||||
- /* Make sure the driver is capable of hash state copy */
|
||||
- sess2.mac = sess1.mac;
|
||||
- if (ioctl(cfd, CIOCGSESSION, &sess2) >= 0) {
|
||||
- cphash.src_ses = sess1.ses;
|
||||
- cphash.dst_ses = sess2.ses;
|
||||
- if (ioctl(cfd, CIOCCPHASH, &cphash) >= 0)
|
||||
- ret = 1;
|
||||
- ioctl(cfd, CIOCFSESSION, &sess2.ses);
|
||||
- }
|
||||
- ioctl(cfd, CIOCFSESSION, &sess1.ses);
|
||||
- return ret;
|
||||
-}
|
||||
-
|
||||
/*
|
||||
- * Keep a table of known nids and associated methods.
|
||||
+ * Keep tables of known nids, associated methods, selected digests, and
|
||||
+ * driver info.
|
||||
* Note that known_digest_nids[] isn't necessarily indexed the same way as
|
||||
- * digest_data[] above, which known_digest_methods[] is.
|
||||
+ * digest_data[] above, which the other tables are.
|
||||
*/
|
||||
static int known_digest_nids[OSSL_NELEM(digest_data)];
|
||||
static int known_digest_nids_amount = -1; /* -1 indicates not yet initialised */
|
||||
static EVP_MD *known_digest_methods[OSSL_NELEM(digest_data)] = { NULL, };
|
||||
+static int selected_digests[OSSL_NELEM(digest_data)];
|
||||
+static struct driver_info_st digest_driver_info[OSSL_NELEM(digest_data)];
|
||||
+
|
||||
+static int devcrypto_test_digest(size_t digest_data_index)
|
||||
+{
|
||||
+ return (digest_driver_info[digest_data_index].status == DEVCRYPTO_STATUS_USABLE
|
||||
+ && selected_digests[digest_data_index] == 1
|
||||
+ && (digest_driver_info[digest_data_index].accelerated
|
||||
+ == DEVCRYPTO_ACCELERATED
|
||||
+ || use_softdrivers == DEVCRYPTO_USE_SOFTWARE
|
||||
+ || (digest_driver_info[digest_data_index].accelerated
|
||||
+ != DEVCRYPTO_NOT_ACCELERATED
|
||||
+ && use_softdrivers == DEVCRYPTO_REJECT_SOFTWARE)));
|
||||
+}
|
||||
+
|
||||
+static void rebuild_known_digest_nids(ENGINE *e)
|
||||
+{
|
||||
+ size_t i;
|
||||
+
|
||||
+ for (i = 0, known_digest_nids_amount = 0; i < OSSL_NELEM(digest_data); i++) {
|
||||
+ if (devcrypto_test_digest(i))
|
||||
+ known_digest_nids[known_digest_nids_amount++] = digest_data[i].nid;
|
||||
+ }
|
||||
+ ENGINE_unregister_digests(e);
|
||||
+ ENGINE_register_digests(e);
|
||||
+}
|
||||
|
||||
static void prepare_digest_methods(void)
|
||||
{
|
||||
size_t i;
|
||||
+ struct session_op sess1, sess2;
|
||||
+#ifdef CIOCGSESSINFO
|
||||
+ struct session_info_op siop;
|
||||
+#endif
|
||||
+ struct cphash_op cphash;
|
||||
+
|
||||
+ memset(&digest_driver_info, 0, sizeof(digest_driver_info));
|
||||
+
|
||||
+ memset(&sess1, 0, sizeof(sess1));
|
||||
+ memset(&sess2, 0, sizeof(sess2));
|
||||
|
||||
for (i = 0, known_digest_nids_amount = 0; i < OSSL_NELEM(digest_data);
|
||||
i++) {
|
||||
|
||||
+ selected_digests[i] = 1;
|
||||
+
|
||||
/*
|
||||
- * Check that the algo is usable
|
||||
+ * Check that the digest is usable
|
||||
*/
|
||||
- if (!devcrypto_test_digest(i))
|
||||
- continue;
|
||||
+ sess1.mac = digest_data[i].devcryptoid;
|
||||
+ sess2.ses = 0;
|
||||
+ if (ioctl(cfd, CIOCGSESSION, &sess1) < 0) {
|
||||
+ digest_driver_info[i].status = DEVCRYPTO_STATUS_UNUSABLE;
|
||||
+ goto finish;
|
||||
+ }
|
||||
|
||||
+#ifdef CIOCGSESSINFO
|
||||
+ /* gather hardware acceleration info from the driver */
|
||||
+ siop.ses = sess1.ses;
|
||||
+ if (ioctl(cfd, CIOCGSESSINFO, &siop) < 0)
|
||||
+ digest_driver_info[i].accelerated = DEVCRYPTO_ACCELERATION_UNKNOWN;
|
||||
+ else if (siop.flags & SIOP_FLAG_KERNEL_DRIVER_ONLY)
|
||||
+ digest_driver_info[i].accelerated = DEVCRYPTO_ACCELERATED;
|
||||
+ else
|
||||
+ digest_driver_info[i].accelerated = DEVCRYPTO_NOT_ACCELERATED;
|
||||
+#endif
|
||||
+
|
||||
+ /* digest must be capable of hash state copy */
|
||||
+ sess2.mac = sess1.mac;
|
||||
+ if (ioctl(cfd, CIOCGSESSION, &sess2) < 0) {
|
||||
+ digest_driver_info[i].status = DEVCRYPTO_STATUS_UNUSABLE;
|
||||
+ goto finish;
|
||||
+ }
|
||||
+ cphash.src_ses = sess1.ses;
|
||||
+ cphash.dst_ses = sess2.ses;
|
||||
+ if (ioctl(cfd, CIOCCPHASH, &cphash) < 0) {
|
||||
+ digest_driver_info[i].status = DEVCRYPTO_STATUS_UNUSABLE;
|
||||
+ goto finish;
|
||||
+ }
|
||||
if ((known_digest_methods[i] = EVP_MD_meth_new(digest_data[i].nid,
|
||||
NID_undef)) == NULL
|
||||
|| !EVP_MD_meth_set_input_blocksize(known_digest_methods[i],
|
||||
@@ -689,11 +852,18 @@ static void prepare_digest_methods(void)
|
||||
|| !EVP_MD_meth_set_cleanup(known_digest_methods[i], digest_cleanup)
|
||||
|| !EVP_MD_meth_set_app_datasize(known_digest_methods[i],
|
||||
sizeof(struct digest_ctx))) {
|
||||
+ digest_driver_info[i].status = DEVCRYPTO_STATUS_UNUSABLE;
|
||||
EVP_MD_meth_free(known_digest_methods[i]);
|
||||
known_digest_methods[i] = NULL;
|
||||
- } else {
|
||||
- known_digest_nids[known_digest_nids_amount++] = digest_data[i].nid;
|
||||
+ goto finish;
|
||||
}
|
||||
+ digest_driver_info[i].status = DEVCRYPTO_STATUS_USABLE;
|
||||
+finish:
|
||||
+ ioctl(cfd, CIOCFSESSION, &sess1.ses);
|
||||
+ if (sess2.ses != 0)
|
||||
+ ioctl(cfd, CIOCFSESSION, &sess2.ses);
|
||||
+ if (devcrypto_test_digest(i))
|
||||
+ known_digest_nids[known_digest_nids_amount++] = digest_data[i].nid;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -739,7 +909,153 @@ static int devcrypto_digests(ENGINE *e,
|
||||
return *digest != NULL;
|
||||
}
|
||||
|
||||
+static void devcrypto_select_all_digests(int *digest_list)
|
||||
+{
|
||||
+ size_t i;
|
||||
+
|
||||
+ for (i = 0; i < OSSL_NELEM(digest_data); i++)
|
||||
+ digest_list[i] = 1;
|
||||
+}
|
||||
+
|
||||
+static int cryptodev_select_digest_cb(const char *str, int len, void *usr)
|
||||
+{
|
||||
+ int *digest_list = (int *)usr;
|
||||
+ char *name;
|
||||
+ const EVP_MD *EVP;
|
||||
+ size_t i;
|
||||
+
|
||||
+ if (len == 0)
|
||||
+ return 1;
|
||||
+ if (usr == NULL || (name = OPENSSL_strndup(str, len)) == NULL)
|
||||
+ return 0;
|
||||
+ EVP = EVP_get_digestbyname(name);
|
||||
+ if (EVP == NULL)
|
||||
+ fprintf(stderr, "devcrypto: unknown digest %s\n", name);
|
||||
+ else if ((i = find_digest_data_index(EVP_MD_type(EVP))) != (size_t)-1)
|
||||
+ digest_list[i] = 1;
|
||||
+ else
|
||||
+ fprintf(stderr, "devcrypto: digest %s not available\n", name);
|
||||
+ OPENSSL_free(name);
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+#endif
|
||||
+
|
||||
+/******************************************************************************
|
||||
+ *
|
||||
+ * CONTROL COMMANDS
|
||||
+ *
|
||||
+ *****/
|
||||
+
|
||||
+#define DEVCRYPTO_CMD_USE_SOFTDRIVERS ENGINE_CMD_BASE
|
||||
+#define DEVCRYPTO_CMD_CIPHERS (ENGINE_CMD_BASE + 1)
|
||||
+#define DEVCRYPTO_CMD_DIGESTS (ENGINE_CMD_BASE + 2)
|
||||
+#define DEVCRYPTO_CMD_DUMP_INFO (ENGINE_CMD_BASE + 3)
|
||||
+
|
||||
+/* Helper macros for CPP string composition */
|
||||
+#ifndef OPENSSL_MSTR
|
||||
+# define OPENSSL_MSTR_HELPER(x) #x
|
||||
+# define OPENSSL_MSTR(x) OPENSSL_MSTR_HELPER(x)
|
||||
+#endif
|
||||
+
|
||||
+static const ENGINE_CMD_DEFN devcrypto_cmds[] = {
|
||||
+#ifdef CIOCGSESSINFO
|
||||
+ {DEVCRYPTO_CMD_USE_SOFTDRIVERS,
|
||||
+ "USE_SOFTDRIVERS",
|
||||
+ "specifies whether to use software (not accelerated) drivers ("
|
||||
+ OPENSSL_MSTR(DEVCRYPTO_REQUIRE_ACCELERATED) "=use only accelerated drivers, "
|
||||
+ OPENSSL_MSTR(DEVCRYPTO_USE_SOFTWARE) "=allow all drivers, "
|
||||
+ OPENSSL_MSTR(DEVCRYPTO_REJECT_SOFTWARE)
|
||||
+ "=use if acceleration can't be determined) [default="
|
||||
+ OPENSSL_MSTR(DEVCRYPTO_DEFAULT_USE_SOFDTRIVERS) "]",
|
||||
+ ENGINE_CMD_FLAG_NUMERIC},
|
||||
+#endif
|
||||
+
|
||||
+ {DEVCRYPTO_CMD_CIPHERS,
|
||||
+ "CIPHERS",
|
||||
+ "either ALL, NONE, or a comma-separated list of ciphers to enable [default=ALL]",
|
||||
+ ENGINE_CMD_FLAG_STRING},
|
||||
+
|
||||
+#ifdef IMPLEMENT_DIGEST
|
||||
+ {DEVCRYPTO_CMD_DIGESTS,
|
||||
+ "DIGESTS",
|
||||
+ "either ALL, NONE, or a comma-separated list of digests to enable [default=ALL]",
|
||||
+ ENGINE_CMD_FLAG_STRING},
|
||||
+#endif
|
||||
+
|
||||
+ {0, NULL, NULL, 0}
|
||||
+};
|
||||
+
|
||||
+static int devcrypto_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void))
|
||||
+{
|
||||
+ int *new_list;
|
||||
+ switch (cmd) {
|
||||
+#ifdef CIOCGSESSINFO
|
||||
+ case DEVCRYPTO_CMD_USE_SOFTDRIVERS:
|
||||
+ switch (i) {
|
||||
+ case DEVCRYPTO_REQUIRE_ACCELERATED:
|
||||
+ case DEVCRYPTO_USE_SOFTWARE:
|
||||
+ case DEVCRYPTO_REJECT_SOFTWARE:
|
||||
+ break;
|
||||
+ default:
|
||||
+ fprintf(stderr, "devcrypto: invalid value (%ld) for USE_SOFTDRIVERS\n", i);
|
||||
+ return 0;
|
||||
+ }
|
||||
+ if (use_softdrivers == i)
|
||||
+ return 1;
|
||||
+ use_softdrivers = i;
|
||||
+#ifdef IMPLEMENT_DIGEST
|
||||
+ rebuild_known_digest_nids(e);
|
||||
#endif
|
||||
+ rebuild_known_cipher_nids(e);
|
||||
+ return 1;
|
||||
+#endif /* CIOCGSESSINFO */
|
||||
+
|
||||
+ case DEVCRYPTO_CMD_CIPHERS:
|
||||
+ if (p == NULL)
|
||||
+ return 1;
|
||||
+ if (strcasecmp((const char *)p, "ALL") == 0) {
|
||||
+ devcrypto_select_all_ciphers(selected_ciphers);
|
||||
+ } else if (strcasecmp((const char*)p, "NONE") == 0) {
|
||||
+ memset(selected_ciphers, 0, sizeof(selected_ciphers));
|
||||
+ } else {
|
||||
+ new_list=OPENSSL_zalloc(sizeof(selected_ciphers));
|
||||
+ if (!CONF_parse_list(p, ',', 1, cryptodev_select_cipher_cb, new_list)) {
|
||||
+ OPENSSL_free(new_list);
|
||||
+ return 0;
|
||||
+ }
|
||||
+ memcpy(selected_ciphers, new_list, sizeof(selected_ciphers));
|
||||
+ OPENSSL_free(new_list);
|
||||
+ }
|
||||
+ rebuild_known_cipher_nids(e);
|
||||
+ return 1;
|
||||
+
|
||||
+#ifdef IMPLEMENT_DIGEST
|
||||
+ case DEVCRYPTO_CMD_DIGESTS:
|
||||
+ if (p == NULL)
|
||||
+ return 1;
|
||||
+ if (strcasecmp((const char *)p, "ALL") == 0) {
|
||||
+ devcrypto_select_all_digests(selected_digests);
|
||||
+ } else if (strcasecmp((const char*)p, "NONE") == 0) {
|
||||
+ memset(selected_digests, 0, sizeof(selected_digests));
|
||||
+ } else {
|
||||
+ new_list=OPENSSL_zalloc(sizeof(selected_digests));
|
||||
+ if (!CONF_parse_list(p, ',', 1, cryptodev_select_digest_cb, new_list)) {
|
||||
+ OPENSSL_free(new_list);
|
||||
+ return 0;
|
||||
+ }
|
||||
+ memcpy(selected_digests, new_list, sizeof(selected_digests));
|
||||
+ OPENSSL_free(new_list);
|
||||
+ }
|
||||
+ rebuild_known_digest_nids(e);
|
||||
+ return 1;
|
||||
+#endif /* IMPLEMENT_DIGEST */
|
||||
+
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
@@ -806,6 +1122,8 @@ void engine_load_devcrypto_int()
|
||||
|
||||
if (!ENGINE_set_id(e, "devcrypto")
|
||||
|| !ENGINE_set_name(e, "/dev/crypto engine")
|
||||
+ || !ENGINE_set_cmd_defns(e, devcrypto_cmds)
|
||||
+ || !ENGINE_set_ctrl_function(e, devcrypto_ctrl)
|
||||
|
||||
/*
|
||||
* Asymmetric ciphers aren't well supported with /dev/crypto. Among the BSD
|
@ -1,273 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Eneas U de Queiroz <cote2004-github@yahoo.com>
|
||||
Date: Tue, 6 Nov 2018 22:54:07 -0200
|
||||
Subject: eng_devcrypto: add command to dump driver info
|
||||
|
||||
This is useful to determine the kernel driver running each algorithm.
|
||||
|
||||
Signed-off-by: Eneas U de Queiroz <cote2004-github@yahoo.com>
|
||||
|
||||
Reviewed-by: Matthias St. Pierre <Matthias.St.Pierre@ncp-e.com>
|
||||
Reviewed-by: Richard Levitte <levitte@openssl.org>
|
||||
(Merged from https://github.com/openssl/openssl/pull/7585)
|
||||
|
||||
--- a/crypto/engine/eng_devcrypto.c
|
||||
+++ b/crypto/engine/eng_devcrypto.c
|
||||
@@ -50,16 +50,20 @@ static int use_softdrivers = DEVCRYPTO_D
|
||||
*/
|
||||
struct driver_info_st {
|
||||
enum devcrypto_status_t {
|
||||
- DEVCRYPTO_STATUS_UNUSABLE = -1, /* session open failed */
|
||||
- DEVCRYPTO_STATUS_UNKNOWN = 0, /* not tested yet */
|
||||
- DEVCRYPTO_STATUS_USABLE = 1 /* algo can be used */
|
||||
+ DEVCRYPTO_STATUS_FAILURE = -3, /* unusable for other reason */
|
||||
+ DEVCRYPTO_STATUS_NO_CIOCCPHASH = -2, /* hash state copy not supported */
|
||||
+ DEVCRYPTO_STATUS_NO_CIOCGSESSION = -1, /* session open failed */
|
||||
+ DEVCRYPTO_STATUS_UNKNOWN = 0, /* not tested yet */
|
||||
+ DEVCRYPTO_STATUS_USABLE = 1 /* algo can be used */
|
||||
} status;
|
||||
|
||||
enum devcrypto_accelerated_t {
|
||||
- DEVCRYPTO_NOT_ACCELERATED = -1, /* software implemented */
|
||||
- DEVCRYPTO_ACCELERATION_UNKNOWN = 0, /* acceleration support unkown */
|
||||
- DEVCRYPTO_ACCELERATED = 1 /* hardware accelerated */
|
||||
+ DEVCRYPTO_NOT_ACCELERATED = -1, /* software implemented */
|
||||
+ DEVCRYPTO_ACCELERATION_UNKNOWN = 0, /* acceleration support unkown */
|
||||
+ DEVCRYPTO_ACCELERATED = 1 /* hardware accelerated */
|
||||
} accelerated;
|
||||
+
|
||||
+ char *driver_name;
|
||||
};
|
||||
|
||||
static int clean_devcrypto_session(struct session_op *sess) {
|
||||
@@ -415,7 +419,7 @@ static void prepare_cipher_methods(void)
|
||||
sess.cipher = cipher_data[i].devcryptoid;
|
||||
sess.keylen = cipher_data[i].keylen;
|
||||
if (ioctl(cfd, CIOCGSESSION, &sess) < 0) {
|
||||
- cipher_driver_info[i].status = DEVCRYPTO_STATUS_UNUSABLE;
|
||||
+ cipher_driver_info[i].status = DEVCRYPTO_STATUS_NO_CIOCGSESSION;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -443,19 +447,24 @@ static void prepare_cipher_methods(void)
|
||||
cipher_cleanup)
|
||||
|| !EVP_CIPHER_meth_set_impl_ctx_size(known_cipher_methods[i],
|
||||
sizeof(struct cipher_ctx))) {
|
||||
- cipher_driver_info[i].status = DEVCRYPTO_STATUS_UNUSABLE;
|
||||
+ cipher_driver_info[i].status = DEVCRYPTO_STATUS_FAILURE;
|
||||
EVP_CIPHER_meth_free(known_cipher_methods[i]);
|
||||
known_cipher_methods[i] = NULL;
|
||||
} else {
|
||||
cipher_driver_info[i].status = DEVCRYPTO_STATUS_USABLE;
|
||||
#ifdef CIOCGSESSINFO
|
||||
siop.ses = sess.ses;
|
||||
- if (ioctl(cfd, CIOCGSESSINFO, &siop) < 0)
|
||||
+ if (ioctl(cfd, CIOCGSESSINFO, &siop) < 0) {
|
||||
cipher_driver_info[i].accelerated = DEVCRYPTO_ACCELERATION_UNKNOWN;
|
||||
- else if (!(siop.flags & SIOP_FLAG_KERNEL_DRIVER_ONLY))
|
||||
- cipher_driver_info[i].accelerated = DEVCRYPTO_NOT_ACCELERATED;
|
||||
- else
|
||||
- cipher_driver_info[i].accelerated = DEVCRYPTO_ACCELERATED;
|
||||
+ } else {
|
||||
+ cipher_driver_info[i].driver_name =
|
||||
+ OPENSSL_strndup(siop.cipher_info.cra_driver_name,
|
||||
+ CRYPTODEV_MAX_ALG_NAME);
|
||||
+ if (!(siop.flags & SIOP_FLAG_KERNEL_DRIVER_ONLY))
|
||||
+ cipher_driver_info[i].accelerated = DEVCRYPTO_NOT_ACCELERATED;
|
||||
+ else
|
||||
+ cipher_driver_info[i].accelerated = DEVCRYPTO_ACCELERATED;
|
||||
+ }
|
||||
#endif /* CIOCGSESSINFO */
|
||||
}
|
||||
ioctl(cfd, CIOCFSESSION, &sess.ses);
|
||||
@@ -505,8 +514,11 @@ static void destroy_all_cipher_methods(v
|
||||
{
|
||||
size_t i;
|
||||
|
||||
- for (i = 0; i < OSSL_NELEM(cipher_data); i++)
|
||||
+ for (i = 0; i < OSSL_NELEM(cipher_data); i++) {
|
||||
destroy_cipher_method(cipher_data[i].nid);
|
||||
+ OPENSSL_free(cipher_driver_info[i].driver_name);
|
||||
+ cipher_driver_info[i].driver_name = NULL;
|
||||
+ }
|
||||
}
|
||||
|
||||
static int devcrypto_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
|
||||
@@ -550,6 +562,40 @@ static int cryptodev_select_cipher_cb(co
|
||||
return 1;
|
||||
}
|
||||
|
||||
+static void dump_cipher_info(void)
|
||||
+{
|
||||
+ size_t i;
|
||||
+ const char *name;
|
||||
+
|
||||
+ fprintf (stderr, "Information about ciphers supported by the /dev/crypto"
|
||||
+ " engine:\n");
|
||||
+#ifndef CIOCGSESSINFO
|
||||
+ fprintf(stderr, "CIOCGSESSINFO (session info call) unavailable\n");
|
||||
+#endif
|
||||
+ for (i = 0; i < OSSL_NELEM(cipher_data); i++) {
|
||||
+ name = OBJ_nid2sn(cipher_data[i].nid);
|
||||
+ fprintf (stderr, "Cipher %s, NID=%d, /dev/crypto info: id=%d, ",
|
||||
+ name ? name : "unknown", cipher_data[i].nid,
|
||||
+ cipher_data[i].devcryptoid);
|
||||
+ if (cipher_driver_info[i].status == DEVCRYPTO_STATUS_NO_CIOCGSESSION ) {
|
||||
+ fprintf (stderr, "CIOCGSESSION (session open call) failed\n");
|
||||
+ continue;
|
||||
+ }
|
||||
+ fprintf (stderr, "driver=%s ", cipher_driver_info[i].driver_name ?
|
||||
+ cipher_driver_info[i].driver_name : "unknown");
|
||||
+ if (cipher_driver_info[i].accelerated == DEVCRYPTO_ACCELERATED)
|
||||
+ fprintf(stderr, "(hw accelerated)");
|
||||
+ else if (cipher_driver_info[i].accelerated == DEVCRYPTO_NOT_ACCELERATED)
|
||||
+ fprintf(stderr, "(software)");
|
||||
+ else
|
||||
+ fprintf(stderr, "(acceleration status unknown)");
|
||||
+ if (cipher_driver_info[i].status == DEVCRYPTO_STATUS_FAILURE)
|
||||
+ fprintf (stderr, ". Cipher setup failed");
|
||||
+ fprintf(stderr, "\n");
|
||||
+ }
|
||||
+ fprintf(stderr, "\n");
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* We only support digests if the cryptodev implementation supports multiple
|
||||
* data updates and session copying. Otherwise, we would be forced to maintain
|
||||
@@ -812,31 +858,36 @@ static void prepare_digest_methods(void)
|
||||
sess1.mac = digest_data[i].devcryptoid;
|
||||
sess2.ses = 0;
|
||||
if (ioctl(cfd, CIOCGSESSION, &sess1) < 0) {
|
||||
- digest_driver_info[i].status = DEVCRYPTO_STATUS_UNUSABLE;
|
||||
+ digest_driver_info[i].status = DEVCRYPTO_STATUS_NO_CIOCGSESSION;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
#ifdef CIOCGSESSINFO
|
||||
/* gather hardware acceleration info from the driver */
|
||||
siop.ses = sess1.ses;
|
||||
- if (ioctl(cfd, CIOCGSESSINFO, &siop) < 0)
|
||||
+ if (ioctl(cfd, CIOCGSESSINFO, &siop) < 0) {
|
||||
digest_driver_info[i].accelerated = DEVCRYPTO_ACCELERATION_UNKNOWN;
|
||||
- else if (siop.flags & SIOP_FLAG_KERNEL_DRIVER_ONLY)
|
||||
- digest_driver_info[i].accelerated = DEVCRYPTO_ACCELERATED;
|
||||
- else
|
||||
- digest_driver_info[i].accelerated = DEVCRYPTO_NOT_ACCELERATED;
|
||||
+ } else {
|
||||
+ digest_driver_info[i].driver_name =
|
||||
+ OPENSSL_strndup(siop.hash_info.cra_driver_name,
|
||||
+ CRYPTODEV_MAX_ALG_NAME);
|
||||
+ if (siop.flags & SIOP_FLAG_KERNEL_DRIVER_ONLY)
|
||||
+ digest_driver_info[i].accelerated = DEVCRYPTO_ACCELERATED;
|
||||
+ else
|
||||
+ digest_driver_info[i].accelerated = DEVCRYPTO_NOT_ACCELERATED;
|
||||
+ }
|
||||
#endif
|
||||
|
||||
/* digest must be capable of hash state copy */
|
||||
sess2.mac = sess1.mac;
|
||||
if (ioctl(cfd, CIOCGSESSION, &sess2) < 0) {
|
||||
- digest_driver_info[i].status = DEVCRYPTO_STATUS_UNUSABLE;
|
||||
+ digest_driver_info[i].status = DEVCRYPTO_STATUS_FAILURE;
|
||||
goto finish;
|
||||
}
|
||||
cphash.src_ses = sess1.ses;
|
||||
cphash.dst_ses = sess2.ses;
|
||||
if (ioctl(cfd, CIOCCPHASH, &cphash) < 0) {
|
||||
- digest_driver_info[i].status = DEVCRYPTO_STATUS_UNUSABLE;
|
||||
+ digest_driver_info[i].status = DEVCRYPTO_STATUS_NO_CIOCCPHASH;
|
||||
goto finish;
|
||||
}
|
||||
if ((known_digest_methods[i] = EVP_MD_meth_new(digest_data[i].nid,
|
||||
@@ -852,7 +903,7 @@ static void prepare_digest_methods(void)
|
||||
|| !EVP_MD_meth_set_cleanup(known_digest_methods[i], digest_cleanup)
|
||||
|| !EVP_MD_meth_set_app_datasize(known_digest_methods[i],
|
||||
sizeof(struct digest_ctx))) {
|
||||
- digest_driver_info[i].status = DEVCRYPTO_STATUS_UNUSABLE;
|
||||
+ digest_driver_info[i].status = DEVCRYPTO_STATUS_FAILURE;
|
||||
EVP_MD_meth_free(known_digest_methods[i]);
|
||||
known_digest_methods[i] = NULL;
|
||||
goto finish;
|
||||
@@ -894,8 +945,11 @@ static void destroy_all_digest_methods(v
|
||||
{
|
||||
size_t i;
|
||||
|
||||
- for (i = 0; i < OSSL_NELEM(digest_data); i++)
|
||||
+ for (i = 0; i < OSSL_NELEM(digest_data); i++) {
|
||||
destroy_digest_method(digest_data[i].nid);
|
||||
+ OPENSSL_free(digest_driver_info[i].driver_name);
|
||||
+ digest_driver_info[i].driver_name = NULL;
|
||||
+ }
|
||||
}
|
||||
|
||||
static int devcrypto_digests(ENGINE *e, const EVP_MD **digest,
|
||||
@@ -939,6 +993,43 @@ static int cryptodev_select_digest_cb(co
|
||||
return 1;
|
||||
}
|
||||
|
||||
+static void dump_digest_info(void)
|
||||
+{
|
||||
+ size_t i;
|
||||
+ const char *name;
|
||||
+
|
||||
+ fprintf (stderr, "Information about digests supported by the /dev/crypto"
|
||||
+ " engine:\n");
|
||||
+#ifndef CIOCGSESSINFO
|
||||
+ fprintf(stderr, "CIOCGSESSINFO (session info call) unavailable\n");
|
||||
+#endif
|
||||
+
|
||||
+ for (i = 0; i < OSSL_NELEM(digest_data); i++) {
|
||||
+ name = OBJ_nid2sn(digest_data[i].nid);
|
||||
+ fprintf (stderr, "Digest %s, NID=%d, /dev/crypto info: id=%d, driver=%s",
|
||||
+ name ? name : "unknown", digest_data[i].nid,
|
||||
+ digest_data[i].devcryptoid,
|
||||
+ digest_driver_info[i].driver_name ? digest_driver_info[i].driver_name : "unknown");
|
||||
+ if (digest_driver_info[i].status == DEVCRYPTO_STATUS_NO_CIOCGSESSION) {
|
||||
+ fprintf (stderr, ". CIOCGSESSION (session open) failed\n");
|
||||
+ continue;
|
||||
+ }
|
||||
+ if (digest_driver_info[i].accelerated == DEVCRYPTO_ACCELERATED)
|
||||
+ fprintf(stderr, " (hw accelerated)");
|
||||
+ else if (digest_driver_info[i].accelerated == DEVCRYPTO_NOT_ACCELERATED)
|
||||
+ fprintf(stderr, " (software)");
|
||||
+ else
|
||||
+ fprintf(stderr, " (acceleration status unknown)");
|
||||
+ if (cipher_driver_info[i].status == DEVCRYPTO_STATUS_FAILURE)
|
||||
+ fprintf (stderr, ". Cipher setup failed\n");
|
||||
+ else if (digest_driver_info[i].status == DEVCRYPTO_STATUS_NO_CIOCCPHASH)
|
||||
+ fprintf(stderr, ", CIOCCPHASH failed\n");
|
||||
+ else
|
||||
+ fprintf(stderr, ", CIOCCPHASH capable\n");
|
||||
+ }
|
||||
+ fprintf(stderr, "\n");
|
||||
+}
|
||||
+
|
||||
#endif
|
||||
|
||||
/******************************************************************************
|
||||
@@ -983,6 +1074,11 @@ static const ENGINE_CMD_DEFN devcrypto_c
|
||||
ENGINE_CMD_FLAG_STRING},
|
||||
#endif
|
||||
|
||||
+ {DEVCRYPTO_CMD_DUMP_INFO,
|
||||
+ "DUMP_INFO",
|
||||
+ "dump info about each algorithm to stderr; use 'openssl engine -pre DUMP_INFO devcrypto'",
|
||||
+ ENGINE_CMD_FLAG_NO_INPUT},
|
||||
+
|
||||
{0, NULL, NULL, 0}
|
||||
};
|
||||
|
||||
@@ -1051,6 +1147,13 @@ static int devcrypto_ctrl(ENGINE *e, int
|
||||
return 1;
|
||||
#endif /* IMPLEMENT_DIGEST */
|
||||
|
||||
+ case DEVCRYPTO_CMD_DUMP_INFO:
|
||||
+ dump_cipher_info();
|
||||
+#ifdef IMPLEMENT_DIGEST
|
||||
+ dump_digest_info();
|
||||
+#endif
|
||||
+ return 1;
|
||||
+
|
||||
default:
|
||||
break;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,41 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Eneas U de Queiroz <cote2004-github@yahoo.com>
|
||||
Date: Mon, 11 Mar 2019 09:29:13 -0300
|
||||
Subject: e_devcrypto: default to not use digests in engine
|
||||
|
||||
Digests are almost always slower when using /dev/crypto because of the
|
||||
cost of the context switches. Only for large blocks it is worth it.
|
||||
|
||||
Also, when forking, the open context structures are duplicated, but the
|
||||
internal kernel sessions are still shared between forks, which means an
|
||||
update/close operation in one fork affects all processes using that
|
||||
session.
|
||||
|
||||
This affects digests, especially for HMAC, where the session with the
|
||||
key hash is used as a source for subsequent operations. At least one
|
||||
popular application does this across a fork. Disabling digests by
|
||||
default will mitigate the problem, while still allowing the user to
|
||||
turn them on if it is safe and fast enough.
|
||||
|
||||
Signed-off-by: Eneas U de Queiroz <cote2004-github@yahoo.com>
|
||||
|
||||
--- a/engines/e_devcrypto.c
|
||||
+++ b/engines/e_devcrypto.c
|
||||
@@ -852,7 +852,7 @@ static void prepare_digest_methods(void)
|
||||
for (i = 0, known_digest_nids_amount = 0; i < OSSL_NELEM(digest_data);
|
||||
i++) {
|
||||
|
||||
- selected_digests[i] = 1;
|
||||
+ selected_digests[i] = 0;
|
||||
|
||||
/*
|
||||
* Check that the digest is usable
|
||||
@@ -1072,7 +1072,7 @@ static const ENGINE_CMD_DEFN devcrypto_c
|
||||
#ifdef IMPLEMENT_DIGEST
|
||||
{DEVCRYPTO_CMD_DIGESTS,
|
||||
"DIGESTS",
|
||||
- "either ALL, NONE, or a comma-separated list of digests to enable [default=ALL]",
|
||||
+ "either ALL, NONE, or a comma-separated list of digests to enable [default=NONE]",
|
||||
ENGINE_CMD_FLAG_STRING},
|
||||
#endif
|
||||
|
@ -1,24 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Eneas U de Queiroz <cote2004-github@yahoo.com>
|
||||
Date: Mon, 11 Mar 2019 10:15:14 -0300
|
||||
Subject: e_devcrypto: ignore error when closing session
|
||||
|
||||
In cipher_init, ignore an eventual error when closing the previous
|
||||
session. It may have been closed by another process after a fork.
|
||||
|
||||
Signed-off-by: Eneas U de Queiroz <cote2004-github@yahoo.com>
|
||||
|
||||
--- a/engines/e_devcrypto.c
|
||||
+++ b/engines/e_devcrypto.c
|
||||
@@ -195,9 +195,8 @@ static int cipher_init(EVP_CIPHER_CTX *c
|
||||
get_cipher_data(EVP_CIPHER_CTX_nid(ctx));
|
||||
|
||||
/* cleanup a previous session */
|
||||
- if (cipher_ctx->sess.ses != 0 &&
|
||||
- clean_devcrypto_session(&cipher_ctx->sess) == 0)
|
||||
- return 0;
|
||||
+ if (cipher_ctx->sess.ses != 0)
|
||||
+ clean_devcrypto_session(&cipher_ctx->sess);
|
||||
|
||||
cipher_ctx->sess.cipher = cipher_d->devcryptoid;
|
||||
cipher_ctx->sess.keylen = cipher_d->keylen;
|
@ -24,12 +24,12 @@ hostapd_append_wep_key() {
|
||||
[1234])
|
||||
for idx in 1 2 3 4; do
|
||||
local zidx
|
||||
zidx=$(($idx - 1))
|
||||
zidx="$(($idx - 1))"
|
||||
json_get_var ckey "key${idx}"
|
||||
[ -n "$ckey" ] && \
|
||||
append $var "wep_key${zidx}=$(prepare_key_wep "$ckey")" "$N$T"
|
||||
done
|
||||
wep_keyidx=$((key - 1))
|
||||
wep_keyidx="$((key - 1))"
|
||||
;;
|
||||
*)
|
||||
append $var "wep_key0=$(prepare_key_wep "$key")" "$N$T"
|
||||
@ -790,7 +790,7 @@ hostapd_set_bss_options() {
|
||||
;;
|
||||
esac
|
||||
|
||||
local auth_algs=$((($auth_mode_shared << 1) | $auth_mode_open))
|
||||
local auth_algs="$((($auth_mode_shared << 1) | $auth_mode_open))"
|
||||
append bss_conf "auth_algs=${auth_algs:-1}" "$N"
|
||||
append bss_conf "wpa=$wpa" "$N"
|
||||
[ -n "$wpa_pairwise" ] && append bss_conf "wpa_pairwise=$wpa_pairwise" "$N"
|
||||
@ -1159,7 +1159,7 @@ hostapd_set_bss_options() {
|
||||
append bss_conf "$val" "$N"
|
||||
done
|
||||
|
||||
bss_md5sum=$(echo $bss_conf | md5sum | cut -d" " -f1)
|
||||
bss_md5sum="$(echo $bss_conf | md5sum | cut -d" " -f1)"
|
||||
append bss_conf "config_id=$bss_md5sum" "$N"
|
||||
|
||||
append "$var" "$bss_conf" "$N"
|
||||
@ -1181,7 +1181,7 @@ hostapd_set_log_options() {
|
||||
set_default log_iapp 1
|
||||
set_default log_mlme 1
|
||||
|
||||
local log_mask=$(( \
|
||||
local log_mask="$(( \
|
||||
($log_80211 << 0) | \
|
||||
($log_8021x << 1) | \
|
||||
($log_radius << 2) | \
|
||||
@ -1189,7 +1189,7 @@ hostapd_set_log_options() {
|
||||
($log_driver << 4) | \
|
||||
($log_iapp << 5) | \
|
||||
($log_mlme << 6) \
|
||||
))
|
||||
))"
|
||||
|
||||
append "$var" "logger_syslog=$log_mask" "$N"
|
||||
append "$var" "logger_syslog_level=$log_level" "$N"
|
||||
@ -1375,11 +1375,11 @@ wpa_supplicant_add_network() {
|
||||
|
||||
key_mgmt="$wpa_key_mgmt"
|
||||
|
||||
if [ ${#key} -eq 64 ]; then
|
||||
passphrase="psk=${key}"
|
||||
if [ "$_w_mode" = "mesh" ] || [ "$auth_type" = "sae" ]; then
|
||||
passphrase="sae_password=\"${key}\""
|
||||
else
|
||||
if [ "$_w_mode" = "mesh" ]; then
|
||||
passphrase="sae_password=\"${key}\""
|
||||
if [ ${#key} -eq 64 ]; then
|
||||
passphrase="psk=${key}"
|
||||
else
|
||||
passphrase="psk=\"${key}\""
|
||||
fi
|
||||
|
@ -0,0 +1,26 @@
|
||||
From 2e8dc541ae207349b51c65391be625ffe1f86e0c Mon Sep 17 00:00:00 2001
|
||||
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
|
||||
Date: Mon, 6 Feb 2023 13:43:41 +0000
|
||||
Subject: [PATCH] nvmem: core: remove spurious white space
|
||||
|
||||
Remove a spurious white space in for the ida_alloc() call.
|
||||
|
||||
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20230206134356.839737-8-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/nvmem/core.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/nvmem/core.c
|
||||
+++ b/drivers/nvmem/core.c
|
||||
@@ -764,7 +764,7 @@ struct nvmem_device *nvmem_register(cons
|
||||
if (!nvmem)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
- rval = ida_alloc(&nvmem_ida, GFP_KERNEL);
|
||||
+ rval = ida_alloc(&nvmem_ida, GFP_KERNEL);
|
||||
if (rval < 0) {
|
||||
kfree(nvmem);
|
||||
return ERR_PTR(rval);
|
@ -0,0 +1,180 @@
|
||||
From 5d8e6e6c10a3d37486d263b16ddc15991a7e4a88 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Walle <michael@walle.cc>
|
||||
Date: Mon, 6 Feb 2023 13:43:46 +0000
|
||||
Subject: [PATCH] nvmem: core: add an index parameter to the cell
|
||||
|
||||
Sometimes a cell can represend multiple values. For example, a base
|
||||
ethernet address stored in the NVMEM can be expanded into multiple
|
||||
discreet ones by adding an offset.
|
||||
|
||||
For this use case, introduce an index parameter which is then used to
|
||||
distiguish between values. This parameter will then be passed to the
|
||||
post process hook which can then use it to create different values
|
||||
during reading.
|
||||
|
||||
At the moment, there is only support for the device tree path. You can
|
||||
add the index to the phandle, e.g.
|
||||
|
||||
&net {
|
||||
nvmem-cells = <&base_mac_address 2>;
|
||||
nvmem-cell-names = "mac-address";
|
||||
};
|
||||
|
||||
&nvmem_provider {
|
||||
base_mac_address: base-mac-address@0 {
|
||||
#nvmem-cell-cells = <1>;
|
||||
reg = <0 6>;
|
||||
};
|
||||
};
|
||||
|
||||
Signed-off-by: Michael Walle <michael@walle.cc>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20230206134356.839737-13-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/nvmem/core.c | 37 ++++++++++++++++++++++++----------
|
||||
drivers/nvmem/imx-ocotp.c | 4 ++--
|
||||
include/linux/nvmem-provider.h | 4 ++--
|
||||
3 files changed, 30 insertions(+), 15 deletions(-)
|
||||
|
||||
--- a/drivers/nvmem/core.c
|
||||
+++ b/drivers/nvmem/core.c
|
||||
@@ -60,6 +60,7 @@ struct nvmem_cell_entry {
|
||||
struct nvmem_cell {
|
||||
struct nvmem_cell_entry *entry;
|
||||
const char *id;
|
||||
+ int index;
|
||||
};
|
||||
|
||||
static DEFINE_MUTEX(nvmem_mutex);
|
||||
@@ -1127,7 +1128,8 @@ struct nvmem_device *devm_nvmem_device_g
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devm_nvmem_device_get);
|
||||
|
||||
-static struct nvmem_cell *nvmem_create_cell(struct nvmem_cell_entry *entry, const char *id)
|
||||
+static struct nvmem_cell *nvmem_create_cell(struct nvmem_cell_entry *entry,
|
||||
+ const char *id, int index)
|
||||
{
|
||||
struct nvmem_cell *cell;
|
||||
const char *name = NULL;
|
||||
@@ -1146,6 +1148,7 @@ static struct nvmem_cell *nvmem_create_c
|
||||
|
||||
cell->id = name;
|
||||
cell->entry = entry;
|
||||
+ cell->index = index;
|
||||
|
||||
return cell;
|
||||
}
|
||||
@@ -1184,7 +1187,7 @@ nvmem_cell_get_from_lookup(struct device
|
||||
__nvmem_device_put(nvmem);
|
||||
cell = ERR_PTR(-ENOENT);
|
||||
} else {
|
||||
- cell = nvmem_create_cell(cell_entry, con_id);
|
||||
+ cell = nvmem_create_cell(cell_entry, con_id, 0);
|
||||
if (IS_ERR(cell))
|
||||
__nvmem_device_put(nvmem);
|
||||
}
|
||||
@@ -1232,15 +1235,27 @@ struct nvmem_cell *of_nvmem_cell_get(str
|
||||
struct nvmem_device *nvmem;
|
||||
struct nvmem_cell_entry *cell_entry;
|
||||
struct nvmem_cell *cell;
|
||||
+ struct of_phandle_args cell_spec;
|
||||
int index = 0;
|
||||
+ int cell_index = 0;
|
||||
+ int ret;
|
||||
|
||||
/* if cell name exists, find index to the name */
|
||||
if (id)
|
||||
index = of_property_match_string(np, "nvmem-cell-names", id);
|
||||
|
||||
- cell_np = of_parse_phandle(np, "nvmem-cells", index);
|
||||
- if (!cell_np)
|
||||
- return ERR_PTR(-ENOENT);
|
||||
+ ret = of_parse_phandle_with_optional_args(np, "nvmem-cells",
|
||||
+ "#nvmem-cell-cells",
|
||||
+ index, &cell_spec);
|
||||
+ if (ret)
|
||||
+ return ERR_PTR(ret);
|
||||
+
|
||||
+ if (cell_spec.args_count > 1)
|
||||
+ return ERR_PTR(-EINVAL);
|
||||
+
|
||||
+ cell_np = cell_spec.np;
|
||||
+ if (cell_spec.args_count)
|
||||
+ cell_index = cell_spec.args[0];
|
||||
|
||||
nvmem_np = of_get_next_parent(cell_np);
|
||||
if (!nvmem_np)
|
||||
@@ -1257,7 +1272,7 @@ struct nvmem_cell *of_nvmem_cell_get(str
|
||||
return ERR_PTR(-ENOENT);
|
||||
}
|
||||
|
||||
- cell = nvmem_create_cell(cell_entry, id);
|
||||
+ cell = nvmem_create_cell(cell_entry, id, cell_index);
|
||||
if (IS_ERR(cell))
|
||||
__nvmem_device_put(nvmem);
|
||||
|
||||
@@ -1410,8 +1425,8 @@ static void nvmem_shift_read_buffer_in_p
|
||||
}
|
||||
|
||||
static int __nvmem_cell_read(struct nvmem_device *nvmem,
|
||||
- struct nvmem_cell_entry *cell,
|
||||
- void *buf, size_t *len, const char *id)
|
||||
+ struct nvmem_cell_entry *cell,
|
||||
+ void *buf, size_t *len, const char *id, int index)
|
||||
{
|
||||
int rc;
|
||||
|
||||
@@ -1425,7 +1440,7 @@ static int __nvmem_cell_read(struct nvme
|
||||
nvmem_shift_read_buffer_in_place(cell, buf);
|
||||
|
||||
if (nvmem->cell_post_process) {
|
||||
- rc = nvmem->cell_post_process(nvmem->priv, id,
|
||||
+ rc = nvmem->cell_post_process(nvmem->priv, id, index,
|
||||
cell->offset, buf, cell->bytes);
|
||||
if (rc)
|
||||
return rc;
|
||||
@@ -1460,7 +1475,7 @@ void *nvmem_cell_read(struct nvmem_cell
|
||||
if (!buf)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
- rc = __nvmem_cell_read(nvmem, cell->entry, buf, len, cell->id);
|
||||
+ rc = __nvmem_cell_read(nvmem, cell->entry, buf, len, cell->id, cell->index);
|
||||
if (rc) {
|
||||
kfree(buf);
|
||||
return ERR_PTR(rc);
|
||||
@@ -1773,7 +1788,7 @@ ssize_t nvmem_device_cell_read(struct nv
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
- rc = __nvmem_cell_read(nvmem, &cell, buf, &len, NULL);
|
||||
+ rc = __nvmem_cell_read(nvmem, &cell, buf, &len, NULL, 0);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
--- a/drivers/nvmem/imx-ocotp.c
|
||||
+++ b/drivers/nvmem/imx-ocotp.c
|
||||
@@ -222,8 +222,8 @@ read_end:
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static int imx_ocotp_cell_pp(void *context, const char *id, unsigned int offset,
|
||||
- void *data, size_t bytes)
|
||||
+static int imx_ocotp_cell_pp(void *context, const char *id, int index,
|
||||
+ unsigned int offset, void *data, size_t bytes)
|
||||
{
|
||||
struct ocotp_priv *priv = context;
|
||||
|
||||
--- a/include/linux/nvmem-provider.h
|
||||
+++ b/include/linux/nvmem-provider.h
|
||||
@@ -20,8 +20,8 @@ typedef int (*nvmem_reg_read_t)(void *pr
|
||||
typedef int (*nvmem_reg_write_t)(void *priv, unsigned int offset,
|
||||
void *val, size_t bytes);
|
||||
/* used for vendor specific post processing of cell data */
|
||||
-typedef int (*nvmem_cell_post_process_t)(void *priv, const char *id, unsigned int offset,
|
||||
- void *buf, size_t bytes);
|
||||
+typedef int (*nvmem_cell_post_process_t)(void *priv, const char *id, int index,
|
||||
+ unsigned int offset, void *buf, size_t bytes);
|
||||
|
||||
enum nvmem_type {
|
||||
NVMEM_TYPE_UNKNOWN = 0,
|
@ -0,0 +1,78 @@
|
||||
From fbd03d27776c6121a483921601418e3c8f0ff37e Mon Sep 17 00:00:00 2001
|
||||
From: Michael Walle <michael@walle.cc>
|
||||
Date: Mon, 6 Feb 2023 13:43:47 +0000
|
||||
Subject: [PATCH] nvmem: core: move struct nvmem_cell_info to nvmem-provider.h
|
||||
|
||||
struct nvmem_cell_info is used to describe a cell. Thus this should
|
||||
really be in the nvmem-provider's header. There are two (unused) nvmem
|
||||
access methods which use the nvmem_cell_info to describe the cell to be
|
||||
accesses. One can argue, that they will create a cell before accessing,
|
||||
thus they are both a provider and a consumer.
|
||||
|
||||
struct nvmem_cell_info will get used more and more by nvmem-providers,
|
||||
don't force them to also include the consumer header, although they are
|
||||
not.
|
||||
|
||||
Signed-off-by: Michael Walle <michael@walle.cc>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20230206134356.839737-14-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
include/linux/nvmem-consumer.h | 10 +---------
|
||||
include/linux/nvmem-provider.h | 19 ++++++++++++++++++-
|
||||
2 files changed, 19 insertions(+), 10 deletions(-)
|
||||
|
||||
--- a/include/linux/nvmem-consumer.h
|
||||
+++ b/include/linux/nvmem-consumer.h
|
||||
@@ -18,15 +18,7 @@ struct device_node;
|
||||
/* consumer cookie */
|
||||
struct nvmem_cell;
|
||||
struct nvmem_device;
|
||||
-
|
||||
-struct nvmem_cell_info {
|
||||
- const char *name;
|
||||
- unsigned int offset;
|
||||
- unsigned int bytes;
|
||||
- unsigned int bit_offset;
|
||||
- unsigned int nbits;
|
||||
- struct device_node *np;
|
||||
-};
|
||||
+struct nvmem_cell_info;
|
||||
|
||||
/**
|
||||
* struct nvmem_cell_lookup - cell lookup entry
|
||||
--- a/include/linux/nvmem-provider.h
|
||||
+++ b/include/linux/nvmem-provider.h
|
||||
@@ -14,7 +14,6 @@
|
||||
#include <linux/gpio/consumer.h>
|
||||
|
||||
struct nvmem_device;
|
||||
-struct nvmem_cell_info;
|
||||
typedef int (*nvmem_reg_read_t)(void *priv, unsigned int offset,
|
||||
void *val, size_t bytes);
|
||||
typedef int (*nvmem_reg_write_t)(void *priv, unsigned int offset,
|
||||
@@ -48,6 +47,24 @@ struct nvmem_keepout {
|
||||
};
|
||||
|
||||
/**
|
||||
+ * struct nvmem_cell_info - NVMEM cell description
|
||||
+ * @name: Name.
|
||||
+ * @offset: Offset within the NVMEM device.
|
||||
+ * @bytes: Length of the cell.
|
||||
+ * @bit_offset: Bit offset if cell is smaller than a byte.
|
||||
+ * @nbits: Number of bits.
|
||||
+ * @np: Optional device_node pointer.
|
||||
+ */
|
||||
+struct nvmem_cell_info {
|
||||
+ const char *name;
|
||||
+ unsigned int offset;
|
||||
+ unsigned int bytes;
|
||||
+ unsigned int bit_offset;
|
||||
+ unsigned int nbits;
|
||||
+ struct device_node *np;
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
* struct nvmem_config - NVMEM device configuration
|
||||
*
|
||||
* @dev: Parent device.
|
@ -0,0 +1,65 @@
|
||||
From cc5bdd323dde6494623f3ffe3a5b887fa21cd375 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Walle <michael@walle.cc>
|
||||
Date: Mon, 6 Feb 2023 13:43:48 +0000
|
||||
Subject: [PATCH] nvmem: core: drop the removal of the cells in
|
||||
nvmem_add_cells()
|
||||
|
||||
If nvmem_add_cells() fails, the whole nvmem_register() will fail
|
||||
and the cells will then be removed anyway. This is a preparation
|
||||
to introduce a nvmem_add_one_cell() which can then be used by
|
||||
nvmem_add_cells().
|
||||
|
||||
This is then the same to what nvmem_add_cells_from_table() and
|
||||
nvmem_add_cells_from_of() do.
|
||||
|
||||
Signed-off-by: Michael Walle <michael@walle.cc>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20230206134356.839737-15-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/nvmem/core.c | 14 ++++----------
|
||||
1 file changed, 4 insertions(+), 10 deletions(-)
|
||||
|
||||
--- a/drivers/nvmem/core.c
|
||||
+++ b/drivers/nvmem/core.c
|
||||
@@ -515,7 +515,7 @@ static int nvmem_add_cells(struct nvmem_
|
||||
int ncells)
|
||||
{
|
||||
struct nvmem_cell_entry **cells;
|
||||
- int i, rval;
|
||||
+ int i, rval = 0;
|
||||
|
||||
cells = kcalloc(ncells, sizeof(*cells), GFP_KERNEL);
|
||||
if (!cells)
|
||||
@@ -525,28 +525,22 @@ static int nvmem_add_cells(struct nvmem_
|
||||
cells[i] = kzalloc(sizeof(**cells), GFP_KERNEL);
|
||||
if (!cells[i]) {
|
||||
rval = -ENOMEM;
|
||||
- goto err;
|
||||
+ goto out;
|
||||
}
|
||||
|
||||
rval = nvmem_cell_info_to_nvmem_cell_entry(nvmem, &info[i], cells[i]);
|
||||
if (rval) {
|
||||
kfree(cells[i]);
|
||||
- goto err;
|
||||
+ goto out;
|
||||
}
|
||||
|
||||
nvmem_cell_entry_add(cells[i]);
|
||||
}
|
||||
|
||||
+out:
|
||||
/* remove tmp array */
|
||||
kfree(cells);
|
||||
|
||||
- return 0;
|
||||
-err:
|
||||
- while (i--)
|
||||
- nvmem_cell_entry_drop(cells[i]);
|
||||
-
|
||||
- kfree(cells);
|
||||
-
|
||||
return rval;
|
||||
}
|
||||
|
@ -0,0 +1,122 @@
|
||||
From 2ded6830d376d5e7bf43d59f7f7fdf1a59abc676 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Walle <michael@walle.cc>
|
||||
Date: Mon, 6 Feb 2023 13:43:49 +0000
|
||||
Subject: [PATCH] nvmem: core: add nvmem_add_one_cell()
|
||||
|
||||
Add a new function to add exactly one cell. This will be used by the
|
||||
nvmem layout drivers to add custom cells. In contrast to the
|
||||
nvmem_add_cells(), this has the advantage that we don't have to assemble
|
||||
a list of cells on runtime.
|
||||
|
||||
Signed-off-by: Michael Walle <michael@walle.cc>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20230206134356.839737-16-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/nvmem/core.c | 59 ++++++++++++++++++++--------------
|
||||
include/linux/nvmem-provider.h | 8 +++++
|
||||
2 files changed, 43 insertions(+), 24 deletions(-)
|
||||
|
||||
--- a/drivers/nvmem/core.c
|
||||
+++ b/drivers/nvmem/core.c
|
||||
@@ -502,6 +502,36 @@ static int nvmem_cell_info_to_nvmem_cell
|
||||
}
|
||||
|
||||
/**
|
||||
+ * nvmem_add_one_cell() - Add one cell information to an nvmem device
|
||||
+ *
|
||||
+ * @nvmem: nvmem device to add cells to.
|
||||
+ * @info: nvmem cell info to add to the device
|
||||
+ *
|
||||
+ * Return: 0 or negative error code on failure.
|
||||
+ */
|
||||
+int nvmem_add_one_cell(struct nvmem_device *nvmem,
|
||||
+ const struct nvmem_cell_info *info)
|
||||
+{
|
||||
+ struct nvmem_cell_entry *cell;
|
||||
+ int rval;
|
||||
+
|
||||
+ cell = kzalloc(sizeof(*cell), GFP_KERNEL);
|
||||
+ if (!cell)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ rval = nvmem_cell_info_to_nvmem_cell_entry(nvmem, info, cell);
|
||||
+ if (rval) {
|
||||
+ kfree(cell);
|
||||
+ return rval;
|
||||
+ }
|
||||
+
|
||||
+ nvmem_cell_entry_add(cell);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(nvmem_add_one_cell);
|
||||
+
|
||||
+/**
|
||||
* nvmem_add_cells() - Add cell information to an nvmem device
|
||||
*
|
||||
* @nvmem: nvmem device to add cells to.
|
||||
@@ -514,34 +544,15 @@ static int nvmem_add_cells(struct nvmem_
|
||||
const struct nvmem_cell_info *info,
|
||||
int ncells)
|
||||
{
|
||||
- struct nvmem_cell_entry **cells;
|
||||
- int i, rval = 0;
|
||||
-
|
||||
- cells = kcalloc(ncells, sizeof(*cells), GFP_KERNEL);
|
||||
- if (!cells)
|
||||
- return -ENOMEM;
|
||||
+ int i, rval;
|
||||
|
||||
for (i = 0; i < ncells; i++) {
|
||||
- cells[i] = kzalloc(sizeof(**cells), GFP_KERNEL);
|
||||
- if (!cells[i]) {
|
||||
- rval = -ENOMEM;
|
||||
- goto out;
|
||||
- }
|
||||
-
|
||||
- rval = nvmem_cell_info_to_nvmem_cell_entry(nvmem, &info[i], cells[i]);
|
||||
- if (rval) {
|
||||
- kfree(cells[i]);
|
||||
- goto out;
|
||||
- }
|
||||
-
|
||||
- nvmem_cell_entry_add(cells[i]);
|
||||
+ rval = nvmem_add_one_cell(nvmem, &info[i]);
|
||||
+ if (rval)
|
||||
+ return rval;
|
||||
}
|
||||
|
||||
-out:
|
||||
- /* remove tmp array */
|
||||
- kfree(cells);
|
||||
-
|
||||
- return rval;
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
--- a/include/linux/nvmem-provider.h
|
||||
+++ b/include/linux/nvmem-provider.h
|
||||
@@ -155,6 +155,9 @@ struct nvmem_device *devm_nvmem_register
|
||||
void nvmem_add_cell_table(struct nvmem_cell_table *table);
|
||||
void nvmem_del_cell_table(struct nvmem_cell_table *table);
|
||||
|
||||
+int nvmem_add_one_cell(struct nvmem_device *nvmem,
|
||||
+ const struct nvmem_cell_info *info);
|
||||
+
|
||||
#else
|
||||
|
||||
static inline struct nvmem_device *nvmem_register(const struct nvmem_config *c)
|
||||
@@ -172,6 +175,11 @@ devm_nvmem_register(struct device *dev,
|
||||
|
||||
static inline void nvmem_add_cell_table(struct nvmem_cell_table *table) {}
|
||||
static inline void nvmem_del_cell_table(struct nvmem_cell_table *table) {}
|
||||
+static inline int nvmem_add_one_cell(struct nvmem_device *nvmem,
|
||||
+ const struct nvmem_cell_info *info)
|
||||
+{
|
||||
+ return -EOPNOTSUPP;
|
||||
+}
|
||||
|
||||
#endif /* CONFIG_NVMEM */
|
||||
#endif /* ifndef _LINUX_NVMEM_PROVIDER_H */
|
@ -0,0 +1,93 @@
|
||||
From 50014d659617dc58780a5d31ceb76c82779a9d8b Mon Sep 17 00:00:00 2001
|
||||
From: Michael Walle <michael@walle.cc>
|
||||
Date: Mon, 6 Feb 2023 13:43:50 +0000
|
||||
Subject: [PATCH] nvmem: core: use nvmem_add_one_cell() in
|
||||
nvmem_add_cells_from_of()
|
||||
|
||||
Convert nvmem_add_cells_from_of() to use the new nvmem_add_one_cell().
|
||||
This will remove duplicate code and it will make it possible to add a
|
||||
hook to a nvmem layout in between, which can change fields before the
|
||||
cell is finally added.
|
||||
|
||||
Signed-off-by: Michael Walle <michael@walle.cc>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20230206134356.839737-17-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/nvmem/core.c | 45 ++++++++++++++------------------------------
|
||||
1 file changed, 14 insertions(+), 31 deletions(-)
|
||||
|
||||
--- a/drivers/nvmem/core.c
|
||||
+++ b/drivers/nvmem/core.c
|
||||
@@ -688,15 +688,14 @@ static int nvmem_validate_keepouts(struc
|
||||
|
||||
static int nvmem_add_cells_from_of(struct nvmem_device *nvmem)
|
||||
{
|
||||
- struct device_node *parent, *child;
|
||||
struct device *dev = &nvmem->dev;
|
||||
- struct nvmem_cell_entry *cell;
|
||||
+ struct device_node *child;
|
||||
const __be32 *addr;
|
||||
- int len;
|
||||
+ int len, ret;
|
||||
|
||||
- parent = dev->of_node;
|
||||
+ for_each_child_of_node(dev->of_node, child) {
|
||||
+ struct nvmem_cell_info info = {0};
|
||||
|
||||
- for_each_child_of_node(parent, child) {
|
||||
addr = of_get_property(child, "reg", &len);
|
||||
if (!addr)
|
||||
continue;
|
||||
@@ -706,40 +705,24 @@ static int nvmem_add_cells_from_of(struc
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
- cell = kzalloc(sizeof(*cell), GFP_KERNEL);
|
||||
- if (!cell) {
|
||||
- of_node_put(child);
|
||||
- return -ENOMEM;
|
||||
- }
|
||||
-
|
||||
- cell->nvmem = nvmem;
|
||||
- cell->offset = be32_to_cpup(addr++);
|
||||
- cell->bytes = be32_to_cpup(addr);
|
||||
- cell->name = kasprintf(GFP_KERNEL, "%pOFn", child);
|
||||
+ info.offset = be32_to_cpup(addr++);
|
||||
+ info.bytes = be32_to_cpup(addr);
|
||||
+ info.name = kasprintf(GFP_KERNEL, "%pOFn", child);
|
||||
|
||||
addr = of_get_property(child, "bits", &len);
|
||||
if (addr && len == (2 * sizeof(u32))) {
|
||||
- cell->bit_offset = be32_to_cpup(addr++);
|
||||
- cell->nbits = be32_to_cpup(addr);
|
||||
+ info.bit_offset = be32_to_cpup(addr++);
|
||||
+ info.nbits = be32_to_cpup(addr);
|
||||
}
|
||||
|
||||
- if (cell->nbits)
|
||||
- cell->bytes = DIV_ROUND_UP(
|
||||
- cell->nbits + cell->bit_offset,
|
||||
- BITS_PER_BYTE);
|
||||
-
|
||||
- if (!IS_ALIGNED(cell->offset, nvmem->stride)) {
|
||||
- dev_err(dev, "cell %s unaligned to nvmem stride %d\n",
|
||||
- cell->name, nvmem->stride);
|
||||
- /* Cells already added will be freed later. */
|
||||
- kfree_const(cell->name);
|
||||
- kfree(cell);
|
||||
+ info.np = of_node_get(child);
|
||||
+
|
||||
+ ret = nvmem_add_one_cell(nvmem, &info);
|
||||
+ kfree(info.name);
|
||||
+ if (ret) {
|
||||
of_node_put(child);
|
||||
- return -EINVAL;
|
||||
+ return ret;
|
||||
}
|
||||
-
|
||||
- cell->np = of_node_get(child);
|
||||
- nvmem_cell_entry_add(cell);
|
||||
}
|
||||
|
||||
return 0;
|
@ -0,0 +1,562 @@
|
||||
From 6a0bc3522e746025e2d9a63ab2cb5d7062c2d39c Mon Sep 17 00:00:00 2001
|
||||
From: Patrick Delaunay <patrick.delaunay@foss.st.com>
|
||||
Date: Mon, 6 Feb 2023 13:43:51 +0000
|
||||
Subject: [PATCH] nvmem: stm32: add OP-TEE support for STM32MP13x
|
||||
|
||||
For boot with OP-TEE on STM32MP13, the communication with the secure
|
||||
world no more use STMicroelectronics SMC but communication with the
|
||||
STM32MP BSEC TA, for data access (read/write) or lock operation:
|
||||
- all the request are sent to OP-TEE trusted application,
|
||||
- for upper OTP with ECC protection and with word programming only
|
||||
each OTP are permanently locked when programmed to avoid ECC error
|
||||
on the second write operation
|
||||
|
||||
Signed-off-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
|
||||
Reviewed-by: Etienne Carriere <etienne.carriere@linaro.org>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20230206134356.839737-18-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/nvmem/Kconfig | 11 +
|
||||
drivers/nvmem/Makefile | 1 +
|
||||
drivers/nvmem/stm32-bsec-optee-ta.c | 298 ++++++++++++++++++++++++++++
|
||||
drivers/nvmem/stm32-bsec-optee-ta.h | 80 ++++++++
|
||||
drivers/nvmem/stm32-romem.c | 54 ++++-
|
||||
5 files changed, 441 insertions(+), 3 deletions(-)
|
||||
create mode 100644 drivers/nvmem/stm32-bsec-optee-ta.c
|
||||
create mode 100644 drivers/nvmem/stm32-bsec-optee-ta.h
|
||||
|
||||
--- a/drivers/nvmem/Kconfig
|
||||
+++ b/drivers/nvmem/Kconfig
|
||||
@@ -290,9 +290,20 @@ config NVMEM_SPRD_EFUSE
|
||||
This driver can also be built as a module. If so, the module
|
||||
will be called nvmem-sprd-efuse.
|
||||
|
||||
+config NVMEM_STM32_BSEC_OPTEE_TA
|
||||
+ bool "STM32MP BSEC OP-TEE TA support for nvmem-stm32-romem driver"
|
||||
+ depends on OPTEE
|
||||
+ help
|
||||
+ Say y here to enable the accesses to STM32MP SoC OTPs by the OP-TEE
|
||||
+ trusted application STM32MP BSEC.
|
||||
+
|
||||
+ This library is a used by stm32-romem driver or included in the module
|
||||
+ called nvmem-stm32-romem.
|
||||
+
|
||||
config NVMEM_STM32_ROMEM
|
||||
tristate "STMicroelectronics STM32 factory-programmed memory support"
|
||||
depends on ARCH_STM32 || COMPILE_TEST
|
||||
+ imply NVMEM_STM32_BSEC_OPTEE_TA
|
||||
help
|
||||
Say y here to enable read-only access for STMicroelectronics STM32
|
||||
factory-programmed memory area.
|
||||
--- a/drivers/nvmem/Makefile
|
||||
+++ b/drivers/nvmem/Makefile
|
||||
@@ -61,6 +61,7 @@ obj-$(CONFIG_NVMEM_SPRD_EFUSE) += nvmem
|
||||
nvmem_sprd_efuse-y := sprd-efuse.o
|
||||
obj-$(CONFIG_NVMEM_STM32_ROMEM) += nvmem_stm32_romem.o
|
||||
nvmem_stm32_romem-y := stm32-romem.o
|
||||
+nvmem_stm32_romem-$(CONFIG_NVMEM_STM32_BSEC_OPTEE_TA) += stm32-bsec-optee-ta.o
|
||||
obj-$(CONFIG_NVMEM_SUNPLUS_OCOTP) += nvmem_sunplus_ocotp.o
|
||||
nvmem_sunplus_ocotp-y := sunplus-ocotp.o
|
||||
obj-$(CONFIG_NVMEM_SUNXI_SID) += nvmem_sunxi_sid.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/nvmem/stm32-bsec-optee-ta.c
|
||||
@@ -0,0 +1,298 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
+/*
|
||||
+ * OP-TEE STM32MP BSEC PTA interface, used by STM32 ROMEM driver
|
||||
+ *
|
||||
+ * Copyright (C) 2022, STMicroelectronics - All Rights Reserved
|
||||
+ */
|
||||
+
|
||||
+#include <linux/tee_drv.h>
|
||||
+
|
||||
+#include "stm32-bsec-optee-ta.h"
|
||||
+
|
||||
+/*
|
||||
+ * Read OTP memory
|
||||
+ *
|
||||
+ * [in] value[0].a OTP start offset in byte
|
||||
+ * [in] value[0].b Access type (0:shadow, 1:fuse, 2:lock)
|
||||
+ * [out] memref[1].buffer Output buffer to store read values
|
||||
+ * [out] memref[1].size Size of OTP to be read
|
||||
+ *
|
||||
+ * Return codes:
|
||||
+ * TEE_SUCCESS - Invoke command success
|
||||
+ * TEE_ERROR_BAD_PARAMETERS - Incorrect input param
|
||||
+ * TEE_ERROR_ACCESS_DENIED - OTP not accessible by caller
|
||||
+ */
|
||||
+#define PTA_BSEC_READ_MEM 0x0
|
||||
+
|
||||
+/*
|
||||
+ * Write OTP memory
|
||||
+ *
|
||||
+ * [in] value[0].a OTP start offset in byte
|
||||
+ * [in] value[0].b Access type (0:shadow, 1:fuse, 2:lock)
|
||||
+ * [in] memref[1].buffer Input buffer to read values
|
||||
+ * [in] memref[1].size Size of OTP to be written
|
||||
+ *
|
||||
+ * Return codes:
|
||||
+ * TEE_SUCCESS - Invoke command success
|
||||
+ * TEE_ERROR_BAD_PARAMETERS - Incorrect input param
|
||||
+ * TEE_ERROR_ACCESS_DENIED - OTP not accessible by caller
|
||||
+ */
|
||||
+#define PTA_BSEC_WRITE_MEM 0x1
|
||||
+
|
||||
+/* value of PTA_BSEC access type = value[in] b */
|
||||
+#define SHADOW_ACCESS 0
|
||||
+#define FUSE_ACCESS 1
|
||||
+#define LOCK_ACCESS 2
|
||||
+
|
||||
+/* Bitfield definition for LOCK status */
|
||||
+#define LOCK_PERM BIT(30)
|
||||
+
|
||||
+/* OP-TEE STM32MP BSEC TA UUID */
|
||||
+static const uuid_t stm32mp_bsec_ta_uuid =
|
||||
+ UUID_INIT(0x94cf71ad, 0x80e6, 0x40b5,
|
||||
+ 0xa7, 0xc6, 0x3d, 0xc5, 0x01, 0xeb, 0x28, 0x03);
|
||||
+
|
||||
+/*
|
||||
+ * Check whether this driver supports the BSEC TA in the TEE instance
|
||||
+ * represented by the params (ver/data) to this function.
|
||||
+ */
|
||||
+static int stm32_bsec_optee_ta_match(struct tee_ioctl_version_data *ver,
|
||||
+ const void *data)
|
||||
+{
|
||||
+ /* Currently this driver only supports GP compliant, OP-TEE based TA */
|
||||
+ if ((ver->impl_id == TEE_IMPL_ID_OPTEE) &&
|
||||
+ (ver->gen_caps & TEE_GEN_CAP_GP))
|
||||
+ return 1;
|
||||
+ else
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/* Open a session to OP-TEE for STM32MP BSEC TA */
|
||||
+static int stm32_bsec_ta_open_session(struct tee_context *ctx, u32 *id)
|
||||
+{
|
||||
+ struct tee_ioctl_open_session_arg sess_arg;
|
||||
+ int rc;
|
||||
+
|
||||
+ memset(&sess_arg, 0, sizeof(sess_arg));
|
||||
+ export_uuid(sess_arg.uuid, &stm32mp_bsec_ta_uuid);
|
||||
+ sess_arg.clnt_login = TEE_IOCTL_LOGIN_REE_KERNEL;
|
||||
+ sess_arg.num_params = 0;
|
||||
+
|
||||
+ rc = tee_client_open_session(ctx, &sess_arg, NULL);
|
||||
+ if ((rc < 0) || (sess_arg.ret != 0)) {
|
||||
+ pr_err("%s: tee_client_open_session failed err:%#x, ret:%#x\n",
|
||||
+ __func__, sess_arg.ret, rc);
|
||||
+ if (!rc)
|
||||
+ rc = -EINVAL;
|
||||
+ } else {
|
||||
+ *id = sess_arg.session;
|
||||
+ }
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+/* close a session to OP-TEE for STM32MP BSEC TA */
|
||||
+static void stm32_bsec_ta_close_session(void *ctx, u32 id)
|
||||
+{
|
||||
+ tee_client_close_session(ctx, id);
|
||||
+}
|
||||
+
|
||||
+/* stm32_bsec_optee_ta_open() - initialize the STM32MP BSEC TA */
|
||||
+int stm32_bsec_optee_ta_open(struct tee_context **ctx)
|
||||
+{
|
||||
+ struct tee_context *tee_ctx;
|
||||
+ u32 session_id;
|
||||
+ int rc;
|
||||
+
|
||||
+ /* Open context with TEE driver */
|
||||
+ tee_ctx = tee_client_open_context(NULL, stm32_bsec_optee_ta_match, NULL, NULL);
|
||||
+ if (IS_ERR(tee_ctx)) {
|
||||
+ rc = PTR_ERR(tee_ctx);
|
||||
+ if (rc == -ENOENT)
|
||||
+ return -EPROBE_DEFER;
|
||||
+ pr_err("%s: tee_client_open_context failed (%d)\n", __func__, rc);
|
||||
+
|
||||
+ return rc;
|
||||
+ }
|
||||
+
|
||||
+ /* Check STM32MP BSEC TA presence */
|
||||
+ rc = stm32_bsec_ta_open_session(tee_ctx, &session_id);
|
||||
+ if (rc) {
|
||||
+ tee_client_close_context(tee_ctx);
|
||||
+ return rc;
|
||||
+ }
|
||||
+
|
||||
+ stm32_bsec_ta_close_session(tee_ctx, session_id);
|
||||
+
|
||||
+ *ctx = tee_ctx;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/* stm32_bsec_optee_ta_open() - release the PTA STM32MP BSEC TA */
|
||||
+void stm32_bsec_optee_ta_close(void *ctx)
|
||||
+{
|
||||
+ tee_client_close_context(ctx);
|
||||
+}
|
||||
+
|
||||
+/* stm32_bsec_optee_ta_read() - nvmem read access using PTA client driver */
|
||||
+int stm32_bsec_optee_ta_read(struct tee_context *ctx, unsigned int offset,
|
||||
+ void *buf, size_t bytes)
|
||||
+{
|
||||
+ struct tee_shm *shm;
|
||||
+ struct tee_ioctl_invoke_arg arg;
|
||||
+ struct tee_param param[2];
|
||||
+ u8 *shm_buf;
|
||||
+ u32 start, num_bytes;
|
||||
+ int ret;
|
||||
+ u32 session_id;
|
||||
+
|
||||
+ ret = stm32_bsec_ta_open_session(ctx, &session_id);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ memset(&arg, 0, sizeof(arg));
|
||||
+ memset(¶m, 0, sizeof(param));
|
||||
+
|
||||
+ arg.func = PTA_BSEC_READ_MEM;
|
||||
+ arg.session = session_id;
|
||||
+ arg.num_params = 2;
|
||||
+
|
||||
+ /* align access on 32bits */
|
||||
+ start = ALIGN_DOWN(offset, 4);
|
||||
+ num_bytes = round_up(offset + bytes - start, 4);
|
||||
+ param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT;
|
||||
+ param[0].u.value.a = start;
|
||||
+ param[0].u.value.b = SHADOW_ACCESS;
|
||||
+
|
||||
+ shm = tee_shm_alloc_kernel_buf(ctx, num_bytes);
|
||||
+ if (IS_ERR(shm)) {
|
||||
+ ret = PTR_ERR(shm);
|
||||
+ goto out_tee_session;
|
||||
+ }
|
||||
+
|
||||
+ param[1].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT;
|
||||
+ param[1].u.memref.shm = shm;
|
||||
+ param[1].u.memref.size = num_bytes;
|
||||
+
|
||||
+ ret = tee_client_invoke_func(ctx, &arg, param);
|
||||
+ if (ret < 0 || arg.ret != 0) {
|
||||
+ pr_err("TA_BSEC invoke failed TEE err:%#x, ret:%#x\n",
|
||||
+ arg.ret, ret);
|
||||
+ if (!ret)
|
||||
+ ret = -EIO;
|
||||
+ }
|
||||
+ if (!ret) {
|
||||
+ shm_buf = tee_shm_get_va(shm, 0);
|
||||
+ if (IS_ERR(shm_buf)) {
|
||||
+ ret = PTR_ERR(shm_buf);
|
||||
+ pr_err("tee_shm_get_va failed for transmit (%d)\n", ret);
|
||||
+ } else {
|
||||
+ /* read data from 32 bits aligned buffer */
|
||||
+ memcpy(buf, &shm_buf[offset % 4], bytes);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ tee_shm_free(shm);
|
||||
+
|
||||
+out_tee_session:
|
||||
+ stm32_bsec_ta_close_session(ctx, session_id);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+/* stm32_bsec_optee_ta_write() - nvmem write access using PTA client driver */
|
||||
+int stm32_bsec_optee_ta_write(struct tee_context *ctx, unsigned int lower,
|
||||
+ unsigned int offset, void *buf, size_t bytes)
|
||||
+{ struct tee_shm *shm;
|
||||
+ struct tee_ioctl_invoke_arg arg;
|
||||
+ struct tee_param param[2];
|
||||
+ u8 *shm_buf;
|
||||
+ int ret;
|
||||
+ u32 session_id;
|
||||
+
|
||||
+ ret = stm32_bsec_ta_open_session(ctx, &session_id);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* Allow only writing complete 32-bits aligned words */
|
||||
+ if ((bytes % 4) || (offset % 4))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ memset(&arg, 0, sizeof(arg));
|
||||
+ memset(¶m, 0, sizeof(param));
|
||||
+
|
||||
+ arg.func = PTA_BSEC_WRITE_MEM;
|
||||
+ arg.session = session_id;
|
||||
+ arg.num_params = 2;
|
||||
+
|
||||
+ param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT;
|
||||
+ param[0].u.value.a = offset;
|
||||
+ param[0].u.value.b = FUSE_ACCESS;
|
||||
+
|
||||
+ shm = tee_shm_alloc_kernel_buf(ctx, bytes);
|
||||
+ if (IS_ERR(shm)) {
|
||||
+ ret = PTR_ERR(shm);
|
||||
+ goto out_tee_session;
|
||||
+ }
|
||||
+
|
||||
+ param[1].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT;
|
||||
+ param[1].u.memref.shm = shm;
|
||||
+ param[1].u.memref.size = bytes;
|
||||
+
|
||||
+ shm_buf = tee_shm_get_va(shm, 0);
|
||||
+ if (IS_ERR(shm_buf)) {
|
||||
+ ret = PTR_ERR(shm_buf);
|
||||
+ pr_err("tee_shm_get_va failed for transmit (%d)\n", ret);
|
||||
+ tee_shm_free(shm);
|
||||
+
|
||||
+ goto out_tee_session;
|
||||
+ }
|
||||
+
|
||||
+ memcpy(shm_buf, buf, bytes);
|
||||
+
|
||||
+ ret = tee_client_invoke_func(ctx, &arg, param);
|
||||
+ if (ret < 0 || arg.ret != 0) {
|
||||
+ pr_err("TA_BSEC invoke failed TEE err:%#x, ret:%#x\n", arg.ret, ret);
|
||||
+ if (!ret)
|
||||
+ ret = -EIO;
|
||||
+ }
|
||||
+ pr_debug("Write OTPs %d to %zu, ret=%d\n", offset / 4, (offset + bytes) / 4, ret);
|
||||
+
|
||||
+ /* Lock the upper OTPs with ECC protection, word programming only */
|
||||
+ if (!ret && ((offset + bytes) >= (lower * 4))) {
|
||||
+ u32 start, nb_lock;
|
||||
+ u32 *lock = (u32 *)shm_buf;
|
||||
+ int i;
|
||||
+
|
||||
+ /*
|
||||
+ * don't lock the lower OTPs, no ECC protection and incremental
|
||||
+ * bit programming, a second write is allowed
|
||||
+ */
|
||||
+ start = max_t(u32, offset, lower * 4);
|
||||
+ nb_lock = (offset + bytes - start) / 4;
|
||||
+
|
||||
+ param[0].u.value.a = start;
|
||||
+ param[0].u.value.b = LOCK_ACCESS;
|
||||
+ param[1].u.memref.size = nb_lock * 4;
|
||||
+
|
||||
+ for (i = 0; i < nb_lock; i++)
|
||||
+ lock[i] = LOCK_PERM;
|
||||
+
|
||||
+ ret = tee_client_invoke_func(ctx, &arg, param);
|
||||
+ if (ret < 0 || arg.ret != 0) {
|
||||
+ pr_err("TA_BSEC invoke failed TEE err:%#x, ret:%#x\n", arg.ret, ret);
|
||||
+ if (!ret)
|
||||
+ ret = -EIO;
|
||||
+ }
|
||||
+ pr_debug("Lock upper OTPs %d to %d, ret=%d\n",
|
||||
+ start / 4, start / 4 + nb_lock, ret);
|
||||
+ }
|
||||
+
|
||||
+ tee_shm_free(shm);
|
||||
+
|
||||
+out_tee_session:
|
||||
+ stm32_bsec_ta_close_session(ctx, session_id);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
--- /dev/null
|
||||
+++ b/drivers/nvmem/stm32-bsec-optee-ta.h
|
||||
@@ -0,0 +1,80 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
+/*
|
||||
+ * OP-TEE STM32MP BSEC PTA interface, used by STM32 ROMEM driver
|
||||
+ *
|
||||
+ * Copyright (C) 2022, STMicroelectronics - All Rights Reserved
|
||||
+ */
|
||||
+
|
||||
+#if IS_ENABLED(CONFIG_NVMEM_STM32_BSEC_OPTEE_TA)
|
||||
+/**
|
||||
+ * stm32_bsec_optee_ta_open() - initialize the STM32 BSEC TA
|
||||
+ * @ctx: the OP-TEE context on success
|
||||
+ *
|
||||
+ * Return:
|
||||
+ * On success, 0. On failure, -errno.
|
||||
+ */
|
||||
+int stm32_bsec_optee_ta_open(struct tee_context **ctx);
|
||||
+
|
||||
+/**
|
||||
+ * stm32_bsec_optee_ta_close() - release the STM32 BSEC TA
|
||||
+ * @ctx: the OP-TEE context
|
||||
+ *
|
||||
+ * This function used to clean the OP-TEE resources initialized in
|
||||
+ * stm32_bsec_optee_ta_open(); it can be used as callback to
|
||||
+ * devm_add_action_or_reset()
|
||||
+ */
|
||||
+void stm32_bsec_optee_ta_close(void *ctx);
|
||||
+
|
||||
+/**
|
||||
+ * stm32_bsec_optee_ta_read() - nvmem read access using TA client driver
|
||||
+ * @ctx: the OP-TEE context provided by stm32_bsec_optee_ta_open
|
||||
+ * @offset: nvmem offset
|
||||
+ * @buf: buffer to fill with nvem values
|
||||
+ * @bytes: number of bytes to read
|
||||
+ *
|
||||
+ * Return:
|
||||
+ * On success, 0. On failure, -errno.
|
||||
+ */
|
||||
+int stm32_bsec_optee_ta_read(struct tee_context *ctx, unsigned int offset,
|
||||
+ void *buf, size_t bytes);
|
||||
+
|
||||
+/**
|
||||
+ * stm32_bsec_optee_ta_write() - nvmem write access using TA client driver
|
||||
+ * @ctx: the OP-TEE context provided by stm32_bsec_optee_ta_open
|
||||
+ * @lower: number of lower OTP, not protected by ECC
|
||||
+ * @offset: nvmem offset
|
||||
+ * @buf: buffer with nvem values
|
||||
+ * @bytes: number of bytes to write
|
||||
+ *
|
||||
+ * Return:
|
||||
+ * On success, 0. On failure, -errno.
|
||||
+ */
|
||||
+int stm32_bsec_optee_ta_write(struct tee_context *ctx, unsigned int lower,
|
||||
+ unsigned int offset, void *buf, size_t bytes);
|
||||
+
|
||||
+#else
|
||||
+
|
||||
+static inline int stm32_bsec_optee_ta_open(struct tee_context **ctx)
|
||||
+{
|
||||
+ return -EOPNOTSUPP;
|
||||
+}
|
||||
+
|
||||
+static inline void stm32_bsec_optee_ta_close(void *ctx)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+static inline int stm32_bsec_optee_ta_read(struct tee_context *ctx,
|
||||
+ unsigned int offset, void *buf,
|
||||
+ size_t bytes)
|
||||
+{
|
||||
+ return -EOPNOTSUPP;
|
||||
+}
|
||||
+
|
||||
+static inline int stm32_bsec_optee_ta_write(struct tee_context *ctx,
|
||||
+ unsigned int lower,
|
||||
+ unsigned int offset, void *buf,
|
||||
+ size_t bytes)
|
||||
+{
|
||||
+ return -EOPNOTSUPP;
|
||||
+}
|
||||
+#endif /* CONFIG_NVMEM_STM32_BSEC_OPTEE_TA */
|
||||
--- a/drivers/nvmem/stm32-romem.c
|
||||
+++ b/drivers/nvmem/stm32-romem.c
|
||||
@@ -11,6 +11,9 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/nvmem-provider.h>
|
||||
#include <linux/of_device.h>
|
||||
+#include <linux/tee_drv.h>
|
||||
+
|
||||
+#include "stm32-bsec-optee-ta.h"
|
||||
|
||||
/* BSEC secure service access from non-secure */
|
||||
#define STM32_SMC_BSEC 0x82001003
|
||||
@@ -25,12 +28,14 @@
|
||||
struct stm32_romem_cfg {
|
||||
int size;
|
||||
u8 lower;
|
||||
+ bool ta;
|
||||
};
|
||||
|
||||
struct stm32_romem_priv {
|
||||
void __iomem *base;
|
||||
struct nvmem_config cfg;
|
||||
u8 lower;
|
||||
+ struct tee_context *ctx;
|
||||
};
|
||||
|
||||
static int stm32_romem_read(void *context, unsigned int offset, void *buf,
|
||||
@@ -138,12 +143,29 @@ static int stm32_bsec_write(void *contex
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int stm32_bsec_pta_read(void *context, unsigned int offset, void *buf,
|
||||
+ size_t bytes)
|
||||
+{
|
||||
+ struct stm32_romem_priv *priv = context;
|
||||
+
|
||||
+ return stm32_bsec_optee_ta_read(priv->ctx, offset, buf, bytes);
|
||||
+}
|
||||
+
|
||||
+static int stm32_bsec_pta_write(void *context, unsigned int offset, void *buf,
|
||||
+ size_t bytes)
|
||||
+{
|
||||
+ struct stm32_romem_priv *priv = context;
|
||||
+
|
||||
+ return stm32_bsec_optee_ta_write(priv->ctx, priv->lower, offset, buf, bytes);
|
||||
+}
|
||||
+
|
||||
static int stm32_romem_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct stm32_romem_cfg *cfg;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct stm32_romem_priv *priv;
|
||||
struct resource *res;
|
||||
+ int rc;
|
||||
|
||||
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
@@ -173,15 +195,31 @@ static int stm32_romem_probe(struct plat
|
||||
} else {
|
||||
priv->cfg.size = cfg->size;
|
||||
priv->lower = cfg->lower;
|
||||
- priv->cfg.reg_read = stm32_bsec_read;
|
||||
- priv->cfg.reg_write = stm32_bsec_write;
|
||||
+ if (cfg->ta) {
|
||||
+ rc = stm32_bsec_optee_ta_open(&priv->ctx);
|
||||
+ /* wait for OP-TEE client driver to be up and ready */
|
||||
+ if (rc)
|
||||
+ return rc;
|
||||
+ }
|
||||
+ if (priv->ctx) {
|
||||
+ rc = devm_add_action_or_reset(dev, stm32_bsec_optee_ta_close, priv->ctx);
|
||||
+ if (rc) {
|
||||
+ dev_err(dev, "devm_add_action_or_reset() failed (%d)\n", rc);
|
||||
+ return rc;
|
||||
+ }
|
||||
+ priv->cfg.reg_read = stm32_bsec_pta_read;
|
||||
+ priv->cfg.reg_write = stm32_bsec_pta_write;
|
||||
+ } else {
|
||||
+ priv->cfg.reg_read = stm32_bsec_read;
|
||||
+ priv->cfg.reg_write = stm32_bsec_write;
|
||||
+ }
|
||||
}
|
||||
|
||||
return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &priv->cfg));
|
||||
}
|
||||
|
||||
/*
|
||||
- * STM32MP15 BSEC OTP regions: 4096 OTP bits (with 3072 effective bits)
|
||||
+ * STM32MP15/13 BSEC OTP regions: 4096 OTP bits (with 3072 effective bits)
|
||||
* => 96 x 32-bits data words
|
||||
* - Lower: 1K bits, 2:1 redundancy, incremental bit programming
|
||||
* => 32 (x 32-bits) lower shadow registers = words 0 to 31
|
||||
@@ -191,6 +229,13 @@ static int stm32_romem_probe(struct plat
|
||||
static const struct stm32_romem_cfg stm32mp15_bsec_cfg = {
|
||||
.size = 384,
|
||||
.lower = 32,
|
||||
+ .ta = false,
|
||||
+};
|
||||
+
|
||||
+static const struct stm32_romem_cfg stm32mp13_bsec_cfg = {
|
||||
+ .size = 384,
|
||||
+ .lower = 32,
|
||||
+ .ta = true,
|
||||
};
|
||||
|
||||
static const struct of_device_id stm32_romem_of_match[] = {
|
||||
@@ -198,7 +243,10 @@ static const struct of_device_id stm32_r
|
||||
.compatible = "st,stm32mp15-bsec",
|
||||
.data = (void *)&stm32mp15_bsec_cfg,
|
||||
}, {
|
||||
+ .compatible = "st,stm32mp13-bsec",
|
||||
+ .data = (void *)&stm32mp13_bsec_cfg,
|
||||
},
|
||||
+ { /* sentinel */ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, stm32_romem_of_match);
|
||||
|
@ -0,0 +1,85 @@
|
||||
From df2f34ef1d924125ffaf29dfdaf7cdbd3183c321 Mon Sep 17 00:00:00 2001
|
||||
From: Patrick Delaunay <patrick.delaunay@foss.st.com>
|
||||
Date: Mon, 6 Feb 2023 13:43:52 +0000
|
||||
Subject: [PATCH] nvmem: stm32: detect bsec pta presence for STM32MP15x
|
||||
|
||||
On STM32MP15x SoC, the SMC backend is optional when OP-TEE is used;
|
||||
the PTA BSEC should be used as it is done on STM32MP13x platform,
|
||||
but the BSEC SMC can be also used: it is a legacy mode in OP-TEE,
|
||||
not recommended but used in previous OP-TEE firmware.
|
||||
|
||||
The presence of OP-TEE is dynamically detected in STM32MP15x device tree
|
||||
and the supported NVMEM backend is dynamically detected:
|
||||
- PTA with stm32_bsec_pta_find
|
||||
- SMC with stm32_bsec_check
|
||||
|
||||
With OP-TEE but without PTA and SMC detection, the probe is deferred for
|
||||
STM32MP15x devices.
|
||||
|
||||
On STM32MP13x platform, only the PTA is supported with cfg->ta = true
|
||||
and this detection is skipped.
|
||||
|
||||
Signed-off-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
|
||||
Reviewed-by: Etienne Carriere <etienne.carriere@linaro.org>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20230206134356.839737-19-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/nvmem/stm32-romem.c | 38 +++++++++++++++++++++++++++++++++----
|
||||
1 file changed, 34 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/nvmem/stm32-romem.c
|
||||
+++ b/drivers/nvmem/stm32-romem.c
|
||||
@@ -159,6 +159,31 @@ static int stm32_bsec_pta_write(void *co
|
||||
return stm32_bsec_optee_ta_write(priv->ctx, priv->lower, offset, buf, bytes);
|
||||
}
|
||||
|
||||
+static bool stm32_bsec_smc_check(void)
|
||||
+{
|
||||
+ u32 val;
|
||||
+ int ret;
|
||||
+
|
||||
+ /* check that the OP-TEE support the BSEC SMC (legacy mode) */
|
||||
+ ret = stm32_bsec_smc(STM32_SMC_READ_SHADOW, 0, 0, &val);
|
||||
+
|
||||
+ return !ret;
|
||||
+}
|
||||
+
|
||||
+static bool optee_presence_check(void)
|
||||
+{
|
||||
+ struct device_node *np;
|
||||
+ bool tee_detected = false;
|
||||
+
|
||||
+ /* check that the OP-TEE node is present and available. */
|
||||
+ np = of_find_compatible_node(NULL, NULL, "linaro,optee-tz");
|
||||
+ if (np && of_device_is_available(np))
|
||||
+ tee_detected = true;
|
||||
+ of_node_put(np);
|
||||
+
|
||||
+ return tee_detected;
|
||||
+}
|
||||
+
|
||||
static int stm32_romem_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct stm32_romem_cfg *cfg;
|
||||
@@ -195,11 +220,16 @@ static int stm32_romem_probe(struct plat
|
||||
} else {
|
||||
priv->cfg.size = cfg->size;
|
||||
priv->lower = cfg->lower;
|
||||
- if (cfg->ta) {
|
||||
+ if (cfg->ta || optee_presence_check()) {
|
||||
rc = stm32_bsec_optee_ta_open(&priv->ctx);
|
||||
- /* wait for OP-TEE client driver to be up and ready */
|
||||
- if (rc)
|
||||
- return rc;
|
||||
+ if (rc) {
|
||||
+ /* wait for OP-TEE client driver to be up and ready */
|
||||
+ if (rc == -EPROBE_DEFER)
|
||||
+ return -EPROBE_DEFER;
|
||||
+ /* BSEC PTA is required or SMC not supported */
|
||||
+ if (cfg->ta || !stm32_bsec_smc_check())
|
||||
+ return rc;
|
||||
+ }
|
||||
}
|
||||
if (priv->ctx) {
|
||||
rc = devm_add_action_or_reset(dev, stm32_bsec_optee_ta_close, priv->ctx);
|
@ -0,0 +1,32 @@
|
||||
From 3e5ac22aa564026e99defc3a8e02082521a5b231 Mon Sep 17 00:00:00 2001
|
||||
From: Randy Dunlap <rdunlap@infradead.org>
|
||||
Date: Mon, 6 Feb 2023 13:43:53 +0000
|
||||
Subject: [PATCH] nvmem: rave-sp-eeprm: fix kernel-doc bad line warning
|
||||
|
||||
Convert an empty line to " *" to avoid a kernel-doc warning:
|
||||
|
||||
drivers/nvmem/rave-sp-eeprom.c:48: warning: bad line:
|
||||
|
||||
Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
|
||||
Cc: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Cc: Andrey Vostrikov <andrey.vostrikov@cogentembedded.com>
|
||||
Cc: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
|
||||
Cc: Andrey Smirnov <andrew.smirnov@gmail.com>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20230206134356.839737-20-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/nvmem/rave-sp-eeprom.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/nvmem/rave-sp-eeprom.c
|
||||
+++ b/drivers/nvmem/rave-sp-eeprom.c
|
||||
@@ -45,7 +45,7 @@ enum rave_sp_eeprom_header_size {
|
||||
* @type: Access type (see enum rave_sp_eeprom_access_type)
|
||||
* @success: Success flag (Success = 1, Failure = 0)
|
||||
* @data: Read data
|
||||
-
|
||||
+ *
|
||||
* Note this structure corresponds to RSP_*_EEPROM payload from RAVE
|
||||
* SP ICD
|
||||
*/
|
@ -0,0 +1,43 @@
|
||||
From eb7dda20f42a9137e9ee53d5ed3b743d49338cb5 Mon Sep 17 00:00:00 2001
|
||||
From: Johan Hovold <johan+linaro@kernel.org>
|
||||
Date: Mon, 6 Feb 2023 13:43:54 +0000
|
||||
Subject: [PATCH] nvmem: qcom-spmi-sdam: register at device init time
|
||||
|
||||
There are currently no in-tree users of the Qualcomm SDAM nvmem driver
|
||||
and there is generally no point in registering a driver that can be
|
||||
built as a module at subsys init time.
|
||||
|
||||
Register the driver at the normal device init time instead and let
|
||||
driver core sort out the probe order.
|
||||
|
||||
Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
|
||||
Reviewed-by: Bjorn Andersson <andersson@kernel.org>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20230206134356.839737-21-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/nvmem/qcom-spmi-sdam.c | 13 +------------
|
||||
1 file changed, 1 insertion(+), 12 deletions(-)
|
||||
|
||||
--- a/drivers/nvmem/qcom-spmi-sdam.c
|
||||
+++ b/drivers/nvmem/qcom-spmi-sdam.c
|
||||
@@ -175,18 +175,7 @@ static struct platform_driver sdam_drive
|
||||
},
|
||||
.probe = sdam_probe,
|
||||
};
|
||||
-
|
||||
-static int __init sdam_init(void)
|
||||
-{
|
||||
- return platform_driver_register(&sdam_driver);
|
||||
-}
|
||||
-subsys_initcall(sdam_init);
|
||||
-
|
||||
-static void __exit sdam_exit(void)
|
||||
-{
|
||||
- return platform_driver_unregister(&sdam_driver);
|
||||
-}
|
||||
-module_exit(sdam_exit);
|
||||
+module_platform_driver(sdam_driver);
|
||||
|
||||
MODULE_DESCRIPTION("QCOM SPMI SDAM driver");
|
||||
MODULE_LICENSE("GPL v2");
|
@ -0,0 +1,46 @@
|
||||
From 1dc7e37bb0ec1c997fac82031332a38c7610352f Mon Sep 17 00:00:00 2001
|
||||
From: Arnd Bergmann <arnd@arndb.de>
|
||||
Date: Mon, 6 Feb 2023 13:43:56 +0000
|
||||
Subject: [PATCH] nvmem: stm32: fix OPTEE dependency
|
||||
|
||||
The stm32 nvmem driver fails to link as built-in when OPTEE
|
||||
is a loadable module:
|
||||
|
||||
aarch64-linux-ld: drivers/nvmem/stm32-bsec-optee-ta.o: in function `stm32_bsec:
|
||||
stm32-bsec-optee-ta.c:(.text+0xc8): undefined reference to `tee_client_open_session'
|
||||
aarch64-linux-ld: drivers/nvmem/stm32-bsec-optee-ta.o: in function `stm32_bsec:
|
||||
stm32-bsec-optee-ta.c:(.text+0x1fc): undefined reference to `tee_client_open_context'
|
||||
|
||||
Change the CONFIG_NVMEM_STM32_ROMEM definition so it can only
|
||||
be built-in if OPTEE is either built-in or disabled, and
|
||||
make NVMEM_STM32_BSEC_OPTEE_TA a hidden symbol instead.
|
||||
|
||||
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20230206134356.839737-23-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/nvmem/Kconfig | 5 ++---
|
||||
1 file changed, 2 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/drivers/nvmem/Kconfig
|
||||
+++ b/drivers/nvmem/Kconfig
|
||||
@@ -291,8 +291,7 @@ config NVMEM_SPRD_EFUSE
|
||||
will be called nvmem-sprd-efuse.
|
||||
|
||||
config NVMEM_STM32_BSEC_OPTEE_TA
|
||||
- bool "STM32MP BSEC OP-TEE TA support for nvmem-stm32-romem driver"
|
||||
- depends on OPTEE
|
||||
+ def_bool NVMEM_STM32_ROMEM && OPTEE
|
||||
help
|
||||
Say y here to enable the accesses to STM32MP SoC OTPs by the OP-TEE
|
||||
trusted application STM32MP BSEC.
|
||||
@@ -303,7 +302,7 @@ config NVMEM_STM32_BSEC_OPTEE_TA
|
||||
config NVMEM_STM32_ROMEM
|
||||
tristate "STMicroelectronics STM32 factory-programmed memory support"
|
||||
depends on ARCH_STM32 || COMPILE_TEST
|
||||
- imply NVMEM_STM32_BSEC_OPTEE_TA
|
||||
+ depends on OPTEE || !OPTEE
|
||||
help
|
||||
Say y here to enable read-only access for STMicroelectronics STM32
|
||||
factory-programmed memory area.
|
@ -0,0 +1,26 @@
|
||||
From 2e8dc541ae207349b51c65391be625ffe1f86e0c Mon Sep 17 00:00:00 2001
|
||||
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
|
||||
Date: Mon, 6 Feb 2023 13:43:41 +0000
|
||||
Subject: [PATCH] nvmem: core: remove spurious white space
|
||||
|
||||
Remove a spurious white space in for the ida_alloc() call.
|
||||
|
||||
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20230206134356.839737-8-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/nvmem/core.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/nvmem/core.c
|
||||
+++ b/drivers/nvmem/core.c
|
||||
@@ -764,7 +764,7 @@ struct nvmem_device *nvmem_register(cons
|
||||
if (!nvmem)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
- rval = ida_alloc(&nvmem_ida, GFP_KERNEL);
|
||||
+ rval = ida_alloc(&nvmem_ida, GFP_KERNEL);
|
||||
if (rval < 0) {
|
||||
kfree(nvmem);
|
||||
return ERR_PTR(rval);
|
@ -0,0 +1,180 @@
|
||||
From 5d8e6e6c10a3d37486d263b16ddc15991a7e4a88 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Walle <michael@walle.cc>
|
||||
Date: Mon, 6 Feb 2023 13:43:46 +0000
|
||||
Subject: [PATCH] nvmem: core: add an index parameter to the cell
|
||||
|
||||
Sometimes a cell can represend multiple values. For example, a base
|
||||
ethernet address stored in the NVMEM can be expanded into multiple
|
||||
discreet ones by adding an offset.
|
||||
|
||||
For this use case, introduce an index parameter which is then used to
|
||||
distiguish between values. This parameter will then be passed to the
|
||||
post process hook which can then use it to create different values
|
||||
during reading.
|
||||
|
||||
At the moment, there is only support for the device tree path. You can
|
||||
add the index to the phandle, e.g.
|
||||
|
||||
&net {
|
||||
nvmem-cells = <&base_mac_address 2>;
|
||||
nvmem-cell-names = "mac-address";
|
||||
};
|
||||
|
||||
&nvmem_provider {
|
||||
base_mac_address: base-mac-address@0 {
|
||||
#nvmem-cell-cells = <1>;
|
||||
reg = <0 6>;
|
||||
};
|
||||
};
|
||||
|
||||
Signed-off-by: Michael Walle <michael@walle.cc>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20230206134356.839737-13-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/nvmem/core.c | 37 ++++++++++++++++++++++++----------
|
||||
drivers/nvmem/imx-ocotp.c | 4 ++--
|
||||
include/linux/nvmem-provider.h | 4 ++--
|
||||
3 files changed, 30 insertions(+), 15 deletions(-)
|
||||
|
||||
--- a/drivers/nvmem/core.c
|
||||
+++ b/drivers/nvmem/core.c
|
||||
@@ -60,6 +60,7 @@ struct nvmem_cell_entry {
|
||||
struct nvmem_cell {
|
||||
struct nvmem_cell_entry *entry;
|
||||
const char *id;
|
||||
+ int index;
|
||||
};
|
||||
|
||||
static DEFINE_MUTEX(nvmem_mutex);
|
||||
@@ -1125,7 +1126,8 @@ struct nvmem_device *devm_nvmem_device_g
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devm_nvmem_device_get);
|
||||
|
||||
-static struct nvmem_cell *nvmem_create_cell(struct nvmem_cell_entry *entry, const char *id)
|
||||
+static struct nvmem_cell *nvmem_create_cell(struct nvmem_cell_entry *entry,
|
||||
+ const char *id, int index)
|
||||
{
|
||||
struct nvmem_cell *cell;
|
||||
const char *name = NULL;
|
||||
@@ -1144,6 +1146,7 @@ static struct nvmem_cell *nvmem_create_c
|
||||
|
||||
cell->id = name;
|
||||
cell->entry = entry;
|
||||
+ cell->index = index;
|
||||
|
||||
return cell;
|
||||
}
|
||||
@@ -1182,7 +1185,7 @@ nvmem_cell_get_from_lookup(struct device
|
||||
__nvmem_device_put(nvmem);
|
||||
cell = ERR_PTR(-ENOENT);
|
||||
} else {
|
||||
- cell = nvmem_create_cell(cell_entry, con_id);
|
||||
+ cell = nvmem_create_cell(cell_entry, con_id, 0);
|
||||
if (IS_ERR(cell))
|
||||
__nvmem_device_put(nvmem);
|
||||
}
|
||||
@@ -1230,15 +1233,27 @@ struct nvmem_cell *of_nvmem_cell_get(str
|
||||
struct nvmem_device *nvmem;
|
||||
struct nvmem_cell_entry *cell_entry;
|
||||
struct nvmem_cell *cell;
|
||||
+ struct of_phandle_args cell_spec;
|
||||
int index = 0;
|
||||
+ int cell_index = 0;
|
||||
+ int ret;
|
||||
|
||||
/* if cell name exists, find index to the name */
|
||||
if (id)
|
||||
index = of_property_match_string(np, "nvmem-cell-names", id);
|
||||
|
||||
- cell_np = of_parse_phandle(np, "nvmem-cells", index);
|
||||
- if (!cell_np)
|
||||
- return ERR_PTR(-ENOENT);
|
||||
+ ret = of_parse_phandle_with_optional_args(np, "nvmem-cells",
|
||||
+ "#nvmem-cell-cells",
|
||||
+ index, &cell_spec);
|
||||
+ if (ret)
|
||||
+ return ERR_PTR(ret);
|
||||
+
|
||||
+ if (cell_spec.args_count > 1)
|
||||
+ return ERR_PTR(-EINVAL);
|
||||
+
|
||||
+ cell_np = cell_spec.np;
|
||||
+ if (cell_spec.args_count)
|
||||
+ cell_index = cell_spec.args[0];
|
||||
|
||||
nvmem_np = of_get_next_parent(cell_np);
|
||||
if (!nvmem_np)
|
||||
@@ -1255,7 +1270,7 @@ struct nvmem_cell *of_nvmem_cell_get(str
|
||||
return ERR_PTR(-ENOENT);
|
||||
}
|
||||
|
||||
- cell = nvmem_create_cell(cell_entry, id);
|
||||
+ cell = nvmem_create_cell(cell_entry, id, cell_index);
|
||||
if (IS_ERR(cell))
|
||||
__nvmem_device_put(nvmem);
|
||||
|
||||
@@ -1408,8 +1423,8 @@ static void nvmem_shift_read_buffer_in_p
|
||||
}
|
||||
|
||||
static int __nvmem_cell_read(struct nvmem_device *nvmem,
|
||||
- struct nvmem_cell_entry *cell,
|
||||
- void *buf, size_t *len, const char *id)
|
||||
+ struct nvmem_cell_entry *cell,
|
||||
+ void *buf, size_t *len, const char *id, int index)
|
||||
{
|
||||
int rc;
|
||||
|
||||
@@ -1423,7 +1438,7 @@ static int __nvmem_cell_read(struct nvme
|
||||
nvmem_shift_read_buffer_in_place(cell, buf);
|
||||
|
||||
if (nvmem->cell_post_process) {
|
||||
- rc = nvmem->cell_post_process(nvmem->priv, id,
|
||||
+ rc = nvmem->cell_post_process(nvmem->priv, id, index,
|
||||
cell->offset, buf, cell->bytes);
|
||||
if (rc)
|
||||
return rc;
|
||||
@@ -1458,7 +1473,7 @@ void *nvmem_cell_read(struct nvmem_cell
|
||||
if (!buf)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
- rc = __nvmem_cell_read(nvmem, cell->entry, buf, len, cell->id);
|
||||
+ rc = __nvmem_cell_read(nvmem, cell->entry, buf, len, cell->id, cell->index);
|
||||
if (rc) {
|
||||
kfree(buf);
|
||||
return ERR_PTR(rc);
|
||||
@@ -1771,7 +1786,7 @@ ssize_t nvmem_device_cell_read(struct nv
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
- rc = __nvmem_cell_read(nvmem, &cell, buf, &len, NULL);
|
||||
+ rc = __nvmem_cell_read(nvmem, &cell, buf, &len, NULL, 0);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
--- a/drivers/nvmem/imx-ocotp.c
|
||||
+++ b/drivers/nvmem/imx-ocotp.c
|
||||
@@ -222,8 +222,8 @@ read_end:
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static int imx_ocotp_cell_pp(void *context, const char *id, unsigned int offset,
|
||||
- void *data, size_t bytes)
|
||||
+static int imx_ocotp_cell_pp(void *context, const char *id, int index,
|
||||
+ unsigned int offset, void *data, size_t bytes)
|
||||
{
|
||||
struct ocotp_priv *priv = context;
|
||||
|
||||
--- a/include/linux/nvmem-provider.h
|
||||
+++ b/include/linux/nvmem-provider.h
|
||||
@@ -20,8 +20,8 @@ typedef int (*nvmem_reg_read_t)(void *pr
|
||||
typedef int (*nvmem_reg_write_t)(void *priv, unsigned int offset,
|
||||
void *val, size_t bytes);
|
||||
/* used for vendor specific post processing of cell data */
|
||||
-typedef int (*nvmem_cell_post_process_t)(void *priv, const char *id, unsigned int offset,
|
||||
- void *buf, size_t bytes);
|
||||
+typedef int (*nvmem_cell_post_process_t)(void *priv, const char *id, int index,
|
||||
+ unsigned int offset, void *buf, size_t bytes);
|
||||
|
||||
enum nvmem_type {
|
||||
NVMEM_TYPE_UNKNOWN = 0,
|
@ -0,0 +1,78 @@
|
||||
From fbd03d27776c6121a483921601418e3c8f0ff37e Mon Sep 17 00:00:00 2001
|
||||
From: Michael Walle <michael@walle.cc>
|
||||
Date: Mon, 6 Feb 2023 13:43:47 +0000
|
||||
Subject: [PATCH] nvmem: core: move struct nvmem_cell_info to nvmem-provider.h
|
||||
|
||||
struct nvmem_cell_info is used to describe a cell. Thus this should
|
||||
really be in the nvmem-provider's header. There are two (unused) nvmem
|
||||
access methods which use the nvmem_cell_info to describe the cell to be
|
||||
accesses. One can argue, that they will create a cell before accessing,
|
||||
thus they are both a provider and a consumer.
|
||||
|
||||
struct nvmem_cell_info will get used more and more by nvmem-providers,
|
||||
don't force them to also include the consumer header, although they are
|
||||
not.
|
||||
|
||||
Signed-off-by: Michael Walle <michael@walle.cc>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20230206134356.839737-14-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
include/linux/nvmem-consumer.h | 10 +---------
|
||||
include/linux/nvmem-provider.h | 19 ++++++++++++++++++-
|
||||
2 files changed, 19 insertions(+), 10 deletions(-)
|
||||
|
||||
--- a/include/linux/nvmem-consumer.h
|
||||
+++ b/include/linux/nvmem-consumer.h
|
||||
@@ -18,15 +18,7 @@ struct device_node;
|
||||
/* consumer cookie */
|
||||
struct nvmem_cell;
|
||||
struct nvmem_device;
|
||||
-
|
||||
-struct nvmem_cell_info {
|
||||
- const char *name;
|
||||
- unsigned int offset;
|
||||
- unsigned int bytes;
|
||||
- unsigned int bit_offset;
|
||||
- unsigned int nbits;
|
||||
- struct device_node *np;
|
||||
-};
|
||||
+struct nvmem_cell_info;
|
||||
|
||||
/**
|
||||
* struct nvmem_cell_lookup - cell lookup entry
|
||||
--- a/include/linux/nvmem-provider.h
|
||||
+++ b/include/linux/nvmem-provider.h
|
||||
@@ -14,7 +14,6 @@
|
||||
#include <linux/gpio/consumer.h>
|
||||
|
||||
struct nvmem_device;
|
||||
-struct nvmem_cell_info;
|
||||
typedef int (*nvmem_reg_read_t)(void *priv, unsigned int offset,
|
||||
void *val, size_t bytes);
|
||||
typedef int (*nvmem_reg_write_t)(void *priv, unsigned int offset,
|
||||
@@ -48,6 +47,24 @@ struct nvmem_keepout {
|
||||
};
|
||||
|
||||
/**
|
||||
+ * struct nvmem_cell_info - NVMEM cell description
|
||||
+ * @name: Name.
|
||||
+ * @offset: Offset within the NVMEM device.
|
||||
+ * @bytes: Length of the cell.
|
||||
+ * @bit_offset: Bit offset if cell is smaller than a byte.
|
||||
+ * @nbits: Number of bits.
|
||||
+ * @np: Optional device_node pointer.
|
||||
+ */
|
||||
+struct nvmem_cell_info {
|
||||
+ const char *name;
|
||||
+ unsigned int offset;
|
||||
+ unsigned int bytes;
|
||||
+ unsigned int bit_offset;
|
||||
+ unsigned int nbits;
|
||||
+ struct device_node *np;
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
* struct nvmem_config - NVMEM device configuration
|
||||
*
|
||||
* @dev: Parent device.
|
@ -0,0 +1,65 @@
|
||||
From cc5bdd323dde6494623f3ffe3a5b887fa21cd375 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Walle <michael@walle.cc>
|
||||
Date: Mon, 6 Feb 2023 13:43:48 +0000
|
||||
Subject: [PATCH] nvmem: core: drop the removal of the cells in
|
||||
nvmem_add_cells()
|
||||
|
||||
If nvmem_add_cells() fails, the whole nvmem_register() will fail
|
||||
and the cells will then be removed anyway. This is a preparation
|
||||
to introduce a nvmem_add_one_cell() which can then be used by
|
||||
nvmem_add_cells().
|
||||
|
||||
This is then the same to what nvmem_add_cells_from_table() and
|
||||
nvmem_add_cells_from_of() do.
|
||||
|
||||
Signed-off-by: Michael Walle <michael@walle.cc>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20230206134356.839737-15-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/nvmem/core.c | 14 ++++----------
|
||||
1 file changed, 4 insertions(+), 10 deletions(-)
|
||||
|
||||
--- a/drivers/nvmem/core.c
|
||||
+++ b/drivers/nvmem/core.c
|
||||
@@ -515,7 +515,7 @@ static int nvmem_add_cells(struct nvmem_
|
||||
int ncells)
|
||||
{
|
||||
struct nvmem_cell_entry **cells;
|
||||
- int i, rval;
|
||||
+ int i, rval = 0;
|
||||
|
||||
cells = kcalloc(ncells, sizeof(*cells), GFP_KERNEL);
|
||||
if (!cells)
|
||||
@@ -525,28 +525,22 @@ static int nvmem_add_cells(struct nvmem_
|
||||
cells[i] = kzalloc(sizeof(**cells), GFP_KERNEL);
|
||||
if (!cells[i]) {
|
||||
rval = -ENOMEM;
|
||||
- goto err;
|
||||
+ goto out;
|
||||
}
|
||||
|
||||
rval = nvmem_cell_info_to_nvmem_cell_entry(nvmem, &info[i], cells[i]);
|
||||
if (rval) {
|
||||
kfree(cells[i]);
|
||||
- goto err;
|
||||
+ goto out;
|
||||
}
|
||||
|
||||
nvmem_cell_entry_add(cells[i]);
|
||||
}
|
||||
|
||||
+out:
|
||||
/* remove tmp array */
|
||||
kfree(cells);
|
||||
|
||||
- return 0;
|
||||
-err:
|
||||
- while (i--)
|
||||
- nvmem_cell_entry_drop(cells[i]);
|
||||
-
|
||||
- kfree(cells);
|
||||
-
|
||||
return rval;
|
||||
}
|
||||
|
@ -0,0 +1,122 @@
|
||||
From 2ded6830d376d5e7bf43d59f7f7fdf1a59abc676 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Walle <michael@walle.cc>
|
||||
Date: Mon, 6 Feb 2023 13:43:49 +0000
|
||||
Subject: [PATCH] nvmem: core: add nvmem_add_one_cell()
|
||||
|
||||
Add a new function to add exactly one cell. This will be used by the
|
||||
nvmem layout drivers to add custom cells. In contrast to the
|
||||
nvmem_add_cells(), this has the advantage that we don't have to assemble
|
||||
a list of cells on runtime.
|
||||
|
||||
Signed-off-by: Michael Walle <michael@walle.cc>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20230206134356.839737-16-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/nvmem/core.c | 59 ++++++++++++++++++++--------------
|
||||
include/linux/nvmem-provider.h | 8 +++++
|
||||
2 files changed, 43 insertions(+), 24 deletions(-)
|
||||
|
||||
--- a/drivers/nvmem/core.c
|
||||
+++ b/drivers/nvmem/core.c
|
||||
@@ -502,6 +502,36 @@ static int nvmem_cell_info_to_nvmem_cell
|
||||
}
|
||||
|
||||
/**
|
||||
+ * nvmem_add_one_cell() - Add one cell information to an nvmem device
|
||||
+ *
|
||||
+ * @nvmem: nvmem device to add cells to.
|
||||
+ * @info: nvmem cell info to add to the device
|
||||
+ *
|
||||
+ * Return: 0 or negative error code on failure.
|
||||
+ */
|
||||
+int nvmem_add_one_cell(struct nvmem_device *nvmem,
|
||||
+ const struct nvmem_cell_info *info)
|
||||
+{
|
||||
+ struct nvmem_cell_entry *cell;
|
||||
+ int rval;
|
||||
+
|
||||
+ cell = kzalloc(sizeof(*cell), GFP_KERNEL);
|
||||
+ if (!cell)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ rval = nvmem_cell_info_to_nvmem_cell_entry(nvmem, info, cell);
|
||||
+ if (rval) {
|
||||
+ kfree(cell);
|
||||
+ return rval;
|
||||
+ }
|
||||
+
|
||||
+ nvmem_cell_entry_add(cell);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(nvmem_add_one_cell);
|
||||
+
|
||||
+/**
|
||||
* nvmem_add_cells() - Add cell information to an nvmem device
|
||||
*
|
||||
* @nvmem: nvmem device to add cells to.
|
||||
@@ -514,34 +544,15 @@ static int nvmem_add_cells(struct nvmem_
|
||||
const struct nvmem_cell_info *info,
|
||||
int ncells)
|
||||
{
|
||||
- struct nvmem_cell_entry **cells;
|
||||
- int i, rval = 0;
|
||||
-
|
||||
- cells = kcalloc(ncells, sizeof(*cells), GFP_KERNEL);
|
||||
- if (!cells)
|
||||
- return -ENOMEM;
|
||||
+ int i, rval;
|
||||
|
||||
for (i = 0; i < ncells; i++) {
|
||||
- cells[i] = kzalloc(sizeof(**cells), GFP_KERNEL);
|
||||
- if (!cells[i]) {
|
||||
- rval = -ENOMEM;
|
||||
- goto out;
|
||||
- }
|
||||
-
|
||||
- rval = nvmem_cell_info_to_nvmem_cell_entry(nvmem, &info[i], cells[i]);
|
||||
- if (rval) {
|
||||
- kfree(cells[i]);
|
||||
- goto out;
|
||||
- }
|
||||
-
|
||||
- nvmem_cell_entry_add(cells[i]);
|
||||
+ rval = nvmem_add_one_cell(nvmem, &info[i]);
|
||||
+ if (rval)
|
||||
+ return rval;
|
||||
}
|
||||
|
||||
-out:
|
||||
- /* remove tmp array */
|
||||
- kfree(cells);
|
||||
-
|
||||
- return rval;
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
--- a/include/linux/nvmem-provider.h
|
||||
+++ b/include/linux/nvmem-provider.h
|
||||
@@ -153,6 +153,9 @@ struct nvmem_device *devm_nvmem_register
|
||||
void nvmem_add_cell_table(struct nvmem_cell_table *table);
|
||||
void nvmem_del_cell_table(struct nvmem_cell_table *table);
|
||||
|
||||
+int nvmem_add_one_cell(struct nvmem_device *nvmem,
|
||||
+ const struct nvmem_cell_info *info);
|
||||
+
|
||||
#else
|
||||
|
||||
static inline struct nvmem_device *nvmem_register(const struct nvmem_config *c)
|
||||
@@ -170,6 +173,11 @@ devm_nvmem_register(struct device *dev,
|
||||
|
||||
static inline void nvmem_add_cell_table(struct nvmem_cell_table *table) {}
|
||||
static inline void nvmem_del_cell_table(struct nvmem_cell_table *table) {}
|
||||
+static inline int nvmem_add_one_cell(struct nvmem_device *nvmem,
|
||||
+ const struct nvmem_cell_info *info)
|
||||
+{
|
||||
+ return -EOPNOTSUPP;
|
||||
+}
|
||||
|
||||
#endif /* CONFIG_NVMEM */
|
||||
#endif /* ifndef _LINUX_NVMEM_PROVIDER_H */
|
@ -0,0 +1,93 @@
|
||||
From 50014d659617dc58780a5d31ceb76c82779a9d8b Mon Sep 17 00:00:00 2001
|
||||
From: Michael Walle <michael@walle.cc>
|
||||
Date: Mon, 6 Feb 2023 13:43:50 +0000
|
||||
Subject: [PATCH] nvmem: core: use nvmem_add_one_cell() in
|
||||
nvmem_add_cells_from_of()
|
||||
|
||||
Convert nvmem_add_cells_from_of() to use the new nvmem_add_one_cell().
|
||||
This will remove duplicate code and it will make it possible to add a
|
||||
hook to a nvmem layout in between, which can change fields before the
|
||||
cell is finally added.
|
||||
|
||||
Signed-off-by: Michael Walle <michael@walle.cc>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20230206134356.839737-17-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/nvmem/core.c | 45 ++++++++++++++------------------------------
|
||||
1 file changed, 14 insertions(+), 31 deletions(-)
|
||||
|
||||
--- a/drivers/nvmem/core.c
|
||||
+++ b/drivers/nvmem/core.c
|
||||
@@ -688,15 +688,14 @@ static int nvmem_validate_keepouts(struc
|
||||
|
||||
static int nvmem_add_cells_from_of(struct nvmem_device *nvmem)
|
||||
{
|
||||
- struct device_node *parent, *child;
|
||||
struct device *dev = &nvmem->dev;
|
||||
- struct nvmem_cell_entry *cell;
|
||||
+ struct device_node *child;
|
||||
const __be32 *addr;
|
||||
- int len;
|
||||
+ int len, ret;
|
||||
|
||||
- parent = dev->of_node;
|
||||
+ for_each_child_of_node(dev->of_node, child) {
|
||||
+ struct nvmem_cell_info info = {0};
|
||||
|
||||
- for_each_child_of_node(parent, child) {
|
||||
addr = of_get_property(child, "reg", &len);
|
||||
if (!addr)
|
||||
continue;
|
||||
@@ -706,40 +705,24 @@ static int nvmem_add_cells_from_of(struc
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
- cell = kzalloc(sizeof(*cell), GFP_KERNEL);
|
||||
- if (!cell) {
|
||||
- of_node_put(child);
|
||||
- return -ENOMEM;
|
||||
- }
|
||||
-
|
||||
- cell->nvmem = nvmem;
|
||||
- cell->offset = be32_to_cpup(addr++);
|
||||
- cell->bytes = be32_to_cpup(addr);
|
||||
- cell->name = kasprintf(GFP_KERNEL, "%pOFn", child);
|
||||
+ info.offset = be32_to_cpup(addr++);
|
||||
+ info.bytes = be32_to_cpup(addr);
|
||||
+ info.name = kasprintf(GFP_KERNEL, "%pOFn", child);
|
||||
|
||||
addr = of_get_property(child, "bits", &len);
|
||||
if (addr && len == (2 * sizeof(u32))) {
|
||||
- cell->bit_offset = be32_to_cpup(addr++);
|
||||
- cell->nbits = be32_to_cpup(addr);
|
||||
+ info.bit_offset = be32_to_cpup(addr++);
|
||||
+ info.nbits = be32_to_cpup(addr);
|
||||
}
|
||||
|
||||
- if (cell->nbits)
|
||||
- cell->bytes = DIV_ROUND_UP(
|
||||
- cell->nbits + cell->bit_offset,
|
||||
- BITS_PER_BYTE);
|
||||
-
|
||||
- if (!IS_ALIGNED(cell->offset, nvmem->stride)) {
|
||||
- dev_err(dev, "cell %s unaligned to nvmem stride %d\n",
|
||||
- cell->name, nvmem->stride);
|
||||
- /* Cells already added will be freed later. */
|
||||
- kfree_const(cell->name);
|
||||
- kfree(cell);
|
||||
+ info.np = of_node_get(child);
|
||||
+
|
||||
+ ret = nvmem_add_one_cell(nvmem, &info);
|
||||
+ kfree(info.name);
|
||||
+ if (ret) {
|
||||
of_node_put(child);
|
||||
- return -EINVAL;
|
||||
+ return ret;
|
||||
}
|
||||
-
|
||||
- cell->np = of_node_get(child);
|
||||
- nvmem_cell_entry_add(cell);
|
||||
}
|
||||
|
||||
return 0;
|
@ -0,0 +1,562 @@
|
||||
From 6a0bc3522e746025e2d9a63ab2cb5d7062c2d39c Mon Sep 17 00:00:00 2001
|
||||
From: Patrick Delaunay <patrick.delaunay@foss.st.com>
|
||||
Date: Mon, 6 Feb 2023 13:43:51 +0000
|
||||
Subject: [PATCH] nvmem: stm32: add OP-TEE support for STM32MP13x
|
||||
|
||||
For boot with OP-TEE on STM32MP13, the communication with the secure
|
||||
world no more use STMicroelectronics SMC but communication with the
|
||||
STM32MP BSEC TA, for data access (read/write) or lock operation:
|
||||
- all the request are sent to OP-TEE trusted application,
|
||||
- for upper OTP with ECC protection and with word programming only
|
||||
each OTP are permanently locked when programmed to avoid ECC error
|
||||
on the second write operation
|
||||
|
||||
Signed-off-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
|
||||
Reviewed-by: Etienne Carriere <etienne.carriere@linaro.org>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20230206134356.839737-18-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/nvmem/Kconfig | 11 +
|
||||
drivers/nvmem/Makefile | 1 +
|
||||
drivers/nvmem/stm32-bsec-optee-ta.c | 298 ++++++++++++++++++++++++++++
|
||||
drivers/nvmem/stm32-bsec-optee-ta.h | 80 ++++++++
|
||||
drivers/nvmem/stm32-romem.c | 54 ++++-
|
||||
5 files changed, 441 insertions(+), 3 deletions(-)
|
||||
create mode 100644 drivers/nvmem/stm32-bsec-optee-ta.c
|
||||
create mode 100644 drivers/nvmem/stm32-bsec-optee-ta.h
|
||||
|
||||
--- a/drivers/nvmem/Kconfig
|
||||
+++ b/drivers/nvmem/Kconfig
|
||||
@@ -290,9 +290,20 @@ config NVMEM_SPRD_EFUSE
|
||||
This driver can also be built as a module. If so, the module
|
||||
will be called nvmem-sprd-efuse.
|
||||
|
||||
+config NVMEM_STM32_BSEC_OPTEE_TA
|
||||
+ bool "STM32MP BSEC OP-TEE TA support for nvmem-stm32-romem driver"
|
||||
+ depends on OPTEE
|
||||
+ help
|
||||
+ Say y here to enable the accesses to STM32MP SoC OTPs by the OP-TEE
|
||||
+ trusted application STM32MP BSEC.
|
||||
+
|
||||
+ This library is a used by stm32-romem driver or included in the module
|
||||
+ called nvmem-stm32-romem.
|
||||
+
|
||||
config NVMEM_STM32_ROMEM
|
||||
tristate "STMicroelectronics STM32 factory-programmed memory support"
|
||||
depends on ARCH_STM32 || COMPILE_TEST
|
||||
+ imply NVMEM_STM32_BSEC_OPTEE_TA
|
||||
help
|
||||
Say y here to enable read-only access for STMicroelectronics STM32
|
||||
factory-programmed memory area.
|
||||
--- a/drivers/nvmem/Makefile
|
||||
+++ b/drivers/nvmem/Makefile
|
||||
@@ -61,6 +61,7 @@ obj-$(CONFIG_NVMEM_SPRD_EFUSE) += nvmem
|
||||
nvmem_sprd_efuse-y := sprd-efuse.o
|
||||
obj-$(CONFIG_NVMEM_STM32_ROMEM) += nvmem_stm32_romem.o
|
||||
nvmem_stm32_romem-y := stm32-romem.o
|
||||
+nvmem_stm32_romem-$(CONFIG_NVMEM_STM32_BSEC_OPTEE_TA) += stm32-bsec-optee-ta.o
|
||||
obj-$(CONFIG_NVMEM_SUNPLUS_OCOTP) += nvmem_sunplus_ocotp.o
|
||||
nvmem_sunplus_ocotp-y := sunplus-ocotp.o
|
||||
obj-$(CONFIG_NVMEM_SUNXI_SID) += nvmem_sunxi_sid.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/nvmem/stm32-bsec-optee-ta.c
|
||||
@@ -0,0 +1,298 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
+/*
|
||||
+ * OP-TEE STM32MP BSEC PTA interface, used by STM32 ROMEM driver
|
||||
+ *
|
||||
+ * Copyright (C) 2022, STMicroelectronics - All Rights Reserved
|
||||
+ */
|
||||
+
|
||||
+#include <linux/tee_drv.h>
|
||||
+
|
||||
+#include "stm32-bsec-optee-ta.h"
|
||||
+
|
||||
+/*
|
||||
+ * Read OTP memory
|
||||
+ *
|
||||
+ * [in] value[0].a OTP start offset in byte
|
||||
+ * [in] value[0].b Access type (0:shadow, 1:fuse, 2:lock)
|
||||
+ * [out] memref[1].buffer Output buffer to store read values
|
||||
+ * [out] memref[1].size Size of OTP to be read
|
||||
+ *
|
||||
+ * Return codes:
|
||||
+ * TEE_SUCCESS - Invoke command success
|
||||
+ * TEE_ERROR_BAD_PARAMETERS - Incorrect input param
|
||||
+ * TEE_ERROR_ACCESS_DENIED - OTP not accessible by caller
|
||||
+ */
|
||||
+#define PTA_BSEC_READ_MEM 0x0
|
||||
+
|
||||
+/*
|
||||
+ * Write OTP memory
|
||||
+ *
|
||||
+ * [in] value[0].a OTP start offset in byte
|
||||
+ * [in] value[0].b Access type (0:shadow, 1:fuse, 2:lock)
|
||||
+ * [in] memref[1].buffer Input buffer to read values
|
||||
+ * [in] memref[1].size Size of OTP to be written
|
||||
+ *
|
||||
+ * Return codes:
|
||||
+ * TEE_SUCCESS - Invoke command success
|
||||
+ * TEE_ERROR_BAD_PARAMETERS - Incorrect input param
|
||||
+ * TEE_ERROR_ACCESS_DENIED - OTP not accessible by caller
|
||||
+ */
|
||||
+#define PTA_BSEC_WRITE_MEM 0x1
|
||||
+
|
||||
+/* value of PTA_BSEC access type = value[in] b */
|
||||
+#define SHADOW_ACCESS 0
|
||||
+#define FUSE_ACCESS 1
|
||||
+#define LOCK_ACCESS 2
|
||||
+
|
||||
+/* Bitfield definition for LOCK status */
|
||||
+#define LOCK_PERM BIT(30)
|
||||
+
|
||||
+/* OP-TEE STM32MP BSEC TA UUID */
|
||||
+static const uuid_t stm32mp_bsec_ta_uuid =
|
||||
+ UUID_INIT(0x94cf71ad, 0x80e6, 0x40b5,
|
||||
+ 0xa7, 0xc6, 0x3d, 0xc5, 0x01, 0xeb, 0x28, 0x03);
|
||||
+
|
||||
+/*
|
||||
+ * Check whether this driver supports the BSEC TA in the TEE instance
|
||||
+ * represented by the params (ver/data) to this function.
|
||||
+ */
|
||||
+static int stm32_bsec_optee_ta_match(struct tee_ioctl_version_data *ver,
|
||||
+ const void *data)
|
||||
+{
|
||||
+ /* Currently this driver only supports GP compliant, OP-TEE based TA */
|
||||
+ if ((ver->impl_id == TEE_IMPL_ID_OPTEE) &&
|
||||
+ (ver->gen_caps & TEE_GEN_CAP_GP))
|
||||
+ return 1;
|
||||
+ else
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/* Open a session to OP-TEE for STM32MP BSEC TA */
|
||||
+static int stm32_bsec_ta_open_session(struct tee_context *ctx, u32 *id)
|
||||
+{
|
||||
+ struct tee_ioctl_open_session_arg sess_arg;
|
||||
+ int rc;
|
||||
+
|
||||
+ memset(&sess_arg, 0, sizeof(sess_arg));
|
||||
+ export_uuid(sess_arg.uuid, &stm32mp_bsec_ta_uuid);
|
||||
+ sess_arg.clnt_login = TEE_IOCTL_LOGIN_REE_KERNEL;
|
||||
+ sess_arg.num_params = 0;
|
||||
+
|
||||
+ rc = tee_client_open_session(ctx, &sess_arg, NULL);
|
||||
+ if ((rc < 0) || (sess_arg.ret != 0)) {
|
||||
+ pr_err("%s: tee_client_open_session failed err:%#x, ret:%#x\n",
|
||||
+ __func__, sess_arg.ret, rc);
|
||||
+ if (!rc)
|
||||
+ rc = -EINVAL;
|
||||
+ } else {
|
||||
+ *id = sess_arg.session;
|
||||
+ }
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+/* close a session to OP-TEE for STM32MP BSEC TA */
|
||||
+static void stm32_bsec_ta_close_session(void *ctx, u32 id)
|
||||
+{
|
||||
+ tee_client_close_session(ctx, id);
|
||||
+}
|
||||
+
|
||||
+/* stm32_bsec_optee_ta_open() - initialize the STM32MP BSEC TA */
|
||||
+int stm32_bsec_optee_ta_open(struct tee_context **ctx)
|
||||
+{
|
||||
+ struct tee_context *tee_ctx;
|
||||
+ u32 session_id;
|
||||
+ int rc;
|
||||
+
|
||||
+ /* Open context with TEE driver */
|
||||
+ tee_ctx = tee_client_open_context(NULL, stm32_bsec_optee_ta_match, NULL, NULL);
|
||||
+ if (IS_ERR(tee_ctx)) {
|
||||
+ rc = PTR_ERR(tee_ctx);
|
||||
+ if (rc == -ENOENT)
|
||||
+ return -EPROBE_DEFER;
|
||||
+ pr_err("%s: tee_client_open_context failed (%d)\n", __func__, rc);
|
||||
+
|
||||
+ return rc;
|
||||
+ }
|
||||
+
|
||||
+ /* Check STM32MP BSEC TA presence */
|
||||
+ rc = stm32_bsec_ta_open_session(tee_ctx, &session_id);
|
||||
+ if (rc) {
|
||||
+ tee_client_close_context(tee_ctx);
|
||||
+ return rc;
|
||||
+ }
|
||||
+
|
||||
+ stm32_bsec_ta_close_session(tee_ctx, session_id);
|
||||
+
|
||||
+ *ctx = tee_ctx;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/* stm32_bsec_optee_ta_open() - release the PTA STM32MP BSEC TA */
|
||||
+void stm32_bsec_optee_ta_close(void *ctx)
|
||||
+{
|
||||
+ tee_client_close_context(ctx);
|
||||
+}
|
||||
+
|
||||
+/* stm32_bsec_optee_ta_read() - nvmem read access using PTA client driver */
|
||||
+int stm32_bsec_optee_ta_read(struct tee_context *ctx, unsigned int offset,
|
||||
+ void *buf, size_t bytes)
|
||||
+{
|
||||
+ struct tee_shm *shm;
|
||||
+ struct tee_ioctl_invoke_arg arg;
|
||||
+ struct tee_param param[2];
|
||||
+ u8 *shm_buf;
|
||||
+ u32 start, num_bytes;
|
||||
+ int ret;
|
||||
+ u32 session_id;
|
||||
+
|
||||
+ ret = stm32_bsec_ta_open_session(ctx, &session_id);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ memset(&arg, 0, sizeof(arg));
|
||||
+ memset(¶m, 0, sizeof(param));
|
||||
+
|
||||
+ arg.func = PTA_BSEC_READ_MEM;
|
||||
+ arg.session = session_id;
|
||||
+ arg.num_params = 2;
|
||||
+
|
||||
+ /* align access on 32bits */
|
||||
+ start = ALIGN_DOWN(offset, 4);
|
||||
+ num_bytes = round_up(offset + bytes - start, 4);
|
||||
+ param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT;
|
||||
+ param[0].u.value.a = start;
|
||||
+ param[0].u.value.b = SHADOW_ACCESS;
|
||||
+
|
||||
+ shm = tee_shm_alloc_kernel_buf(ctx, num_bytes);
|
||||
+ if (IS_ERR(shm)) {
|
||||
+ ret = PTR_ERR(shm);
|
||||
+ goto out_tee_session;
|
||||
+ }
|
||||
+
|
||||
+ param[1].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT;
|
||||
+ param[1].u.memref.shm = shm;
|
||||
+ param[1].u.memref.size = num_bytes;
|
||||
+
|
||||
+ ret = tee_client_invoke_func(ctx, &arg, param);
|
||||
+ if (ret < 0 || arg.ret != 0) {
|
||||
+ pr_err("TA_BSEC invoke failed TEE err:%#x, ret:%#x\n",
|
||||
+ arg.ret, ret);
|
||||
+ if (!ret)
|
||||
+ ret = -EIO;
|
||||
+ }
|
||||
+ if (!ret) {
|
||||
+ shm_buf = tee_shm_get_va(shm, 0);
|
||||
+ if (IS_ERR(shm_buf)) {
|
||||
+ ret = PTR_ERR(shm_buf);
|
||||
+ pr_err("tee_shm_get_va failed for transmit (%d)\n", ret);
|
||||
+ } else {
|
||||
+ /* read data from 32 bits aligned buffer */
|
||||
+ memcpy(buf, &shm_buf[offset % 4], bytes);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ tee_shm_free(shm);
|
||||
+
|
||||
+out_tee_session:
|
||||
+ stm32_bsec_ta_close_session(ctx, session_id);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+/* stm32_bsec_optee_ta_write() - nvmem write access using PTA client driver */
|
||||
+int stm32_bsec_optee_ta_write(struct tee_context *ctx, unsigned int lower,
|
||||
+ unsigned int offset, void *buf, size_t bytes)
|
||||
+{ struct tee_shm *shm;
|
||||
+ struct tee_ioctl_invoke_arg arg;
|
||||
+ struct tee_param param[2];
|
||||
+ u8 *shm_buf;
|
||||
+ int ret;
|
||||
+ u32 session_id;
|
||||
+
|
||||
+ ret = stm32_bsec_ta_open_session(ctx, &session_id);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* Allow only writing complete 32-bits aligned words */
|
||||
+ if ((bytes % 4) || (offset % 4))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ memset(&arg, 0, sizeof(arg));
|
||||
+ memset(¶m, 0, sizeof(param));
|
||||
+
|
||||
+ arg.func = PTA_BSEC_WRITE_MEM;
|
||||
+ arg.session = session_id;
|
||||
+ arg.num_params = 2;
|
||||
+
|
||||
+ param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT;
|
||||
+ param[0].u.value.a = offset;
|
||||
+ param[0].u.value.b = FUSE_ACCESS;
|
||||
+
|
||||
+ shm = tee_shm_alloc_kernel_buf(ctx, bytes);
|
||||
+ if (IS_ERR(shm)) {
|
||||
+ ret = PTR_ERR(shm);
|
||||
+ goto out_tee_session;
|
||||
+ }
|
||||
+
|
||||
+ param[1].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT;
|
||||
+ param[1].u.memref.shm = shm;
|
||||
+ param[1].u.memref.size = bytes;
|
||||
+
|
||||
+ shm_buf = tee_shm_get_va(shm, 0);
|
||||
+ if (IS_ERR(shm_buf)) {
|
||||
+ ret = PTR_ERR(shm_buf);
|
||||
+ pr_err("tee_shm_get_va failed for transmit (%d)\n", ret);
|
||||
+ tee_shm_free(shm);
|
||||
+
|
||||
+ goto out_tee_session;
|
||||
+ }
|
||||
+
|
||||
+ memcpy(shm_buf, buf, bytes);
|
||||
+
|
||||
+ ret = tee_client_invoke_func(ctx, &arg, param);
|
||||
+ if (ret < 0 || arg.ret != 0) {
|
||||
+ pr_err("TA_BSEC invoke failed TEE err:%#x, ret:%#x\n", arg.ret, ret);
|
||||
+ if (!ret)
|
||||
+ ret = -EIO;
|
||||
+ }
|
||||
+ pr_debug("Write OTPs %d to %zu, ret=%d\n", offset / 4, (offset + bytes) / 4, ret);
|
||||
+
|
||||
+ /* Lock the upper OTPs with ECC protection, word programming only */
|
||||
+ if (!ret && ((offset + bytes) >= (lower * 4))) {
|
||||
+ u32 start, nb_lock;
|
||||
+ u32 *lock = (u32 *)shm_buf;
|
||||
+ int i;
|
||||
+
|
||||
+ /*
|
||||
+ * don't lock the lower OTPs, no ECC protection and incremental
|
||||
+ * bit programming, a second write is allowed
|
||||
+ */
|
||||
+ start = max_t(u32, offset, lower * 4);
|
||||
+ nb_lock = (offset + bytes - start) / 4;
|
||||
+
|
||||
+ param[0].u.value.a = start;
|
||||
+ param[0].u.value.b = LOCK_ACCESS;
|
||||
+ param[1].u.memref.size = nb_lock * 4;
|
||||
+
|
||||
+ for (i = 0; i < nb_lock; i++)
|
||||
+ lock[i] = LOCK_PERM;
|
||||
+
|
||||
+ ret = tee_client_invoke_func(ctx, &arg, param);
|
||||
+ if (ret < 0 || arg.ret != 0) {
|
||||
+ pr_err("TA_BSEC invoke failed TEE err:%#x, ret:%#x\n", arg.ret, ret);
|
||||
+ if (!ret)
|
||||
+ ret = -EIO;
|
||||
+ }
|
||||
+ pr_debug("Lock upper OTPs %d to %d, ret=%d\n",
|
||||
+ start / 4, start / 4 + nb_lock, ret);
|
||||
+ }
|
||||
+
|
||||
+ tee_shm_free(shm);
|
||||
+
|
||||
+out_tee_session:
|
||||
+ stm32_bsec_ta_close_session(ctx, session_id);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
--- /dev/null
|
||||
+++ b/drivers/nvmem/stm32-bsec-optee-ta.h
|
||||
@@ -0,0 +1,80 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
+/*
|
||||
+ * OP-TEE STM32MP BSEC PTA interface, used by STM32 ROMEM driver
|
||||
+ *
|
||||
+ * Copyright (C) 2022, STMicroelectronics - All Rights Reserved
|
||||
+ */
|
||||
+
|
||||
+#if IS_ENABLED(CONFIG_NVMEM_STM32_BSEC_OPTEE_TA)
|
||||
+/**
|
||||
+ * stm32_bsec_optee_ta_open() - initialize the STM32 BSEC TA
|
||||
+ * @ctx: the OP-TEE context on success
|
||||
+ *
|
||||
+ * Return:
|
||||
+ * On success, 0. On failure, -errno.
|
||||
+ */
|
||||
+int stm32_bsec_optee_ta_open(struct tee_context **ctx);
|
||||
+
|
||||
+/**
|
||||
+ * stm32_bsec_optee_ta_close() - release the STM32 BSEC TA
|
||||
+ * @ctx: the OP-TEE context
|
||||
+ *
|
||||
+ * This function used to clean the OP-TEE resources initialized in
|
||||
+ * stm32_bsec_optee_ta_open(); it can be used as callback to
|
||||
+ * devm_add_action_or_reset()
|
||||
+ */
|
||||
+void stm32_bsec_optee_ta_close(void *ctx);
|
||||
+
|
||||
+/**
|
||||
+ * stm32_bsec_optee_ta_read() - nvmem read access using TA client driver
|
||||
+ * @ctx: the OP-TEE context provided by stm32_bsec_optee_ta_open
|
||||
+ * @offset: nvmem offset
|
||||
+ * @buf: buffer to fill with nvem values
|
||||
+ * @bytes: number of bytes to read
|
||||
+ *
|
||||
+ * Return:
|
||||
+ * On success, 0. On failure, -errno.
|
||||
+ */
|
||||
+int stm32_bsec_optee_ta_read(struct tee_context *ctx, unsigned int offset,
|
||||
+ void *buf, size_t bytes);
|
||||
+
|
||||
+/**
|
||||
+ * stm32_bsec_optee_ta_write() - nvmem write access using TA client driver
|
||||
+ * @ctx: the OP-TEE context provided by stm32_bsec_optee_ta_open
|
||||
+ * @lower: number of lower OTP, not protected by ECC
|
||||
+ * @offset: nvmem offset
|
||||
+ * @buf: buffer with nvem values
|
||||
+ * @bytes: number of bytes to write
|
||||
+ *
|
||||
+ * Return:
|
||||
+ * On success, 0. On failure, -errno.
|
||||
+ */
|
||||
+int stm32_bsec_optee_ta_write(struct tee_context *ctx, unsigned int lower,
|
||||
+ unsigned int offset, void *buf, size_t bytes);
|
||||
+
|
||||
+#else
|
||||
+
|
||||
+static inline int stm32_bsec_optee_ta_open(struct tee_context **ctx)
|
||||
+{
|
||||
+ return -EOPNOTSUPP;
|
||||
+}
|
||||
+
|
||||
+static inline void stm32_bsec_optee_ta_close(void *ctx)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+static inline int stm32_bsec_optee_ta_read(struct tee_context *ctx,
|
||||
+ unsigned int offset, void *buf,
|
||||
+ size_t bytes)
|
||||
+{
|
||||
+ return -EOPNOTSUPP;
|
||||
+}
|
||||
+
|
||||
+static inline int stm32_bsec_optee_ta_write(struct tee_context *ctx,
|
||||
+ unsigned int lower,
|
||||
+ unsigned int offset, void *buf,
|
||||
+ size_t bytes)
|
||||
+{
|
||||
+ return -EOPNOTSUPP;
|
||||
+}
|
||||
+#endif /* CONFIG_NVMEM_STM32_BSEC_OPTEE_TA */
|
||||
--- a/drivers/nvmem/stm32-romem.c
|
||||
+++ b/drivers/nvmem/stm32-romem.c
|
||||
@@ -11,6 +11,9 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/nvmem-provider.h>
|
||||
#include <linux/of_device.h>
|
||||
+#include <linux/tee_drv.h>
|
||||
+
|
||||
+#include "stm32-bsec-optee-ta.h"
|
||||
|
||||
/* BSEC secure service access from non-secure */
|
||||
#define STM32_SMC_BSEC 0x82001003
|
||||
@@ -25,12 +28,14 @@
|
||||
struct stm32_romem_cfg {
|
||||
int size;
|
||||
u8 lower;
|
||||
+ bool ta;
|
||||
};
|
||||
|
||||
struct stm32_romem_priv {
|
||||
void __iomem *base;
|
||||
struct nvmem_config cfg;
|
||||
u8 lower;
|
||||
+ struct tee_context *ctx;
|
||||
};
|
||||
|
||||
static int stm32_romem_read(void *context, unsigned int offset, void *buf,
|
||||
@@ -138,12 +143,29 @@ static int stm32_bsec_write(void *contex
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int stm32_bsec_pta_read(void *context, unsigned int offset, void *buf,
|
||||
+ size_t bytes)
|
||||
+{
|
||||
+ struct stm32_romem_priv *priv = context;
|
||||
+
|
||||
+ return stm32_bsec_optee_ta_read(priv->ctx, offset, buf, bytes);
|
||||
+}
|
||||
+
|
||||
+static int stm32_bsec_pta_write(void *context, unsigned int offset, void *buf,
|
||||
+ size_t bytes)
|
||||
+{
|
||||
+ struct stm32_romem_priv *priv = context;
|
||||
+
|
||||
+ return stm32_bsec_optee_ta_write(priv->ctx, priv->lower, offset, buf, bytes);
|
||||
+}
|
||||
+
|
||||
static int stm32_romem_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct stm32_romem_cfg *cfg;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct stm32_romem_priv *priv;
|
||||
struct resource *res;
|
||||
+ int rc;
|
||||
|
||||
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
@@ -173,15 +195,31 @@ static int stm32_romem_probe(struct plat
|
||||
} else {
|
||||
priv->cfg.size = cfg->size;
|
||||
priv->lower = cfg->lower;
|
||||
- priv->cfg.reg_read = stm32_bsec_read;
|
||||
- priv->cfg.reg_write = stm32_bsec_write;
|
||||
+ if (cfg->ta) {
|
||||
+ rc = stm32_bsec_optee_ta_open(&priv->ctx);
|
||||
+ /* wait for OP-TEE client driver to be up and ready */
|
||||
+ if (rc)
|
||||
+ return rc;
|
||||
+ }
|
||||
+ if (priv->ctx) {
|
||||
+ rc = devm_add_action_or_reset(dev, stm32_bsec_optee_ta_close, priv->ctx);
|
||||
+ if (rc) {
|
||||
+ dev_err(dev, "devm_add_action_or_reset() failed (%d)\n", rc);
|
||||
+ return rc;
|
||||
+ }
|
||||
+ priv->cfg.reg_read = stm32_bsec_pta_read;
|
||||
+ priv->cfg.reg_write = stm32_bsec_pta_write;
|
||||
+ } else {
|
||||
+ priv->cfg.reg_read = stm32_bsec_read;
|
||||
+ priv->cfg.reg_write = stm32_bsec_write;
|
||||
+ }
|
||||
}
|
||||
|
||||
return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &priv->cfg));
|
||||
}
|
||||
|
||||
/*
|
||||
- * STM32MP15 BSEC OTP regions: 4096 OTP bits (with 3072 effective bits)
|
||||
+ * STM32MP15/13 BSEC OTP regions: 4096 OTP bits (with 3072 effective bits)
|
||||
* => 96 x 32-bits data words
|
||||
* - Lower: 1K bits, 2:1 redundancy, incremental bit programming
|
||||
* => 32 (x 32-bits) lower shadow registers = words 0 to 31
|
||||
@@ -191,6 +229,13 @@ static int stm32_romem_probe(struct plat
|
||||
static const struct stm32_romem_cfg stm32mp15_bsec_cfg = {
|
||||
.size = 384,
|
||||
.lower = 32,
|
||||
+ .ta = false,
|
||||
+};
|
||||
+
|
||||
+static const struct stm32_romem_cfg stm32mp13_bsec_cfg = {
|
||||
+ .size = 384,
|
||||
+ .lower = 32,
|
||||
+ .ta = true,
|
||||
};
|
||||
|
||||
static const struct of_device_id stm32_romem_of_match[] = {
|
||||
@@ -198,7 +243,10 @@ static const struct of_device_id stm32_r
|
||||
.compatible = "st,stm32mp15-bsec",
|
||||
.data = (void *)&stm32mp15_bsec_cfg,
|
||||
}, {
|
||||
+ .compatible = "st,stm32mp13-bsec",
|
||||
+ .data = (void *)&stm32mp13_bsec_cfg,
|
||||
},
|
||||
+ { /* sentinel */ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, stm32_romem_of_match);
|
||||
|
@ -0,0 +1,85 @@
|
||||
From df2f34ef1d924125ffaf29dfdaf7cdbd3183c321 Mon Sep 17 00:00:00 2001
|
||||
From: Patrick Delaunay <patrick.delaunay@foss.st.com>
|
||||
Date: Mon, 6 Feb 2023 13:43:52 +0000
|
||||
Subject: [PATCH] nvmem: stm32: detect bsec pta presence for STM32MP15x
|
||||
|
||||
On STM32MP15x SoC, the SMC backend is optional when OP-TEE is used;
|
||||
the PTA BSEC should be used as it is done on STM32MP13x platform,
|
||||
but the BSEC SMC can be also used: it is a legacy mode in OP-TEE,
|
||||
not recommended but used in previous OP-TEE firmware.
|
||||
|
||||
The presence of OP-TEE is dynamically detected in STM32MP15x device tree
|
||||
and the supported NVMEM backend is dynamically detected:
|
||||
- PTA with stm32_bsec_pta_find
|
||||
- SMC with stm32_bsec_check
|
||||
|
||||
With OP-TEE but without PTA and SMC detection, the probe is deferred for
|
||||
STM32MP15x devices.
|
||||
|
||||
On STM32MP13x platform, only the PTA is supported with cfg->ta = true
|
||||
and this detection is skipped.
|
||||
|
||||
Signed-off-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
|
||||
Reviewed-by: Etienne Carriere <etienne.carriere@linaro.org>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20230206134356.839737-19-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/nvmem/stm32-romem.c | 38 +++++++++++++++++++++++++++++++++----
|
||||
1 file changed, 34 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/nvmem/stm32-romem.c
|
||||
+++ b/drivers/nvmem/stm32-romem.c
|
||||
@@ -159,6 +159,31 @@ static int stm32_bsec_pta_write(void *co
|
||||
return stm32_bsec_optee_ta_write(priv->ctx, priv->lower, offset, buf, bytes);
|
||||
}
|
||||
|
||||
+static bool stm32_bsec_smc_check(void)
|
||||
+{
|
||||
+ u32 val;
|
||||
+ int ret;
|
||||
+
|
||||
+ /* check that the OP-TEE support the BSEC SMC (legacy mode) */
|
||||
+ ret = stm32_bsec_smc(STM32_SMC_READ_SHADOW, 0, 0, &val);
|
||||
+
|
||||
+ return !ret;
|
||||
+}
|
||||
+
|
||||
+static bool optee_presence_check(void)
|
||||
+{
|
||||
+ struct device_node *np;
|
||||
+ bool tee_detected = false;
|
||||
+
|
||||
+ /* check that the OP-TEE node is present and available. */
|
||||
+ np = of_find_compatible_node(NULL, NULL, "linaro,optee-tz");
|
||||
+ if (np && of_device_is_available(np))
|
||||
+ tee_detected = true;
|
||||
+ of_node_put(np);
|
||||
+
|
||||
+ return tee_detected;
|
||||
+}
|
||||
+
|
||||
static int stm32_romem_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct stm32_romem_cfg *cfg;
|
||||
@@ -195,11 +220,16 @@ static int stm32_romem_probe(struct plat
|
||||
} else {
|
||||
priv->cfg.size = cfg->size;
|
||||
priv->lower = cfg->lower;
|
||||
- if (cfg->ta) {
|
||||
+ if (cfg->ta || optee_presence_check()) {
|
||||
rc = stm32_bsec_optee_ta_open(&priv->ctx);
|
||||
- /* wait for OP-TEE client driver to be up and ready */
|
||||
- if (rc)
|
||||
- return rc;
|
||||
+ if (rc) {
|
||||
+ /* wait for OP-TEE client driver to be up and ready */
|
||||
+ if (rc == -EPROBE_DEFER)
|
||||
+ return -EPROBE_DEFER;
|
||||
+ /* BSEC PTA is required or SMC not supported */
|
||||
+ if (cfg->ta || !stm32_bsec_smc_check())
|
||||
+ return rc;
|
||||
+ }
|
||||
}
|
||||
if (priv->ctx) {
|
||||
rc = devm_add_action_or_reset(dev, stm32_bsec_optee_ta_close, priv->ctx);
|
@ -0,0 +1,32 @@
|
||||
From 3e5ac22aa564026e99defc3a8e02082521a5b231 Mon Sep 17 00:00:00 2001
|
||||
From: Randy Dunlap <rdunlap@infradead.org>
|
||||
Date: Mon, 6 Feb 2023 13:43:53 +0000
|
||||
Subject: [PATCH] nvmem: rave-sp-eeprm: fix kernel-doc bad line warning
|
||||
|
||||
Convert an empty line to " *" to avoid a kernel-doc warning:
|
||||
|
||||
drivers/nvmem/rave-sp-eeprom.c:48: warning: bad line:
|
||||
|
||||
Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
|
||||
Cc: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Cc: Andrey Vostrikov <andrey.vostrikov@cogentembedded.com>
|
||||
Cc: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
|
||||
Cc: Andrey Smirnov <andrew.smirnov@gmail.com>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20230206134356.839737-20-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/nvmem/rave-sp-eeprom.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/nvmem/rave-sp-eeprom.c
|
||||
+++ b/drivers/nvmem/rave-sp-eeprom.c
|
||||
@@ -45,7 +45,7 @@ enum rave_sp_eeprom_header_size {
|
||||
* @type: Access type (see enum rave_sp_eeprom_access_type)
|
||||
* @success: Success flag (Success = 1, Failure = 0)
|
||||
* @data: Read data
|
||||
-
|
||||
+ *
|
||||
* Note this structure corresponds to RSP_*_EEPROM payload from RAVE
|
||||
* SP ICD
|
||||
*/
|
@ -0,0 +1,43 @@
|
||||
From eb7dda20f42a9137e9ee53d5ed3b743d49338cb5 Mon Sep 17 00:00:00 2001
|
||||
From: Johan Hovold <johan+linaro@kernel.org>
|
||||
Date: Mon, 6 Feb 2023 13:43:54 +0000
|
||||
Subject: [PATCH] nvmem: qcom-spmi-sdam: register at device init time
|
||||
|
||||
There are currently no in-tree users of the Qualcomm SDAM nvmem driver
|
||||
and there is generally no point in registering a driver that can be
|
||||
built as a module at subsys init time.
|
||||
|
||||
Register the driver at the normal device init time instead and let
|
||||
driver core sort out the probe order.
|
||||
|
||||
Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
|
||||
Reviewed-by: Bjorn Andersson <andersson@kernel.org>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20230206134356.839737-21-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/nvmem/qcom-spmi-sdam.c | 13 +------------
|
||||
1 file changed, 1 insertion(+), 12 deletions(-)
|
||||
|
||||
--- a/drivers/nvmem/qcom-spmi-sdam.c
|
||||
+++ b/drivers/nvmem/qcom-spmi-sdam.c
|
||||
@@ -175,18 +175,7 @@ static struct platform_driver sdam_drive
|
||||
},
|
||||
.probe = sdam_probe,
|
||||
};
|
||||
-
|
||||
-static int __init sdam_init(void)
|
||||
-{
|
||||
- return platform_driver_register(&sdam_driver);
|
||||
-}
|
||||
-subsys_initcall(sdam_init);
|
||||
-
|
||||
-static void __exit sdam_exit(void)
|
||||
-{
|
||||
- return platform_driver_unregister(&sdam_driver);
|
||||
-}
|
||||
-module_exit(sdam_exit);
|
||||
+module_platform_driver(sdam_driver);
|
||||
|
||||
MODULE_DESCRIPTION("QCOM SPMI SDAM driver");
|
||||
MODULE_LICENSE("GPL v2");
|
@ -0,0 +1,46 @@
|
||||
From 1dc7e37bb0ec1c997fac82031332a38c7610352f Mon Sep 17 00:00:00 2001
|
||||
From: Arnd Bergmann <arnd@arndb.de>
|
||||
Date: Mon, 6 Feb 2023 13:43:56 +0000
|
||||
Subject: [PATCH] nvmem: stm32: fix OPTEE dependency
|
||||
|
||||
The stm32 nvmem driver fails to link as built-in when OPTEE
|
||||
is a loadable module:
|
||||
|
||||
aarch64-linux-ld: drivers/nvmem/stm32-bsec-optee-ta.o: in function `stm32_bsec:
|
||||
stm32-bsec-optee-ta.c:(.text+0xc8): undefined reference to `tee_client_open_session'
|
||||
aarch64-linux-ld: drivers/nvmem/stm32-bsec-optee-ta.o: in function `stm32_bsec:
|
||||
stm32-bsec-optee-ta.c:(.text+0x1fc): undefined reference to `tee_client_open_context'
|
||||
|
||||
Change the CONFIG_NVMEM_STM32_ROMEM definition so it can only
|
||||
be built-in if OPTEE is either built-in or disabled, and
|
||||
make NVMEM_STM32_BSEC_OPTEE_TA a hidden symbol instead.
|
||||
|
||||
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20230206134356.839737-23-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/nvmem/Kconfig | 5 ++---
|
||||
1 file changed, 2 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/drivers/nvmem/Kconfig
|
||||
+++ b/drivers/nvmem/Kconfig
|
||||
@@ -291,8 +291,7 @@ config NVMEM_SPRD_EFUSE
|
||||
will be called nvmem-sprd-efuse.
|
||||
|
||||
config NVMEM_STM32_BSEC_OPTEE_TA
|
||||
- bool "STM32MP BSEC OP-TEE TA support for nvmem-stm32-romem driver"
|
||||
- depends on OPTEE
|
||||
+ def_bool NVMEM_STM32_ROMEM && OPTEE
|
||||
help
|
||||
Say y here to enable the accesses to STM32MP SoC OTPs by the OP-TEE
|
||||
trusted application STM32MP BSEC.
|
||||
@@ -303,7 +302,7 @@ config NVMEM_STM32_BSEC_OPTEE_TA
|
||||
config NVMEM_STM32_ROMEM
|
||||
tristate "STMicroelectronics STM32 factory-programmed memory support"
|
||||
depends on ARCH_STM32 || COMPILE_TEST
|
||||
- imply NVMEM_STM32_BSEC_OPTEE_TA
|
||||
+ depends on OPTEE || !OPTEE
|
||||
help
|
||||
Say y here to enable read-only access for STMicroelectronics STM32
|
||||
factory-programmed memory area.
|
@ -18,8 +18,7 @@ ocedo,panda)
|
||||
"0:lan" "1:lan" "2:lan" "3:lan" "4:lan" "5:lan" "6:lan" "7:lan" "8u@eth0"
|
||||
;;
|
||||
tplink,tl-wdr4900-v1)
|
||||
ucidef_add_switch "switch0" \
|
||||
"0@eth0" "2:lan:1" "3:lan:2" "4:lan:3" "5:lan:4" "1:wan"
|
||||
ucidef_set_interfaces_lan_wan "lan1 lan2 lan3 lan4" "wan"
|
||||
ucidef_set_interface_macaddr "wan" "$(macaddr_add $(mtd_get_mac_binary u-boot 0x4fc00) 1)"
|
||||
;;
|
||||
*)
|
||||
|
@ -0,0 +1,15 @@
|
||||
|
||||
. /lib/functions.sh
|
||||
. /lib/functions/uci-defaults.sh
|
||||
|
||||
board_config_update
|
||||
|
||||
case "$(board_name)" in
|
||||
tplink,tl-wdr4900-v1)
|
||||
ucidef_set_compat_version "1.1"
|
||||
;;
|
||||
esac
|
||||
|
||||
board_config_flush
|
||||
|
||||
exit 0
|
@ -1,8 +1,6 @@
|
||||
# CONFIG_40x is not set
|
||||
# CONFIG_44x is not set
|
||||
# CONFIG_ADVANCED_OPTIONS is not set
|
||||
CONFIG_AR8216_PHY=y
|
||||
CONFIG_AR8216_PHY_LEDS=y
|
||||
CONFIG_ARCH_32BIT_OFF_T=y
|
||||
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
|
||||
CONFIG_ARCH_KEEP_MEMBLOCK=y
|
||||
@ -36,15 +34,12 @@ CONFIG_COMPAT_32BIT_TIME=y
|
||||
# CONFIG_CPM2 is not set
|
||||
CONFIG_CPU_BIG_ENDIAN=y
|
||||
# CONFIG_CRYPTO_AES_PPC_SPE is not set
|
||||
CONFIG_CRYPTO_AKCIPHER=y
|
||||
CONFIG_CRYPTO_AKCIPHER2=y
|
||||
CONFIG_CRYPTO_AUTHENC=y
|
||||
CONFIG_CRYPTO_BLAKE2S=y
|
||||
CONFIG_CRYPTO_HW=y
|
||||
CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
|
||||
CONFIG_CRYPTO_LIB_POLY1305_RSIZE=1
|
||||
# CONFIG_CRYPTO_MD5_PPC is not set
|
||||
CONFIG_CRYPTO_NULL=y
|
||||
CONFIG_CRYPTO_RNG=y
|
||||
CONFIG_CRYPTO_RNG2=y
|
||||
CONFIG_CRYPTO_RSA=y
|
||||
@ -68,7 +63,6 @@ CONFIG_EDAC_LEGACY_SYSFS=y
|
||||
CONFIG_EDAC_MPC85XX=y
|
||||
CONFIG_EDAC_SUPPORT=y
|
||||
CONFIG_ENABLE_MUST_CHECK=y
|
||||
CONFIG_ETHERNET_PACKET_MANGLE=y
|
||||
CONFIG_FIXED_PHY=y
|
||||
CONFIG_FSL_BOOKE=y
|
||||
CONFIG_FSL_EMB_PERFMON=y
|
||||
@ -84,7 +78,6 @@ CONFIG_GENERIC_ATOMIC64=y
|
||||
CONFIG_GENERIC_BUG=y
|
||||
CONFIG_GENERIC_CLOCKEVENTS=y
|
||||
CONFIG_GENERIC_CMOS_UPDATE=y
|
||||
CONFIG_GENERIC_CPU=y
|
||||
CONFIG_GENERIC_CPU_AUTOPROBE=y
|
||||
CONFIG_GENERIC_CPU_VULNERABILITIES=y
|
||||
CONFIG_GENERIC_EARLY_IOREMAP=y
|
||||
@ -106,7 +99,6 @@ CONFIG_HAS_IOMEM=y
|
||||
CONFIG_HAS_IOPORT_MAP=y
|
||||
# CONFIG_HIVEAP_330 is not set
|
||||
CONFIG_HW_RANDOM=y
|
||||
# CONFIG_HW_RANDOM_XIPHERA is not set
|
||||
CONFIG_HZ_PERIODIC=y
|
||||
CONFIG_I2C=y
|
||||
CONFIG_I2C_BOARDINFO=y
|
||||
@ -130,8 +122,8 @@ CONFIG_LXT_PHY=y
|
||||
# CONFIG_MATH_EMULATION is not set
|
||||
CONFIG_MDIO_BUS=y
|
||||
CONFIG_MDIO_DEVICE=y
|
||||
CONFIG_MDIO_DEVRES=y
|
||||
CONFIG_MEMFD_CREATE=y
|
||||
# CONFIG_MFD_ROHM_BD71828 is not set
|
||||
CONFIG_MIGRATION=y
|
||||
CONFIG_MMU_GATHER_PAGE_SIZE=y
|
||||
CONFIG_MODULES_USE_ELF_RELA=y
|
||||
@ -224,7 +216,6 @@ CONFIG_RAS=y
|
||||
# CONFIG_RED_15W_REV1 is not set
|
||||
CONFIG_RTC_CLASS=y
|
||||
CONFIG_RTC_DRV_GENERIC=y
|
||||
# CONFIG_RTC_DRV_RV3032 is not set
|
||||
CONFIG_RTC_I2C_AND_SPI=y
|
||||
CONFIG_RTC_MC146818_LIB=y
|
||||
# CONFIG_SBC8548 is not set
|
||||
@ -246,9 +237,10 @@ CONFIG_SPI_MEM=y
|
||||
CONFIG_SRCU=y
|
||||
# CONFIG_STRIP_ASM_SYMS is not set
|
||||
# CONFIG_STX_GP3 is not set
|
||||
CONFIG_SWCONFIG=y
|
||||
CONFIG_SWPHY=y
|
||||
CONFIG_SYSCTL_EXCEPTION_TRACE=y
|
||||
CONFIG_TARGET_CPU="8540"
|
||||
CONFIG_TARGET_CPU_BOOL=y
|
||||
CONFIG_TASK_SIZE=0xc0000000
|
||||
CONFIG_THREAD_INFO_IN_TASK=y
|
||||
CONFIG_THREAD_SHIFT=13
|
||||
|
@ -1,8 +1,6 @@
|
||||
# CONFIG_40x is not set
|
||||
# CONFIG_44x is not set
|
||||
# CONFIG_ADVANCED_OPTIONS is not set
|
||||
CONFIG_AR8216_PHY=y
|
||||
CONFIG_AR8216_PHY_LEDS=y
|
||||
CONFIG_ARCH_32BIT_OFF_T=y
|
||||
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
|
||||
CONFIG_ARCH_KEEP_MEMBLOCK=y
|
||||
@ -14,7 +12,7 @@ CONFIG_ARCH_MMAP_RND_BITS_MAX=17
|
||||
CONFIG_ARCH_MMAP_RND_BITS_MIN=11
|
||||
CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=17
|
||||
CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11
|
||||
CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y
|
||||
CONFIG_ARCH_STACKWALK=y
|
||||
CONFIG_ARCH_SUSPEND_POSSIBLE=y
|
||||
CONFIG_ARCH_WEAK_RELEASE_ACQUIRE=y
|
||||
CONFIG_ASN1=y
|
||||
@ -36,15 +34,11 @@ CONFIG_COMPAT_32BIT_TIME=y
|
||||
# CONFIG_CPM2 is not set
|
||||
CONFIG_CPU_BIG_ENDIAN=y
|
||||
# CONFIG_CRYPTO_AES_PPC_SPE is not set
|
||||
CONFIG_CRYPTO_AKCIPHER=y
|
||||
CONFIG_CRYPTO_AKCIPHER2=y
|
||||
CONFIG_CRYPTO_AUTHENC=y
|
||||
CONFIG_CRYPTO_BLAKE2S=y
|
||||
CONFIG_CRYPTO_HW=y
|
||||
CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
|
||||
CONFIG_CRYPTO_LIB_POLY1305_RSIZE=1
|
||||
# CONFIG_CRYPTO_MD5_PPC is not set
|
||||
CONFIG_CRYPTO_NULL=y
|
||||
CONFIG_CRYPTO_RNG=y
|
||||
CONFIG_CRYPTO_RNG2=y
|
||||
CONFIG_CRYPTO_RSA=y
|
||||
@ -55,11 +49,8 @@ CONFIG_DATA_SHIFT=12
|
||||
CONFIG_DEBUG_BUGVERBOSE=y
|
||||
CONFIG_DNOTIFY=y
|
||||
CONFIG_DTC=y
|
||||
# CONFIG_E200 is not set
|
||||
CONFIG_E500=y
|
||||
CONFIG_E500_CPU=y
|
||||
# CONFIG_E5500_CPU is not set
|
||||
# CONFIG_E6500_CPU is not set
|
||||
CONFIG_EARLY_PRINTK=y
|
||||
CONFIG_EDAC=y
|
||||
CONFIG_EDAC_ATOMIC_SCRUB=y
|
||||
@ -67,8 +58,6 @@ CONFIG_EDAC_ATOMIC_SCRUB=y
|
||||
CONFIG_EDAC_LEGACY_SYSFS=y
|
||||
CONFIG_EDAC_MPC85XX=y
|
||||
CONFIG_EDAC_SUPPORT=y
|
||||
CONFIG_ENABLE_MUST_CHECK=y
|
||||
CONFIG_ETHERNET_PACKET_MANGLE=y
|
||||
CONFIG_FIXED_PHY=y
|
||||
CONFIG_FSL_BOOKE=y
|
||||
# CONFIG_FSL_DPAA2_SWITCH is not set
|
||||
@ -79,16 +68,18 @@ CONFIG_FSL_PCI=y
|
||||
CONFIG_FSL_PQ_MDIO=y
|
||||
CONFIG_FSL_SOC=y
|
||||
CONFIG_FSL_SOC_BOOKE=y
|
||||
CONFIG_FWNODE_MDIO=y
|
||||
CONFIG_FW_LOADER_PAGED_BUF=y
|
||||
CONFIG_GENERIC_ALLOCATOR=y
|
||||
CONFIG_GENERIC_ATOMIC64=y
|
||||
CONFIG_GENERIC_BUG=y
|
||||
CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
|
||||
CONFIG_GENERIC_CLOCKEVENTS=y
|
||||
CONFIG_GENERIC_CMOS_UPDATE=y
|
||||
CONFIG_GENERIC_CPU=y
|
||||
CONFIG_GENERIC_CPU_AUTOPROBE=y
|
||||
CONFIG_GENERIC_CPU_VULNERABILITIES=y
|
||||
CONFIG_GENERIC_EARLY_IOREMAP=y
|
||||
CONFIG_GENERIC_GETTIMEOFDAY=y
|
||||
CONFIG_GENERIC_IRQ_SHOW=y
|
||||
CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
|
||||
CONFIG_GENERIC_ISA_DMA=y
|
||||
@ -100,6 +91,7 @@ CONFIG_GENERIC_TIME_VSYSCALL=y
|
||||
CONFIG_GEN_RTC=y
|
||||
# CONFIG_GE_IMP3A is not set
|
||||
CONFIG_GIANFAR=y
|
||||
CONFIG_GPIO_CDEV=y
|
||||
CONFIG_GPIO_GENERIC=y
|
||||
CONFIG_GPIO_MPC8XXX=y
|
||||
CONFIG_HAS_DMA=y
|
||||
@ -107,7 +99,6 @@ CONFIG_HAS_IOMEM=y
|
||||
CONFIG_HAS_IOPORT_MAP=y
|
||||
# CONFIG_HIVEAP_330 is not set
|
||||
CONFIG_HW_RANDOM=y
|
||||
# CONFIG_HW_RANDOM_XIPHERA is not set
|
||||
CONFIG_HZ_PERIODIC=y
|
||||
CONFIG_I2C=y
|
||||
CONFIG_I2C_BOARDINFO=y
|
||||
@ -131,8 +122,8 @@ CONFIG_LXT_PHY=y
|
||||
# CONFIG_MATH_EMULATION is not set
|
||||
CONFIG_MDIO_BUS=y
|
||||
CONFIG_MDIO_DEVICE=y
|
||||
CONFIG_MDIO_DEVRES=y
|
||||
CONFIG_MEMFD_CREATE=y
|
||||
# CONFIG_MFD_ROHM_BD71828 is not set
|
||||
CONFIG_MIGRATION=y
|
||||
CONFIG_MMU_GATHER_PAGE_SIZE=y
|
||||
CONFIG_MODULES_USE_ELF_RELA=y
|
||||
@ -156,7 +147,9 @@ CONFIG_MTD_SPI_NOR=y
|
||||
# CONFIG_MVME2500 is not set
|
||||
CONFIG_NEED_PER_CPU_KM=y
|
||||
CONFIG_NEED_SG_DMA_LENGTH=y
|
||||
CONFIG_NET_SELFTESTS=y
|
||||
CONFIG_NLS=y
|
||||
CONFIG_NR_CPUS=1
|
||||
CONFIG_NR_IRQS=512
|
||||
CONFIG_NVMEM=y
|
||||
CONFIG_OF=y
|
||||
@ -168,7 +161,6 @@ CONFIG_OF_GPIO=y
|
||||
CONFIG_OF_IRQ=y
|
||||
CONFIG_OF_KOBJ=y
|
||||
CONFIG_OF_MDIO=y
|
||||
CONFIG_OF_NET=y
|
||||
CONFIG_OLD_SIGACTION=y
|
||||
CONFIG_OLD_SIGSUSPEND=y
|
||||
# CONFIG_P1010_RDB is not set
|
||||
@ -196,7 +188,6 @@ CONFIG_PHYSICAL_START=0x00000000
|
||||
CONFIG_PPC=y
|
||||
CONFIG_PPC32=y
|
||||
# CONFIG_PPC64 is not set
|
||||
# CONFIG_PPC_BOOK3S_32 is not set
|
||||
CONFIG_PPC_85xx=y
|
||||
# CONFIG_PPC_8xx is not set
|
||||
CONFIG_PPC_ADV_DEBUG_DACS=2
|
||||
@ -205,31 +196,27 @@ CONFIG_PPC_ADV_DEBUG_IACS=2
|
||||
CONFIG_PPC_ADV_DEBUG_REGS=y
|
||||
CONFIG_PPC_BARRIER_NOSPEC=y
|
||||
CONFIG_PPC_BOOK3E_MMU=y
|
||||
# CONFIG_PPC_BOOK3S_6xx is not set
|
||||
# CONFIG_PPC_BOOK3S_32 is not set
|
||||
CONFIG_PPC_DOORBELL=y
|
||||
# CONFIG_PPC_E500MC is not set
|
||||
# CONFIG_PPC_EARLY_DEBUG is not set
|
||||
CONFIG_PPC_FSL_BOOK3E=y
|
||||
CONFIG_PPC_INDIRECT_PCI=y
|
||||
# CONFIG_PPC_IRQ_SOFT_MASK_DEBUG is not set
|
||||
CONFIG_PPC_MMU_NOHASH=y
|
||||
CONFIG_PPC_MMU_NOHASH_32=y
|
||||
CONFIG_PPC_PAGE_SHIFT=12
|
||||
# CONFIG_PPC_PTDUMP is not set
|
||||
# CONFIG_PPC_QEMU_E500 is not set
|
||||
CONFIG_PPC_SMP_MUXED_IPI=y
|
||||
CONFIG_PPC_UDBG_16550=y
|
||||
CONFIG_PPC_WERROR=y
|
||||
CONFIG_PTP_1588_CLOCK_OPTIONAL=y
|
||||
CONFIG_QE_GPIO=y
|
||||
CONFIG_QUICC_ENGINE=y
|
||||
CONFIG_RAS=y
|
||||
# CONFIG_RED_15W_REV1 is not set
|
||||
CONFIG_RTC_CLASS=y
|
||||
CONFIG_RTC_DRV_GENERIC=y
|
||||
# CONFIG_RTC_DRV_RV3032 is not set
|
||||
CONFIG_RTC_I2C_AND_SPI=y
|
||||
CONFIG_RTC_MC146818_LIB=y
|
||||
# CONFIG_SBC8548 is not set
|
||||
# CONFIG_SCOM_DEBUGFS is not set
|
||||
CONFIG_SERIAL_8250_EXTENDED=y
|
||||
CONFIG_SERIAL_8250_FSL=y
|
||||
@ -248,9 +235,10 @@ CONFIG_SPI_MEM=y
|
||||
CONFIG_SRCU=y
|
||||
# CONFIG_STRIP_ASM_SYMS is not set
|
||||
# CONFIG_STX_GP3 is not set
|
||||
CONFIG_SWCONFIG=y
|
||||
CONFIG_SWPHY=y
|
||||
CONFIG_SYSCTL_EXCEPTION_TRACE=y
|
||||
CONFIG_TARGET_CPU="8540"
|
||||
CONFIG_TARGET_CPU_BOOL=y
|
||||
CONFIG_TASK_SIZE=0xc0000000
|
||||
CONFIG_THREAD_INFO_IN_TASK=y
|
||||
CONFIG_THREAD_SHIFT=13
|
||||
|
@ -102,20 +102,78 @@
|
||||
};
|
||||
|
||||
mdio@24000 {
|
||||
phy0: ethernet-phy@0 {
|
||||
reg = <0x0>;
|
||||
qca,ar8327-initvals = <
|
||||
0x00004 0x07600000 /* PAD0_MODE */
|
||||
0x00008 0x00000000 /* PAD5_MODE */
|
||||
0x0000c 0x01000000 /* PAD6_MODE */
|
||||
0x00010 0x40000000 /* POWER_ON_STRAP */
|
||||
0x00050 0xcf35cf35 /* LED_CTRL0 */
|
||||
0x00054 0xcf35cf35 /* LED_CTRL1 */
|
||||
0x00058 0xcf35cf35 /* LED_CTRL2 */
|
||||
0x0005c 0x03ffff00 /* LED_CTRL3 */
|
||||
0x0007c 0x0000007e /* PORT0_STATUS */
|
||||
0x00094 0x00000200 /* PORT6_STATUS */
|
||||
>;
|
||||
|
||||
phy_port1: phy@0 {
|
||||
reg = <0>;
|
||||
};
|
||||
|
||||
phy_port2: phy@1 {
|
||||
reg = <1>;
|
||||
};
|
||||
|
||||
phy_port3: phy@2 {
|
||||
reg = <2>;
|
||||
};
|
||||
|
||||
phy_port4: phy@3 {
|
||||
reg = <3>;
|
||||
};
|
||||
|
||||
phy_port5: phy@4 {
|
||||
reg = <4>;
|
||||
};
|
||||
|
||||
switch@0 {
|
||||
compatible = "qca,qca8327";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <0x10>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
ethernet = <&enet0>;
|
||||
phy-mode = "rgmii-id";
|
||||
|
||||
fixed-link {
|
||||
speed = <1000>;
|
||||
full-duplex;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
label = "wan";
|
||||
phy-handle = <&phy_port1>;
|
||||
};
|
||||
|
||||
port@2 {
|
||||
reg = <2>;
|
||||
label = "lan1";
|
||||
phy-handle = <&phy_port2>;
|
||||
};
|
||||
|
||||
port@3 {
|
||||
reg = <3>;
|
||||
label = "lan2";
|
||||
phy-handle = <&phy_port3>;
|
||||
};
|
||||
|
||||
port@4 {
|
||||
reg = <4>;
|
||||
label = "lan3";
|
||||
phy-handle = <&phy_port4>;
|
||||
};
|
||||
|
||||
port@5 {
|
||||
reg = <5>;
|
||||
label = "lan4";
|
||||
phy-handle = <&phy_port5>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@ -128,10 +186,14 @@
|
||||
};
|
||||
|
||||
enet0: ethernet@b0000 {
|
||||
phy-handle = <&phy0>;
|
||||
phy-connection-type = "rgmii-id";
|
||||
nvmem-cells = <&macaddr_uboot_4fc00>;
|
||||
nvmem-cell-names = "mac-address";
|
||||
|
||||
fixed-link {
|
||||
speed = <1000>;
|
||||
full-duplex;
|
||||
};
|
||||
};
|
||||
|
||||
enet1: ethernet@b1000 {
|
||||
|
@ -18,6 +18,8 @@ define Device/tplink_tl-wdr4900-v1
|
||||
DEVICE_VENDOR := TP-Link
|
||||
DEVICE_MODEL := TL-WDR4900
|
||||
DEVICE_VARIANT := v1
|
||||
DEVICE_COMPAT_VERSION := 1.1
|
||||
DEVICE_COMPAT_MESSAGE := Config cannot be migrated from swconfig to DSA
|
||||
TPLINK_HEADER_VERSION := 1
|
||||
TPLINK_HWID := 0x49000001
|
||||
TPLINK_HWREV := 1
|
||||
|
@ -1,3 +1,4 @@
|
||||
CONFIG_AT803X_PHY=y
|
||||
# CONFIG_FSL_CORENET_CF is not set
|
||||
CONFIG_MTD_NAND_FSL_IFC=y
|
||||
CONFIG_MTD_SPLIT_FIRMWARE=y
|
||||
@ -6,7 +7,15 @@ CONFIG_MTD_UBI=y
|
||||
CONFIG_MTD_UBI_BEB_LIMIT=20
|
||||
CONFIG_MTD_UBI_BLOCK=y
|
||||
CONFIG_MTD_UBI_WL_THRESHOLD=4096
|
||||
CONFIG_NET_DEVLINK=y
|
||||
CONFIG_NET_DSA=y
|
||||
CONFIG_NET_DSA_QCA8K=y
|
||||
CONFIG_NET_DSA_TAG_QCA=y
|
||||
CONFIG_NET_SWITCHDEV=y
|
||||
CONFIG_PHYLINK=y
|
||||
CONFIG_REALTEK_PHY=y
|
||||
CONFIG_RED_15W_REV1=y
|
||||
CONFIG_REGMAP=y
|
||||
CONFIG_REGULATOR=y
|
||||
CONFIG_TL_WDR4900_V1=y
|
||||
CONFIG_UBIFS_FS=y
|
||||
|
@ -43,6 +43,7 @@ CONFIG_RPS=y
|
||||
CONFIG_RWSEM_SPIN_ON_OWNER=y
|
||||
CONFIG_SMP=y
|
||||
CONFIG_SPI_GPIO=y
|
||||
CONFIG_SWCONFIG=y
|
||||
CONFIG_SWCONFIG_B53=y
|
||||
# CONFIG_SWCONFIG_B53_MMAP_DRIVER is not set
|
||||
CONFIG_SWCONFIG_B53_PHY_DRIVER=y
|
||||
|
@ -445,4 +445,5 @@
|
||||
phys = <&cp0_comphy5 2>;
|
||||
phy-names = "cp0-pcie2-x1-phy";
|
||||
reset-gpio = <&cp0_gpio1 9 GPIO_ACTIVE_LOW>;
|
||||
ranges = <0x82000000 0x0 0xc0000000 0x0 0xc0000000 0x0 0x8000000>;
|
||||
};
|
||||
|
@ -121,7 +121,7 @@
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&pcie0 {
|
||||
&pcie1 {
|
||||
wifi@0,0 {
|
||||
compatible = "mediatek,mt76";
|
||||
reg = <0x0000 0 0 0 0>;
|
||||
@ -135,7 +135,7 @@
|
||||
};
|
||||
};
|
||||
|
||||
&pcie1 {
|
||||
&pcie2 {
|
||||
wifi1: wifi@0,0 {
|
||||
compatible = "mediatek,mt76";
|
||||
reg = <0x0000 0 0 0 0>;
|
||||
|
@ -2613,6 +2613,8 @@ define Device/zbtlink_zbt-we1326
|
||||
IMAGE_SIZE := 16064k
|
||||
DEVICE_VENDOR := Zbtlink
|
||||
DEVICE_MODEL := ZBT-WE1326
|
||||
DEVICE_ALT0_VENDOR := Wiflyer
|
||||
DEVICE_ALT0_MODEL := WF3526-P
|
||||
DEVICE_PACKAGES := kmod-mt7603 kmod-mt76x2 kmod-usb3 kmod-sdhci-mt7620
|
||||
SUPPORTED_DEVICES += zbt-we1326
|
||||
endef
|
||||
|
@ -29,7 +29,6 @@ EXCLUDE_DIRS:= \
|
||||
*/man \
|
||||
*/info \
|
||||
*/root-* \
|
||||
initial \
|
||||
*.install.clean \
|
||||
*.install.flags \
|
||||
*.install \
|
||||
|
@ -37,6 +37,12 @@ PATCH_DIR:=./patches/$(PKG_VERSION)
|
||||
|
||||
include $(INCLUDE_DIR)/toolchain-build.mk
|
||||
|
||||
ifdef CONFIG_GCC_USE_GRAPHITE
|
||||
GRAPHITE_CONFIGURE:= --with-isl=$(STAGING_DIR_HOST)
|
||||
else
|
||||
GRAPHITE_CONFIGURE:= --without-isl --without-cloog
|
||||
endif
|
||||
|
||||
HOST_CONFIGURE_ARGS = \
|
||||
--prefix=$(TOOLCHAIN_DIR) \
|
||||
--build=$(GNU_HOST_NAME) \
|
||||
@ -78,7 +84,6 @@ define Host/Prepare
|
||||
$(call Host/Prepare/Default)
|
||||
ln -snf $(notdir $(HOST_BUILD_DIR)) $(BUILD_DIR_TOOLCHAIN)/$(PKG_NAME)
|
||||
$(CP) $(SCRIPT_DIR)/config.{guess,sub} $(HOST_BUILD_DIR)/
|
||||
$(SED) 's, " Linaro.*,,' $(HOST_BUILD_DIR)/bfd/version.h
|
||||
endef
|
||||
|
||||
define Host/Compile
|
||||
@ -86,22 +91,10 @@ define Host/Compile
|
||||
endef
|
||||
|
||||
define Host/Install
|
||||
mkdir -p $(TOOLCHAIN_DIR)/initial
|
||||
$(MAKE) -C $(HOST_BUILD_DIR) \
|
||||
prefix=$(TOOLCHAIN_DIR)/initial \
|
||||
install
|
||||
$(MAKE) -C $(HOST_BUILD_DIR) \
|
||||
prefix=$(TOOLCHAIN_DIR) \
|
||||
install
|
||||
$(call FixupLibdir,$(TOOLCHAIN_DIR)/initial)
|
||||
$(RM) $(TOOLCHAIN_DIR)/initial/lib/libiberty.a
|
||||
$(call FixupLibdir,$(TOOLCHAIN_DIR))
|
||||
$(CP) $(TOOLCHAIN_DIR)/bin/$(REAL_GNU_TARGET_NAME)-readelf $(HOST_BUILD_PREFIX)/bin/readelf
|
||||
# ARC gcc requires extlib.
|
||||
# If extlib is not available in "initial" folder
|
||||
# initial gcc will fail to build libc.
|
||||
if [ -d $(TOOLCHAIN_DIR)/extlib ]; then \
|
||||
$(CP) -r $(TOOLCHAIN_DIR)/extlib $(TOOLCHAIN_DIR)/initial/; \
|
||||
fi
|
||||
endef
|
||||
|
||||
define Host/Clean
|
||||
|
@ -19,18 +19,10 @@ endef
|
||||
|
||||
define Host/Install
|
||||
+$(GCC_MAKE) $(HOST_JOBS) -C $(GCC_BUILD_DIR) \
|
||||
prefix="$(TOOLCHAIN_DIR)/initial" \
|
||||
install-gcc \
|
||||
install-target-libgcc
|
||||
|
||||
# XXX: glibc insists on linking against libgcc_eh
|
||||
( cd $(TOOLCHAIN_DIR)/initial/lib/gcc/$(REAL_GNU_TARGET_NAME)/$(PKG_VERSION) ; \
|
||||
[ -e libgcc_eh.a ] || ln -sf libgcc.a libgcc_eh.a ; \
|
||||
cp libgcc.a libgcc_initial.a; \
|
||||
)
|
||||
|
||||
$(call FixupLibdir,$(TOOLCHAIN_DIR)/initial)
|
||||
$$(call file_copy,$(TOOLCHAIN_DIR)/initial/.,$(TOOLCHAIN_DIR)/)
|
||||
$(call FixupLibdir,$(TOOLCHAIN_DIR))
|
||||
endef
|
||||
|
||||
$(eval $(call HostBuild))
|
||||
|
@ -20,7 +20,7 @@ define Host/Install
|
||||
install
|
||||
( cd $(TOOLCHAIN_DIR) ; \
|
||||
for d in lib usr/lib ; do \
|
||||
for f in libc.so libpthread.so libgcc_s.so ; do \
|
||||
for f in libc.so libm.so libpthread.so libgcc_s.so ; do \
|
||||
if [ -f $$$$d/$$$$f -a ! -L $$$$d/$$$$f ] ; then \
|
||||
$(SED) 's,/usr/lib/,,g;s,/lib/,,g' $$$$d/$$$$f ; \
|
||||
fi \
|
||||
|
@ -9,7 +9,7 @@ HOST_BUILD_PARALLEL:=1
|
||||
|
||||
MUSL_MAKEOPTS = -C $(HOST_BUILD_DIR) \
|
||||
DESTDIR="$(TOOLCHAIN_DIR)/" \
|
||||
LIBCC="$(subst libgcc.a,libgcc_initial.a,$(shell $(TARGET_CC) -print-libgcc-file-name))"
|
||||
LIBCC="$(shell $(TARGET_CC) -print-libgcc-file-name)"
|
||||
|
||||
define Host/SetToolchainInfo
|
||||
$(SED) 's,^\(LIBC_TYPE\)=.*,\1=$(PKG_NAME),' $(TOOLCHAIN_DIR)/info.mk
|
||||
|
@ -59,7 +59,7 @@ tools-y += patch-image
|
||||
tools-y += patchelf
|
||||
tools-y += pkgconf
|
||||
tools-y += quilt
|
||||
tools-y += squashfskit4
|
||||
tools-y += squashfs4
|
||||
tools-y += sstrip
|
||||
tools-y += zip
|
||||
tools-y += zlib
|
||||
@ -119,11 +119,11 @@ $(curdir)/pkgconf/compile := $(curdir)/meson/compile
|
||||
$(curdir)/quilt/compile := $(curdir)/autoconf/compile $(curdir)/findutils/compile
|
||||
$(curdir)/sdcc/compile := $(curdir)/bison/compile
|
||||
$(curdir)/squashfs3-lzma/compile := $(curdir)/lzma-old/compile
|
||||
$(curdir)/squashfskit4/compile := $(curdir)/xz/compile $(curdir)/zlib/compile
|
||||
$(curdir)/squashfs4/compile := $(curdir)/xz/compile $(curdir)/zlib/compile
|
||||
$(curdir)/zstd/compile := $(curdir)/meson/compile
|
||||
|
||||
ifneq ($(HOST_OS),Linux)
|
||||
$(curdir)/squashfskit4/compile += $(curdir)/coreutils/compile
|
||||
$(curdir)/squashfs4/compile += $(curdir)/coreutils/compile
|
||||
tools-y += coreutils
|
||||
endif
|
||||
ifeq ($(HOST_OS),Darwin)
|
||||
|
@ -1,19 +1,21 @@
|
||||
#
|
||||
# Copyright (C) 2009-2012 OpenWrt.org
|
||||
# Copyright (C) 2006-2012 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=squashfskit4
|
||||
PKG_VERSION:=4.14
|
||||
PKG_RELEASE:=3
|
||||
PKG_SOURCE:=squashfskit-v$(PKG_VERSION).tar.xz
|
||||
PKG_SOURCE_URL:=https://github.com/squashfskit/squashfskit/releases/download/v$(PKG_VERSION)/
|
||||
PKG_HASH:=5761aaa3aedc4f7112b708367d891c9abdc1ffea972e3fe47923ddba23984d95
|
||||
PKG_NAME:=squashfs4
|
||||
PKG_CPE_ID:=cpe:/a:phillip_lougher:squashfs
|
||||
PKG_VERSION:=4.5.1
|
||||
PKG_RELEASE=1
|
||||
|
||||
HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/squashfskit-v$(PKG_VERSION)
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL:=https://github.com/plougher/squashfs-tools
|
||||
PKG_SOURCE_DATE:=2022-03-17
|
||||
PKG_SOURCE_VERSION:=afdd63fc386919b4aa40d573b0a6069414d14317
|
||||
PKG_MIRROR_HASH:=caedb66cf6dcbdcee0d1525923e203d003ef15f34a13a328686794666f16171f
|
||||
|
||||
include $(INCLUDE_DIR)/host-build.mk
|
||||
|
||||
@ -22,8 +24,6 @@ define Host/Compile
|
||||
$(MAKE) -C $(HOST_BUILD_DIR)/squashfs-tools \
|
||||
XZ_SUPPORT=1 \
|
||||
LZMA_XZ_SUPPORT=1 \
|
||||
XATTR_SUPPORT=1 \
|
||||
LZMA_LIB="$(STAGING_DIR_HOST)/lib/liblzma.a" \
|
||||
EXTRA_CFLAGS="-I$(STAGING_DIR_HOST)/include" \
|
||||
mksquashfs unsquashfs
|
||||
endef
|
@ -0,0 +1,39 @@
|
||||
From a9119c969af0a5aa961d56978d5dd4f3eb952667 Mon Sep 17 00:00:00 2001
|
||||
From: Phillip Lougher <phillip@squashfs.org.uk>
|
||||
Date: Mon, 15 Aug 2022 17:04:43 +0100
|
||||
Subject: [PATCH 1/1] Unsquashfs: Add and make some header includes conditional
|
||||
|
||||
Fixes https://github.com/plougher/squashfs-tools/issues/122
|
||||
|
||||
Signed-off-by: Phillip Lougher <phillip@squashfs.org.uk>
|
||||
---
|
||||
squashfs-tools/reader.c | 1 +
|
||||
squashfs-tools/unsquashfs.c | 5 +++++
|
||||
2 files changed, 6 insertions(+)
|
||||
|
||||
--- a/squashfs-tools/reader.c
|
||||
+++ b/squashfs-tools/reader.c
|
||||
@@ -38,6 +38,7 @@
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
+#include <signal.h>
|
||||
#include "squashfs_fs.h"
|
||||
#include "mksquashfs.h"
|
||||
#include "caches-queues-lists.h"
|
||||
--- a/squashfs-tools/unsquashfs.c
|
||||
+++ b/squashfs-tools/unsquashfs.c
|
||||
@@ -32,8 +32,13 @@
|
||||
#include "stdarg.h"
|
||||
#include "fnmatch_compat.h"
|
||||
|
||||
+#ifdef __linux__
|
||||
#include <sys/sysinfo.h>
|
||||
#include <sys/sysmacros.h>
|
||||
+#elif defined __FreeBSD__
|
||||
+#include <sys/sysctl.h>
|
||||
+#endif
|
||||
+
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
@ -0,0 +1,30 @@
|
||||
From 374e39a786a5acda841056bec26fd0e0c4d40dac Mon Sep 17 00:00:00 2001
|
||||
From: Phillip Lougher <phillip@squashfs.org.uk>
|
||||
Date: Mon, 15 Aug 2022 17:09:05 +0100
|
||||
Subject: [PATCH 1/1] Mksquashfs: Make sysinfo() conditional
|
||||
|
||||
Fixes https://github.com/plougher/squashfs-tools/issues/123
|
||||
|
||||
Signed-off-by: Phillip Lougher <phillip@squashfs.org.uk>
|
||||
---
|
||||
squashfs-tools/mksquashfs.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
--- a/squashfs-tools/mksquashfs.c
|
||||
+++ b/squashfs-tools/mksquashfs.c
|
||||
@@ -5802,6 +5802,7 @@ static int get_physical_memory()
|
||||
long long page_size = sysconf(_SC_PAGESIZE);
|
||||
int phys_mem;
|
||||
|
||||
+#ifdef __linux__
|
||||
if(num_pages == -1 || page_size == -1) {
|
||||
struct sysinfo sys;
|
||||
int res = sysinfo(&sys);
|
||||
@@ -5812,6 +5813,7 @@ static int get_physical_memory()
|
||||
num_pages = sys.totalram;
|
||||
page_size = sys.mem_unit;
|
||||
}
|
||||
+#endif
|
||||
|
||||
phys_mem = num_pages * page_size >> 20;
|
||||
|
92
tools/squashfs4/patches/003-Only-use-available-CPUs.patch
Normal file
92
tools/squashfs4/patches/003-Only-use-available-CPUs.patch
Normal file
@ -0,0 +1,92 @@
|
||||
From bc8e655a420d2f62bb0597947e96dce7b4d3fb36 Mon Sep 17 00:00:00 2001
|
||||
From: Wessel Dankers <wsl@fruit.je>
|
||||
Date: Sun, 30 Oct 2022 19:29:28 +0100
|
||||
Subject: [PATCH] Only use available CPUs
|
||||
|
||||
Not all online CPUs may be available for the current process,
|
||||
especially when CPU affinity is involved. In such cases too many
|
||||
threads will be created, which will then compete unnecessarily
|
||||
for CPU time.
|
||||
|
||||
Use sched_getaffinity() to determine the correct number of threads
|
||||
to create.
|
||||
---
|
||||
squashfs-tools/mksquashfs.c | 16 ++++++++++++----
|
||||
squashfs-tools/unsquashfs.c | 13 ++++++++++---
|
||||
2 files changed, 22 insertions(+), 7 deletions(-)
|
||||
|
||||
--- a/squashfs-tools/mksquashfs.c
|
||||
+++ b/squashfs-tools/mksquashfs.c
|
||||
@@ -52,7 +52,9 @@
|
||||
#include <ctype.h>
|
||||
#include <sys/sysinfo.h>
|
||||
|
||||
-#ifndef linux
|
||||
+#ifdef linux
|
||||
+#include <sched.h>
|
||||
+#else
|
||||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
|
||||
@@ -5079,7 +5081,15 @@ static void initialise_threads(int readq
|
||||
BAD_ERROR("Failed to set signal mask in intialise_threads\n");
|
||||
|
||||
if(processors == -1) {
|
||||
-#ifndef linux
|
||||
+#ifdef linux
|
||||
+ cpu_set_t cpu_set;
|
||||
+ CPU_ZERO(&cpu_set);
|
||||
+
|
||||
+ if(sched_getaffinity(0, sizeof cpu_set, &cpu_set) == -1)
|
||||
+ processors = sysconf(_SC_NPROCESSORS_ONLN);
|
||||
+ else
|
||||
+ processors = CPU_COUNT(&cpu_set);
|
||||
+#else
|
||||
int mib[2];
|
||||
size_t len = sizeof(processors);
|
||||
|
||||
@@ -5096,8 +5106,6 @@ static void initialise_threads(int readq
|
||||
ERROR_EXIT(" Defaulting to 1\n");
|
||||
processors = 1;
|
||||
}
|
||||
-#else
|
||||
- processors = sysconf(_SC_NPROCESSORS_ONLN);
|
||||
#endif
|
||||
}
|
||||
|
||||
--- a/squashfs-tools/unsquashfs.c
|
||||
+++ b/squashfs-tools/unsquashfs.c
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "fnmatch_compat.h"
|
||||
|
||||
#ifdef __linux__
|
||||
+#include <sched.h>
|
||||
#include <sys/sysinfo.h>
|
||||
#include <sys/sysmacros.h>
|
||||
#elif defined __FreeBSD__
|
||||
@@ -2719,7 +2720,15 @@ void initialise_threads(int fragment_buf
|
||||
}
|
||||
|
||||
if(processors == -1) {
|
||||
-#ifndef linux
|
||||
+#ifdef linux
|
||||
+ cpu_set_t cpu_set;
|
||||
+ CPU_ZERO(&cpu_set);
|
||||
+
|
||||
+ if(sched_getaffinity(0, sizeof cpu_set, &cpu_set) == -1)
|
||||
+ processors = sysconf(_SC_NPROCESSORS_ONLN);
|
||||
+ else
|
||||
+ processors = CPU_COUNT(&cpu_set);
|
||||
+#else
|
||||
int mib[2];
|
||||
size_t len = sizeof(processors);
|
||||
|
||||
@@ -2735,8 +2744,6 @@ void initialise_threads(int fragment_buf
|
||||
"Defaulting to 1\n");
|
||||
processors = 1;
|
||||
}
|
||||
-#else
|
||||
- processors = sysconf(_SC_NPROCESSORS_ONLN);
|
||||
#endif
|
||||
}
|
||||
|
@ -0,0 +1,37 @@
|
||||
From 92e628ec0e26cf091d82356e3b74f73bedf4cfc8 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Date: Sat, 15 Oct 2022 00:11:20 +0200
|
||||
Subject: [PATCH] action: rework strdupa with POSIX strdup and free
|
||||
|
||||
strdupa is not POSIX and cause compilation error on macos.
|
||||
Fix this by using strdup and free.
|
||||
|
||||
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Signed-off-by: Phillip Lougher <phillip@squashfs.org.uk>
|
||||
---
|
||||
squashfs-tools/action.c | 14 +++++++++++---
|
||||
1 file changed, 11 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/squashfs-tools/action.c
|
||||
+++ b/squashfs-tools/action.c
|
||||
@@ -2415,9 +2415,17 @@ static char *get_start(char *s, int n)
|
||||
|
||||
static int subpathname_fn(struct atom *atom, struct action_data *action_data)
|
||||
{
|
||||
- return fnmatch(atom->argv[0], get_start(strdupa(action_data->subpath),
|
||||
- count_components(atom->argv[0])),
|
||||
- FNM_PATHNAME|FNM_EXTMATCH) == 0;
|
||||
+ char *s, *tmp;
|
||||
+ int ret;
|
||||
+
|
||||
+ s = tmp = strdup(action_data->subpath);
|
||||
+ tmp = get_start(tmp, count_components(atom->argv[0]));
|
||||
+
|
||||
+ ret = fnmatch(atom->argv[0], tmp, FNM_PATHNAME|FNM_EXTMATCH);
|
||||
+
|
||||
+ free(s);
|
||||
+
|
||||
+ return ret == 0;
|
||||
}
|
||||
|
||||
/*
|
@ -0,0 +1,192 @@
|
||||
From dbe9747b4f09bd2f4d63af06e55c2c3ed35bfca1 Mon Sep 17 00:00:00 2001
|
||||
From: Phillip Lougher <phillip@squashfs.org.uk>
|
||||
Date: Tue, 7 Feb 2023 23:09:30 +0000
|
||||
Subject: [PATCH] Don't use sigwaitinfo()/sigtimedwait() if not supported
|
||||
|
||||
If sigwaitinfo() and sigtimedwait() are not supported,
|
||||
use sigwait() instead.
|
||||
|
||||
This will disable the queue/caches dump if ^\ (SIGQUIT)
|
||||
is hit twice within a second.
|
||||
|
||||
But the queue/caches dump is still available if SIGHUP
|
||||
is sent to the program.
|
||||
|
||||
Currently this check is applied to MAC OS X. FreeBSD and
|
||||
NetBSD appear to have these functions.
|
||||
|
||||
Signed-off-by: Phillip Lougher <phillip@squashfs.org.uk>
|
||||
---
|
||||
squashfs-tools/info.c | 25 ++-------------
|
||||
squashfs-tools/signals.h | 54 ++++++++++++++++++++++++++++++++
|
||||
squashfs-tools/unsquashfs_info.c | 25 ++-------------
|
||||
3 files changed, 60 insertions(+), 44 deletions(-)
|
||||
create mode 100644 squashfs-tools/signals.h
|
||||
|
||||
--- a/squashfs-tools/info.c
|
||||
+++ b/squashfs-tools/info.c
|
||||
@@ -2,7 +2,7 @@
|
||||
* Create a squashfs filesystem. This is a highly compressed read only
|
||||
* filesystem.
|
||||
*
|
||||
- * Copyright (c) 2013, 2014, 2019, 2021
|
||||
+ * Copyright (c) 2013, 2014, 2019, 2021, 2022, 2023
|
||||
* Phillip Lougher <phillip@squashfs.org.uk>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
@@ -42,6 +42,7 @@
|
||||
#include "mksquashfs_error.h"
|
||||
#include "progressbar.h"
|
||||
#include "caches-queues-lists.h"
|
||||
+#include "signals.h"
|
||||
|
||||
static int silent = 0;
|
||||
static struct dir_ent *ent = NULL;
|
||||
@@ -144,7 +145,6 @@ void dump_state()
|
||||
void *info_thrd(void *arg)
|
||||
{
|
||||
sigset_t sigmask;
|
||||
- struct timespec timespec = { .tv_sec = 1, .tv_nsec = 0 };
|
||||
int sig, waiting = 0;
|
||||
|
||||
sigemptyset(&sigmask);
|
||||
@@ -152,26 +152,7 @@ void *info_thrd(void *arg)
|
||||
sigaddset(&sigmask, SIGHUP);
|
||||
|
||||
while(1) {
|
||||
- if(waiting)
|
||||
- sig = sigtimedwait(&sigmask, NULL, ×pec);
|
||||
- else
|
||||
- sig = sigwaitinfo(&sigmask, NULL);
|
||||
-
|
||||
- if(sig == -1) {
|
||||
- switch(errno) {
|
||||
- case EAGAIN:
|
||||
- /* interval timed out */
|
||||
- waiting = 0;
|
||||
- /* FALLTHROUGH */
|
||||
- case EINTR:
|
||||
- /* if waiting, the wait will be longer, but
|
||||
- that's OK */
|
||||
- continue;
|
||||
- default:
|
||||
- BAD_ERROR("sigtimedwait/sigwaitinfo failed "
|
||||
- "because %s\n", strerror(errno));
|
||||
- }
|
||||
- }
|
||||
+ sig = wait_for_signal(&sigmask, &waiting);
|
||||
|
||||
if(sig == SIGQUIT && !waiting) {
|
||||
print_filename();
|
||||
--- /dev/null
|
||||
+++ b/squashfs-tools/signals.h
|
||||
@@ -0,0 +1,54 @@
|
||||
+#ifndef SIGNALS_H
|
||||
+#define SIGNALS_H
|
||||
+/*
|
||||
+ * Create a squashfs filesystem. This is a highly compressed read only
|
||||
+ * filesystem.
|
||||
+ *
|
||||
+ * Copyright (c) 2023
|
||||
+ * Phillip Lougher <phillip@squashfs.org.uk>
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU General Public License
|
||||
+ * as published by the Free Software Foundation; either version 2,
|
||||
+ * or (at your option) any later version.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License
|
||||
+ * along with this program; if not, write to the Free Software
|
||||
+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
+ *
|
||||
+ * signals.h
|
||||
+ */
|
||||
+
|
||||
+static inline int wait_for_signal(sigset_t *sigmask, int *waiting)
|
||||
+{
|
||||
+ int sig;
|
||||
+
|
||||
+#if defined(__APPLE__) && defined(__MACH__)
|
||||
+ sigwait(sigmask, &sig);
|
||||
+ *waiting = 0;
|
||||
+#else
|
||||
+ struct timespec timespec = { .tv_sec = 1, .tv_nsec = 0 };
|
||||
+
|
||||
+ while(1) {
|
||||
+ if(*waiting)
|
||||
+ sig = sigtimedwait(sigmask, NULL, ×pec);
|
||||
+ else
|
||||
+ sig = sigwaitinfo(sigmask, NULL);
|
||||
+
|
||||
+ if(sig != -1)
|
||||
+ break;
|
||||
+
|
||||
+ if(errno == EAGAIN)
|
||||
+ *waiting = 0;
|
||||
+ else if(errno != EINTR)
|
||||
+ BAD_ERROR("sigtimedwait/sigwaitinfo failed because %s\n", strerror(errno));
|
||||
+ }
|
||||
+#endif
|
||||
+ return sig;
|
||||
+}
|
||||
+#endif
|
||||
--- a/squashfs-tools/unsquashfs_info.c
|
||||
+++ b/squashfs-tools/unsquashfs_info.c
|
||||
@@ -2,7 +2,7 @@
|
||||
* Create a squashfs filesystem. This is a highly compressed read only
|
||||
* filesystem.
|
||||
*
|
||||
- * Copyright (c) 2013, 2021
|
||||
+ * Copyright (c) 2013, 2021, 2023
|
||||
* Phillip Lougher <phillip@squashfs.org.uk>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
@@ -40,6 +40,7 @@
|
||||
#include "squashfs_fs.h"
|
||||
#include "unsquashfs.h"
|
||||
#include "unsquashfs_error.h"
|
||||
+#include "signals.h"
|
||||
|
||||
char *pathname = NULL;
|
||||
|
||||
@@ -96,7 +97,6 @@ void dump_state()
|
||||
void *info_thrd(void *arg)
|
||||
{
|
||||
sigset_t sigmask;
|
||||
- struct timespec timespec = { .tv_sec = 1, .tv_nsec = 0 };
|
||||
int sig, waiting = 0;
|
||||
|
||||
sigemptyset(&sigmask);
|
||||
@@ -104,26 +104,7 @@ void *info_thrd(void *arg)
|
||||
sigaddset(&sigmask, SIGHUP);
|
||||
|
||||
while(1) {
|
||||
- if(waiting)
|
||||
- sig = sigtimedwait(&sigmask, NULL, ×pec);
|
||||
- else
|
||||
- sig = sigwaitinfo(&sigmask, NULL);
|
||||
-
|
||||
- if(sig == -1) {
|
||||
- switch(errno) {
|
||||
- case EAGAIN:
|
||||
- /* interval timed out */
|
||||
- waiting = 0;
|
||||
- /* FALLTHROUGH */
|
||||
- case EINTR:
|
||||
- /* if waiting, the wait will be longer, but
|
||||
- that's OK */
|
||||
- continue;
|
||||
- default:
|
||||
- BAD_ERROR("sigtimedwait/sigwaitinfo failed "
|
||||
- "because %s\n", strerror(errno));
|
||||
- }
|
||||
- }
|
||||
+ sig = wait_for_signal(&sigmask, &waiting);
|
||||
|
||||
if(sig == SIGQUIT && !waiting) {
|
||||
if(pathname)
|
@ -0,0 +1,49 @@
|
||||
From b2f6454a2b2517cfba7a24cf02e9bdf3b959c86a Mon Sep 17 00:00:00 2001
|
||||
From: Tony Butler <spudz76@gmail.com>
|
||||
Date: Sat, 18 Feb 2023 13:20:48 -0800
|
||||
Subject: [PATCH] Move sysinfo.h into the linux-only section, should fix build
|
||||
on MacOS.
|
||||
|
||||
All compilers set `__linux__`, but `linux` may not be defined, and usage
|
||||
was mixed. Use `__linux__` everywhere instead.
|
||||
|
||||
Signed-off-by: Tony Butler <spudz76@gmail.com>
|
||||
---
|
||||
squashfs-tools/mksquashfs.c | 6 +++---
|
||||
squashfs-tools/unsquashfs.c | 2 +-
|
||||
2 files changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/squashfs-tools/mksquashfs.c
|
||||
+++ b/squashfs-tools/mksquashfs.c
|
||||
@@ -50,9 +50,9 @@
|
||||
#include <sys/wait.h>
|
||||
#include <limits.h>
|
||||
#include <ctype.h>
|
||||
-#include <sys/sysinfo.h>
|
||||
|
||||
-#ifdef linux
|
||||
+#ifdef __linux__
|
||||
+#include <sys/sysinfo.h>
|
||||
#include <sched.h>
|
||||
#else
|
||||
#include <sys/sysctl.h>
|
||||
@@ -5081,7 +5081,7 @@ static void initialise_threads(int readq
|
||||
BAD_ERROR("Failed to set signal mask in intialise_threads\n");
|
||||
|
||||
if(processors == -1) {
|
||||
-#ifdef linux
|
||||
+#ifdef __linux__
|
||||
cpu_set_t cpu_set;
|
||||
CPU_ZERO(&cpu_set);
|
||||
|
||||
--- a/squashfs-tools/unsquashfs.c
|
||||
+++ b/squashfs-tools/unsquashfs.c
|
||||
@@ -2720,7 +2720,7 @@ void initialise_threads(int fragment_buf
|
||||
}
|
||||
|
||||
if(processors == -1) {
|
||||
-#ifdef linux
|
||||
+#ifdef __linux__
|
||||
cpu_set_t cpu_set;
|
||||
CPU_ZERO(&cpu_set);
|
||||
|
@ -0,0 +1,26 @@
|
||||
From dcf492077ef10ed7550b6e2b38b81318645bbdd5 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Date: Sun, 19 Feb 2023 04:36:01 +0100
|
||||
Subject: [PATCH] Unsquashfs: fix compilation error for missing sysctl.h on
|
||||
macos
|
||||
|
||||
Currently the include of sys/sysctl.h is guarded and done only for
|
||||
FreeBSD system. Remove this to fix compilation error on macos following
|
||||
the same pattern done in mksquashfs.c
|
||||
|
||||
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
---
|
||||
squashfs-tools/unsquashfs.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/squashfs-tools/unsquashfs.c
|
||||
+++ b/squashfs-tools/unsquashfs.c
|
||||
@@ -36,7 +36,7 @@
|
||||
#include <sched.h>
|
||||
#include <sys/sysinfo.h>
|
||||
#include <sys/sysmacros.h>
|
||||
-#elif defined __FreeBSD__
|
||||
+#else
|
||||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
|
@ -1,14 +1,14 @@
|
||||
--- a/squashfs-tools/xattr.c
|
||||
+++ b/squashfs-tools/xattr.c
|
||||
@@ -113,6 +113,7 @@ static int get_prefix(struct xattr_list
|
||||
|
||||
@@ -115,6 +115,7 @@ int xattr_get_prefix(struct xattr_list *
|
||||
|
||||
static int read_xattrs_from_system(char *filename, struct xattr_list **xattrs)
|
||||
{
|
||||
+#if defined(linux)
|
||||
ssize_t size, vsize;
|
||||
char *xattr_names, *p;
|
||||
int i;
|
||||
@@ -222,6 +223,10 @@ failed:
|
||||
@@ -227,6 +228,10 @@ failed:
|
||||
free(xattr_list);
|
||||
free(xattr_names);
|
||||
return 0;
|
||||
@ -21,17 +21,17 @@
|
||||
|
||||
--- a/squashfs-tools/unsquashfs_xattr.c
|
||||
+++ b/squashfs-tools/unsquashfs_xattr.c
|
||||
@@ -34,6 +34,7 @@ extern int user_xattrs;
|
||||
@@ -36,6 +36,7 @@ extern int strict_errors;
|
||||
|
||||
void write_xattr(char *pathname, unsigned int xattr)
|
||||
int write_xattr(char *pathname, unsigned int xattr)
|
||||
{
|
||||
+#if defined(linux)
|
||||
unsigned int count;
|
||||
struct xattr_list *xattr_list;
|
||||
int i;
|
||||
@@ -136,4 +137,5 @@ void write_xattr(char *pathname, unsigne
|
||||
}
|
||||
|
||||
@@ -147,4 +148,5 @@ int write_xattr(char *pathname, unsigned
|
||||
free_xattr(xattr_list, count);
|
||||
|
||||
return !failed;
|
||||
+#endif
|
||||
}
|
@ -0,0 +1,167 @@
|
||||
From f49793cfbd72fdc40ab75dbffef42dca774701d1 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Date: Fri, 14 Oct 2022 15:59:16 +0200
|
||||
Subject: [PATCH] xz_wrapper: support multiple lzma configuration options
|
||||
|
||||
Add option to configure preset, lc, lp and pb lzma parameters.
|
||||
-Xpreset can be both a level or set to 'extreme' to use the lzma extreme
|
||||
compression options.
|
||||
|
||||
New option added:
|
||||
-Xpreset
|
||||
-Xlc
|
||||
-Xlp
|
||||
-Xpb
|
||||
|
||||
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
---
|
||||
squashfs-tools/xz_wrapper.c | 112 +++++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 109 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/squashfs-tools/xz_wrapper.c
|
||||
+++ b/squashfs-tools/xz_wrapper.c
|
||||
@@ -44,7 +44,10 @@ static struct bcj bcj[] = {
|
||||
static int filter_count = 1;
|
||||
static int dictionary_size = 0;
|
||||
static float dictionary_percent = 0;
|
||||
-
|
||||
+static int preset = LZMA_PRESET_DEFAULT;
|
||||
+static int lc = -1;
|
||||
+static int lp = -1;
|
||||
+static int pb = -1;
|
||||
|
||||
/*
|
||||
* This function is called by the options parsing code in mksquashfs.c
|
||||
@@ -53,6 +56,11 @@ static float dictionary_percent = 0;
|
||||
* Two specific options are supported:
|
||||
* -Xbcj
|
||||
* -Xdict-size
|
||||
+ * -Xpreset
|
||||
+ * -Xe
|
||||
+ * -Xlc
|
||||
+ * -Xlp
|
||||
+ * -Xpb
|
||||
*
|
||||
* This function returns:
|
||||
* >=0 (number of additional args parsed) on success
|
||||
@@ -141,6 +149,85 @@ static int xz_options(char *argv[], int
|
||||
}
|
||||
|
||||
return 1;
|
||||
+ } else if(strcmp(argv[0], "-Xpreset") == 0) {
|
||||
+ char *b;
|
||||
+ long val;
|
||||
+
|
||||
+ if(argc < 2) {
|
||||
+ fprintf(stderr, "xz: -Xpreset missing preset-level\n");
|
||||
+ goto failed;
|
||||
+ }
|
||||
+
|
||||
+ if (strcmp(argv[1], "extreme") == 0) {
|
||||
+ preset = LZMA_PRESET_EXTREME;
|
||||
+
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ val = strtol(argv[1], &b, 10);
|
||||
+ if ((int) val < 0 || (int) val & ~LZMA_PRESET_LEVEL_MASK) {
|
||||
+ fprintf(stderr, "xz: -Xpreset can't be "
|
||||
+ "negative or more than the max preset\n");
|
||||
+ goto failed;
|
||||
+ }
|
||||
+
|
||||
+ preset = (int) val;
|
||||
+
|
||||
+ return 1;
|
||||
+ } else if(strcmp(argv[0], "-Xlc") == 0) {
|
||||
+ char *b;
|
||||
+ long val;
|
||||
+
|
||||
+ if(argc < 2) {
|
||||
+ fprintf(stderr, "xz: -Xlc missing value\n");
|
||||
+ goto failed;
|
||||
+ }
|
||||
+
|
||||
+ val = strtol(argv[1], &b, 10);
|
||||
+ if ((int) val < LZMA_LCLP_MIN || (int) val > LZMA_LCLP_MAX) {
|
||||
+ fprintf(stderr, "xz: -Xlc invalid value\n");
|
||||
+ goto failed;
|
||||
+ }
|
||||
+
|
||||
+ lc = (int) val;
|
||||
+
|
||||
+ return 1;
|
||||
+ } else if(strcmp(argv[0], "-Xlp") == 0) {
|
||||
+ char *b;
|
||||
+ long val;
|
||||
+
|
||||
+ if(argc < 2) {
|
||||
+ fprintf(stderr, "xz: -Xlp missing value\n");
|
||||
+ goto failed;
|
||||
+ }
|
||||
+
|
||||
+ val = strtol(argv[1], &b, 10);
|
||||
+ if ((int) val < LZMA_LCLP_MIN || (int) val > LZMA_LCLP_MAX) {
|
||||
+ fprintf(stderr, "xz: -Xlc invalid value\n");
|
||||
+ goto failed;
|
||||
+ }
|
||||
+
|
||||
+ lp = (int) val;
|
||||
+
|
||||
+ return 1;
|
||||
+ } else if(strcmp(argv[0], "-Xpb") == 0) {
|
||||
+ char *b;
|
||||
+ long val;
|
||||
+
|
||||
+ if(argc < 2) {
|
||||
+ fprintf(stderr, "xz: -Xpb missing value\n");
|
||||
+ goto failed;
|
||||
+ }
|
||||
+
|
||||
+ val = strtol(argv[1], &b, 10);
|
||||
+ if ((int) val < LZMA_PB_MIN || (int) val > LZMA_PB_MAX) {
|
||||
+ fprintf(stderr, "xz: -Xlc invalid value\n");
|
||||
+ goto failed;
|
||||
+ }
|
||||
+
|
||||
+ pb = (int) val;
|
||||
+
|
||||
+ return 1;
|
||||
}
|
||||
|
||||
return -1;
|
||||
@@ -446,11 +533,20 @@ static int xz_compress(void *strm, void
|
||||
for(i = 0; i < stream->filters; i++) {
|
||||
struct filter *filter = &stream->filter[i];
|
||||
|
||||
- if(lzma_lzma_preset(&stream->opt, LZMA_PRESET_DEFAULT))
|
||||
+ if(lzma_lzma_preset(&stream->opt, preset))
|
||||
goto failed;
|
||||
|
||||
stream->opt.dict_size = stream->dictionary_size;
|
||||
|
||||
+ if (lc >= 0)
|
||||
+ stream->opt.lc = lc;
|
||||
+
|
||||
+ if (lp >= 0)
|
||||
+ stream->opt.lp = lp;
|
||||
+
|
||||
+ if (pb >= 0)
|
||||
+ stream->opt.pb = pb;
|
||||
+
|
||||
filter->length = 0;
|
||||
res = lzma_stream_buffer_encode(filter->filter,
|
||||
LZMA_CHECK_CRC32, NULL, src, size, filter->buffer,
|
||||
@@ -521,6 +617,12 @@ static void xz_usage(FILE *stream)
|
||||
fprintf(stream, " header as either 2^n or as 2^n+2^(n+1).\n\t\t");
|
||||
fprintf(stream, "Example dict-sizes are 75%%, 50%%, 37.5%%, 25%%, or");
|
||||
fprintf(stream, " 32K, 16K, 8K\n\t\tetc.\n");
|
||||
+ fprintf(stream, "\t -Xpreset <preset-level or extreme>\n");
|
||||
+ fprintf(stream, "\t\tUse <preset-value> as the custom preset to use");
|
||||
+ fprintf(stream, " on compress. Can be a level number or extreme.\n");
|
||||
+ fprintf(stream, "\t -Xlc <value>\n");
|
||||
+ fprintf(stream, "\t -Xlp <value>\n");
|
||||
+ fprintf(stream, "\t -Xpb <value>\n");
|
||||
}
|
||||
|
||||
|
@ -1,21 +0,0 @@
|
||||
--- a/squashfs-tools/version.sh
|
||||
+++ b/squashfs-tools/version.sh
|
||||
@@ -27,13 +27,11 @@ if [ -z "$OUTPUT" ] ; then
|
||||
fi
|
||||
|
||||
our_date() {
|
||||
-case $(uname) in
|
||||
-NetBSD|OpenBSD|DragonFly|FreeBSD|Darwin)
|
||||
- date -r "$1" "$2"
|
||||
- ;;
|
||||
-*)
|
||||
- date -d "@$1" "$2"
|
||||
-esac
|
||||
+ if date --version 2>&1 | grep -q "GNU coreutils"; then
|
||||
+ date -d "@$1" "$2"
|
||||
+ else
|
||||
+ date -r "$1" "$2"
|
||||
+ fi
|
||||
}
|
||||
|
||||
try_version() {
|
@ -1,41 +0,0 @@
|
||||
From fe2f5da4b0f8994169c53e84b7cb8a0feefc97b5 Mon Sep 17 00:00:00 2001
|
||||
From: Sergei Trofimovich <slyfox@gentoo.org>
|
||||
Date: Sun, 26 Jan 2020 18:35:13 +0000
|
||||
Subject: [PATCH] squashfs-tools: fix build failure against gcc-10
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
On gcc-10 (and gcc-9 -fno-common) build fails as:
|
||||
|
||||
```
|
||||
cc ... -o mksquashfs
|
||||
ld: read_fs.o:(.bss+0x0):
|
||||
multiple definition of `fwriter_buffer'; mksquashfs.o:(.bss+0x400c90): first defined here
|
||||
ld: read_fs.o:(.bss+0x8):
|
||||
multiple definition of `bwriter_buffer'; mksquashfs.o:(.bss+0x400c98): first defined here
|
||||
```
|
||||
|
||||
gcc-10 will change the default from -fcommon to fno-common:
|
||||
https://gcc.gnu.org/PR85678.
|
||||
|
||||
The error also happens if CFLAGS=-fno-common passed explicitly.
|
||||
|
||||
Reported-by: Toralf Förster
|
||||
Bug: https://bugs.gentoo.org/706456
|
||||
Signed-off-by: Sergei Trofimovich <slyfox@gentoo.org>
|
||||
---
|
||||
squashfs-tools/mksquashfs.h | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/squashfs-tools/mksquashfs.h
|
||||
+++ b/squashfs-tools/mksquashfs.h
|
||||
@@ -133,7 +133,7 @@ struct append_file {
|
||||
#define BLOCK_OFFSET 2
|
||||
|
||||
extern struct cache *reader_buffer, *fragment_buffer, *reserve_cache;
|
||||
-struct cache *bwriter_buffer, *fwriter_buffer;
|
||||
+extern struct cache *bwriter_buffer, *fwriter_buffer;
|
||||
extern struct queue *to_reader, *to_deflate, *to_writer, *from_writer,
|
||||
*locked_fragment, *to_process_frag;
|
||||
extern struct append_file **file_mapping;
|
@ -1,14 +0,0 @@
|
||||
--- a/squashfs-tools/xz_wrapper.c
|
||||
+++ b/squashfs-tools/xz_wrapper.c
|
||||
@@ -192,7 +192,10 @@ static void xz_display_options(void *buf
|
||||
if(size != sizeof(struct comp_opts))
|
||||
goto failed;
|
||||
|
||||
- SQUASHFS_INSWAP_LZMA_COMP_OPTS(comp_opts);
|
||||
+#if __BYTE_ORDER == __BIG_ENDIAN
|
||||
+ comp_opts->dictionary_size = inswap_le32(comp_opts->dictionary_size);
|
||||
+ comp_opts->flags = inswap_le32(comp_opts->flags);
|
||||
+#endif
|
||||
|
||||
dictionary_size = comp_opts->dictionary_size;
|
||||
flags = comp_opts->flags;
|
Loading…
x
Reference in New Issue
Block a user