Merge Official Source
Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
This commit is contained in:
commit
fa9ca4d5cb
@ -447,9 +447,10 @@ $(eval $(call KernelPackage,phy-micrel))
|
||||
define KernelPackage/phy-realtek
|
||||
SUBMENU:=$(NETWORK_DEVICES_MENU)
|
||||
TITLE:=Realtek Ethernet PHY driver
|
||||
KCONFIG:=CONFIG_REALTEK_PHY
|
||||
DEPENDS:=+kmod-libphy
|
||||
FILES:=$(LINUX_DIR)/drivers/net/phy/realtek.ko
|
||||
KCONFIG:=CONFIG_REALTEK_PHY \
|
||||
CONFIG_REALTEK_PHY_HWMON=y
|
||||
DEPENDS:=+kmod-libphy +kmod-hwmon-core
|
||||
FILES:=$(LINUX_DIR)/drivers/net/phy/realtek/realtek.ko
|
||||
AUTOLOAD:=$(call AutoLoad,18,realtek,1)
|
||||
endef
|
||||
|
||||
@ -959,7 +960,7 @@ $(eval $(call KernelPackage,8139cp))
|
||||
define KernelPackage/r8169
|
||||
SUBMENU:=$(NETWORK_DEVICES_MENU)
|
||||
TITLE:=RealTek RTL-8169 PCI Gigabit Ethernet Adapter kernel support
|
||||
DEPENDS:=@PCI_SUPPORT +kmod-mii +r8169-firmware +kmod-phy-realtek +kmod-mdio-devres +kmod-hwmon-core
|
||||
DEPENDS:=@PCI_SUPPORT +kmod-mii +r8169-firmware +kmod-phy-realtek +kmod-mdio-devres
|
||||
KCONFIG:= \
|
||||
CONFIG_R8169 \
|
||||
CONFIG_R8169_LEDS=y
|
||||
|
@ -65,8 +65,9 @@ function cpu_mask(cpu)
|
||||
return sprintf("%x", mask);
|
||||
}
|
||||
|
||||
function set_netdev_cpu(dev, cpu) {
|
||||
let queues = glob(`/sys/class/net/${dev}/queues/rx-*/rps_cpus`);
|
||||
function set_netdev_cpu(dev, cpu, rx_queue) {
|
||||
rx_queue ??= "rx-*";
|
||||
let queues = glob(`/sys/class/net/${dev}/queues/${rx_queue}/rps_cpus`);
|
||||
let val = cpu_mask(cpu);
|
||||
if (disable)
|
||||
val = 0;
|
||||
@ -76,7 +77,7 @@ function set_netdev_cpu(dev, cpu) {
|
||||
if (!do_nothing)
|
||||
writefile(queue, `${val}`);
|
||||
}
|
||||
queues = glob(`/sys/class/net/${dev}/queues/rx-*/rps_flow_cnt`);
|
||||
queues = glob(`/sys/class/net/${dev}/queues/${rx_queue}/rps_flow_cnt`);
|
||||
for (let queue in queues) {
|
||||
if (debug || do_nothing)
|
||||
warn(`echo ${local_flows} > ${queue}\n`);
|
||||
@ -160,6 +161,9 @@ for (let dev in netdevs) {
|
||||
netdev: [],
|
||||
phy: [],
|
||||
tasks: [],
|
||||
rx_tasks: [],
|
||||
rx_queues: map(glob(`/sys/class/net/${dev}/queues/rx-*/rps_cpus`),
|
||||
(v) => basename(dirname(v))),
|
||||
};
|
||||
}
|
||||
|
||||
@ -187,11 +191,51 @@ for (let path in glob("/proc/*/exe")) {
|
||||
continue;
|
||||
|
||||
push(dev.tasks, pid);
|
||||
|
||||
let napi_match = match(name, /napi\/([^-]*)-(\d+)/);
|
||||
if (napi_match && napi_match[2] > 0)
|
||||
push(dev.rx_tasks, pid);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function assign_dev_queues_cpu(dev) {
|
||||
let num = length(dev.rx_queues);
|
||||
if (num < length(dev.rx_tasks))
|
||||
num = length(dev.rx_tasks);
|
||||
|
||||
for (let i = 0; i < num; i++) {
|
||||
let cpu;
|
||||
|
||||
let task = dev.rx_tasks[i];
|
||||
if (num >= length(cpus))
|
||||
cpu = i % length(cpus);
|
||||
else if (task)
|
||||
cpu = get_next_cpu(napi_weight);
|
||||
else
|
||||
cpu = -1;
|
||||
set_task_cpu(task, cpu);
|
||||
|
||||
let rxq = dev.rx_queues[i];
|
||||
if (!rxq)
|
||||
continue;
|
||||
|
||||
if (num >= length(cpus))
|
||||
cpu = (i + 1) % length(cpus);
|
||||
else if (all_cpus)
|
||||
cpu = -1;
|
||||
else
|
||||
cpu = get_next_cpu(napi_weight, cpu);
|
||||
for (let netdev in dev.netdev)
|
||||
set_netdev_cpu(netdev, cpu, rxq);
|
||||
}
|
||||
}
|
||||
|
||||
function assign_dev_cpu(dev) {
|
||||
if (length(dev.rx_queues) > 1 &&
|
||||
length(dev.rx_tasks) > 1)
|
||||
return assign_dev_queues_cpu(dev);
|
||||
|
||||
if (length(dev.tasks) > 0) {
|
||||
let cpu = dev.napi_cpu = get_next_cpu(napi_weight);
|
||||
for (let task in dev.tasks)
|
||||
@ -204,7 +248,6 @@ function assign_dev_cpu(dev) {
|
||||
cpu = -1;
|
||||
else
|
||||
cpu = get_next_cpu(rx_weight, dev.napi_cpu);
|
||||
dev.rx_cpu = cpu;
|
||||
for (let netdev in dev.netdev)
|
||||
set_netdev_cpu(netdev, cpu);
|
||||
}
|
||||
|
@ -71,12 +71,22 @@ export function parse_encryption(config) {
|
||||
config.auth_type = 'eap2';
|
||||
break;
|
||||
|
||||
case 'psk-mixed':
|
||||
config.auth_type = "psk";
|
||||
break;
|
||||
|
||||
case 'psk3':
|
||||
config.auth_type = 'sae';
|
||||
break;
|
||||
|
||||
case 'psk3-mixed':
|
||||
case 'sae-mixed':
|
||||
config.auth_type = 'psk-sae';
|
||||
break;
|
||||
|
||||
case 'wpa':
|
||||
case 'wpa2':
|
||||
case 'wpa-mixed':
|
||||
config.auth_type = 'eap';
|
||||
break;
|
||||
}
|
||||
|
@ -13,9 +13,9 @@ PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE_URL=$(PROJECT_GIT)/project/uci.git
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_DATE:=2024-11-26
|
||||
PKG_SOURCE_VERSION:=10f7996ec29449915640acca5d65b592365a4b14
|
||||
PKG_MIRROR_HASH:=8556add0dd77b85a5702faa94feb811606390c045d7f5004317a4ab3e07f773b
|
||||
PKG_SOURCE_DATE:=2025-01-17
|
||||
PKG_SOURCE_VERSION:=fb3c2343b17b759b175f11aec5b3fbb1cf48bbc3
|
||||
PKG_MIRROR_HASH:=c9302f4a1cb400134cb9fc0622fb6a04bbe8c55bcc83ec454caadb1e62f3257e
|
||||
|
||||
PKG_LICENSE:=LGPL-2.1
|
||||
PKG_LICENSE_FILES:=
|
||||
@ -33,7 +33,7 @@ define Package/libuci
|
||||
CATEGORY:=Libraries
|
||||
TITLE:=C library for the Unified Configuration Interface (UCI)
|
||||
DEPENDS:=+libubox
|
||||
ABI_VERSION:=20130104
|
||||
ABI_VERSION:=20250117
|
||||
endef
|
||||
|
||||
define Package/uci
|
||||
|
44
package/utils/ucode-mod-pkgen/Makefile
Normal file
44
package/utils/ucode-mod-pkgen/Makefile
Normal file
@ -0,0 +1,44 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=ucode-mod-pkgen
|
||||
PKG_RELEASE:=1
|
||||
PKG_LICENSE:=GPL-2.0-or-later
|
||||
PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
include $(INCLUDE_DIR)/cmake.mk
|
||||
|
||||
CMAKE_INSTALL := 1
|
||||
|
||||
define Package/ucode-mod-pkgen
|
||||
SECTION:=utils
|
||||
CATEGORY:=Utilities
|
||||
TITLE:=ucode module for generating public keys/certificates
|
||||
DEPENDS:=+libucode +libmbedtls
|
||||
endef
|
||||
|
||||
define Package/ucode-mod-pkgen/description
|
||||
The pkgen module provides functionality for generating cryptographic keys and
|
||||
(self-)signed certificates. It supports exporting PEM/DER format files, as
|
||||
well as PKCS#12 bundle for client cert/key pairs with CA.
|
||||
endef
|
||||
|
||||
define Package/pkgen
|
||||
SECTION:=utils
|
||||
CATEGORY:=Utilities
|
||||
TITLE:=ucode script for generating public keys/certificates
|
||||
DEPENDS:=+ucode +ucode-mod-pkgen +ucode-mod-fs
|
||||
endef
|
||||
|
||||
define Package/ucode-mod-pkgen/install
|
||||
$(INSTALL_DIR) $(1)/usr/lib/ucode
|
||||
$(CP) $(PKG_INSTALL_DIR)/usr/lib/ucode/pkgen.so $(1)/usr/lib/ucode/
|
||||
endef
|
||||
|
||||
define Package/pkgen/install
|
||||
$(INSTALL_DIR) $(1)/usr/bin
|
||||
$(INSTALL_BIN) ./files/pkgen $(1)/usr/bin
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,ucode-mod-pkgen))
|
||||
$(eval $(call BuildPackage,pkgen))
|
252
package/utils/ucode-mod-pkgen/files/pkgen
Executable file
252
package/utils/ucode-mod-pkgen/files/pkgen
Executable file
@ -0,0 +1,252 @@
|
||||
#!/usr/bin/env ucode
|
||||
'use strict';
|
||||
|
||||
import { basename, readfile, writefile, stdin } from "fs";
|
||||
let pk = require("pkgen");
|
||||
let valid_from = "20240101000000";
|
||||
let valid_to = "21001231235959";
|
||||
let subject, password, password_stdin;
|
||||
let keytype = "ec";
|
||||
let keylen = 2048;
|
||||
let keyexp = 65537;
|
||||
let keycurve = "secp256r1";
|
||||
let no_ca;
|
||||
let legacy;
|
||||
|
||||
const usage_message = `Usage: ${basename(sourcepath())} [<options>] <command> [<arguments>]
|
||||
|
||||
Commands:
|
||||
ca <ca.pem>: Create a new CA.
|
||||
(creates ca.pem, ca.key, ca.serial)
|
||||
|
||||
cert <ca.pem> <cert.pem>: Create a new certificate/key using the CA
|
||||
from ca.pem. (creates cert.pem and ca.key)
|
||||
|
||||
cert_p12 <ca.pem> <cert.p12>: Create a new PKCS#12 certificate/key
|
||||
using the CA from ca.pem. (creates ca.p12)
|
||||
|
||||
selfsigned <cert.pem>: Create a self-signed certificate
|
||||
(creates cert.pem)
|
||||
|
||||
Options:
|
||||
-C <curve> Set EC curve type (default: ${keycurve})
|
||||
Possible values: secp521r1, secp384r1, secp256r1,
|
||||
secp256k1, secp224r1, secp224k1, secp192r1,
|
||||
secp192k1
|
||||
-E <exponent> Set RSA key exponent (default: ${keyexp})
|
||||
-L <len> Set RSA key length (default: ${keylen})
|
||||
-N Omit CA certificate for PKCS#12 files
|
||||
-p <password> Set PKCS#12 password to <password>
|
||||
-P Read PKCS#12 password from stdin
|
||||
(default: random password, printed to stdout)
|
||||
-s <name> Set subject for generated certificate to <name>.
|
||||
-t rsa|ec Set key type to rsa or ec (default: ec)
|
||||
-V <from> <to> Set validity for generated certificates.
|
||||
(default: ${valid_from} ${valid_to})
|
||||
-W Use weaker PKCS#12 encryption for
|
||||
compatibility with Windows and Apple systems
|
||||
|
||||
`;
|
||||
|
||||
function perror(msg) {
|
||||
let err = pk.errno() == -1 ? "Invalid arguments" : pk.error();
|
||||
warn(`${msg}: ${err}\n`);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
function usage() {
|
||||
warn(usage_message);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
function check_pem_path(pem_file) {
|
||||
if (substr(pem_file, -4) != ".pem") {
|
||||
warn(`Path with .pem extension expected\n`);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return pem_file;
|
||||
}
|
||||
|
||||
|
||||
function gen_key() {
|
||||
let key = pk.generate_key({
|
||||
type: keytype,
|
||||
curve: keycurve,
|
||||
size: keylen,
|
||||
exponent: keyexp,
|
||||
});
|
||||
|
||||
if (!key)
|
||||
perror("Failed to generate CA key");
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
function gen_cert(key, args) {
|
||||
let cert = pk.generate_cert({
|
||||
subject_name: subject,
|
||||
subject_key: key,
|
||||
validity: [ valid_from, valid_to ],
|
||||
...args
|
||||
});
|
||||
|
||||
if (!cert)
|
||||
perror("Failed to generate certificate");
|
||||
|
||||
cert = cert.pem();
|
||||
if (!cert)
|
||||
perror("Failed to complete certificate");
|
||||
|
||||
return cert;
|
||||
}
|
||||
|
||||
function gen_client_cert(ca_file, ca_data, key) {
|
||||
let ca_base = substr(ca_file, 0, -4);
|
||||
let ca_info = pk.cert_info(ca_data);
|
||||
if (!length(ca_info))
|
||||
perror("Failed to load CA certificate");
|
||||
|
||||
let ca_key = pk.load_key(readfile(ca_base + ".key"));
|
||||
if (!ca_key)
|
||||
perror("Failed to load CA key");
|
||||
let ca_serial = +readfile(ca_base + ".serial");
|
||||
if (!ca_serial)
|
||||
perror("Failed to load CA serial");
|
||||
|
||||
let cert = gen_cert(key, {
|
||||
serial: ++ca_serial,
|
||||
issuer_name: ca_info[0].subject,
|
||||
issuer_key: ca_key,
|
||||
});
|
||||
writefile(ca_base + ".serial", "" + ca_serial);
|
||||
|
||||
return cert;
|
||||
}
|
||||
|
||||
let cmds = {
|
||||
ca: function(args) {
|
||||
let ca_file = check_pem_path(shift(args));
|
||||
let ca_base = substr(ca_file, 0, -4);
|
||||
|
||||
let key = gen_key();
|
||||
let ca_cert = gen_cert(key, {
|
||||
ca: true,
|
||||
serial: 1,
|
||||
issuer_name: subject,
|
||||
issuer_key: key,
|
||||
key_usage: [ "key_cert_sign" ],
|
||||
});
|
||||
|
||||
writefile(ca_file, ca_cert);
|
||||
writefile(ca_base + ".key", key.pem());
|
||||
writefile(ca_base + ".serial", "1");
|
||||
},
|
||||
|
||||
cert: function (args) {
|
||||
let ca_file = check_pem_path(shift(args));
|
||||
let crt_file = check_pem_path(shift(args));
|
||||
let crt_base = substr(crt_file, 0, -4);
|
||||
|
||||
let key = gen_key();
|
||||
let ca_data = readfile(ca_file);
|
||||
let cert = gen_client_cert(ca_file, ca_data, key);
|
||||
|
||||
writefile(crt_base + ".key", key.pem());
|
||||
writefile(crt_file, cert);
|
||||
},
|
||||
|
||||
cert_p12: function (args) {
|
||||
let ca_file = check_pem_path(shift(args));
|
||||
let p12_file = shift(args);
|
||||
if (!p12_file)
|
||||
usage();
|
||||
|
||||
let key = gen_key();
|
||||
let ca_data = readfile(ca_file);
|
||||
let cert = gen_client_cert(ca_file, ca_data, key);
|
||||
|
||||
if (password_stdin)
|
||||
password = rtrim(stdin.read("line"));
|
||||
else if (!password)
|
||||
print((password = hexenc(readfile("/dev/urandom", 8))) + "\n");
|
||||
|
||||
let p12 = pk.generate_pkcs12({
|
||||
password, cert, key, legacy,
|
||||
extra: no_ca ? null : [ ca_data ],
|
||||
});
|
||||
|
||||
writefile(p12_file, p12);
|
||||
},
|
||||
|
||||
selfsigned: function(args) {
|
||||
let crt_file = check_pem_path(shift(args));
|
||||
let crt_base = substr(crt_file, 0, -4);
|
||||
|
||||
let key = gen_key();
|
||||
let cert = gen_cert(key, {
|
||||
serial: 1,
|
||||
issuer_name: subject,
|
||||
issuer_key: key,
|
||||
});
|
||||
|
||||
writefile(crt_base + ".key", key.pem());
|
||||
writefile(crt_file, cert);
|
||||
},
|
||||
};
|
||||
|
||||
while (substr(ARGV[0], 0, 1) == "-") {
|
||||
let opt = substr(shift(ARGV), 1);
|
||||
switch (opt) {
|
||||
case 'C':
|
||||
keycurve = shift(ARGV);
|
||||
break;
|
||||
case 'L':
|
||||
keylen = +shift(ARGV);
|
||||
break;
|
||||
case 'N':
|
||||
no_ca = true;
|
||||
break;
|
||||
case 'p':
|
||||
password = shift(ARGV);
|
||||
if (password_stdin)
|
||||
usage();
|
||||
break;
|
||||
case 'P':
|
||||
password_stdin = true;
|
||||
if (password)
|
||||
usage();
|
||||
break;
|
||||
case 's':
|
||||
subject = shift(ARGV);
|
||||
break;
|
||||
case 't':
|
||||
keytype = shift(ARGV);
|
||||
if (keytype != "rsa" && keytype != "ec") {
|
||||
warn(`Unsupported key type ${keytype}\n`);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 'V':
|
||||
valid_from = shift(ARGV);
|
||||
valid_to = shift(ARGV);
|
||||
break;
|
||||
case 'W':
|
||||
legacy = true;
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
let cmd = shift(ARGV);
|
||||
if (!cmd || !cmds[cmd])
|
||||
usage();
|
||||
|
||||
if (subject == null) {
|
||||
warn(`Missing -s option\n`);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
cmds[cmd](ARGV);
|
35
package/utils/ucode-mod-pkgen/src/CMakeLists.txt
Normal file
35
package/utils/ucode-mod-pkgen/src/CMakeLists.txt
Normal file
@ -0,0 +1,35 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
|
||||
PROJECT(ucode-pkgen C)
|
||||
ADD_DEFINITIONS(-Os -ggdb -Wall -Werror --std=gnu99 -ffunction-sections -fwrapv -D_GNU_SOURCE)
|
||||
|
||||
IF(CMAKE_C_COMPILER_VERSION VERSION_GREATER 6)
|
||||
ADD_DEFINITIONS(-Wextra -Werror=implicit-function-declaration)
|
||||
ADD_DEFINITIONS(-Wformat -Werror=format-security -Werror=format-nonliteral)
|
||||
ENDIF()
|
||||
ADD_DEFINITIONS(-Wmissing-declarations -Wno-error=unused-variable -Wno-unused-parameter)
|
||||
|
||||
IF(APPLE)
|
||||
SET(UCODE_MODULE_LINK_OPTIONS "LINKER:-undefined,dynamic_lookup")
|
||||
ELSE()
|
||||
SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "-Wl,--gc-sections")
|
||||
ENDIF()
|
||||
|
||||
IF(DEBUG)
|
||||
ADD_DEFINITIONS(-DDEBUG -g3 -O0)
|
||||
ELSE()
|
||||
ADD_DEFINITIONS(-DNDEBUG)
|
||||
ENDIF()
|
||||
|
||||
FIND_LIBRARY(mbedtls NAMES mbedtls)
|
||||
FIND_LIBRARY(ucode NAMES ucode)
|
||||
FIND_PATH(mbedtls_include_dir NAMES mbedtls/pk.h)
|
||||
FIND_PATH(ucode_include_dir NAMES ucode/module.h)
|
||||
INCLUDE_DIRECTORIES(${mbedtls_include_dir} ${ucode_include_dir})
|
||||
|
||||
ADD_LIBRARY(pkgen_lib MODULE ucode.c pkcs12.c)
|
||||
SET_TARGET_PROPERTIES(pkgen_lib PROPERTIES OUTPUT_NAME pkgen PREFIX "")
|
||||
TARGET_LINK_OPTIONS(pkgen_lib PRIVATE ${UCODE_MODULE_LINK_OPTIONS})
|
||||
TARGET_LINK_LIBRARIES(pkgen_lib ${mbedtls})
|
||||
|
||||
INSTALL(TARGETS pkgen_lib LIBRARY DESTINATION lib/ucode)
|
45
package/utils/ucode-mod-pkgen/src/pk.h
Normal file
45
package/utils/ucode-mod-pkgen/src/pk.h
Normal file
@ -0,0 +1,45 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* Copyright (C) 2024 Felix Fietkau <nbd@nbd.name>
|
||||
*/
|
||||
#ifndef __UCODE_PK_H
|
||||
#define __UCODE_PK_H
|
||||
|
||||
#include <ucode/lib.h>
|
||||
#include <ucode/vm.h>
|
||||
|
||||
#include <mbedtls/bignum.h>
|
||||
#include <mbedtls/pk.h>
|
||||
#include <mbedtls/oid.h>
|
||||
#include <mbedtls/error.h>
|
||||
#include <mbedtls/version.h>
|
||||
|
||||
#if MBEDTLS_VERSION_MAJOR < 3
|
||||
#define MBEDTLS_LEGACY
|
||||
#endif
|
||||
|
||||
int random_cb(void *ctx, unsigned char *out, size_t len);
|
||||
uc_value_t *uc_generate_pkcs12(uc_vm_t *vm, size_t nargs);
|
||||
int64_t get_int_arg(uc_value_t *obj, const char *key, int64_t defval);
|
||||
extern int mbedtls_errno;
|
||||
extern char buf[32 * 1024];
|
||||
|
||||
#define C(ret) \
|
||||
({ \
|
||||
int __ret = (ret); \
|
||||
mbedtls_errno = __ret < 0 ? __ret : 0; \
|
||||
__ret; \
|
||||
})
|
||||
|
||||
#define CHECK(ret) do { \
|
||||
if (C(ret) < 0) \
|
||||
return NULL; \
|
||||
} while (0)
|
||||
#define CHECK_INT(ret) do { \
|
||||
if (C(ret) < 0) \
|
||||
return -1; \
|
||||
} while (0)
|
||||
|
||||
#define INVALID_ARG() do { C(-1); return NULL; } while (0)
|
||||
|
||||
#endif
|
612
package/utils/ucode-mod-pkgen/src/pkcs12.c
Normal file
612
package/utils/ucode-mod-pkgen/src/pkcs12.c
Normal file
@ -0,0 +1,612 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* Copyright (C) 2024 Felix Fietkau <nbd@nbd.name>
|
||||
*/
|
||||
#include "pk.h"
|
||||
#include <mbedtls/x509_crt.h>
|
||||
#include <mbedtls/ecp.h>
|
||||
#include <mbedtls/rsa.h>
|
||||
#include <mbedtls/asn1write.h>
|
||||
#include <mbedtls/pkcs5.h>
|
||||
#include <mbedtls/pkcs12.h>
|
||||
#include <mbedtls/base64.h>
|
||||
#include <mbedtls/sha1.h>
|
||||
|
||||
#define OID_TAG(n) MBEDTLS_OID_##n, MBEDTLS_OID_SIZE(MBEDTLS_OID_##n)
|
||||
|
||||
#ifndef MBEDTLS_OID_AES_256_CBC
|
||||
#define MBEDTLS_OID_AES_256_CBC MBEDTLS_OID_AES "\x2a"
|
||||
#endif
|
||||
|
||||
#define MBEDTLS_OID_PKCS9_LOCAL_KEY_ID MBEDTLS_OID_PKCS9 "\x15"
|
||||
#define MBEDTLS_OID_PKCS9_CERT_TYPE MBEDTLS_OID_PKCS9 "\x16"
|
||||
#define MBEDTLS_OID_PKCS9_CERT_TYPE_X509 MBEDTLS_OID_PKCS9_CERT_TYPE "\x01"
|
||||
|
||||
#define MBEDTLS_OID_PKCS12_KEY_BAG MBEDTLS_OID_PKCS12 "\x0a\x01\x01"
|
||||
#define MBEDTLS_OID_PKCS12_SHROUDED_KEY_BAG MBEDTLS_OID_PKCS12 "\x0a\x01\x02"
|
||||
#define MBEDTLS_OID_PKCS12_CERT_BAG MBEDTLS_OID_PKCS12 "\x0a\x01\x03"
|
||||
|
||||
#ifndef MBEDTLS_OID_PKCS7
|
||||
#define MBEDTLS_OID_PKCS7 MBEDTLS_OID_PKCS "\x07"
|
||||
#define MBEDTLS_OID_PKCS7_DATA MBEDTLS_OID_PKCS7 "\x01"
|
||||
#define MBEDTLS_OID_PKCS7_ENCRYPTED_DATA MBEDTLS_OID_PKCS7 "\x06"
|
||||
#endif
|
||||
|
||||
#define NUM_ITER 2048
|
||||
#define SALT_LEN 16
|
||||
#define IV_LEN 16
|
||||
#define IV_LEN_LEGACY 8
|
||||
#define KEY_LEN 32
|
||||
#define CERT_HASH_LEN 20
|
||||
|
||||
#define CONTEXT_TAG(n) (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | (n))
|
||||
#define SEQUENCE_TAG (MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)
|
||||
#define SET_TAG (MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET)
|
||||
|
||||
#define CTX_ADD(ctx, n) \
|
||||
do { \
|
||||
int __n = (n); \
|
||||
if ((ctx)->p - (ctx)->start <= __n) \
|
||||
return -1; \
|
||||
(ctx)->p -= __n; \
|
||||
} while (0)
|
||||
|
||||
struct pkcs12_ctx {
|
||||
uint8_t *p, *start;
|
||||
|
||||
uint8_t cert_hash[20];
|
||||
uint8_t *key_cert_hash;
|
||||
|
||||
uint8_t salt[SALT_LEN];
|
||||
uint8_t iv[IV_LEN];
|
||||
|
||||
const char *password;
|
||||
uint8_t *pwd;
|
||||
size_t pwd_len;
|
||||
|
||||
bool legacy;
|
||||
};
|
||||
|
||||
#ifdef MBEDTLS_LEGACY
|
||||
static inline int
|
||||
mbedtls_pkcs5_pbkdf2_hmac_ext(mbedtls_md_type_t md_alg, const unsigned char *password,
|
||||
size_t plen, const unsigned char *salt, size_t slen,
|
||||
unsigned int iteration_count,
|
||||
uint32_t key_length, unsigned char *output)
|
||||
{
|
||||
mbedtls_md_context_t md_ctx;
|
||||
const mbedtls_md_info_t *md_info;
|
||||
int ret;
|
||||
|
||||
md_info = mbedtls_md_info_from_type(md_alg);
|
||||
if (!md_info)
|
||||
return MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE;
|
||||
|
||||
mbedtls_md_init(&md_ctx);
|
||||
ret = mbedtls_md_setup(&md_ctx, md_info, 1);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
ret = mbedtls_pkcs5_pbkdf2_hmac(&md_ctx, password, plen, salt, slen,
|
||||
iteration_count, key_length, output);
|
||||
|
||||
out:
|
||||
mbedtls_md_free(&md_ctx);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
uc_p12_add_tag(struct pkcs12_ctx *ctx, uint8_t *end, uint8_t tag)
|
||||
{
|
||||
mbedtls_asn1_write_len(&ctx->p, ctx->start, end - ctx->p);
|
||||
mbedtls_asn1_write_tag(&ctx->p, ctx->start, tag);
|
||||
}
|
||||
|
||||
static void
|
||||
uc_p12_add_sequence(struct pkcs12_ctx *ctx, uint8_t *end)
|
||||
{
|
||||
uc_p12_add_tag(ctx, end, SEQUENCE_TAG);
|
||||
}
|
||||
|
||||
static void
|
||||
uc_p12_add_algo(struct pkcs12_ctx *ctx, const char *oid, size_t oid_len, size_t par_len)
|
||||
{
|
||||
mbedtls_asn1_write_algorithm_identifier(&ctx->p, ctx->start, oid, oid_len, par_len);
|
||||
}
|
||||
|
||||
static void
|
||||
uc_p12_add_attribute(struct pkcs12_ctx *ctx, uint8_t *end, const char *oid, size_t oid_len)
|
||||
{
|
||||
uc_p12_add_tag(ctx, end, SET_TAG);
|
||||
mbedtls_asn1_write_oid(&ctx->p, ctx->start, oid, oid_len);
|
||||
uc_p12_add_sequence(ctx, end);
|
||||
}
|
||||
|
||||
static void
|
||||
uc_p12_add_localkeyid(struct pkcs12_ctx *ctx, bool key)
|
||||
{
|
||||
uint8_t *end = ctx->p;
|
||||
|
||||
ctx->p -= CERT_HASH_LEN;
|
||||
if (key)
|
||||
ctx->key_cert_hash = ctx->p;
|
||||
else if (ctx->key_cert_hash)
|
||||
memcpy(ctx->p, ctx->key_cert_hash, CERT_HASH_LEN);
|
||||
uc_p12_add_tag(ctx, end, MBEDTLS_ASN1_OCTET_STRING);
|
||||
uc_p12_add_attribute(ctx, end, OID_TAG(PKCS9_LOCAL_KEY_ID));
|
||||
}
|
||||
|
||||
static void
|
||||
uc_p12_add_bag(struct pkcs12_ctx *ctx, uint8_t *data_end, uint8_t *end, const char *oid, size_t oid_len)
|
||||
{
|
||||
uc_p12_add_tag(ctx, data_end, CONTEXT_TAG(0));
|
||||
mbedtls_asn1_write_oid(&ctx->p, ctx->start, oid, oid_len);
|
||||
uc_p12_add_sequence(ctx, end);
|
||||
}
|
||||
|
||||
static int
|
||||
uc_p12_enc_setup(struct pkcs12_ctx *ctx, mbedtls_cipher_context_t *cipher)
|
||||
{
|
||||
const mbedtls_cipher_info_t *cipher_info;
|
||||
uint8_t key[KEY_LEN];
|
||||
int ret;
|
||||
|
||||
random_cb(NULL, ctx->iv, IV_LEN);
|
||||
ret = mbedtls_pkcs5_pbkdf2_hmac_ext(MBEDTLS_MD_SHA256,
|
||||
(void *)ctx->password, strlen(ctx->password),
|
||||
ctx->salt, SALT_LEN, NUM_ITER,
|
||||
KEY_LEN, key);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
cipher_info = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_256_CBC);
|
||||
ret = mbedtls_cipher_setup(cipher, cipher_info);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return mbedtls_cipher_setkey(cipher, key, 8 * KEY_LEN, MBEDTLS_ENCRYPT);
|
||||
}
|
||||
|
||||
static int
|
||||
uc_p12_enc_legacy(struct pkcs12_ctx *ctx, mbedtls_cipher_context_t *cipher)
|
||||
{
|
||||
const mbedtls_cipher_info_t *cipher_info;
|
||||
uint8_t key[24];
|
||||
int ret;
|
||||
|
||||
ret = mbedtls_pkcs12_derivation(key, sizeof(key), ctx->pwd, ctx->pwd_len,
|
||||
ctx->salt, SALT_LEN, MBEDTLS_MD_SHA1,
|
||||
MBEDTLS_PKCS12_DERIVE_KEY, NUM_ITER);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = mbedtls_pkcs12_derivation(ctx->iv, IV_LEN_LEGACY, ctx->pwd, ctx->pwd_len,
|
||||
ctx->salt, SALT_LEN, MBEDTLS_MD_SHA1,
|
||||
MBEDTLS_PKCS12_DERIVE_IV, NUM_ITER);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
cipher_info = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_DES_EDE3_CBC);
|
||||
ret = mbedtls_cipher_setup(cipher, cipher_info);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return mbedtls_cipher_setkey(cipher, key, 8 * sizeof(key), MBEDTLS_ENCRYPT);
|
||||
}
|
||||
|
||||
static int
|
||||
uc_p12_encrypt(struct pkcs12_ctx *ctx, uint8_t *end)
|
||||
{
|
||||
mbedtls_cipher_context_t cipher;
|
||||
size_t iv_len = ctx->legacy ? IV_LEN_LEGACY : IV_LEN;
|
||||
size_t out_len = 0;
|
||||
int ret;
|
||||
|
||||
random_cb(NULL, ctx->salt, SALT_LEN);
|
||||
|
||||
if (ctx->legacy)
|
||||
ret = uc_p12_enc_legacy(ctx, &cipher);
|
||||
else
|
||||
ret = uc_p12_enc_setup(ctx, &cipher);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
ret = mbedtls_cipher_set_padding_mode(&cipher, MBEDTLS_PADDING_PKCS7);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
ret = mbedtls_cipher_crypt(&cipher, ctx->iv, iv_len, ctx->p, end - ctx->p,
|
||||
(void *)buf, &out_len);
|
||||
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
CTX_ADD(ctx, out_len - (end - ctx->p));
|
||||
memcpy(ctx->p, buf, out_len);
|
||||
uc_p12_add_tag(ctx, end, MBEDTLS_ASN1_OCTET_STRING);
|
||||
|
||||
out:
|
||||
mbedtls_cipher_free(&cipher);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
uc_p12_add_enc_params(struct pkcs12_ctx *ctx)
|
||||
{
|
||||
uint8_t *par_end = ctx->p;
|
||||
uint8_t *kdf_end;
|
||||
|
||||
if (ctx->legacy) {
|
||||
mbedtls_asn1_write_int(&ctx->p, ctx->start, NUM_ITER);
|
||||
|
||||
CTX_ADD(ctx, SALT_LEN);
|
||||
memcpy(ctx->p, ctx->salt, SALT_LEN);
|
||||
uc_p12_add_tag(ctx, ctx->p + SALT_LEN, MBEDTLS_ASN1_OCTET_STRING);
|
||||
|
||||
uc_p12_add_sequence(ctx, par_end);
|
||||
|
||||
uc_p12_add_algo(ctx, OID_TAG(PKCS12_PBE_SHA1_DES3_EDE_CBC), par_end - ctx->p);
|
||||
} else {
|
||||
CTX_ADD(ctx, IV_LEN);
|
||||
memcpy(ctx->p, ctx->iv, IV_LEN);
|
||||
|
||||
uc_p12_add_tag(ctx, par_end, MBEDTLS_ASN1_OCTET_STRING);
|
||||
uc_p12_add_algo(ctx, OID_TAG(AES_256_CBC), par_end - ctx->p);
|
||||
|
||||
kdf_end = ctx->p;
|
||||
uc_p12_add_algo(ctx, OID_TAG(HMAC_SHA256), 0);
|
||||
mbedtls_asn1_write_int(&ctx->p, ctx->start, NUM_ITER);
|
||||
CTX_ADD(ctx, SALT_LEN);
|
||||
memcpy(ctx->p, ctx->salt, SALT_LEN);
|
||||
uc_p12_add_tag(ctx, ctx->p + SALT_LEN, MBEDTLS_ASN1_OCTET_STRING);
|
||||
uc_p12_add_sequence(ctx, kdf_end);
|
||||
|
||||
uc_p12_add_algo(ctx, OID_TAG(PKCS5_PBKDF2), kdf_end - ctx->p);
|
||||
uc_p12_add_sequence(ctx, par_end);
|
||||
|
||||
uc_p12_add_algo(ctx, OID_TAG(PKCS5_PBES2), par_end - ctx->p);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
uc_p12_add_cert(struct pkcs12_ctx *ctx, uc_value_t *arg, bool ca)
|
||||
{
|
||||
const char *str = ucv_string_get(arg), *str_end;
|
||||
uint8_t *bag_end, *end;
|
||||
size_t len;
|
||||
int ret;
|
||||
|
||||
#define START_TAG "-----BEGIN CERTIFICATE-----"
|
||||
#define END_TAG "-----END CERTIFICATE-----"
|
||||
|
||||
if (!str)
|
||||
return -1;
|
||||
|
||||
str = strstr(str, START_TAG);
|
||||
if (!str)
|
||||
return -1;
|
||||
|
||||
str += sizeof(START_TAG);
|
||||
str_end = strstr(str, END_TAG);
|
||||
if (!str_end)
|
||||
return -1;
|
||||
|
||||
if ((size_t)(str_end - str) > sizeof(buf) / 2)
|
||||
return -1;
|
||||
|
||||
ret = mbedtls_base64_decode((void *)buf, sizeof(buf) / 2, &len,
|
||||
(const void *)str, str_end - str);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
bag_end = ctx->p;
|
||||
if (!ca && ctx->key_cert_hash) {
|
||||
mbedtls_sha1((const void *)buf, len, ctx->key_cert_hash);
|
||||
uc_p12_add_localkeyid(ctx, false);
|
||||
uc_p12_add_tag(ctx, bag_end, SET_TAG);
|
||||
}
|
||||
|
||||
end = ctx->p;
|
||||
CTX_ADD(ctx, len);
|
||||
memcpy(ctx->p, buf, len);
|
||||
uc_p12_add_tag(ctx, end, MBEDTLS_ASN1_OCTET_STRING);
|
||||
|
||||
/* CertBag */
|
||||
uc_p12_add_tag(ctx, end, CONTEXT_TAG(0));
|
||||
mbedtls_asn1_write_oid(&ctx->p, ctx->start, OID_TAG(PKCS9_CERT_TYPE_X509));
|
||||
uc_p12_add_sequence(ctx, end);
|
||||
|
||||
uc_p12_add_bag(ctx, end, bag_end, OID_TAG(PKCS12_CERT_BAG));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
uc_p12_add_key(struct pkcs12_ctx *ctx, uc_value_t *arg)
|
||||
{
|
||||
mbedtls_pk_context *pk = ucv_resource_data(arg, "mbedtls.pk");
|
||||
uint8_t *bag_end, *end;
|
||||
uint8_t *param = NULL;
|
||||
size_t param_len = 0;
|
||||
const char *oid;
|
||||
size_t oid_len = 0;
|
||||
int ret, len;
|
||||
|
||||
if (!pk)
|
||||
return -1;
|
||||
|
||||
bag_end = ctx->p;
|
||||
uc_p12_add_localkeyid(ctx, true);
|
||||
uc_p12_add_tag(ctx, bag_end, SET_TAG);
|
||||
|
||||
end = ctx->p;
|
||||
len = mbedtls_pk_write_key_der(pk, (void *)ctx->start, end - ctx->start);
|
||||
if (len < 0)
|
||||
return len;
|
||||
|
||||
ctx->p -= len;
|
||||
|
||||
/* Convert EC key contents to PKCS#8 style */
|
||||
if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_ECKEY) {
|
||||
mbedtls_ecp_group_id grp_id;
|
||||
mbedtls_asn1_buf tag_buf;
|
||||
uint8_t *pkey_start, *pkey_end;
|
||||
size_t seq_len, pkey_len, param_tag_len;
|
||||
uint8_t *p = ctx->p;
|
||||
uint8_t *_end = end;
|
||||
uint8_t *_start;
|
||||
int version;
|
||||
|
||||
ret = mbedtls_asn1_get_tag(&p, end, &seq_len, SEQUENCE_TAG);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
_start = p;
|
||||
_end = p + seq_len;
|
||||
ret = mbedtls_asn1_get_int(&p, _end, &version);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* private key */
|
||||
ret = mbedtls_asn1_get_tag(&p, _end, &pkey_len, MBEDTLS_ASN1_OCTET_STRING);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
pkey_start = p;
|
||||
p += pkey_len;
|
||||
pkey_end = p;
|
||||
|
||||
/* parameters */
|
||||
ret = mbedtls_asn1_get_tag(&p, _end, ¶m_len, CONTEXT_TAG(0));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
param = memcpy(buf, p, param_len);
|
||||
p += param_len;
|
||||
|
||||
/* overwrite parameters */
|
||||
param_tag_len = p - pkey_end;
|
||||
ctx->p += param_tag_len;
|
||||
_start += param_tag_len;
|
||||
memmove(ctx->p, ctx->p - param_tag_len, p - ctx->p);
|
||||
|
||||
/* replace sequence tag */
|
||||
ctx->p = _start;
|
||||
uc_p12_add_sequence(ctx, end);
|
||||
|
||||
/* check for Curve25519 or Curve448 */
|
||||
tag_buf = (mbedtls_asn1_buf){
|
||||
.p = (uint8_t *)buf,
|
||||
.len = param_len,
|
||||
};
|
||||
tag_buf.tag = *tag_buf.p;
|
||||
ret = mbedtls_asn1_get_tag(&tag_buf.p, tag_buf.p + param_len, &tag_buf.len, tag_buf.tag);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
oid = MBEDTLS_OID_EC_ALG_UNRESTRICTED;
|
||||
oid_len = MBEDTLS_OID_SIZE(MBEDTLS_OID_EC_ALG_UNRESTRICTED);
|
||||
|
||||
#ifdef MBEDTLS_LEGACY
|
||||
(void)pkey_start;
|
||||
(void)grp_id;
|
||||
#else
|
||||
ret = mbedtls_oid_get_ec_grp_algid(&tag_buf, &grp_id);
|
||||
if (!ret && (grp_id == MBEDTLS_ECP_DP_CURVE25519 ||
|
||||
grp_id == MBEDTLS_ECP_DP_CURVE448)) {
|
||||
ctx->p = end - pkey_len;
|
||||
memmove(ctx->p, pkey_start, pkey_len);
|
||||
uc_p12_add_tag(ctx, end, MBEDTLS_ASN1_OCTET_STRING);
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
mbedtls_oid_get_oid_by_pk_alg(mbedtls_pk_get_type(pk), &oid, &oid_len);
|
||||
}
|
||||
|
||||
uc_p12_add_tag(ctx, end, MBEDTLS_ASN1_OCTET_STRING);
|
||||
|
||||
/* KeyBag */
|
||||
if (param_len) {
|
||||
CTX_ADD(ctx, param_len);
|
||||
memcpy(ctx->p, param, param_len);
|
||||
}
|
||||
uc_p12_add_algo(ctx, oid, oid_len, param_len);
|
||||
mbedtls_asn1_write_int(&ctx->p, ctx->start, 0);
|
||||
uc_p12_add_sequence(ctx, end);
|
||||
|
||||
ret = uc_p12_encrypt(ctx, end);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = uc_p12_add_enc_params(ctx);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
uc_p12_add_sequence(ctx, end);
|
||||
|
||||
uc_p12_add_bag(ctx, end, bag_end, OID_TAG(PKCS12_SHROUDED_KEY_BAG));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
uc_p12_add_authsafe(struct pkcs12_ctx *ctx, uc_value_t *arg)
|
||||
{
|
||||
uc_value_t *extra;
|
||||
uint8_t *end = ctx->p;
|
||||
size_t len;
|
||||
int ret;
|
||||
|
||||
/* authSafe contents */
|
||||
extra = ucv_object_get(arg, "extra", NULL);
|
||||
if (extra) {
|
||||
size_t len;
|
||||
|
||||
if (ucv_type(extra) != UC_ARRAY)
|
||||
return -1;
|
||||
|
||||
len = ucv_array_length(extra);
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
ret = uc_p12_add_cert(ctx, ucv_array_get(extra, i), true);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
ret = uc_p12_add_key(ctx, ucv_object_get(arg, "key", NULL));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = uc_p12_add_cert(ctx, ucv_object_get(arg, "cert", NULL), false);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* encrypted */
|
||||
uc_p12_add_sequence(ctx, end);
|
||||
|
||||
ret = uc_p12_encrypt(ctx, end);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
uc_p12_add_tag(ctx, end, CONTEXT_TAG(0));
|
||||
|
||||
ret = uc_p12_add_enc_params(ctx);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
mbedtls_asn1_write_oid(&ctx->p, ctx->start, OID_TAG(PKCS7_DATA));
|
||||
uc_p12_add_sequence(ctx, end);
|
||||
|
||||
mbedtls_asn1_write_int(&ctx->p, ctx->start, 0);
|
||||
uc_p12_add_sequence(ctx, end);
|
||||
uc_p12_add_tag(ctx, end, CONTEXT_TAG(0));
|
||||
mbedtls_asn1_write_oid(&ctx->p, ctx->start, OID_TAG(PKCS7_ENCRYPTED_DATA));
|
||||
uc_p12_add_sequence(ctx, end);
|
||||
|
||||
/* authSafe contents */
|
||||
uc_p12_add_sequence(ctx, end);
|
||||
|
||||
/* authSafe header */
|
||||
len = end - ctx->p;
|
||||
uc_p12_add_tag(ctx, end, MBEDTLS_ASN1_OCTET_STRING);
|
||||
uc_p12_add_tag(ctx, end, CONTEXT_TAG(0));
|
||||
mbedtls_asn1_write_oid(&ctx->p, ctx->start, OID_TAG(PKCS7_DATA));
|
||||
uc_p12_add_sequence(ctx, end);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static void *
|
||||
uc_p12_add_mac_digest_info(struct pkcs12_ctx *ctx)
|
||||
{
|
||||
uint8_t *end = ctx->p;
|
||||
size_t len = 20;
|
||||
|
||||
ctx->p -= len;
|
||||
uc_p12_add_tag(ctx, end, MBEDTLS_ASN1_OCTET_STRING);
|
||||
uc_p12_add_algo(ctx, OID_TAG(DIGEST_ALG_SHA1), 0);
|
||||
uc_p12_add_sequence(ctx, end);
|
||||
|
||||
return end - len;
|
||||
}
|
||||
|
||||
uc_value_t *uc_generate_pkcs12(uc_vm_t *vm, size_t nargs)
|
||||
{
|
||||
uc_value_t *arg = uc_fn_arg(0), *pwd_arg;
|
||||
mbedtls_md_context_t hmac;
|
||||
uint8_t *end = (uint8_t *)&buf[sizeof(buf)];
|
||||
struct pkcs12_ctx ctx = {
|
||||
.start = (uint8_t *)&buf[sizeof(buf) / 2],
|
||||
.p = end,
|
||||
};
|
||||
uint8_t *hash, *data;
|
||||
uint8_t key[20], *salt;
|
||||
size_t salt_len = 8;
|
||||
int data_len;
|
||||
uc_value_t *ret = NULL;
|
||||
const char *passwd;
|
||||
|
||||
if (ucv_type(arg) != UC_OBJECT)
|
||||
INVALID_ARG();
|
||||
|
||||
ctx.legacy = ucv_is_truish(ucv_object_get(arg, "legacy", NULL));
|
||||
|
||||
mbedtls_md_init(&hmac);
|
||||
pwd_arg = ucv_object_get(arg, "password", NULL);
|
||||
passwd = ucv_string_get(pwd_arg);
|
||||
if (!passwd)
|
||||
INVALID_ARG();
|
||||
|
||||
/* password is expected to be a UTF-16 string */
|
||||
ctx.password = passwd;
|
||||
ctx.pwd_len = 2 * strlen(passwd) + 2;
|
||||
ctx.pwd = malloc(ctx.pwd_len);
|
||||
for (size_t i = 0; i < ctx.pwd_len; i += 2) {
|
||||
ctx.pwd[i] = 0;
|
||||
ctx.pwd[i + 1] = passwd[i / 2];
|
||||
}
|
||||
|
||||
/* MacData */
|
||||
mbedtls_asn1_write_int(&ctx.p, ctx.start, NUM_ITER);
|
||||
|
||||
ctx.p -= salt_len;
|
||||
salt = ctx.p;
|
||||
random_cb(NULL, salt, salt_len);
|
||||
uc_p12_add_tag(&ctx, salt + salt_len, MBEDTLS_ASN1_OCTET_STRING);
|
||||
|
||||
hash = uc_p12_add_mac_digest_info(&ctx);
|
||||
uc_p12_add_sequence(&ctx, end);
|
||||
|
||||
data = ctx.p;
|
||||
data_len = uc_p12_add_authsafe(&ctx, arg);
|
||||
if (C(data_len) < 0)
|
||||
goto out;
|
||||
data -= data_len;
|
||||
|
||||
mbedtls_asn1_write_int(&ctx.p, ctx.start, 3);
|
||||
uc_p12_add_sequence(&ctx, end);
|
||||
|
||||
if (C(mbedtls_pkcs12_derivation(key, sizeof(key), ctx.pwd, ctx.pwd_len,
|
||||
salt, salt_len, MBEDTLS_MD_SHA1,
|
||||
MBEDTLS_PKCS12_DERIVE_MAC_KEY, NUM_ITER)))
|
||||
goto out;
|
||||
|
||||
if (C(mbedtls_md_setup(&hmac, mbedtls_md_info_from_type(MBEDTLS_MD_SHA1), 1)))
|
||||
goto out;
|
||||
if (C(mbedtls_md_hmac_starts(&hmac, key, sizeof(key))))
|
||||
goto out;
|
||||
if (C(mbedtls_md_hmac_update(&hmac, data, data_len)))
|
||||
goto out;
|
||||
if (C(mbedtls_md_hmac_finish(&hmac, hash)))
|
||||
goto out;
|
||||
|
||||
ret = ucv_string_new_length((char *)ctx.p, end - ctx.p);
|
||||
|
||||
out:
|
||||
free(ctx.pwd);
|
||||
mbedtls_md_free(&hmac);
|
||||
return ret;
|
||||
}
|
598
package/utils/ucode-mod-pkgen/src/ucode.c
Normal file
598
package/utils/ucode-mod-pkgen/src/ucode.c
Normal file
@ -0,0 +1,598 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* Copyright (C) 2024 Felix Fietkau <nbd@nbd.name>
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#include <sys/random.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <limits.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <mbedtls/entropy.h>
|
||||
#include <mbedtls/x509_crt.h>
|
||||
#include <mbedtls/ecp.h>
|
||||
#include <mbedtls/rsa.h>
|
||||
|
||||
#include <ucode/module.h>
|
||||
|
||||
#include "pk.h"
|
||||
|
||||
/* mbedtls < 3.x compat */
|
||||
#ifdef MBEDTLS_LEGACY
|
||||
#define mbedtls_pk_parse_key(pk, key, keylen, passwd, passwdlen, random, random_ctx) \
|
||||
mbedtls_pk_parse_key(pk, key, keylen, passwd, passwdlen)
|
||||
#endif
|
||||
|
||||
static uc_resource_type_t *uc_pk_type, *uc_crt_type;
|
||||
static uc_value_t *registry;
|
||||
char buf[32 * 1024];
|
||||
int mbedtls_errno;
|
||||
|
||||
struct uc_cert_wr {
|
||||
mbedtls_x509write_cert crt; /* must be first */
|
||||
mbedtls_mpi mpi;
|
||||
unsigned int reg;
|
||||
};
|
||||
|
||||
static unsigned int uc_reg_add(uc_value_t *val)
|
||||
{
|
||||
size_t i = 0;
|
||||
|
||||
while (ucv_array_get(registry, i))
|
||||
i++;
|
||||
|
||||
ucv_array_set(registry, i, ucv_get(val));
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
int random_cb(void *ctx, unsigned char *out, size_t len)
|
||||
{
|
||||
#ifdef linux
|
||||
if (getrandom(out, len, 0) != (ssize_t) len)
|
||||
return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
|
||||
#else
|
||||
static FILE *f;
|
||||
|
||||
if (!f)
|
||||
f = fopen("/dev/urandom", "r");
|
||||
if (fread(out, len, 1, f) != 1)
|
||||
return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int64_t get_int_arg(uc_value_t *obj, const char *key, int64_t defval)
|
||||
{
|
||||
uc_value_t *uval = ucv_object_get(obj, key, NULL);
|
||||
int64_t val;
|
||||
|
||||
if (!uval)
|
||||
return defval;
|
||||
|
||||
val = ucv_int64_get(uval);
|
||||
if (errno || val < 0 || val > INT_MAX)
|
||||
return INT_MIN;
|
||||
|
||||
return val ? val : defval;
|
||||
}
|
||||
|
||||
static int
|
||||
gen_rsa_key(mbedtls_pk_context *pk, uc_value_t *arg)
|
||||
{
|
||||
int64_t key_size, exp;
|
||||
|
||||
key_size = get_int_arg(arg, "size", 2048);
|
||||
exp = get_int_arg(arg, "exponent", 65537);
|
||||
if (key_size < 0 || exp < 0)
|
||||
return -1;
|
||||
|
||||
return mbedtls_rsa_gen_key(mbedtls_pk_rsa(*pk), random_cb, NULL, key_size, exp);
|
||||
}
|
||||
|
||||
static int
|
||||
gen_ec_key(mbedtls_pk_context *pk, uc_value_t *arg)
|
||||
{
|
||||
mbedtls_ecp_group_id curve;
|
||||
const char *c_name;
|
||||
uc_value_t *c_arg;
|
||||
|
||||
c_arg = ucv_object_get(arg, "curve", NULL);
|
||||
if (c_arg && ucv_type(c_arg) != UC_STRING)
|
||||
return -1;
|
||||
|
||||
c_name = ucv_string_get(c_arg);
|
||||
if (!c_name)
|
||||
curve = MBEDTLS_ECP_DP_SECP256R1;
|
||||
else {
|
||||
const mbedtls_ecp_curve_info *curve_info;
|
||||
curve_info = mbedtls_ecp_curve_info_from_name(c_name);
|
||||
if (!curve_info)
|
||||
return MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE;
|
||||
|
||||
curve = curve_info->grp_id;
|
||||
}
|
||||
|
||||
return mbedtls_ecp_gen_key(curve, mbedtls_pk_ec(*pk), random_cb, NULL);
|
||||
}
|
||||
|
||||
static void free_pk(void *pk)
|
||||
{
|
||||
if (!pk)
|
||||
return;
|
||||
|
||||
mbedtls_pk_free(pk);
|
||||
free(pk);
|
||||
}
|
||||
|
||||
static void free_crt(void *ptr)
|
||||
{
|
||||
struct uc_cert_wr *crt = ptr;
|
||||
|
||||
if (!crt)
|
||||
return;
|
||||
|
||||
mbedtls_x509write_crt_free(&crt->crt);
|
||||
mbedtls_mpi_free(&crt->mpi);
|
||||
ucv_array_set(registry, crt->reg, NULL);
|
||||
free(crt);
|
||||
}
|
||||
|
||||
static uc_value_t *
|
||||
uc_generate_key(uc_vm_t *vm, size_t nargs)
|
||||
{
|
||||
uc_value_t *cur, *arg = uc_fn_arg(0);
|
||||
mbedtls_pk_type_t pk_type;
|
||||
mbedtls_pk_context *pk;
|
||||
const char *type;
|
||||
int ret;
|
||||
|
||||
if (ucv_type(arg) != UC_OBJECT)
|
||||
INVALID_ARG();
|
||||
|
||||
cur = ucv_object_get(arg, "type", NULL);
|
||||
type = ucv_string_get(cur);
|
||||
if (!type)
|
||||
INVALID_ARG();
|
||||
|
||||
if (!strcmp(type, "rsa"))
|
||||
pk_type = MBEDTLS_PK_RSA;
|
||||
else if (!strcmp(type, "ec"))
|
||||
pk_type = MBEDTLS_PK_ECKEY;
|
||||
else
|
||||
INVALID_ARG();
|
||||
|
||||
pk = calloc(1, sizeof(*pk));
|
||||
mbedtls_pk_init(pk);
|
||||
mbedtls_pk_setup(pk, mbedtls_pk_info_from_type(pk_type));
|
||||
switch (pk_type) {
|
||||
case MBEDTLS_PK_RSA:
|
||||
ret = C(gen_rsa_key(pk, arg));
|
||||
break;
|
||||
case MBEDTLS_PK_ECKEY:
|
||||
ret = C(gen_ec_key(pk, arg));
|
||||
break;
|
||||
default:
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
free_pk(pk);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return uc_resource_new(uc_pk_type, pk);
|
||||
}
|
||||
|
||||
static uc_value_t *
|
||||
uc_load_key(uc_vm_t *vm, size_t nargs)
|
||||
{
|
||||
uc_value_t *keystr = uc_fn_arg(0);
|
||||
uc_value_t *pub = uc_fn_arg(1);
|
||||
uc_value_t *passwd = uc_fn_arg(2);
|
||||
mbedtls_pk_context *pk;
|
||||
int ret;
|
||||
|
||||
if (ucv_type(keystr) != UC_STRING ||
|
||||
(pub && ucv_type(pub) != UC_BOOLEAN) ||
|
||||
(passwd && ucv_type(passwd) != UC_STRING))
|
||||
INVALID_ARG();
|
||||
|
||||
pk = calloc(1, sizeof(*pk));
|
||||
mbedtls_pk_init(pk);
|
||||
if (ucv_is_truish(pub))
|
||||
ret = C(mbedtls_pk_parse_public_key(pk, (const uint8_t *)ucv_string_get(keystr),
|
||||
ucv_string_length(keystr) + 1));
|
||||
else
|
||||
ret = C(mbedtls_pk_parse_key(pk, (const uint8_t *)ucv_string_get(keystr),
|
||||
ucv_string_length(keystr) + 1,
|
||||
(const uint8_t *)ucv_string_get(passwd),
|
||||
ucv_string_length(passwd) + 1,
|
||||
random_cb, NULL));
|
||||
if (ret) {
|
||||
free_pk(pk);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return uc_resource_new(uc_pk_type, pk);
|
||||
}
|
||||
|
||||
static void
|
||||
uc_cert_info_add(uc_value_t *info, const char *name, int len)
|
||||
{
|
||||
uc_value_t *val;
|
||||
|
||||
if (len < 0)
|
||||
return;
|
||||
|
||||
val = ucv_string_new_length(buf, len);
|
||||
ucv_object_add(info, name, ucv_get(val));
|
||||
}
|
||||
|
||||
static void
|
||||
uc_cert_info_add_name(uc_value_t *info, const char *name, mbedtls_x509_name *dn)
|
||||
{
|
||||
int len;
|
||||
|
||||
len = mbedtls_x509_dn_gets(buf, sizeof(buf), dn);
|
||||
uc_cert_info_add(info, name, len);
|
||||
}
|
||||
|
||||
static void
|
||||
uc_cert_info_add_time(uc_value_t *info, const char *name, mbedtls_x509_time *t)
|
||||
{
|
||||
int len;
|
||||
|
||||
len = snprintf(buf, sizeof(buf), "%04d%02d%02d%02d%02d%02d",
|
||||
t->year, t->mon, t->day, t->hour, t->min, t->sec);
|
||||
uc_cert_info_add(info, name, len);
|
||||
}
|
||||
|
||||
static uc_value_t *
|
||||
uc_cert_info(uc_vm_t *vm, size_t nargs)
|
||||
{
|
||||
uc_value_t *arg = uc_fn_arg(0);
|
||||
mbedtls_x509_crt crt, *cur;
|
||||
uc_value_t *ret = NULL;
|
||||
|
||||
if (ucv_type(arg) != UC_STRING)
|
||||
return NULL;
|
||||
|
||||
mbedtls_x509_crt_init(&crt);
|
||||
if (C(mbedtls_x509_crt_parse(&crt, (const void *)ucv_string_get(arg), ucv_string_length(arg) + 1)) < 0)
|
||||
goto out;
|
||||
|
||||
ret = ucv_array_new(vm);
|
||||
for (cur = &crt; cur && cur->version != 0; cur = cur->next) {
|
||||
uc_value_t *info = ucv_object_new(vm);
|
||||
int len;
|
||||
|
||||
ucv_array_push(ret, ucv_get(info));
|
||||
ucv_object_add(info, "version", ucv_int64_new(cur->version));
|
||||
|
||||
uc_cert_info_add_name(info, "issuer", &cur->issuer);
|
||||
uc_cert_info_add_name(info, "subject", &cur->issuer);
|
||||
uc_cert_info_add_time(info, "valid_from", &cur->valid_from);
|
||||
uc_cert_info_add_time(info, "valid_to", &cur->valid_to);
|
||||
|
||||
len = mbedtls_x509_serial_gets(buf, sizeof(buf), &cur->serial);
|
||||
uc_cert_info_add(info, "serial", len);
|
||||
}
|
||||
|
||||
out:
|
||||
mbedtls_x509_crt_free(&crt);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uc_value_t *
|
||||
uc_pk_pem(uc_vm_t *vm, size_t nargs)
|
||||
{
|
||||
mbedtls_pk_context *pk = uc_fn_thisval("mbedtls.pk");
|
||||
uc_value_t *pub = uc_fn_arg(0);
|
||||
|
||||
if (!pk)
|
||||
return NULL;
|
||||
|
||||
if (ucv_is_truish(pub))
|
||||
CHECK(mbedtls_pk_write_pubkey_pem(pk, (void *)buf, sizeof(buf)));
|
||||
else
|
||||
CHECK(mbedtls_pk_write_key_pem(pk, (void *)buf, sizeof(buf)));
|
||||
|
||||
return ucv_string_new(buf);
|
||||
}
|
||||
|
||||
static uc_value_t *
|
||||
uc_pk_der(uc_vm_t *vm, size_t nargs)
|
||||
{
|
||||
mbedtls_pk_context *pk = uc_fn_thisval("mbedtls.pk");
|
||||
uc_value_t *pub = uc_fn_arg(0);
|
||||
int len;
|
||||
|
||||
if (!pk)
|
||||
return NULL;
|
||||
|
||||
if (ucv_is_truish(pub))
|
||||
len = mbedtls_pk_write_pubkey_der(pk, (void *)buf, sizeof(buf));
|
||||
else
|
||||
len = mbedtls_pk_write_key_der(pk, (void *)buf, sizeof(buf));
|
||||
if (len < 0)
|
||||
CHECK(len);
|
||||
|
||||
return ucv_string_new_length(buf + sizeof(buf) - len, len);
|
||||
}
|
||||
|
||||
static uc_value_t *
|
||||
uc_crt_pem(uc_vm_t *vm, size_t nargs)
|
||||
{
|
||||
mbedtls_x509write_cert *crt = uc_fn_thisval("mbedtls.crt");
|
||||
if (!crt)
|
||||
return NULL;
|
||||
|
||||
CHECK(mbedtls_x509write_crt_pem(crt, (void *)buf, sizeof(buf), random_cb, NULL));
|
||||
|
||||
return ucv_string_new(buf);
|
||||
}
|
||||
|
||||
static uc_value_t *
|
||||
uc_crt_der(uc_vm_t *vm, size_t nargs)
|
||||
{
|
||||
mbedtls_x509write_cert *crt = uc_fn_thisval("mbedtls.crt");
|
||||
int len;
|
||||
|
||||
if (!crt)
|
||||
return NULL;
|
||||
|
||||
len = mbedtls_x509write_crt_der(crt, (void *)buf, sizeof(buf), random_cb, NULL);
|
||||
if (len < 0)
|
||||
CHECK(len);
|
||||
|
||||
return ucv_string_new_length(buf, len);
|
||||
}
|
||||
|
||||
static int
|
||||
uc_cert_set_validity(mbedtls_x509write_cert *crt, uc_value_t *arg)
|
||||
{
|
||||
uc_value_t *from = ucv_array_get(arg, 0);
|
||||
uc_value_t *to = ucv_array_get(arg, 1);
|
||||
|
||||
if (ucv_type(from) != UC_STRING || ucv_type(to) != UC_STRING)
|
||||
return -1;
|
||||
|
||||
return mbedtls_x509write_crt_set_validity(crt, ucv_string_get(from), ucv_string_get(to));
|
||||
}
|
||||
|
||||
static int
|
||||
uc_cert_init(mbedtls_x509write_cert *crt, mbedtls_mpi *mpi, uc_value_t *reg, uc_value_t *arg)
|
||||
{
|
||||
uc_value_t *cur;
|
||||
int64_t serial;
|
||||
int path_len;
|
||||
int version;
|
||||
bool ca;
|
||||
|
||||
mbedtls_mpi_init(mpi);
|
||||
mbedtls_x509write_crt_init(crt);
|
||||
mbedtls_x509write_crt_set_md_alg(crt, MBEDTLS_MD_SHA256);
|
||||
|
||||
ca = ucv_is_truish(ucv_object_get(arg, "ca", NULL));
|
||||
path_len = get_int_arg(arg, "max_pathlen", ca ? -1 : 0);
|
||||
if (path_len < -1)
|
||||
return -1;
|
||||
|
||||
version = get_int_arg(arg, "version", 3);
|
||||
if (version < 0 || version > 3)
|
||||
return -1;
|
||||
|
||||
serial = get_int_arg(arg, "serial", 1);
|
||||
if (serial < 0)
|
||||
return -1;
|
||||
|
||||
mbedtls_mpi_lset(mpi, serial);
|
||||
mbedtls_x509write_crt_set_serial(crt, mpi);
|
||||
mbedtls_x509write_crt_set_version(crt, version - 1);
|
||||
CHECK_INT(mbedtls_x509write_crt_set_basic_constraints(crt, ca, path_len));
|
||||
|
||||
cur = ucv_object_get(arg, "subject_name", NULL);
|
||||
if (ucv_type(cur) == UC_STRING)
|
||||
CHECK_INT(mbedtls_x509write_crt_set_subject_name(crt, ucv_string_get(cur)));
|
||||
else
|
||||
return -1;
|
||||
cur = ucv_object_get(arg, "subject_key", NULL);
|
||||
if (cur) {
|
||||
mbedtls_pk_context *key = ucv_resource_data(cur, "mbedtls.pk");
|
||||
if (!key)
|
||||
return -1;
|
||||
|
||||
ucv_array_set(reg, 0, ucv_get(cur));
|
||||
mbedtls_x509write_crt_set_subject_key(crt, key);
|
||||
mbedtls_x509write_crt_set_subject_key_identifier(crt);
|
||||
} else
|
||||
return -1;
|
||||
|
||||
cur = ucv_object_get(arg, "issuer_name", NULL);
|
||||
if (ucv_type(cur) == UC_STRING)
|
||||
CHECK_INT(mbedtls_x509write_crt_set_issuer_name(crt, ucv_string_get(cur)));
|
||||
else
|
||||
return -1;
|
||||
cur = ucv_object_get(arg, "issuer_key", NULL);
|
||||
if (cur) {
|
||||
mbedtls_pk_context *key = ucv_resource_data(cur, "mbedtls.pk");
|
||||
if (!key)
|
||||
return -1;
|
||||
|
||||
ucv_array_set(reg, 1, ucv_get(cur));
|
||||
mbedtls_x509write_crt_set_issuer_key(crt, key);
|
||||
mbedtls_x509write_crt_set_authority_key_identifier(crt);
|
||||
} else
|
||||
return -1;
|
||||
|
||||
cur = ucv_object_get(arg, "validity", NULL);
|
||||
if (ucv_type(cur) != UC_ARRAY || ucv_array_length(cur) != 2)
|
||||
return -1;
|
||||
if (uc_cert_set_validity(crt, cur))
|
||||
return -1;
|
||||
|
||||
cur = ucv_object_get(arg, "key_usage", NULL);
|
||||
if (ucv_type(cur) == UC_ARRAY) {
|
||||
static const struct {
|
||||
const char *name;
|
||||
uint8_t val;
|
||||
} key_flags[] = {
|
||||
{ "digital_signature", MBEDTLS_X509_KU_DIGITAL_SIGNATURE },
|
||||
{ "non_repudiation", MBEDTLS_X509_KU_NON_REPUDIATION },
|
||||
{ "key_encipherment", MBEDTLS_X509_KU_KEY_ENCIPHERMENT },
|
||||
{ "data_encipherment", MBEDTLS_X509_KU_DATA_ENCIPHERMENT },
|
||||
{ "key_agreement", MBEDTLS_X509_KU_KEY_AGREEMENT },
|
||||
{ "key_cert_sign", MBEDTLS_X509_KU_KEY_CERT_SIGN },
|
||||
{ "crl_sign", MBEDTLS_X509_KU_CRL_SIGN },
|
||||
};
|
||||
uint8_t key_usage = 0;
|
||||
size_t len = ucv_array_length(cur);
|
||||
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
uc_value_t *val = ucv_array_get(cur, i);
|
||||
const char *str;
|
||||
size_t k;
|
||||
|
||||
str = ucv_string_get(val);
|
||||
if (!str)
|
||||
return -1;
|
||||
|
||||
for (k = 0; k < ARRAY_SIZE(key_flags); k++)
|
||||
if (!strcmp(str, key_flags[k].name))
|
||||
break;
|
||||
if (k == ARRAY_SIZE(key_flags))
|
||||
return -1;
|
||||
|
||||
key_usage |= key_flags[k].val;
|
||||
}
|
||||
CHECK_INT(mbedtls_x509write_crt_set_key_usage(crt, key_usage));
|
||||
} else if (cur)
|
||||
return -1;
|
||||
|
||||
#ifndef MBEDTLS_LEGACY
|
||||
cur = ucv_object_get(arg, "ext_key_usage", NULL);
|
||||
if (ucv_type(cur) == UC_ARRAY && ucv_array_length(cur)) {
|
||||
static const struct {
|
||||
const char *name;
|
||||
struct mbedtls_asn1_buf val;
|
||||
} key_flags[] = {
|
||||
#define __oid(name, val) \
|
||||
{ \
|
||||
name, \
|
||||
{ \
|
||||
.tag = MBEDTLS_ASN1_OID, \
|
||||
.len = sizeof(MBEDTLS_OID_##val), \
|
||||
.p = (uint8_t *)MBEDTLS_OID_##val, \
|
||||
} \
|
||||
}
|
||||
__oid("server_auth", SERVER_AUTH),
|
||||
__oid("client_auth", CLIENT_AUTH),
|
||||
__oid("code_signing", CODE_SIGNING),
|
||||
__oid("email_protection", EMAIL_PROTECTION),
|
||||
__oid("time_stamping", TIME_STAMPING),
|
||||
__oid("ocsp_signing", OCSP_SIGNING),
|
||||
__oid("any", ANY_EXTENDED_KEY_USAGE)
|
||||
};
|
||||
struct mbedtls_asn1_sequence *elem;
|
||||
size_t len = ucv_array_length(cur);
|
||||
|
||||
elem = calloc(len, sizeof(*elem));
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
uc_value_t *val = ucv_array_get(cur, i);
|
||||
const char *str;
|
||||
size_t k;
|
||||
|
||||
str = ucv_string_get(val);
|
||||
if (!str)
|
||||
return -1;
|
||||
|
||||
for (k = 0; k < ARRAY_SIZE(key_flags); k++)
|
||||
if (!strcmp(str, key_flags[k].name))
|
||||
break;
|
||||
|
||||
if (k == ARRAY_SIZE(key_flags)) {
|
||||
free(elem);
|
||||
return -1;
|
||||
}
|
||||
elem[i].buf = key_flags[k].val;
|
||||
if (i + 1 < len)
|
||||
elem[i].next = &elem[i + 1];
|
||||
}
|
||||
|
||||
CHECK_INT(mbedtls_x509write_crt_set_ext_key_usage(crt, elem));
|
||||
} else if (cur)
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uc_value_t *
|
||||
uc_generate_cert(uc_vm_t *vm, size_t nargs)
|
||||
{
|
||||
struct uc_cert_wr *crt;
|
||||
uc_value_t *arg = uc_fn_arg(0);
|
||||
uc_value_t *reg;
|
||||
|
||||
if (ucv_type(arg) != UC_OBJECT)
|
||||
return NULL;
|
||||
|
||||
reg = ucv_array_new(vm);
|
||||
crt = calloc(1, sizeof(*crt));
|
||||
if (C(uc_cert_init(&crt->crt, &crt->mpi, reg, arg))) {
|
||||
free(crt);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
crt->reg = uc_reg_add(reg);
|
||||
|
||||
return uc_resource_new(uc_crt_type, crt);
|
||||
}
|
||||
|
||||
static uc_value_t *
|
||||
uc_mbedtls_error(uc_vm_t *vm, size_t nargs)
|
||||
{
|
||||
mbedtls_strerror(mbedtls_errno, buf, sizeof(buf));
|
||||
|
||||
return ucv_string_new(buf);
|
||||
}
|
||||
|
||||
static uc_value_t *
|
||||
uc_mbedtls_errno(uc_vm_t *vm, size_t nargs)
|
||||
{
|
||||
return ucv_int64_new(mbedtls_errno);
|
||||
}
|
||||
|
||||
|
||||
static const uc_function_list_t pk_fns[] = {
|
||||
{ "pem", uc_pk_pem },
|
||||
{ "der", uc_pk_der },
|
||||
};
|
||||
|
||||
static const uc_function_list_t crt_fns[] = {
|
||||
{ "pem", uc_crt_pem },
|
||||
{ "der", uc_crt_der },
|
||||
};
|
||||
|
||||
static const uc_function_list_t global_fns[] = {
|
||||
{ "load_key", uc_load_key },
|
||||
{ "cert_info", uc_cert_info },
|
||||
{ "generate_key", uc_generate_key },
|
||||
{ "generate_cert", uc_generate_cert },
|
||||
{ "generate_pkcs12", uc_generate_pkcs12 },
|
||||
{ "errno", uc_mbedtls_errno },
|
||||
{ "error", uc_mbedtls_error },
|
||||
};
|
||||
|
||||
void uc_module_init(uc_vm_t *vm, uc_value_t *scope)
|
||||
{
|
||||
uc_pk_type = uc_type_declare(vm, "mbedtls.pk", pk_fns, free_pk);
|
||||
uc_crt_type = uc_type_declare(vm, "mbedtls.crt", crt_fns, free_crt);
|
||||
uc_function_list_register(scope, global_fns);
|
||||
|
||||
registry = ucv_array_new(vm);
|
||||
uc_vm_registry_set(vm, "pkgen.registry", registry);
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
From b56e4d660a9688ff83f5cbdc6e3ea063352d0d79 Mon Sep 17 00:00:00 2001
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Sun, 12 Jan 2025 19:32:45 +0100
|
||||
Subject: [PATCH] net: airoha: Enforce ETS Qdisc priomap
|
||||
|
||||
EN7581 SoC supports fixed QoS band priority where WRR queues have lowest
|
||||
priorities with respect to SP ones.
|
||||
E.g: WRR0, WRR1, .., WRRm, SP0, SP1, .., SPn
|
||||
|
||||
Enforce ETS Qdisc priomap according to the hw capabilities.
|
||||
|
||||
Suggested-by: Davide Caratti <dcaratti@redhat.com>
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Reviewed-by: Davide Caratti <dcaratti@redhat.com>
|
||||
Link: https://patch.msgid.link/20250112-airoha_ets_priomap-v1-1-fb616de159ba@kernel.org
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/mediatek/airoha_eth.c | 17 +++++++++++++++--
|
||||
1 file changed, 15 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/mediatek/airoha_eth.c
|
||||
@@ -2786,7 +2786,7 @@ static int airoha_qdma_set_tx_ets_sched(
|
||||
struct tc_ets_qopt_offload_replace_params *p = &opt->replace_params;
|
||||
enum tx_sched_mode mode = TC_SCH_SP;
|
||||
u16 w[AIROHA_NUM_QOS_QUEUES] = {};
|
||||
- int i, nstrict = 0;
|
||||
+ int i, nstrict = 0, nwrr, qidx;
|
||||
|
||||
if (p->bands > AIROHA_NUM_QOS_QUEUES)
|
||||
return -EINVAL;
|
||||
@@ -2800,7 +2800,20 @@ static int airoha_qdma_set_tx_ets_sched(
|
||||
if (nstrict == AIROHA_NUM_QOS_QUEUES - 1)
|
||||
return -EINVAL;
|
||||
|
||||
- for (i = 0; i < p->bands - nstrict; i++)
|
||||
+ /* EN7581 SoC supports fixed QoS band priority where WRR queues have
|
||||
+ * lowest priorities with respect to SP ones.
|
||||
+ * e.g: WRR0, WRR1, .., WRRm, SP0, SP1, .., SPn
|
||||
+ */
|
||||
+ nwrr = p->bands - nstrict;
|
||||
+ qidx = nstrict && nwrr ? nstrict : 0;
|
||||
+ for (i = 1; i <= p->bands; i++) {
|
||||
+ if (p->priomap[i % AIROHA_NUM_QOS_QUEUES] != qidx)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ qidx = i == nwrr ? 0 : qidx + 1;
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < nwrr; i++)
|
||||
w[i] = p->weights[nstrict + i];
|
||||
|
||||
if (!nstrict)
|
@ -86,7 +86,7 @@ Best regards,
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/mediatek/airoha_eth.c
|
||||
@@ -2833,11 +2833,14 @@ static int airoha_qdma_get_tx_ets_stats(
|
||||
@@ -2846,11 +2846,14 @@ static int airoha_qdma_get_tx_ets_stats(
|
||||
static int airoha_tc_setup_qdisc_ets(struct airoha_gdm_port *port,
|
||||
struct tc_ets_qopt_offload *opt)
|
||||
{
|
||||
|
@ -0,0 +1,58 @@
|
||||
From 0e7a622da17da0042294860cdb7a2fac091d25b1 Mon Sep 17 00:00:00 2001
|
||||
Message-ID: <0e7a622da17da0042294860cdb7a2fac091d25b1.1736960708.git.lorenzo@kernel.org>
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Wed, 8 Jan 2025 10:50:40 +0100
|
||||
Subject: [PATCH 1/6] PCI: mediatek-gen3: Rely on clk_bulk_prepare_enable() in
|
||||
mtk_pcie_en7581_power_up()
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Replace clk_bulk_prepare() and clk_bulk_enable() with
|
||||
clk_bulk_prepare_enable() in mtk_pcie_en7581_power_up() routine.
|
||||
|
||||
Link: https://lore.kernel.org/r/20250108-pcie-en7581-fixes-v6-1-21ac939a3b9b@kernel.org
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
|
||||
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
|
||||
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
|
||||
---
|
||||
drivers/pci/controller/pcie-mediatek-gen3.c | 14 +++-----------
|
||||
1 file changed, 3 insertions(+), 11 deletions(-)
|
||||
|
||||
--- a/drivers/pci/controller/pcie-mediatek-gen3.c
|
||||
+++ b/drivers/pci/controller/pcie-mediatek-gen3.c
|
||||
@@ -907,12 +907,6 @@ static int mtk_pcie_en7581_power_up(stru
|
||||
pm_runtime_enable(dev);
|
||||
pm_runtime_get_sync(dev);
|
||||
|
||||
- err = clk_bulk_prepare(pcie->num_clks, pcie->clks);
|
||||
- if (err) {
|
||||
- dev_err(dev, "failed to prepare clock\n");
|
||||
- goto err_clk_prepare;
|
||||
- }
|
||||
-
|
||||
val = FIELD_PREP(PCIE_VAL_LN0_DOWNSTREAM, 0x47) |
|
||||
FIELD_PREP(PCIE_VAL_LN1_DOWNSTREAM, 0x47) |
|
||||
FIELD_PREP(PCIE_VAL_LN0_UPSTREAM, 0x41) |
|
||||
@@ -925,17 +919,15 @@ static int mtk_pcie_en7581_power_up(stru
|
||||
FIELD_PREP(PCIE_K_FINETUNE_MAX, 0xf);
|
||||
writel_relaxed(val, pcie->base + PCIE_PIPE4_PIE8_REG);
|
||||
|
||||
- err = clk_bulk_enable(pcie->num_clks, pcie->clks);
|
||||
+ err = clk_bulk_prepare_enable(pcie->num_clks, pcie->clks);
|
||||
if (err) {
|
||||
dev_err(dev, "failed to prepare clock\n");
|
||||
- goto err_clk_enable;
|
||||
+ goto err_clk_prepare_enable;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
-err_clk_enable:
|
||||
- clk_bulk_unprepare(pcie->num_clks, pcie->clks);
|
||||
-err_clk_prepare:
|
||||
+err_clk_prepare_enable:
|
||||
pm_runtime_put_sync(dev);
|
||||
pm_runtime_disable(dev);
|
||||
reset_control_bulk_assert(pcie->soc->phy_resets.num_resets, pcie->phy_resets);
|
@ -0,0 +1,89 @@
|
||||
From e4c7dfd953f7618f0ccb70d87c1629634f306fab Mon Sep 17 00:00:00 2001
|
||||
Message-ID: <e4c7dfd953f7618f0ccb70d87c1629634f306fab.1736960708.git.lorenzo@kernel.org>
|
||||
In-Reply-To: <0e7a622da17da0042294860cdb7a2fac091d25b1.1736960708.git.lorenzo@kernel.org>
|
||||
References: <0e7a622da17da0042294860cdb7a2fac091d25b1.1736960708.git.lorenzo@kernel.org>
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Wed, 8 Jan 2025 10:50:41 +0100
|
||||
Subject: [PATCH 2/6] PCI: mediatek-gen3: Move reset/assert callbacks in
|
||||
.power_up()
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
In order to make the code more readable, the reset_control_bulk_assert()
|
||||
function for PHY reset lines is moved to make it pair with
|
||||
reset_control_bulk_deassert() in mtk_pcie_power_up() and
|
||||
mtk_pcie_en7581_power_up(). The same change is done for
|
||||
reset_control_assert() used to assert MAC reset line.
|
||||
|
||||
Introduce PCIE_MTK_RESET_TIME_US macro for the time needed to
|
||||
complete PCIe reset on MediaTek controller.
|
||||
|
||||
Link: https://lore.kernel.org/r/20250108-pcie-en7581-fixes-v6-2-21ac939a3b9b@kernel.org
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
|
||||
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
|
||||
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
|
||||
---
|
||||
drivers/pci/controller/pcie-mediatek-gen3.c | 28 +++++++++++++--------
|
||||
1 file changed, 18 insertions(+), 10 deletions(-)
|
||||
|
||||
--- a/drivers/pci/controller/pcie-mediatek-gen3.c
|
||||
+++ b/drivers/pci/controller/pcie-mediatek-gen3.c
|
||||
@@ -120,6 +120,8 @@
|
||||
|
||||
#define MAX_NUM_PHY_RESETS 3
|
||||
|
||||
+#define PCIE_MTK_RESET_TIME_US 10
|
||||
+
|
||||
/* Time in ms needed to complete PCIe reset on EN7581 SoC */
|
||||
#define PCIE_EN7581_RESET_TIME_MS 100
|
||||
|
||||
@@ -875,9 +877,14 @@ static int mtk_pcie_en7581_power_up(stru
|
||||
u32 val;
|
||||
|
||||
/*
|
||||
- * Wait for the time needed to complete the bulk assert in
|
||||
- * mtk_pcie_setup for EN7581 SoC.
|
||||
+ * The controller may have been left out of reset by the bootloader
|
||||
+ * so make sure that we get a clean start by asserting resets here.
|
||||
*/
|
||||
+ reset_control_bulk_assert(pcie->soc->phy_resets.num_resets,
|
||||
+ pcie->phy_resets);
|
||||
+ reset_control_assert(pcie->mac_reset);
|
||||
+
|
||||
+ /* Wait for the time needed to complete the reset lines assert. */
|
||||
mdelay(PCIE_EN7581_RESET_TIME_MS);
|
||||
|
||||
err = phy_init(pcie->phy);
|
||||
@@ -944,6 +951,15 @@ static int mtk_pcie_power_up(struct mtk_
|
||||
struct device *dev = pcie->dev;
|
||||
int err;
|
||||
|
||||
+ /*
|
||||
+ * The controller may have been left out of reset by the bootloader
|
||||
+ * so make sure that we get a clean start by asserting resets here.
|
||||
+ */
|
||||
+ reset_control_bulk_assert(pcie->soc->phy_resets.num_resets,
|
||||
+ pcie->phy_resets);
|
||||
+ reset_control_assert(pcie->mac_reset);
|
||||
+ usleep_range(PCIE_MTK_RESET_TIME_US, 2 * PCIE_MTK_RESET_TIME_US);
|
||||
+
|
||||
/* PHY power on and enable pipe clock */
|
||||
err = reset_control_bulk_deassert(pcie->soc->phy_resets.num_resets, pcie->phy_resets);
|
||||
if (err) {
|
||||
@@ -1016,14 +1032,6 @@ static int mtk_pcie_setup(struct mtk_gen
|
||||
* counter since the bulk is shared.
|
||||
*/
|
||||
reset_control_bulk_deassert(pcie->soc->phy_resets.num_resets, pcie->phy_resets);
|
||||
- /*
|
||||
- * The controller may have been left out of reset by the bootloader
|
||||
- * so make sure that we get a clean start by asserting resets here.
|
||||
- */
|
||||
- reset_control_bulk_assert(pcie->soc->phy_resets.num_resets, pcie->phy_resets);
|
||||
-
|
||||
- reset_control_assert(pcie->mac_reset);
|
||||
- usleep_range(10, 20);
|
||||
|
||||
/* Don't touch the hardware registers before power up */
|
||||
err = pcie->soc->power_up(pcie);
|
@ -0,0 +1,38 @@
|
||||
From 0c9d2d2ef0d916b490a9222ed20ff4616fca876d Mon Sep 17 00:00:00 2001
|
||||
Message-ID: <0c9d2d2ef0d916b490a9222ed20ff4616fca876d.1736960708.git.lorenzo@kernel.org>
|
||||
In-Reply-To: <0e7a622da17da0042294860cdb7a2fac091d25b1.1736960708.git.lorenzo@kernel.org>
|
||||
References: <0e7a622da17da0042294860cdb7a2fac091d25b1.1736960708.git.lorenzo@kernel.org>
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Wed, 8 Jan 2025 10:50:42 +0100
|
||||
Subject: [PATCH 3/6] PCI: mediatek-gen3: Add comment about initialization
|
||||
order in mtk_pcie_en7581_power_up()
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Add a comment in mtk_pcie_en7581_power_up() to clarify, unlike the other
|
||||
MediaTek Gen3 controllers, the Airoha EN7581 requires PHY initialization
|
||||
and power-on before PHY reset deassert.
|
||||
|
||||
Link: https://lore.kernel.org/r/20250108-pcie-en7581-fixes-v6-3-21ac939a3b9b@kernel.org
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
|
||||
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
|
||||
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
|
||||
---
|
||||
drivers/pci/controller/pcie-mediatek-gen3.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
--- a/drivers/pci/controller/pcie-mediatek-gen3.c
|
||||
+++ b/drivers/pci/controller/pcie-mediatek-gen3.c
|
||||
@@ -887,6 +887,10 @@ static int mtk_pcie_en7581_power_up(stru
|
||||
/* Wait for the time needed to complete the reset lines assert. */
|
||||
mdelay(PCIE_EN7581_RESET_TIME_MS);
|
||||
|
||||
+ /*
|
||||
+ * Unlike the other MediaTek Gen3 controllers, the Airoha EN7581
|
||||
+ * requires PHY initialization and power-on before PHY reset deassert.
|
||||
+ */
|
||||
err = phy_init(pcie->phy);
|
||||
if (err) {
|
||||
dev_err(dev, "failed to initialize PHY\n");
|
@ -0,0 +1,62 @@
|
||||
From 90d4e466c9ea2010f33880a36317a8486ccbe082 Mon Sep 17 00:00:00 2001
|
||||
Message-ID: <90d4e466c9ea2010f33880a36317a8486ccbe082.1736960708.git.lorenzo@kernel.org>
|
||||
In-Reply-To: <0e7a622da17da0042294860cdb7a2fac091d25b1.1736960708.git.lorenzo@kernel.org>
|
||||
References: <0e7a622da17da0042294860cdb7a2fac091d25b1.1736960708.git.lorenzo@kernel.org>
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Wed, 8 Jan 2025 10:50:43 +0100
|
||||
Subject: [PATCH 4/6] PCI: mediatek-gen3: Move reset delay in
|
||||
mtk_pcie_en7581_power_up()
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Airoha EN7581 has a hw bug asserting/releasing PCIE_PE_RSTB signal
|
||||
causing occasional PCIe link down issues. In order to overcome the
|
||||
problem, PCIe block is reset using REG_PCI_CONTROL (0x88) and
|
||||
REG_RESET_CONTROL (0x834) registers available in the clock module
|
||||
running clk_bulk_prepare_enable() in mtk_pcie_en7581_power_up().
|
||||
|
||||
In order to make the code more readable, move the wait for the time
|
||||
needed to complete the PCIe reset from en7581_pci_enable() to
|
||||
mtk_pcie_en7581_power_up().
|
||||
|
||||
Reduce reset timeout from 250ms to the standard PCIE_T_PVPERL_MS value
|
||||
(100ms) since it has no impact on the driver behavior.
|
||||
|
||||
Link: https://lore.kernel.org/r/20250108-pcie-en7581-fixes-v6-4-21ac939a3b9b@kernel.org
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
|
||||
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
|
||||
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
|
||||
Acked-by: Stephen Boyd <sboyd@kernel.org>
|
||||
---
|
||||
drivers/clk/clk-en7523.c | 1 -
|
||||
drivers/pci/controller/pcie-mediatek-gen3.c | 7 +++++++
|
||||
2 files changed, 7 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/clk/clk-en7523.c
|
||||
+++ b/drivers/clk/clk-en7523.c
|
||||
@@ -489,7 +489,6 @@ static int en7581_pci_enable(struct clk_
|
||||
REG_PCI_CONTROL_PERSTOUT;
|
||||
val = readl(np_base + REG_PCI_CONTROL);
|
||||
writel(val | mask, np_base + REG_PCI_CONTROL);
|
||||
- msleep(250);
|
||||
|
||||
return 0;
|
||||
}
|
||||
--- a/drivers/pci/controller/pcie-mediatek-gen3.c
|
||||
+++ b/drivers/pci/controller/pcie-mediatek-gen3.c
|
||||
@@ -936,6 +936,13 @@ static int mtk_pcie_en7581_power_up(stru
|
||||
goto err_clk_prepare_enable;
|
||||
}
|
||||
|
||||
+ /*
|
||||
+ * Airoha EN7581 performs PCIe reset via clk callbacks since it has a
|
||||
+ * hw issue with PCIE_PE_RSTB signal. Add wait for the time needed to
|
||||
+ * complete the PCIe reset.
|
||||
+ */
|
||||
+ msleep(PCIE_T_PVPERL_MS);
|
||||
+
|
||||
return 0;
|
||||
|
||||
err_clk_prepare_enable:
|
@ -0,0 +1,44 @@
|
||||
From c98bee18d0a094e37100c85effe5e161418f8644 Mon Sep 17 00:00:00 2001
|
||||
Message-ID: <c98bee18d0a094e37100c85effe5e161418f8644.1736960708.git.lorenzo@kernel.org>
|
||||
In-Reply-To: <0e7a622da17da0042294860cdb7a2fac091d25b1.1736960708.git.lorenzo@kernel.org>
|
||||
References: <0e7a622da17da0042294860cdb7a2fac091d25b1.1736960708.git.lorenzo@kernel.org>
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Wed, 8 Jan 2025 10:50:44 +0100
|
||||
Subject: [PATCH 5/6] PCI: mediatek-gen3: Rely on msleep() in
|
||||
mtk_pcie_en7581_power_up()
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Since mtk_pcie_en7581_power_up() runs in non-atomic context, rely on
|
||||
msleep() routine instead of mdelay().
|
||||
|
||||
Link: https://lore.kernel.org/r/20250108-pcie-en7581-fixes-v6-5-21ac939a3b9b@kernel.org
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
|
||||
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
|
||||
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
|
||||
---
|
||||
drivers/pci/controller/pcie-mediatek-gen3.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/pci/controller/pcie-mediatek-gen3.c
|
||||
+++ b/drivers/pci/controller/pcie-mediatek-gen3.c
|
||||
@@ -885,7 +885,7 @@ static int mtk_pcie_en7581_power_up(stru
|
||||
reset_control_assert(pcie->mac_reset);
|
||||
|
||||
/* Wait for the time needed to complete the reset lines assert. */
|
||||
- mdelay(PCIE_EN7581_RESET_TIME_MS);
|
||||
+ msleep(PCIE_EN7581_RESET_TIME_MS);
|
||||
|
||||
/*
|
||||
* Unlike the other MediaTek Gen3 controllers, the Airoha EN7581
|
||||
@@ -913,7 +913,7 @@ static int mtk_pcie_en7581_power_up(stru
|
||||
* Wait for the time needed to complete the bulk de-assert above.
|
||||
* This time is specific for EN7581 SoC.
|
||||
*/
|
||||
- mdelay(PCIE_EN7581_RESET_TIME_MS);
|
||||
+ msleep(PCIE_EN7581_RESET_TIME_MS);
|
||||
|
||||
pm_runtime_enable(dev);
|
||||
pm_runtime_get_sync(dev);
|
@ -0,0 +1,131 @@
|
||||
From 491cb9c5084790aafa02e843349492c284373231 Mon Sep 17 00:00:00 2001
|
||||
Message-ID: <491cb9c5084790aafa02e843349492c284373231.1736960708.git.lorenzo@kernel.org>
|
||||
In-Reply-To: <0e7a622da17da0042294860cdb7a2fac091d25b1.1736960708.git.lorenzo@kernel.org>
|
||||
References: <0e7a622da17da0042294860cdb7a2fac091d25b1.1736960708.git.lorenzo@kernel.org>
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Thu, 9 Jan 2025 00:30:45 +0100
|
||||
Subject: [PATCH 6/6] PCI: mediatek-gen3: Avoid PCIe resetting via PERST# for
|
||||
Airoha EN7581 SoC
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Airoha EN7581 has a hw bug asserting/releasing PERST# signal causing
|
||||
occasional PCIe link down issues. In order to overcome the problem,
|
||||
PERST# signal is not asserted/released during device probe or
|
||||
suspend/resume phase and the PCIe block is reset using
|
||||
en7523_reset_assert() and en7581_pci_enable().
|
||||
|
||||
Introduce flags field in the mtk_gen3_pcie_pdata struct in order to
|
||||
specify per-SoC capabilities.
|
||||
|
||||
Link: https://lore.kernel.org/r/20250109-pcie-en7581-rst-fix-v4-1-4a45c89fb143@kernel.org
|
||||
Tested-by: Hui Ma <hui.ma@airoha.com>
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
|
||||
---
|
||||
drivers/pci/controller/pcie-mediatek-gen3.c | 59 ++++++++++++++-------
|
||||
1 file changed, 41 insertions(+), 18 deletions(-)
|
||||
|
||||
--- a/drivers/pci/controller/pcie-mediatek-gen3.c
|
||||
+++ b/drivers/pci/controller/pcie-mediatek-gen3.c
|
||||
@@ -127,10 +127,18 @@
|
||||
|
||||
struct mtk_gen3_pcie;
|
||||
|
||||
+enum mtk_gen3_pcie_flags {
|
||||
+ SKIP_PCIE_RSTB = BIT(0), /* Skip PERST# assertion during device
|
||||
+ * probing or suspend/resume phase to
|
||||
+ * avoid hw bugs/issues.
|
||||
+ */
|
||||
+};
|
||||
+
|
||||
/**
|
||||
* struct mtk_gen3_pcie_pdata - differentiate between host generations
|
||||
* @power_up: pcie power_up callback
|
||||
* @phy_resets: phy reset lines SoC data.
|
||||
+ * @flags: pcie device flags.
|
||||
*/
|
||||
struct mtk_gen3_pcie_pdata {
|
||||
int (*power_up)(struct mtk_gen3_pcie *pcie);
|
||||
@@ -138,6 +146,7 @@ struct mtk_gen3_pcie_pdata {
|
||||
const char *id[MAX_NUM_PHY_RESETS];
|
||||
int num_resets;
|
||||
} phy_resets;
|
||||
+ u32 flags;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -404,22 +413,33 @@ static int mtk_pcie_startup_port(struct
|
||||
val |= PCIE_DISABLE_DVFSRC_VLT_REQ;
|
||||
writel_relaxed(val, pcie->base + PCIE_MISC_CTRL_REG);
|
||||
|
||||
- /* Assert all reset signals */
|
||||
- val = readl_relaxed(pcie->base + PCIE_RST_CTRL_REG);
|
||||
- val |= PCIE_MAC_RSTB | PCIE_PHY_RSTB | PCIE_BRG_RSTB | PCIE_PE_RSTB;
|
||||
- writel_relaxed(val, pcie->base + PCIE_RST_CTRL_REG);
|
||||
-
|
||||
/*
|
||||
- * Described in PCIe CEM specification sections 2.2 (PERST# Signal)
|
||||
- * and 2.2.1 (Initial Power-Up (G3 to S0)).
|
||||
- * The deassertion of PERST# should be delayed 100ms (TPVPERL)
|
||||
- * for the power and clock to become stable.
|
||||
+ * Airoha EN7581 has a hw bug asserting/releasing PCIE_PE_RSTB signal
|
||||
+ * causing occasional PCIe link down. In order to overcome the issue,
|
||||
+ * PCIE_RSTB signals are not asserted/released at this stage and the
|
||||
+ * PCIe block is reset using en7523_reset_assert() and
|
||||
+ * en7581_pci_enable().
|
||||
*/
|
||||
- msleep(100);
|
||||
-
|
||||
- /* De-assert reset signals */
|
||||
- val &= ~(PCIE_MAC_RSTB | PCIE_PHY_RSTB | PCIE_BRG_RSTB | PCIE_PE_RSTB);
|
||||
- writel_relaxed(val, pcie->base + PCIE_RST_CTRL_REG);
|
||||
+ if (!(pcie->soc->flags & SKIP_PCIE_RSTB)) {
|
||||
+ /* Assert all reset signals */
|
||||
+ val = readl_relaxed(pcie->base + PCIE_RST_CTRL_REG);
|
||||
+ val |= PCIE_MAC_RSTB | PCIE_PHY_RSTB | PCIE_BRG_RSTB |
|
||||
+ PCIE_PE_RSTB;
|
||||
+ writel_relaxed(val, pcie->base + PCIE_RST_CTRL_REG);
|
||||
+
|
||||
+ /*
|
||||
+ * Described in PCIe CEM specification revision 6.0.
|
||||
+ *
|
||||
+ * The deassertion of PERST# should be delayed 100ms (TPVPERL)
|
||||
+ * for the power and clock to become stable.
|
||||
+ */
|
||||
+ msleep(PCIE_T_PVPERL_MS);
|
||||
+
|
||||
+ /* De-assert reset signals */
|
||||
+ val &= ~(PCIE_MAC_RSTB | PCIE_PHY_RSTB | PCIE_BRG_RSTB |
|
||||
+ PCIE_PE_RSTB);
|
||||
+ writel_relaxed(val, pcie->base + PCIE_RST_CTRL_REG);
|
||||
+ }
|
||||
|
||||
/* Check if the link is up or not */
|
||||
err = readl_poll_timeout(pcie->base + PCIE_LINK_STATUS_REG, val,
|
||||
@@ -1178,10 +1198,12 @@ static int mtk_pcie_suspend_noirq(struct
|
||||
return err;
|
||||
}
|
||||
|
||||
- /* Pull down the PERST# pin */
|
||||
- val = readl_relaxed(pcie->base + PCIE_RST_CTRL_REG);
|
||||
- val |= PCIE_PE_RSTB;
|
||||
- writel_relaxed(val, pcie->base + PCIE_RST_CTRL_REG);
|
||||
+ if (!(pcie->soc->flags & SKIP_PCIE_RSTB)) {
|
||||
+ /* Assert the PERST# pin */
|
||||
+ val = readl_relaxed(pcie->base + PCIE_RST_CTRL_REG);
|
||||
+ val |= PCIE_PE_RSTB;
|
||||
+ writel_relaxed(val, pcie->base + PCIE_RST_CTRL_REG);
|
||||
+ }
|
||||
|
||||
dev_dbg(pcie->dev, "entered L2 states successfully");
|
||||
|
||||
@@ -1232,6 +1254,7 @@ static const struct mtk_gen3_pcie_pdata
|
||||
.id[2] = "phy-lane2",
|
||||
.num_resets = 3,
|
||||
},
|
||||
+ .flags = SKIP_PCIE_RSTB,
|
||||
};
|
||||
|
||||
static const struct of_device_id mtk_pcie_of_match[] = {
|
@ -1,11 +1,9 @@
|
||||
From 2285d3b428c7d8f1c4fda2fb995e7e46a05350e0 Mon Sep 17 00:00:00 2001
|
||||
Message-ID: <2285d3b428c7d8f1c4fda2fb995e7e46a05350e0.1736324542.git.lorenzo@kernel.org>
|
||||
In-Reply-To: <0c0ae72f5c84c5a29495337b254ac3cc2d5c16bb.1736324541.git.lorenzo@kernel.org>
|
||||
References: <0c0ae72f5c84c5a29495337b254ac3cc2d5c16bb.1736324541.git.lorenzo@kernel.org>
|
||||
From ca4217f3117dceb2d01e179d02031a8758404624 Mon Sep 17 00:00:00 2001
|
||||
Message-ID: <ca4217f3117dceb2d01e179d02031a8758404624.1736961235.git.lorenzo@kernel.org>
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Tue, 3 Sep 2024 23:14:02 +0200
|
||||
Subject: [PATCH 2/2] PCI: mediatek-gen3: configure PBUS_CSR registers for
|
||||
EN7581 SoC
|
||||
Subject: [PATCH] PCI: mediatek-gen3: Configure PBUS_CSR registers for EN7581
|
||||
SoC
|
||||
|
||||
Configure PBus base address and address mask in order to allow the hw
|
||||
detecting if a given address is on PCIE0, PCIE1 or PCIE2.
|
||||
@ -33,9 +31,9 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
#include <linux/reset.h>
|
||||
|
||||
#include "../pci.h"
|
||||
@@ -120,6 +122,13 @@
|
||||
@@ -122,6 +124,13 @@
|
||||
|
||||
#define MAX_NUM_PHY_RESETS 3
|
||||
#define PCIE_MTK_RESET_TIME_US 10
|
||||
|
||||
+#define PCIE_EN7581_PBUS_ADDR(_n) (0x00 + ((_n) << 3))
|
||||
+#define PCIE_EN7581_PBUS_ADDR_MASK(_n) (0x04 + ((_n) << 3))
|
||||
@ -47,7 +45,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
/* Time in ms needed to complete PCIe reset on EN7581 SoC */
|
||||
#define PCIE_EN7581_RESET_TIME_MS 100
|
||||
|
||||
@@ -871,7 +880,8 @@ static int mtk_pcie_parse_port(struct mt
|
||||
@@ -893,7 +902,8 @@ static int mtk_pcie_parse_port(struct mt
|
||||
static int mtk_pcie_en7581_power_up(struct mtk_gen3_pcie *pcie)
|
||||
{
|
||||
struct device *dev = pcie->dev;
|
||||
@ -57,9 +55,9 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
u32 val;
|
||||
|
||||
/*
|
||||
@@ -880,6 +890,23 @@ static int mtk_pcie_en7581_power_up(stru
|
||||
*/
|
||||
mdelay(PCIE_EN7581_RESET_TIME_MS);
|
||||
@@ -907,6 +917,23 @@ static int mtk_pcie_en7581_power_up(stru
|
||||
/* Wait for the time needed to complete the reset lines assert. */
|
||||
msleep(PCIE_EN7581_RESET_TIME_MS);
|
||||
|
||||
+ map = syscon_regmap_lookup_by_compatible("airoha,en7581-pbus-csr");
|
||||
+ if (IS_ERR(map))
|
||||
@ -78,6 +76,6 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
+ regmap_write(map, PCIE_EN7581_PBUS_ADDR_MASK(slot),
|
||||
+ PCIE_EN7581_PBUS_BASE_ADDR_MASK);
|
||||
+
|
||||
err = phy_init(pcie->phy);
|
||||
if (err) {
|
||||
dev_err(dev, "failed to initialize PHY\n");
|
||||
/*
|
||||
* Unlike the other MediaTek Gen3 controllers, the Airoha EN7581
|
||||
* requires PHY initialization and power-on before PHY reset deassert.
|
@ -0,0 +1,26 @@
|
||||
From c4defe43ce17a87e6341d126ba736d9f7ebdc541 Mon Sep 17 00:00:00 2001
|
||||
Message-ID: <c4defe43ce17a87e6341d126ba736d9f7ebdc541.1736962769.git.lorenzo@kernel.org>
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Wed, 15 Jan 2025 18:36:26 +0100
|
||||
Subject: [PATCH] PCI: mediatek-gen3: Remove mac_reset assert leftover for
|
||||
Airoha EN7581 SoC.
|
||||
|
||||
Remove a leftover assert for mac_reset line in mtk_pcie_en7581_power_up().
|
||||
This is not armful since EN7581 does not requires mac_reset and
|
||||
mac_reset is not defined in EN7581 device tree.
|
||||
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
---
|
||||
drivers/pci/controller/pcie-mediatek-gen3.c | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
--- a/drivers/pci/controller/pcie-mediatek-gen3.c
|
||||
+++ b/drivers/pci/controller/pcie-mediatek-gen3.c
|
||||
@@ -912,7 +912,6 @@ static int mtk_pcie_en7581_power_up(stru
|
||||
*/
|
||||
reset_control_bulk_assert(pcie->soc->phy_resets.num_resets,
|
||||
pcie->phy_resets);
|
||||
- reset_control_assert(pcie->mac_reset);
|
||||
|
||||
/* Wait for the time needed to complete the reset lines assert. */
|
||||
msleep(PCIE_EN7581_RESET_TIME_MS);
|
@ -1,83 +0,0 @@
|
||||
From 1ffcc8d41306fd2e5f140b276820714a26a11cc4 Mon Sep 17 00:00:00 2001
|
||||
From: Heiner Kallweit <hkallweit1@gmail.com>
|
||||
Date: Mon, 7 Oct 2024 20:34:12 +0200
|
||||
Subject: [PATCH] r8169: add support for the temperature sensor being available
|
||||
from RTL8125B
|
||||
|
||||
This adds support for the temperature sensor being available from
|
||||
RTL8125B. Register information was taken from r8125 vendor driver.
|
||||
|
||||
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
|
||||
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/ethernet/realtek/r8169_main.c | 44 +++++++++++++++++++++++
|
||||
1 file changed, 44 insertions(+)
|
||||
|
||||
--- a/drivers/net/ethernet/realtek/r8169_main.c
|
||||
+++ b/drivers/net/ethernet/realtek/r8169_main.c
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/ethtool.h>
|
||||
+#include <linux/hwmon.h>
|
||||
#include <linux/phy.h>
|
||||
#include <linux/if_vlan.h>
|
||||
#include <linux/in.h>
|
||||
@@ -5373,6 +5374,43 @@ static bool rtl_aspm_is_safe(struct rtl8
|
||||
return false;
|
||||
}
|
||||
|
||||
+static umode_t r8169_hwmon_is_visible(const void *drvdata,
|
||||
+ enum hwmon_sensor_types type,
|
||||
+ u32 attr, int channel)
|
||||
+{
|
||||
+ return 0444;
|
||||
+}
|
||||
+
|
||||
+static int r8169_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
|
||||
+ u32 attr, int channel, long *val)
|
||||
+{
|
||||
+ struct rtl8169_private *tp = dev_get_drvdata(dev);
|
||||
+ int val_raw;
|
||||
+
|
||||
+ val_raw = phy_read_paged(tp->phydev, 0xbd8, 0x12) & 0x3ff;
|
||||
+ if (val_raw >= 512)
|
||||
+ val_raw -= 1024;
|
||||
+
|
||||
+ *val = 1000 * val_raw / 2;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct hwmon_ops r8169_hwmon_ops = {
|
||||
+ .is_visible = r8169_hwmon_is_visible,
|
||||
+ .read = r8169_hwmon_read,
|
||||
+};
|
||||
+
|
||||
+static const struct hwmon_channel_info * const r8169_hwmon_info[] = {
|
||||
+ HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT),
|
||||
+ NULL
|
||||
+};
|
||||
+
|
||||
+static const struct hwmon_chip_info r8169_hwmon_chip_info = {
|
||||
+ .ops = &r8169_hwmon_ops,
|
||||
+ .info = r8169_hwmon_info,
|
||||
+};
|
||||
+
|
||||
static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
{
|
||||
struct rtl8169_private *tp;
|
||||
@@ -5547,6 +5585,12 @@ static int rtl_init_one(struct pci_dev *
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
+ /* The temperature sensor is available from RTl8125B */
|
||||
+ if (IS_REACHABLE(CONFIG_HWMON) && tp->mac_version >= RTL_GIGA_MAC_VER_63)
|
||||
+ /* ignore errors */
|
||||
+ devm_hwmon_device_register_with_info(&pdev->dev, "nic_temp", tp,
|
||||
+ &r8169_hwmon_chip_info,
|
||||
+ NULL);
|
||||
rc = register_netdev(dev);
|
||||
if (rc)
|
||||
return rc;
|
@ -19,7 +19,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
--- a/drivers/net/ethernet/realtek/r8169_main.c
|
||||
+++ b/drivers/net/ethernet/realtek/r8169_main.c
|
||||
@@ -4779,11 +4779,7 @@ static void r8169_phylink_handler(struct
|
||||
@@ -4778,11 +4778,7 @@ static void r8169_phylink_handler(struct
|
||||
if (netif_carrier_ok(ndev)) {
|
||||
rtl_link_chg_patch(tp);
|
||||
pm_request_resume(d);
|
||||
|
@ -20,7 +20,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
|
||||
--- a/drivers/net/ethernet/realtek/r8169_main.c
|
||||
+++ b/drivers/net/ethernet/realtek/r8169_main.c
|
||||
@@ -5529,11 +5529,6 @@ static int rtl_init_one(struct pci_dev *
|
||||
@@ -5491,11 +5491,6 @@ static int rtl_init_one(struct pci_dev *
|
||||
|
||||
dev->features |= dev->hw_features;
|
||||
|
||||
@ -32,7 +32,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
if (rtl_chip_supports_csum_v2(tp)) {
|
||||
dev->hw_features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6;
|
||||
netif_set_tso_max_size(dev, RTL_GSO_MAX_SIZE_V2);
|
||||
@@ -5544,6 +5539,17 @@ static int rtl_init_one(struct pci_dev *
|
||||
@@ -5506,6 +5501,17 @@ static int rtl_init_one(struct pci_dev *
|
||||
netif_set_tso_max_segs(dev, RTL_GSO_MAX_SEGS_V1);
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
--- a/drivers/net/ethernet/realtek/r8169_main.c
|
||||
+++ b/drivers/net/ethernet/realtek/r8169_main.c
|
||||
@@ -2162,6 +2162,19 @@ static void rtl8169_get_ringparam(struct
|
||||
@@ -2161,6 +2161,19 @@ static void rtl8169_get_ringparam(struct
|
||||
data->tx_pending = NUM_TX_DESC;
|
||||
}
|
||||
|
||||
@ -36,7 +36,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
static void rtl8169_get_pauseparam(struct net_device *dev,
|
||||
struct ethtool_pauseparam *data)
|
||||
{
|
||||
@@ -2188,6 +2201,69 @@ static int rtl8169_set_pauseparam(struct
|
||||
@@ -2187,6 +2200,69 @@ static int rtl8169_set_pauseparam(struct
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -106,7 +106,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
static const struct ethtool_ops rtl8169_ethtool_ops = {
|
||||
.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
|
||||
ETHTOOL_COALESCE_MAX_FRAMES,
|
||||
@@ -2209,8 +2285,11 @@ static const struct ethtool_ops rtl8169_
|
||||
@@ -2208,8 +2284,11 @@ static const struct ethtool_ops rtl8169_
|
||||
.get_link_ksettings = phy_ethtool_get_link_ksettings,
|
||||
.set_link_ksettings = phy_ethtool_set_link_ksettings,
|
||||
.get_ringparam = rtl8169_get_ringparam,
|
||||
@ -118,7 +118,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
};
|
||||
|
||||
static enum mac_version rtl8169_get_mac_version(u16 xid, bool gmii)
|
||||
@@ -3895,6 +3974,9 @@ static void rtl_hw_start_8125(struct rtl
|
||||
@@ -3894,6 +3973,9 @@ static void rtl_hw_start_8125(struct rtl
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,7 @@ Signed-off-by: Andrew Lunn <andrew@lunn.ch>
|
||||
|
||||
--- a/drivers/net/ethernet/realtek/r8169_main.c
|
||||
+++ b/drivers/net/ethernet/realtek/r8169_main.c
|
||||
@@ -4802,10 +4802,8 @@ static void rtl_task(struct work_struct
|
||||
@@ -4801,10 +4801,8 @@ static void rtl_task(struct work_struct
|
||||
container_of(work, struct rtl8169_private, wk.work);
|
||||
int ret;
|
||||
|
||||
@ -30,7 +30,7 @@ Signed-off-by: Andrew Lunn <andrew@lunn.ch>
|
||||
|
||||
if (test_and_clear_bit(RTL_FLAG_TASK_TX_TIMEOUT, tp->wk.flags)) {
|
||||
/* if chip isn't accessible, reset bus to revive it */
|
||||
@@ -4814,7 +4812,7 @@ static void rtl_task(struct work_struct
|
||||
@@ -4813,7 +4811,7 @@ static void rtl_task(struct work_struct
|
||||
if (ret < 0) {
|
||||
netdev_err(tp->dev, "Can't reset secondary PCI bus, detach NIC\n");
|
||||
netif_device_detach(tp->dev);
|
||||
@ -39,7 +39,7 @@ Signed-off-by: Andrew Lunn <andrew@lunn.ch>
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4833,8 +4831,6 @@ reset:
|
||||
@@ -4832,8 +4830,6 @@ reset:
|
||||
} else if (test_and_clear_bit(RTL_FLAG_TASK_RESET_NO_QUEUE_WAKE, tp->wk.flags)) {
|
||||
rtl_reset_work(tp);
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ Signed-off-by: Andrew Lunn <andrew@lunn.ch>
|
||||
|
||||
--- a/drivers/net/ethernet/realtek/r8169_main.c
|
||||
+++ b/drivers/net/ethernet/realtek/r8169_main.c
|
||||
@@ -1347,40 +1347,19 @@ static void rtl8168ep_stop_cmac(struct r
|
||||
@@ -1346,40 +1346,19 @@ static void rtl8168ep_stop_cmac(struct r
|
||||
RTL_W8(tp, IBCR0, RTL_R8(tp, IBCR0) & ~0x01);
|
||||
}
|
||||
|
||||
@ -60,7 +60,7 @@ Signed-off-by: Andrew Lunn <andrew@lunn.ch>
|
||||
}
|
||||
|
||||
static void rtl8168_driver_start(struct rtl8169_private *tp)
|
||||
@@ -1394,7 +1373,8 @@ static void rtl8168_driver_start(struct
|
||||
@@ -1393,7 +1372,8 @@ static void rtl8168_driver_start(struct
|
||||
static void rtl8168dp_driver_stop(struct rtl8169_private *tp)
|
||||
{
|
||||
r8168dp_oob_notify(tp, OOB_CMD_DRIVER_STOP);
|
||||
@ -70,7 +70,7 @@ Signed-off-by: Andrew Lunn <andrew@lunn.ch>
|
||||
}
|
||||
|
||||
static void rtl8168ep_driver_stop(struct rtl8169_private *tp)
|
||||
@@ -1402,7 +1382,8 @@ static void rtl8168ep_driver_stop(struct
|
||||
@@ -1401,7 +1381,8 @@ static void rtl8168ep_driver_stop(struct
|
||||
rtl8168ep_stop_cmac(tp);
|
||||
r8168ep_ocp_write(tp, 0x01, 0x180, OOB_CMD_DRIVER_STOP);
|
||||
r8168ep_ocp_write(tp, 0x01, 0x30, r8168ep_ocp_read(tp, 0x30) | 0x01);
|
||||
|
@ -29,7 +29,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
RTL_GIGA_MAC_NONE
|
||||
--- a/drivers/net/ethernet/realtek/r8169_main.c
|
||||
+++ b/drivers/net/ethernet/realtek/r8169_main.c
|
||||
@@ -56,6 +56,7 @@
|
||||
@@ -55,6 +55,7 @@
|
||||
#define FIRMWARE_8107E_2 "rtl_nic/rtl8107e-2.fw"
|
||||
#define FIRMWARE_8125A_3 "rtl_nic/rtl8125a-3.fw"
|
||||
#define FIRMWARE_8125B_2 "rtl_nic/rtl8125b-2.fw"
|
||||
@ -37,7 +37,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
#define FIRMWARE_8126A_2 "rtl_nic/rtl8126a-2.fw"
|
||||
#define FIRMWARE_8126A_3 "rtl_nic/rtl8126a-3.fw"
|
||||
|
||||
@@ -139,6 +140,7 @@ static const struct {
|
||||
@@ -138,6 +139,7 @@ static const struct {
|
||||
[RTL_GIGA_MAC_VER_61] = {"RTL8125A", FIRMWARE_8125A_3},
|
||||
/* reserve 62 for CFG_METHOD_4 in the vendor driver */
|
||||
[RTL_GIGA_MAC_VER_63] = {"RTL8125B", FIRMWARE_8125B_2},
|
||||
@ -45,7 +45,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
[RTL_GIGA_MAC_VER_65] = {"RTL8126A", FIRMWARE_8126A_2},
|
||||
[RTL_GIGA_MAC_VER_66] = {"RTL8126A", FIRMWARE_8126A_3},
|
||||
};
|
||||
@@ -708,6 +710,7 @@ MODULE_FIRMWARE(FIRMWARE_8168FP_3);
|
||||
@@ -707,6 +709,7 @@ MODULE_FIRMWARE(FIRMWARE_8168FP_3);
|
||||
MODULE_FIRMWARE(FIRMWARE_8107E_2);
|
||||
MODULE_FIRMWARE(FIRMWARE_8125A_3);
|
||||
MODULE_FIRMWARE(FIRMWARE_8125B_2);
|
||||
@ -53,7 +53,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
MODULE_FIRMWARE(FIRMWARE_8126A_2);
|
||||
MODULE_FIRMWARE(FIRMWARE_8126A_3);
|
||||
|
||||
@@ -2080,10 +2083,7 @@ static void rtl_set_eee_txidle_timer(str
|
||||
@@ -2079,10 +2082,7 @@ static void rtl_set_eee_txidle_timer(str
|
||||
tp->tx_lpi_timer = timer_val;
|
||||
r8168_mac_ocp_write(tp, 0xe048, timer_val);
|
||||
break;
|
||||
@ -65,7 +65,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
tp->tx_lpi_timer = timer_val;
|
||||
RTL_W16(tp, EEE_TXIDLE_TIMER_8125, timer_val);
|
||||
break;
|
||||
@@ -2295,6 +2295,9 @@ static enum mac_version rtl8169_get_mac_
|
||||
@@ -2294,6 +2294,9 @@ static enum mac_version rtl8169_get_mac_
|
||||
{ 0x7cf, 0x64a, RTL_GIGA_MAC_VER_66 },
|
||||
{ 0x7cf, 0x649, RTL_GIGA_MAC_VER_65 },
|
||||
|
||||
@ -75,7 +75,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
/* 8125B family. */
|
||||
{ 0x7cf, 0x641, RTL_GIGA_MAC_VER_63 },
|
||||
|
||||
@@ -2562,9 +2565,7 @@ static void rtl_init_rxcfg(struct rtl816
|
||||
@@ -2561,9 +2564,7 @@ static void rtl_init_rxcfg(struct rtl816
|
||||
case RTL_GIGA_MAC_VER_61:
|
||||
RTL_W32(tp, RxConfig, RX_FETCH_DFLT_8125 | RX_DMA_BURST);
|
||||
break;
|
||||
@ -86,7 +86,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
RTL_W32(tp, RxConfig, RX_FETCH_DFLT_8125 | RX_DMA_BURST |
|
||||
RX_PAUSE_SLOT_ON);
|
||||
break;
|
||||
@@ -3876,6 +3877,12 @@ static void rtl_hw_start_8125b(struct rt
|
||||
@@ -3875,6 +3876,12 @@ static void rtl_hw_start_8125b(struct rt
|
||||
rtl_hw_start_8125_common(tp);
|
||||
}
|
||||
|
||||
@ -99,7 +99,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
static void rtl_hw_start_8126a(struct rtl8169_private *tp)
|
||||
{
|
||||
rtl_set_def_aspm_entry_latency(tp);
|
||||
@@ -3924,6 +3931,7 @@ static void rtl_hw_config(struct rtl8169
|
||||
@@ -3923,6 +3930,7 @@ static void rtl_hw_config(struct rtl8169
|
||||
[RTL_GIGA_MAC_VER_53] = rtl_hw_start_8117,
|
||||
[RTL_GIGA_MAC_VER_61] = rtl_hw_start_8125a_2,
|
||||
[RTL_GIGA_MAC_VER_63] = rtl_hw_start_8125b,
|
||||
@ -107,7 +107,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
[RTL_GIGA_MAC_VER_65] = rtl_hw_start_8126a,
|
||||
[RTL_GIGA_MAC_VER_66] = rtl_hw_start_8126a,
|
||||
};
|
||||
@@ -3941,6 +3949,7 @@ static void rtl_hw_start_8125(struct rtl
|
||||
@@ -3940,6 +3948,7 @@ static void rtl_hw_start_8125(struct rtl
|
||||
/* disable interrupt coalescing */
|
||||
switch (tp->mac_version) {
|
||||
case RTL_GIGA_MAC_VER_61:
|
||||
|
@ -19,7 +19,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
--- a/drivers/net/ethernet/realtek/r8169_main.c
|
||||
+++ b/drivers/net/ethernet/realtek/r8169_main.c
|
||||
@@ -2227,7 +2227,7 @@ static void rtl8169_get_eth_mac_stats(st
|
||||
@@ -2226,7 +2226,7 @@ static void rtl8169_get_eth_mac_stats(st
|
||||
le64_to_cpu(tp->counters->tx_broadcast64);
|
||||
mac_stats->MulticastFramesReceivedOK =
|
||||
le64_to_cpu(tp->counters->rx_multicast64);
|
||||
|
@ -16,7 +16,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
--- a/drivers/net/ethernet/realtek/r8169_main.c
|
||||
+++ b/drivers/net/ethernet/realtek/r8169_main.c
|
||||
@@ -347,6 +347,8 @@ enum rtl8125_registers {
|
||||
@@ -346,6 +346,8 @@ enum rtl8125_registers {
|
||||
TxPoll_8125 = 0x90,
|
||||
LEDSEL3 = 0x96,
|
||||
MAC0_BKP = 0x19e0,
|
||||
@ -25,7 +25,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
EEE_TXIDLE_TIMER_8125 = 0x6048,
|
||||
};
|
||||
|
||||
@@ -3770,8 +3772,8 @@ static void rtl_hw_start_8125_common(str
|
||||
@@ -3769,8 +3771,8 @@ static void rtl_hw_start_8125_common(str
|
||||
rtl_pcie_state_l2l3_disable(tp);
|
||||
|
||||
RTL_W16(tp, 0x382, 0x221b);
|
||||
|
@ -15,7 +15,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
--- a/drivers/net/ethernet/realtek/r8169_main.c
|
||||
+++ b/drivers/net/ethernet/realtek/r8169_main.c
|
||||
@@ -663,13 +663,9 @@ struct rtl8169_private {
|
||||
@@ -662,13 +662,9 @@ struct rtl8169_private {
|
||||
struct work_struct work;
|
||||
} wk;
|
||||
|
||||
@ -29,7 +29,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
unsigned supports_gmii:1;
|
||||
unsigned aspm_manageable:1;
|
||||
unsigned dash_enabled:1;
|
||||
@@ -723,22 +719,12 @@ static inline struct device *tp_to_dev(s
|
||||
@@ -722,22 +718,12 @@ static inline struct device *tp_to_dev(s
|
||||
|
||||
static void rtl_lock_config_regs(struct rtl8169_private *tp)
|
||||
{
|
||||
@ -54,7 +54,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
}
|
||||
|
||||
static void rtl_pci_commit(struct rtl8169_private *tp)
|
||||
@@ -749,24 +735,18 @@ static void rtl_pci_commit(struct rtl816
|
||||
@@ -748,24 +734,18 @@ static void rtl_pci_commit(struct rtl816
|
||||
|
||||
static void rtl_mod_config2(struct rtl8169_private *tp, u8 clear, u8 set)
|
||||
{
|
||||
@ -79,7 +79,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
}
|
||||
|
||||
static bool rtl_is_8125(struct rtl8169_private *tp)
|
||||
@@ -1572,7 +1552,6 @@ static void __rtl8169_set_wol(struct rtl
|
||||
@@ -1571,7 +1551,6 @@ static void __rtl8169_set_wol(struct rtl
|
||||
{ WAKE_MAGIC, Config3, MagicPacket }
|
||||
};
|
||||
unsigned int i, tmp = ARRAY_SIZE(cfg);
|
||||
@ -87,7 +87,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
u8 options;
|
||||
|
||||
rtl_unlock_config_regs(tp);
|
||||
@@ -1591,14 +1570,12 @@ static void __rtl8169_set_wol(struct rtl
|
||||
@@ -1590,14 +1569,12 @@ static void __rtl8169_set_wol(struct rtl
|
||||
r8168_mac_ocp_modify(tp, 0xc0b6, BIT(0), 0);
|
||||
}
|
||||
|
||||
@ -102,7 +102,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
switch (tp->mac_version) {
|
||||
case RTL_GIGA_MAC_VER_02 ... RTL_GIGA_MAC_VER_06:
|
||||
@@ -5498,8 +5475,6 @@ static int rtl_init_one(struct pci_dev *
|
||||
@@ -5460,8 +5437,6 @@ static int rtl_init_one(struct pci_dev *
|
||||
tp->supports_gmii = ent->driver_data == RTL_CFG_NO_GBIT ? 0 : 1;
|
||||
tp->ocp_base = OCP_STD_PHY_BASE;
|
||||
|
||||
|
@ -16,7 +16,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
--- a/drivers/net/ethernet/realtek/r8169_main.c
|
||||
+++ b/drivers/net/ethernet/realtek/r8169_main.c
|
||||
@@ -749,6 +749,20 @@ static void rtl_mod_config5(struct rtl81
|
||||
@@ -748,6 +748,20 @@ static void rtl_mod_config5(struct rtl81
|
||||
RTL_W8(tp, Config5, (val & ~clear) | set);
|
||||
}
|
||||
|
||||
@ -37,7 +37,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
static bool rtl_is_8125(struct rtl8169_private *tp)
|
||||
{
|
||||
return tp->mac_version >= RTL_GIGA_MAC_VER_61;
|
||||
@@ -1539,58 +1553,37 @@ static void rtl8169_get_wol(struct net_d
|
||||
@@ -1538,58 +1552,37 @@ static void rtl8169_get_wol(struct net_d
|
||||
|
||||
static void __rtl8169_set_wol(struct rtl8169_private *tp, u32 wolopts)
|
||||
{
|
||||
|
@ -17,7 +17,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
--- a/drivers/net/ethernet/realtek/r8169_main.c
|
||||
+++ b/drivers/net/ethernet/realtek/r8169_main.c
|
||||
@@ -1432,19 +1432,11 @@ static enum rtl_dash_type rtl_get_dash_t
|
||||
@@ -1431,19 +1431,11 @@ static enum rtl_dash_type rtl_get_dash_t
|
||||
|
||||
static void rtl_set_d3_pll_down(struct rtl8169_private *tp, bool enable)
|
||||
{
|
||||
|
@ -17,7 +17,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
--- a/drivers/net/ethernet/realtek/r8169_main.c
|
||||
+++ b/drivers/net/ethernet/realtek/r8169_main.c
|
||||
@@ -1563,6 +1563,9 @@ static void __rtl8169_set_wol(struct rtl
|
||||
@@ -1562,6 +1562,9 @@ static void __rtl8169_set_wol(struct rtl
|
||||
}
|
||||
|
||||
r8169_mod_reg8_cond(tp, Config3, LinkUp, wolopts & WAKE_PHY);
|
||||
|
@ -17,7 +17,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
--- a/drivers/net/ethernet/realtek/r8169_main.c
|
||||
+++ b/drivers/net/ethernet/realtek/r8169_main.c
|
||||
@@ -2547,86 +2547,31 @@ static void rtl8169_init_ring_indexes(st
|
||||
@@ -2546,86 +2546,31 @@ static void rtl8169_init_ring_indexes(st
|
||||
tp->dirty_tx = tp->cur_tx = tp->cur_rx = 0;
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,52 @@
|
||||
From 34d5a86ff7bbe225fba3ad91f9b4dc85fb408e18 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Wed, 15 Jan 2025 14:43:35 +0000
|
||||
Subject: [PATCH] net: phy: realtek: clear 1000Base-T lpa if link is down
|
||||
|
||||
Only read 1000Base-T link partner advertisement if autonegotiation has
|
||||
completed and otherwise 1000Base-T link partner advertisement bits.
|
||||
|
||||
This fixes bogus 1000Base-T link partner advertisement after link goes
|
||||
down (eg. by disconnecting the wire).
|
||||
Fixes: 5cb409b3960e ("net: phy: realtek: clear 1000Base-T link partner advertisement")
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Reviewed-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/phy/realtek.c | 19 ++++++++-----------
|
||||
1 file changed, 8 insertions(+), 11 deletions(-)
|
||||
|
||||
--- a/drivers/net/phy/realtek.c
|
||||
+++ b/drivers/net/phy/realtek.c
|
||||
@@ -1023,23 +1023,20 @@ static int rtl822x_c45_read_status(struc
|
||||
{
|
||||
int ret, val;
|
||||
|
||||
- ret = genphy_c45_read_status(phydev);
|
||||
- if (ret < 0)
|
||||
- return ret;
|
||||
-
|
||||
- if (phydev->autoneg == AUTONEG_DISABLE ||
|
||||
- !genphy_c45_aneg_done(phydev))
|
||||
- mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, 0);
|
||||
-
|
||||
/* Vendor register as C45 has no standardized support for 1000BaseT */
|
||||
- if (phydev->autoneg == AUTONEG_ENABLE) {
|
||||
+ if (phydev->autoneg == AUTONEG_ENABLE && genphy_c45_aneg_done(phydev)) {
|
||||
val = phy_read_mmd(phydev, MDIO_MMD_VEND2,
|
||||
RTL822X_VND2_GANLPAR);
|
||||
if (val < 0)
|
||||
return val;
|
||||
-
|
||||
- mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, val);
|
||||
+ } else {
|
||||
+ val = 0;
|
||||
}
|
||||
+ mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, val);
|
||||
+
|
||||
+ ret = genphy_c45_read_status(phydev);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
|
||||
if (!phydev->link)
|
||||
return 0;
|
@ -0,0 +1,35 @@
|
||||
From ea8318cb33e593bbfc59d637eae45a69732c5387 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Wed, 15 Jan 2025 14:43:43 +0000
|
||||
Subject: [PATCH] net: phy: realtek: clear master_slave_state if link is down
|
||||
|
||||
rtlgen_decode_physr() which sets master_slave_state isn't called in case
|
||||
the link is down and other than rtlgen_read_status(),
|
||||
rtl822x_c45_read_status() doesn't implicitely clear master_slave_state.
|
||||
|
||||
Avoid stale master_slave_state by always setting it to
|
||||
MASTER_SLAVE_STATE_UNKNOWN in rtl822x_c45_read_status() in case the link
|
||||
is down.
|
||||
|
||||
Fixes: 081c9c0265c9 ("net: phy: realtek: read duplex and gbit master from PHYSR register")
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Reviewed-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/phy/realtek.c | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/phy/realtek.c
|
||||
+++ b/drivers/net/phy/realtek.c
|
||||
@@ -1038,8 +1038,10 @@ static int rtl822x_c45_read_status(struc
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
- if (!phydev->link)
|
||||
+ if (!phydev->link) {
|
||||
+ phydev->master_slave_state = MASTER_SLAVE_STATE_UNKNOWN;
|
||||
return 0;
|
||||
+ }
|
||||
|
||||
/* Read actual speed from vendor register. */
|
||||
val = phy_read_mmd(phydev, MDIO_MMD_VEND2, RTL_VND2_PHYSR);
|
@ -0,0 +1,42 @@
|
||||
From d3eb58549842c60ed46f37da7f4da969e3d6ecd3 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Wed, 15 Jan 2025 14:45:00 +0000
|
||||
Subject: [PATCH] net: phy: realtek: always clear NBase-T lpa
|
||||
|
||||
Clear NBase-T link partner advertisement before calling
|
||||
rtlgen_read_status() to avoid phy_resolve_aneg_linkmode() wrongly
|
||||
setting speed and duplex.
|
||||
|
||||
This fixes bogus 2.5G/5G/10G link partner advertisement and thus
|
||||
speed and duplex being set by phy_resolve_aneg_linkmode() due to stale
|
||||
NBase-T lpa.
|
||||
|
||||
Fixes: 68d5cd09e891 ("net: phy: realtek: change order of calls in C22 read_status()")
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Reviewed-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/phy/realtek.c | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/drivers/net/phy/realtek.c
|
||||
+++ b/drivers/net/phy/realtek.c
|
||||
@@ -952,15 +952,15 @@ static int rtl822x_read_status(struct ph
|
||||
{
|
||||
int lpadv, ret;
|
||||
|
||||
+ mii_10gbt_stat_mod_linkmode_lpa_t(phydev->lp_advertising, 0);
|
||||
+
|
||||
ret = rtlgen_read_status(phydev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (phydev->autoneg == AUTONEG_DISABLE ||
|
||||
- !phydev->autoneg_complete) {
|
||||
- mii_10gbt_stat_mod_linkmode_lpa_t(phydev->lp_advertising, 0);
|
||||
+ !phydev->autoneg_complete)
|
||||
return 0;
|
||||
- }
|
||||
|
||||
lpadv = phy_read_paged(phydev, 0xa5d, 0x13);
|
||||
if (lpadv < 0)
|
@ -0,0 +1,47 @@
|
||||
From 3d483a10327f38595f714f9f9e9dde43a622cb0f Mon Sep 17 00:00:00 2001
|
||||
From: Heiner Kallweit <hkallweit1@gmail.com>
|
||||
Date: Sat, 11 Jan 2025 21:49:31 +0100
|
||||
Subject: [PATCH] net: phy: realtek: add support for reading MDIO_MMD_VEND2
|
||||
regs on RTL8125/RTL8126
|
||||
|
||||
RTL8125/RTL8126 don't support MMD access to the internal PHY, but
|
||||
provide a mechanism to access at least all MDIO_MMD_VEND2 registers.
|
||||
By exposing this mechanism standard MMD access functions can be used
|
||||
to access the MDIO_MMD_VEND2 registers.
|
||||
|
||||
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Link: https://patch.msgid.link/e821b302-5fe6-49ab-aabd-05da500581c0@gmail.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/phy/realtek.c | 12 ++++++++++--
|
||||
1 file changed, 10 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/phy/realtek.c
|
||||
+++ b/drivers/net/phy/realtek.c
|
||||
@@ -736,7 +736,11 @@ static int rtlgen_read_mmd(struct phy_de
|
||||
{
|
||||
int ret;
|
||||
|
||||
- if (devnum == MDIO_MMD_PCS && regnum == MDIO_PCS_EEE_ABLE) {
|
||||
+ if (devnum == MDIO_MMD_VEND2) {
|
||||
+ rtl821x_write_page(phydev, regnum >> 4);
|
||||
+ ret = __phy_read(phydev, 0x10 + ((regnum & 0xf) >> 1));
|
||||
+ rtl821x_write_page(phydev, 0);
|
||||
+ } else if (devnum == MDIO_MMD_PCS && regnum == MDIO_PCS_EEE_ABLE) {
|
||||
rtl821x_write_page(phydev, 0xa5c);
|
||||
ret = __phy_read(phydev, 0x12);
|
||||
rtl821x_write_page(phydev, 0);
|
||||
@@ -760,7 +764,11 @@ static int rtlgen_write_mmd(struct phy_d
|
||||
{
|
||||
int ret;
|
||||
|
||||
- if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV) {
|
||||
+ if (devnum == MDIO_MMD_VEND2) {
|
||||
+ rtl821x_write_page(phydev, regnum >> 4);
|
||||
+ ret = __phy_write(phydev, 0x10 + ((regnum & 0xf) >> 1), val);
|
||||
+ rtl821x_write_page(phydev, 0);
|
||||
+ } else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV) {
|
||||
rtl821x_write_page(phydev, 0xa5d);
|
||||
ret = __phy_write(phydev, 0x10, val);
|
||||
rtl821x_write_page(phydev, 0);
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,180 @@
|
||||
From 33700ca45b7d2e1655d4cad95e25671e8a94e2f0 Mon Sep 17 00:00:00 2001
|
||||
From: Heiner Kallweit <hkallweit1@gmail.com>
|
||||
Date: Sat, 11 Jan 2025 21:51:24 +0100
|
||||
Subject: [PATCH] net: phy: realtek: add hwmon support for temp sensor on
|
||||
RTL822x
|
||||
|
||||
This adds hwmon support for the temperature sensor on RTL822x.
|
||||
It's available on the standalone versions of the PHY's, and on
|
||||
the integrated PHY's in RTL8125B/RTL8125D/RTL8126.
|
||||
|
||||
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Link: https://patch.msgid.link/ad6bfe9f-6375-4a00-84b4-bfb38a21bd71@gmail.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/phy/realtek/Kconfig | 6 ++
|
||||
drivers/net/phy/realtek/Makefile | 1 +
|
||||
drivers/net/phy/realtek/realtek.h | 10 ++++
|
||||
drivers/net/phy/realtek/realtek_hwmon.c | 79 +++++++++++++++++++++++++
|
||||
drivers/net/phy/realtek/realtek_main.c | 12 ++++
|
||||
5 files changed, 108 insertions(+)
|
||||
create mode 100644 drivers/net/phy/realtek/realtek.h
|
||||
create mode 100644 drivers/net/phy/realtek/realtek_hwmon.c
|
||||
|
||||
--- a/drivers/net/phy/realtek/Kconfig
|
||||
+++ b/drivers/net/phy/realtek/Kconfig
|
||||
@@ -3,3 +3,9 @@ config REALTEK_PHY
|
||||
tristate "Realtek PHYs"
|
||||
help
|
||||
Currently supports RTL821x/RTL822x and fast ethernet PHYs
|
||||
+
|
||||
+config REALTEK_PHY_HWMON
|
||||
+ def_bool REALTEK_PHY && HWMON
|
||||
+ depends on !(REALTEK_PHY=y && HWMON=m)
|
||||
+ help
|
||||
+ Optional hwmon support for the temperature sensor
|
||||
--- a/drivers/net/phy/realtek/Makefile
|
||||
+++ b/drivers/net/phy/realtek/Makefile
|
||||
@@ -1,3 +1,4 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
realtek-y += realtek_main.o
|
||||
+realtek-$(CONFIG_REALTEK_PHY_HWMON) += realtek_hwmon.o
|
||||
obj-$(CONFIG_REALTEK_PHY) += realtek.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/phy/realtek/realtek.h
|
||||
@@ -0,0 +1,10 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0 */
|
||||
+
|
||||
+#ifndef REALTEK_H
|
||||
+#define REALTEK_H
|
||||
+
|
||||
+#include <linux/phy.h>
|
||||
+
|
||||
+int rtl822x_hwmon_init(struct phy_device *phydev);
|
||||
+
|
||||
+#endif /* REALTEK_H */
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/phy/realtek/realtek_hwmon.c
|
||||
@@ -0,0 +1,86 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0+
|
||||
+/*
|
||||
+ * HWMON support for Realtek PHY's
|
||||
+ *
|
||||
+ * Author: Heiner Kallweit <hkallweit1@gmail.com>
|
||||
+ */
|
||||
+
|
||||
+#include <linux/hwmon.h>
|
||||
+#include <linux/phy.h>
|
||||
+
|
||||
+#include "realtek.h"
|
||||
+
|
||||
+#define RTL822X_VND2_TSALRM 0xa662
|
||||
+#define RTL822X_VND2_TSRR 0xbd84
|
||||
+#define RTL822X_VND2_TSSR 0xb54c
|
||||
+
|
||||
+static umode_t rtl822x_hwmon_is_visible(const void *drvdata,
|
||||
+ enum hwmon_sensor_types type,
|
||||
+ u32 attr, int channel)
|
||||
+{
|
||||
+ return 0444;
|
||||
+}
|
||||
+
|
||||
+static int rtl822x_hwmon_get_temp(int raw)
|
||||
+{
|
||||
+ if (raw >= 512)
|
||||
+ raw -= 1024;
|
||||
+
|
||||
+ return 1000 * raw / 2;
|
||||
+}
|
||||
+
|
||||
+static int rtl822x_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
|
||||
+ u32 attr, int channel, long *val)
|
||||
+{
|
||||
+ struct phy_device *phydev = dev_get_drvdata(dev);
|
||||
+ int raw;
|
||||
+
|
||||
+ switch (attr) {
|
||||
+ case hwmon_temp_input:
|
||||
+ raw = phy_read_mmd(phydev, MDIO_MMD_VEND2, RTL822X_VND2_TSRR) & 0x3ff;
|
||||
+ *val = rtl822x_hwmon_get_temp(raw);
|
||||
+ break;
|
||||
+ case hwmon_temp_max:
|
||||
+ /* Chip reduces speed to 1G if threshold is exceeded */
|
||||
+ raw = phy_read_mmd(phydev, MDIO_MMD_VEND2, RTL822X_VND2_TSSR) >> 6;
|
||||
+ *val = rtl822x_hwmon_get_temp(raw);
|
||||
+ break;
|
||||
+ default:
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct hwmon_ops rtl822x_hwmon_ops = {
|
||||
+ .is_visible = rtl822x_hwmon_is_visible,
|
||||
+ .read = rtl822x_hwmon_read,
|
||||
+};
|
||||
+
|
||||
+static const struct hwmon_channel_info * const rtl822x_hwmon_info[] = {
|
||||
+ HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT | HWMON_T_MAX),
|
||||
+ NULL
|
||||
+};
|
||||
+
|
||||
+static const struct hwmon_chip_info rtl822x_hwmon_chip_info = {
|
||||
+ .ops = &rtl822x_hwmon_ops,
|
||||
+ .info = rtl822x_hwmon_info,
|
||||
+};
|
||||
+
|
||||
+int rtl822x_hwmon_init(struct phy_device *phydev)
|
||||
+{
|
||||
+ struct device *hwdev, *dev = &phydev->mdio.dev;
|
||||
+ const char *name;
|
||||
+
|
||||
+ /* Ensure over-temp alarm is reset. */
|
||||
+ phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, RTL822X_VND2_TSALRM, 3);
|
||||
+
|
||||
+ name = devm_hwmon_sanitize_name(dev, dev_name(dev));
|
||||
+ if (IS_ERR(name))
|
||||
+ return PTR_ERR(name);
|
||||
+
|
||||
+ hwdev = devm_hwmon_device_register_with_info(dev, name, phydev,
|
||||
+ &rtl822x_hwmon_chip_info,
|
||||
+ NULL);
|
||||
+ return PTR_ERR_OR_ZERO(hwdev);
|
||||
+}
|
||||
--- a/drivers/net/phy/realtek/realtek_main.c
|
||||
+++ b/drivers/net/phy/realtek/realtek_main.c
|
||||
@@ -14,6 +14,8 @@
|
||||
#include <linux/delay.h>
|
||||
#include <linux/clk.h>
|
||||
|
||||
+#include "realtek.h"
|
||||
+
|
||||
#define RTL821x_PHYSR 0x11
|
||||
#define RTL821x_PHYSR_DUPLEX BIT(13)
|
||||
#define RTL821x_PHYSR_SPEED GENMASK(15, 14)
|
||||
@@ -820,6 +822,15 @@ static int rtl822x_write_mmd(struct phy_
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static int rtl822x_probe(struct phy_device *phydev)
|
||||
+{
|
||||
+ if (IS_ENABLED(CONFIG_REALTEK_PHY_HWMON) &&
|
||||
+ phydev->phy_id != RTL_GENERIC_PHYID)
|
||||
+ return rtl822x_hwmon_init(phydev);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int rtl822xb_config_init(struct phy_device *phydev)
|
||||
{
|
||||
bool has_2500, has_sgmii;
|
||||
@@ -1518,6 +1529,7 @@ static struct phy_driver realtek_drvs[]
|
||||
.match_phy_device = rtl_internal_nbaset_match_phy_device,
|
||||
.name = "Realtek Internal NBASE-T PHY",
|
||||
.flags = PHY_IS_INTERNAL,
|
||||
+ .probe = rtl822x_probe,
|
||||
.get_features = rtl822x_get_features,
|
||||
.config_aneg = rtl822x_config_aneg,
|
||||
.read_status = rtl822x_read_status,
|
@ -10,12 +10,12 @@ the PHY.
|
||||
Reported-by: Yevhen Kolomeiko <jarvis2709@gmail.com>
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
drivers/net/phy/realtek.c | 6 ++++++
|
||||
drivers/net/phy/realtek/realtek_main.c | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
--- a/drivers/net/phy/realtek.c
|
||||
+++ b/drivers/net/phy/realtek.c
|
||||
@@ -1412,6 +1412,7 @@ static struct phy_driver realtek_drvs[]
|
||||
--- a/drivers/net/phy/realtek/realtek_main.c
|
||||
+++ b/drivers/net/phy/realtek/realtek_main.c
|
||||
@@ -1430,6 +1430,7 @@ static struct phy_driver realtek_drvs[]
|
||||
}, {
|
||||
.name = "RTL8226 2.5Gbps PHY",
|
||||
.match_phy_device = rtl8226_match_phy_device,
|
||||
@ -23,7 +23,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
.get_features = rtl822x_get_features,
|
||||
.config_aneg = rtl822x_config_aneg,
|
||||
.read_status = rtl822x_read_status,
|
||||
@@ -1422,6 +1423,7 @@ static struct phy_driver realtek_drvs[]
|
||||
@@ -1440,6 +1441,7 @@ static struct phy_driver realtek_drvs[]
|
||||
}, {
|
||||
.match_phy_device = rtl8221b_match_phy_device,
|
||||
.name = "RTL8226B_RTL8221B 2.5Gbps PHY",
|
||||
@ -31,7 +31,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
.get_features = rtl822x_get_features,
|
||||
.config_aneg = rtl822x_config_aneg,
|
||||
.config_init = rtl822xb_config_init,
|
||||
@@ -1434,6 +1436,7 @@ static struct phy_driver realtek_drvs[]
|
||||
@@ -1452,6 +1454,7 @@ static struct phy_driver realtek_drvs[]
|
||||
}, {
|
||||
PHY_ID_MATCH_EXACT(0x001cc838),
|
||||
.name = "RTL8226-CG 2.5Gbps PHY",
|
||||
@ -39,7 +39,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
.get_features = rtl822x_get_features,
|
||||
.config_aneg = rtl822x_config_aneg,
|
||||
.read_status = rtl822x_read_status,
|
||||
@@ -1444,6 +1447,7 @@ static struct phy_driver realtek_drvs[]
|
||||
@@ -1462,6 +1465,7 @@ static struct phy_driver realtek_drvs[]
|
||||
}, {
|
||||
PHY_ID_MATCH_EXACT(0x001cc848),
|
||||
.name = "RTL8226B-CG_RTL8221B-CG 2.5Gbps PHY",
|
||||
@ -47,7 +47,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
.get_features = rtl822x_get_features,
|
||||
.config_aneg = rtl822x_config_aneg,
|
||||
.config_init = rtl822xb_config_init,
|
||||
@@ -1456,6 +1460,7 @@ static struct phy_driver realtek_drvs[]
|
||||
@@ -1474,6 +1478,7 @@ static struct phy_driver realtek_drvs[]
|
||||
}, {
|
||||
.match_phy_device = rtl8221b_vb_cg_c22_match_phy_device,
|
||||
.name = "RTL8221B-VB-CG 2.5Gbps PHY (C22)",
|
||||
@ -55,7 +55,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
.get_features = rtl822x_get_features,
|
||||
.config_aneg = rtl822x_config_aneg,
|
||||
.config_init = rtl822xb_config_init,
|
||||
@@ -1468,6 +1473,7 @@ static struct phy_driver realtek_drvs[]
|
||||
@@ -1486,6 +1491,7 @@ static struct phy_driver realtek_drvs[]
|
||||
}, {
|
||||
.match_phy_device = rtl8221b_vb_cg_c45_match_phy_device,
|
||||
.name = "RTL8221B-VB-CG 2.5Gbps PHY (C45)",
|
||||
@ -63,7 +63,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
.config_init = rtl822xb_config_init,
|
||||
.get_rate_matching = rtl822xb_get_rate_matching,
|
||||
.get_features = rtl822x_c45_get_features,
|
||||
@@ -1478,6 +1484,7 @@ static struct phy_driver realtek_drvs[]
|
||||
@@ -1496,6 +1502,7 @@ static struct phy_driver realtek_drvs[]
|
||||
}, {
|
||||
.match_phy_device = rtl8221b_vn_cg_c22_match_phy_device,
|
||||
.name = "RTL8221B-VM-CG 2.5Gbps PHY (C22)",
|
||||
@ -71,7 +71,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
.get_features = rtl822x_get_features,
|
||||
.config_aneg = rtl822x_config_aneg,
|
||||
.config_init = rtl822xb_config_init,
|
||||
@@ -1490,6 +1497,7 @@ static struct phy_driver realtek_drvs[]
|
||||
@@ -1508,6 +1515,7 @@ static struct phy_driver realtek_drvs[]
|
||||
}, {
|
||||
.match_phy_device = rtl8221b_vn_cg_c45_match_phy_device,
|
||||
.name = "RTL8221B-VN-CG 2.5Gbps PHY (C45)",
|
||||
|
@ -15,12 +15,12 @@ Reported-by: Yevhen Kolomeiko <jarvis2709@gmail.com>
|
||||
Tested-by: Yevhen Kolomeiko <jarvis2709@gmail.com>
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
drivers/net/phy/realtek.c | 27 +++++++++++++++++++++++++--
|
||||
drivers/net/phy/realtek/realtek_main.c | 27 +++++++++++++++++++++++++--
|
||||
1 file changed, 25 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/phy/realtek.c
|
||||
+++ b/drivers/net/phy/realtek.c
|
||||
@@ -815,8 +815,8 @@ static int rtl822x_write_mmd(struct phy_
|
||||
--- a/drivers/net/phy/realtek/realtek_main.c
|
||||
+++ b/drivers/net/phy/realtek/realtek_main.c
|
||||
@@ -834,8 +834,8 @@ static int rtl822x_probe(struct phy_devi
|
||||
static int rtl822xb_config_init(struct phy_device *phydev)
|
||||
{
|
||||
bool has_2500, has_sgmii;
|
||||
@ -30,7 +30,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
|
||||
has_2500 = test_bit(PHY_INTERFACE_MODE_2500BASEX,
|
||||
phydev->host_interfaces) ||
|
||||
@@ -866,7 +866,29 @@ static int rtl822xb_config_init(struct p
|
||||
@@ -885,7 +885,29 @@ static int rtl822xb_config_init(struct p
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
@ -13,12 +13,12 @@ rtl821x_write_page instead of 3 individually locked MDIO bus operations.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
drivers/net/phy/realtek.c | 8 +++++---
|
||||
drivers/net/phy/realtek/realtek_main.c | 8 +++++---
|
||||
1 file changed, 5 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/drivers/net/phy/realtek.c
|
||||
+++ b/drivers/net/phy/realtek.c
|
||||
@@ -1093,9 +1093,11 @@ static bool rtlgen_supports_2_5gbps(stru
|
||||
--- a/drivers/net/phy/realtek/realtek_main.c
|
||||
+++ b/drivers/net/phy/realtek/realtek_main.c
|
||||
@@ -1111,9 +1111,11 @@ static bool rtlgen_supports_2_5gbps(stru
|
||||
{
|
||||
int val;
|
||||
|
||||
|
@ -8,12 +8,12 @@ just like for RTL821x 1GE PHYs.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
drivers/net/phy/realtek.c | 11 +++++++++++
|
||||
drivers/net/phy/realtek/realtek_main.c | 11 +++++++++++
|
||||
1 file changed, 11 insertions(+)
|
||||
|
||||
--- a/drivers/net/phy/realtek.c
|
||||
+++ b/drivers/net/phy/realtek.c
|
||||
@@ -80,6 +80,10 @@
|
||||
--- a/drivers/net/phy/realtek/realtek_main.c
|
||||
+++ b/drivers/net/phy/realtek/realtek_main.c
|
||||
@@ -82,6 +82,10 @@
|
||||
|
||||
#define RTL822X_VND2_GANLPAR 0xa414
|
||||
|
||||
@ -24,11 +24,11 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
#define RTL8366RB_POWER_SAVE 0x15
|
||||
#define RTL8366RB_POWER_SAVE_ON BIT(12)
|
||||
|
||||
@@ -1189,6 +1193,25 @@ static int rtl8251b_c45_match_phy_device
|
||||
@@ -1207,6 +1211,25 @@ static int rtl8251b_c45_match_phy_device
|
||||
return rtlgen_is_c45_match(phydev, RTL_8251B, true);
|
||||
}
|
||||
|
||||
+static int rtl822x_probe(struct phy_device *phydev)
|
||||
+static int rtl822x_aldps_probe(struct phy_device *phydev)
|
||||
+{
|
||||
+ struct device *dev = &phydev->mdio.dev;
|
||||
+ int val;
|
||||
@ -50,51 +50,51 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
static int rtlgen_resume(struct phy_device *phydev)
|
||||
{
|
||||
int ret = genphy_resume(phydev);
|
||||
@@ -1460,6 +1483,7 @@ static struct phy_driver realtek_drvs[]
|
||||
@@ -1478,6 +1501,7 @@ static struct phy_driver realtek_drvs[]
|
||||
}, {
|
||||
PHY_ID_MATCH_EXACT(0x001cc838),
|
||||
.name = "RTL8226-CG 2.5Gbps PHY",
|
||||
+ .probe = rtl822x_probe,
|
||||
+ .probe = rtl822x_aldps_probe,
|
||||
.soft_reset = genphy_soft_reset,
|
||||
.get_features = rtl822x_get_features,
|
||||
.config_aneg = rtl822x_config_aneg,
|
||||
@@ -1471,6 +1495,7 @@ static struct phy_driver realtek_drvs[]
|
||||
@@ -1489,6 +1513,7 @@ static struct phy_driver realtek_drvs[]
|
||||
}, {
|
||||
PHY_ID_MATCH_EXACT(0x001cc848),
|
||||
.name = "RTL8226B-CG_RTL8221B-CG 2.5Gbps PHY",
|
||||
+ .probe = rtl822x_probe,
|
||||
+ .probe = rtl822x_aldps_probe,
|
||||
.soft_reset = genphy_soft_reset,
|
||||
.get_features = rtl822x_get_features,
|
||||
.config_aneg = rtl822x_config_aneg,
|
||||
@@ -1484,6 +1509,7 @@ static struct phy_driver realtek_drvs[]
|
||||
@@ -1502,6 +1527,7 @@ static struct phy_driver realtek_drvs[]
|
||||
}, {
|
||||
.match_phy_device = rtl8221b_vb_cg_c22_match_phy_device,
|
||||
.name = "RTL8221B-VB-CG 2.5Gbps PHY (C22)",
|
||||
+ .probe = rtl822x_probe,
|
||||
+ .probe = rtl822x_aldps_probe,
|
||||
.soft_reset = genphy_soft_reset,
|
||||
.get_features = rtl822x_get_features,
|
||||
.config_aneg = rtl822x_config_aneg,
|
||||
@@ -1497,6 +1523,7 @@ static struct phy_driver realtek_drvs[]
|
||||
@@ -1515,6 +1541,7 @@ static struct phy_driver realtek_drvs[]
|
||||
}, {
|
||||
.match_phy_device = rtl8221b_vb_cg_c45_match_phy_device,
|
||||
.name = "RTL8221B-VB-CG 2.5Gbps PHY (C45)",
|
||||
+ .probe = rtl822x_probe,
|
||||
+ .probe = rtl822x_aldps_probe,
|
||||
.soft_reset = genphy_soft_reset,
|
||||
.config_init = rtl822xb_config_init,
|
||||
.get_rate_matching = rtl822xb_get_rate_matching,
|
||||
@@ -1508,6 +1535,7 @@ static struct phy_driver realtek_drvs[]
|
||||
@@ -1526,6 +1553,7 @@ static struct phy_driver realtek_drvs[]
|
||||
}, {
|
||||
.match_phy_device = rtl8221b_vn_cg_c22_match_phy_device,
|
||||
.name = "RTL8221B-VM-CG 2.5Gbps PHY (C22)",
|
||||
+ .probe = rtl822x_probe,
|
||||
+ .probe = rtl822x_aldps_probe,
|
||||
.soft_reset = genphy_soft_reset,
|
||||
.get_features = rtl822x_get_features,
|
||||
.config_aneg = rtl822x_config_aneg,
|
||||
@@ -1521,6 +1549,7 @@ static struct phy_driver realtek_drvs[]
|
||||
@@ -1539,6 +1567,7 @@ static struct phy_driver realtek_drvs[]
|
||||
}, {
|
||||
.match_phy_device = rtl8221b_vn_cg_c45_match_phy_device,
|
||||
.name = "RTL8221B-VN-CG 2.5Gbps PHY (C45)",
|
||||
+ .probe = rtl822x_probe,
|
||||
+ .probe = rtl822x_aldps_probe,
|
||||
.soft_reset = genphy_soft_reset,
|
||||
.config_init = rtl822xb_config_init,
|
||||
.get_rate_matching = rtl822xb_get_rate_matching,
|
||||
|
@ -12,9 +12,9 @@ over the implemented MMDs.
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
[forward-port by @namiltd]
|
||||
Signed-off-by: Mieczyslaw Nalewaj <namiltd@yahoo.com>
|
||||
--- a/drivers/net/phy/realtek.c
|
||||
+++ b/drivers/net/phy/realtek.c
|
||||
@@ -1139,10 +1139,32 @@ static int rtl8226_match_phy_device(stru
|
||||
--- a/drivers/net/phy/realtek/realtek_main.c
|
||||
+++ b/drivers/net/phy/realtek/realtek_main.c
|
||||
@@ -1157,10 +1157,32 @@ static int rtl8226_match_phy_device(stru
|
||||
static int rtlgen_is_c45_match(struct phy_device *phydev, unsigned int id,
|
||||
bool is_c45)
|
||||
{
|
||||
|
@ -7,12 +7,12 @@ This commit introduces interrupt support for RTL8221B.
|
||||
|
||||
Signed-off-by: Jianhui Zhao <zhaojh329@gmail.com>
|
||||
---
|
||||
drivers/net/phy/realtek.c | 47 +++++++++++++++++++++++++++++++++++++++
|
||||
drivers/net/phy/realtek/realtek_main.c | 47 +++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 47 insertions(+)
|
||||
|
||||
--- a/drivers/net/phy/realtek.c
|
||||
+++ b/drivers/net/phy/realtek.c
|
||||
@@ -1369,6 +1369,51 @@ static irqreturn_t rtl9000a_handle_inter
|
||||
--- a/drivers/net/phy/realtek/realtek_main.c
|
||||
+++ b/drivers/net/phy/realtek/realtek_main.c
|
||||
@@ -1387,6 +1387,51 @@ static irqreturn_t rtl9000a_handle_inter
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
@ -64,39 +64,39 @@ Signed-off-by: Jianhui Zhao <zhaojh329@gmail.com>
|
||||
static struct phy_driver realtek_drvs[] = {
|
||||
{
|
||||
PHY_ID_MATCH_EXACT(0x00008201),
|
||||
@@ -1531,6 +1576,8 @@ static struct phy_driver realtek_drvs[]
|
||||
@@ -1549,6 +1594,8 @@ static struct phy_driver realtek_drvs[]
|
||||
}, {
|
||||
.match_phy_device = rtl8221b_vb_cg_c22_match_phy_device,
|
||||
.name = "RTL8221B-VB-CG 2.5Gbps PHY (C22)",
|
||||
+ .config_intr = rtl8221b_config_intr,
|
||||
+ .handle_interrupt = rtl8221b_handle_interrupt,
|
||||
.probe = rtl822x_probe,
|
||||
.probe = rtl822x_aldps_probe,
|
||||
.soft_reset = genphy_soft_reset,
|
||||
.get_features = rtl822x_get_features,
|
||||
@@ -1545,6 +1592,8 @@ static struct phy_driver realtek_drvs[]
|
||||
@@ -1563,6 +1610,8 @@ static struct phy_driver realtek_drvs[]
|
||||
}, {
|
||||
.match_phy_device = rtl8221b_vb_cg_c45_match_phy_device,
|
||||
.name = "RTL8221B-VB-CG 2.5Gbps PHY (C45)",
|
||||
+ .config_intr = rtl8221b_config_intr,
|
||||
+ .handle_interrupt = rtl8221b_handle_interrupt,
|
||||
.probe = rtl822x_probe,
|
||||
.probe = rtl822x_aldps_probe,
|
||||
.soft_reset = genphy_soft_reset,
|
||||
.config_init = rtl822xb_config_init,
|
||||
@@ -1557,6 +1606,8 @@ static struct phy_driver realtek_drvs[]
|
||||
@@ -1575,6 +1624,8 @@ static struct phy_driver realtek_drvs[]
|
||||
}, {
|
||||
.match_phy_device = rtl8221b_vn_cg_c22_match_phy_device,
|
||||
.name = "RTL8221B-VM-CG 2.5Gbps PHY (C22)",
|
||||
+ .config_intr = rtl8221b_config_intr,
|
||||
+ .handle_interrupt = rtl8221b_handle_interrupt,
|
||||
.probe = rtl822x_probe,
|
||||
.probe = rtl822x_aldps_probe,
|
||||
.soft_reset = genphy_soft_reset,
|
||||
.get_features = rtl822x_get_features,
|
||||
@@ -1571,6 +1622,8 @@ static struct phy_driver realtek_drvs[]
|
||||
@@ -1589,6 +1640,8 @@ static struct phy_driver realtek_drvs[]
|
||||
}, {
|
||||
.match_phy_device = rtl8221b_vn_cg_c45_match_phy_device,
|
||||
.name = "RTL8221B-VN-CG 2.5Gbps PHY (C45)",
|
||||
+ .config_intr = rtl8221b_config_intr,
|
||||
+ .handle_interrupt = rtl8221b_handle_interrupt,
|
||||
.probe = rtl822x_probe,
|
||||
.probe = rtl822x_aldps_probe,
|
||||
.soft_reset = genphy_soft_reset,
|
||||
.config_init = rtl822xb_config_init,
|
||||
|
@ -1,14 +0,0 @@
|
||||
[ ifup = "$ACTION" ] && {
|
||||
[ -n "$DEVICE" ] && {
|
||||
if [ "$INTERFACE" == "lan" ]; then
|
||||
if [ -f /usr/sbin/ethtool ]; then
|
||||
ifname=eth0
|
||||
lan_ip=`uci -q get network.lan.ipaddr`
|
||||
ethdrv=`ethtool -i $ifname | grep mtk_soc_eth`
|
||||
[ -n "$ethdrv" ] && {
|
||||
ethtool -N $ifname flow-type tcp4 dst-ip $lan_ip loc 0
|
||||
}
|
||||
fi
|
||||
fi
|
||||
}
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
set_rps_sock_flow() {
|
||||
echo 1024 > /proc/sys/net/core/rps_sock_flow_entries
|
||||
}
|
||||
|
||||
boot_hook_add preinit_main set_rps_sock_flow
|
||||
|
@ -1,6 +1,6 @@
|
||||
--- a/drivers/net/phy/Kconfig
|
||||
+++ b/drivers/net/phy/Kconfig
|
||||
@@ -419,6 +419,12 @@ config ROCKCHIP_PHY
|
||||
@@ -416,6 +416,12 @@ config ROCKCHIP_PHY
|
||||
help
|
||||
Currently supports the integrated Ethernet PHY.
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
--- a/drivers/net/phy/Makefile
|
||||
+++ b/drivers/net/phy/Makefile
|
||||
@@ -102,6 +102,7 @@ obj-$(CONFIG_QSEMI_PHY) += qsemi.o
|
||||
obj-$(CONFIG_REALTEK_PHY) += realtek.o
|
||||
obj-$(CONFIG_REALTEK_PHY) += realtek/
|
||||
obj-$(CONFIG_RENESAS_PHY) += uPD60620.o
|
||||
obj-$(CONFIG_ROCKCHIP_PHY) += rockchip.o
|
||||
+obj-$(CONFIG_RTL8367S_GSW) += rtk/
|
||||
|
@ -1,8 +1,8 @@
|
||||
--- a/drivers/net/phy/Kconfig
|
||||
+++ b/drivers/net/phy/Kconfig
|
||||
@@ -399,6 +399,8 @@ config REALTEK_PHY
|
||||
help
|
||||
Supports the Realtek 821x PHY.
|
||||
@@ -396,6 +396,8 @@ config QSEMI_PHY
|
||||
|
||||
source "drivers/net/phy/realtek/Kconfig"
|
||||
|
||||
+source "drivers/net/phy/rtl8261n/Kconfig"
|
||||
+
|
||||
@ -14,7 +14,7 @@
|
||||
@@ -100,6 +100,7 @@ obj-$(CONFIG_NXP_TJA11XX_PHY) += nxp-tja
|
||||
obj-y += qcom/
|
||||
obj-$(CONFIG_QSEMI_PHY) += qsemi.o
|
||||
obj-$(CONFIG_REALTEK_PHY) += realtek.o
|
||||
obj-$(CONFIG_REALTEK_PHY) += realtek/
|
||||
+obj-y += rtl8261n/
|
||||
obj-$(CONFIG_RENESAS_PHY) += uPD60620.o
|
||||
obj-$(CONFIG_ROCKCHIP_PHY) += rockchip.o
|
||||
|
@ -16,9 +16,9 @@ Signed-off-by: Yangyu Chen <cyy@cyyself.name>
|
||||
drivers/net/phy/realtek.c | 28 +++++++++++++++++++++++++++-
|
||||
1 file changed, 27 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/phy/realtek.c
|
||||
+++ b/drivers/net/phy/realtek.c
|
||||
@@ -84,6 +84,12 @@
|
||||
--- a/drivers/net/phy/realtek/realtek_main.c
|
||||
+++ b/drivers/net/phy/realtek/realtek_main.c
|
||||
@@ -86,6 +86,12 @@
|
||||
#define RTL8221B_PHYCR1_ALDPS_EN BIT(2)
|
||||
#define RTL8221B_PHYCR1_ALDPS_XTAL_OFF_EN BIT(12)
|
||||
|
||||
@ -31,8 +31,8 @@ Signed-off-by: Yangyu Chen <cyy@cyyself.name>
|
||||
#define RTL8366RB_POWER_SAVE 0x15
|
||||
#define RTL8366RB_POWER_SAVE_ON BIT(12)
|
||||
|
||||
@@ -815,6 +821,45 @@ static int rtl822x_write_mmd(struct phy_
|
||||
return ret;
|
||||
@@ -835,6 +841,45 @@ static int rtl822x_probe(struct phy_devi
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int rtl8221b_config_led(struct phy_device *phydev) {
|
||||
@ -77,7 +77,7 @@ Signed-off-by: Yangyu Chen <cyy@cyyself.name>
|
||||
static int rtl822xb_config_init(struct phy_device *phydev)
|
||||
{
|
||||
bool has_2500, has_sgmii;
|
||||
@@ -891,7 +936,7 @@ static int rtl822xb_config_init(struct p
|
||||
@@ -911,7 +956,7 @@ static int rtl822xb_config_init(struct p
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
@ -14,9 +14,9 @@ Submitted-by: Birger Koblitz <mail@birger-koblitz.de>
|
||||
|
||||
--- a/drivers/net/phy/Kconfig
|
||||
+++ b/drivers/net/phy/Kconfig
|
||||
@@ -410,6 +410,12 @@ config REALTEK_PHY
|
||||
help
|
||||
Supports the Realtek 821x PHY.
|
||||
@@ -407,6 +407,12 @@ config QSEMI_PHY
|
||||
|
||||
source "drivers/net/phy/realtek/Kconfig"
|
||||
|
||||
+config REALTEK_SOC_PHY
|
||||
+ tristate "Realtek SoC PHYs"
|
||||
@ -32,7 +32,7 @@ Submitted-by: Birger Koblitz <mail@birger-koblitz.de>
|
||||
@@ -100,6 +100,7 @@ obj-$(CONFIG_NXP_TJA11XX_PHY) += nxp-tja
|
||||
obj-y += qcom/
|
||||
obj-$(CONFIG_QSEMI_PHY) += qsemi.o
|
||||
obj-$(CONFIG_REALTEK_PHY) += realtek.o
|
||||
obj-$(CONFIG_REALTEK_PHY) += realtek/
|
||||
+obj-$(CONFIG_REALTEK_SOC_PHY) += rtl83xx-phy.o
|
||||
obj-$(CONFIG_RENESAS_PHY) += uPD60620.o
|
||||
obj-$(CONFIG_ROCKCHIP_PHY) += rockchip.o
|
||||
|
@ -103,7 +103,7 @@ Signed-off-by: Sander Vanheule <sander@svanheule.net>
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ err = regmap_read_poll_timeout(ctrl->map, ctrl->cmd_reg, run, (run != cmd), 3, 100);
|
||||
+ err = regmap_read_poll_timeout_atomic(ctrl->map, ctrl->cmd_reg, run, (run != cmd), 3, 100);
|
||||
+
|
||||
+ if ((run & ~mask_volatile) != (cmd & ~mask_volatile)) {
|
||||
+ dev_err(ctrl->dev, "Command modified. Is offloading still active?");
|
||||
|
@ -1,6 +1,6 @@
|
||||
--- a/drivers/net/ethernet/realtek/r8169_main.c
|
||||
+++ b/drivers/net/ethernet/realtek/r8169_main.c
|
||||
@@ -22,6 +22,7 @@
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <linux/in.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/ip.h>
|
||||
@ -8,7 +8,7 @@
|
||||
#include <linux/tcp.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
@@ -5393,6 +5394,7 @@ static int rtl_init_one(struct pci_dev *
|
||||
@@ -5355,6 +5356,7 @@ static int rtl_init_one(struct pci_dev *
|
||||
int jumbo_max, region, rc;
|
||||
enum mac_version chipset;
|
||||
struct net_device *dev;
|
||||
@ -16,7 +16,7 @@
|
||||
u32 txconfig;
|
||||
u16 xid;
|
||||
|
||||
@@ -5400,6 +5402,9 @@ static int rtl_init_one(struct pci_dev *
|
||||
@@ -5362,6 +5364,9 @@ static int rtl_init_one(struct pci_dev *
|
||||
if (!dev)
|
||||
return -ENOMEM;
|
||||
|
||||
|
@ -7,9 +7,9 @@ Subject: [PATCH] net: phy: realtek: add LED configuration from OF for 8211f
|
||||
drivers/net/phy/realtek.c | 9 +++++++++
|
||||
1 file changed, 9 insertions(+)
|
||||
|
||||
--- a/drivers/net/phy/realtek.c
|
||||
+++ b/drivers/net/phy/realtek.c
|
||||
@@ -32,6 +32,7 @@
|
||||
--- a/drivers/net/phy/realtek/realtek_main.c
|
||||
+++ b/drivers/net/phy/realtek/realtek_main.c
|
||||
@@ -34,6 +34,7 @@
|
||||
#define RTL8211F_PHYCR2 0x19
|
||||
#define RTL8211F_INSR 0x1d
|
||||
|
||||
@ -17,7 +17,7 @@ Subject: [PATCH] net: phy: realtek: add LED configuration from OF for 8211f
|
||||
#define RTL8211F_LEDCR 0x10
|
||||
#define RTL8211F_LEDCR_MODE BIT(15)
|
||||
#define RTL8211F_LEDCR_ACT_TXRX BIT(4)
|
||||
@@ -380,6 +381,7 @@ static int rtl8211f_config_init(struct p
|
||||
@@ -382,6 +383,7 @@ static int rtl8211f_config_init(struct p
|
||||
struct rtl821x_priv *priv = phydev->priv;
|
||||
struct device *dev = &phydev->mdio.dev;
|
||||
u16 val_txdly, val_rxdly;
|
||||
@ -25,7 +25,7 @@ Subject: [PATCH] net: phy: realtek: add LED configuration from OF for 8211f
|
||||
int ret;
|
||||
|
||||
ret = phy_modify_paged_changed(phydev, 0xa43, RTL8211F_PHYCR1,
|
||||
@@ -446,6 +448,15 @@ static int rtl8211f_config_init(struct p
|
||||
@@ -448,6 +450,15 @@ static int rtl8211f_config_init(struct p
|
||||
val_rxdly ? "enabled" : "disabled");
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user