Update On Tue Sep 23 20:37:39 CEST 2025

This commit is contained in:
github-action[bot]
2025-09-23 20:37:39 +02:00
parent 6774a15632
commit 1f6f1f8a02
154 changed files with 23222 additions and 2903 deletions
+1
View File
@@ -1129,3 +1129,4 @@ Update On Fri Sep 19 20:36:14 CEST 2025
Update On Sat Sep 20 20:32:16 CEST 2025
Update On Sun Sep 21 20:36:55 CEST 2025
Update On Mon Sep 22 20:36:16 CEST 2025
Update On Tue Sep 23 20:37:30 CEST 2025
@@ -5,6 +5,7 @@ import (
"fmt"
"net"
"strconv"
"strings"
"sync"
CN "github.com/metacubex/mihomo/common/net"
@@ -30,8 +31,8 @@ type MieruOption struct {
BasicOption
Name string `proxy:"name"`
Server string `proxy:"server"`
Port int `proxy:"port,omitempty"`
PortRange string `proxy:"port-range,omitempty"`
Port string `proxy:"port,omitempty"`
PortRange string `proxy:"port-range,omitempty"` // deprecated
Transport string `proxy:"transport"`
UDP bool `proxy:"udp,omitempty"`
UserName string `proxy:"username"`
@@ -123,13 +124,19 @@ func NewMieru(option MieruOption) (*Mieru, error) {
}
// Client is started lazily on the first use.
// Use the first port to construct the address.
var addr string
if option.Port != 0 {
addr = net.JoinHostPort(option.Server, strconv.Itoa(option.Port))
var portStr string
if option.Port != "" {
portStr = option.Port
} else {
beginPort, _, _ := beginAndEndPortFromPortRange(option.PortRange)
addr = net.JoinHostPort(option.Server, strconv.Itoa(beginPort))
portStr = option.PortRange
}
firstPort, err := getFirstPort(portStr)
if err != nil {
return nil, fmt.Errorf("failed to get first port from port string %q: %w", portStr, err)
}
addr = net.JoinHostPort(option.Server, strconv.Itoa(firstPort))
outbound := &Mieru{
Base: &Base{
name: option.Name,
@@ -183,54 +190,62 @@ func buildMieruClientConfig(option MieruOption) (*mieruclient.ClientConfig, erro
}
transportProtocol := mierupb.TransportProtocol_TCP.Enum()
var server *mierupb.ServerEndpoint
if net.ParseIP(option.Server) != nil {
// server is an IP address
if option.PortRange != "" {
server = &mierupb.ServerEndpoint{
IpAddress: proto.String(option.Server),
PortBindings: []*mierupb.PortBinding{
{
PortRange: proto.String(option.PortRange),
portBindings := make([]*mierupb.PortBinding, 0)
if option.Port != "" {
parts := strings.Split(option.Port, ",")
for _, part := range parts {
part = strings.TrimSpace(part)
if strings.Contains(part, "-") {
_, _, err := beginAndEndPortFromPortRange(part)
if err == nil {
portBindings = append(portBindings, &mierupb.PortBinding{
PortRange: proto.String(part),
Protocol: transportProtocol,
},
},
}
} else {
server = &mierupb.ServerEndpoint{
IpAddress: proto.String(option.Server),
PortBindings: []*mierupb.PortBinding{
{
Port: proto.Int32(int32(option.Port)),
Protocol: transportProtocol,
},
},
}
}
} else {
// server is a domain name
if option.PortRange != "" {
server = &mierupb.ServerEndpoint{
DomainName: proto.String(option.Server),
PortBindings: []*mierupb.PortBinding{
{
PortRange: proto.String(option.PortRange),
Protocol: transportProtocol,
},
},
}
} else {
server = &mierupb.ServerEndpoint{
DomainName: proto.String(option.Server),
PortBindings: []*mierupb.PortBinding{
{
Port: proto.Int32(int32(option.Port)),
Protocol: transportProtocol,
},
},
})
} else {
return nil, err
}
} else {
p, err := strconv.Atoi(part)
if err != nil {
return nil, fmt.Errorf("invalid port value: %s", part)
}
portBindings = append(portBindings, &mierupb.PortBinding{
Port: proto.Int32(int32(p)),
Protocol: transportProtocol,
})
}
}
}
if option.PortRange != "" {
parts := strings.Split(option.PortRange, ",")
for _, part := range parts {
part = strings.TrimSpace(part)
if _, _, err := beginAndEndPortFromPortRange(part); err == nil {
portBindings = append(portBindings, &mierupb.PortBinding{
PortRange: proto.String(part),
Protocol: transportProtocol,
})
}
}
}
var server *mierupb.ServerEndpoint
if net.ParseIP(option.Server) != nil {
// server is an IP address
server = &mierupb.ServerEndpoint{
IpAddress: proto.String(option.Server),
PortBindings: portBindings,
}
} else {
// server is a domain name
server = &mierupb.ServerEndpoint{
DomainName: proto.String(option.Server),
PortBindings: portBindings,
}
}
config := &mieruclient.ClientConfig{
Profile: &mierupb.ClientProfile{
ProfileName: proto.String(option.Name),
@@ -259,31 +274,9 @@ func validateMieruOption(option MieruOption) error {
if option.Server == "" {
return fmt.Errorf("server is empty")
}
if option.Port == 0 && option.PortRange == "" {
return fmt.Errorf("either port or port-range must be set")
if option.Port == "" && option.PortRange == "" {
return fmt.Errorf("port must be set")
}
if option.Port != 0 && option.PortRange != "" {
return fmt.Errorf("port and port-range cannot be set at the same time")
}
if option.Port != 0 && (option.Port < 1 || option.Port > 65535) {
return fmt.Errorf("port must be between 1 and 65535")
}
if option.PortRange != "" {
begin, end, err := beginAndEndPortFromPortRange(option.PortRange)
if err != nil {
return fmt.Errorf("invalid port-range format")
}
if begin < 1 || begin > 65535 {
return fmt.Errorf("begin port must be between 1 and 65535")
}
if end < 1 || end > 65535 {
return fmt.Errorf("end port must be between 1 and 65535")
}
if begin > end {
return fmt.Errorf("begin port must be less than or equal to end port")
}
}
if option.Transport != "TCP" {
return fmt.Errorf("transport must be TCP")
}
@@ -306,8 +299,36 @@ func validateMieruOption(option MieruOption) error {
return nil
}
func getFirstPort(portStr string) (int, error) {
if portStr == "" {
return 0, fmt.Errorf("port string is empty")
}
parts := strings.Split(portStr, ",")
firstPart := parts[0]
if strings.Contains(firstPart, "-") {
begin, _, err := beginAndEndPortFromPortRange(firstPart)
if err != nil {
return 0, err
}
return begin, nil
}
port, err := strconv.Atoi(firstPart)
if err != nil {
return 0, fmt.Errorf("invalid port format: %s", firstPart)
}
return port, nil
}
func beginAndEndPortFromPortRange(portRange string) (int, int, error) {
var begin, end int
_, err := fmt.Sscanf(portRange, "%d-%d", &begin, &end)
if err != nil {
return 0, 0, fmt.Errorf("invalid port range format: %w", err)
}
if begin > end {
return 0, 0, fmt.Errorf("begin port is greater than end port: %s", portRange)
}
return begin, end, err
}
@@ -1,22 +1,51 @@
package outbound
import "testing"
import (
"reflect"
"testing"
mieruclient "github.com/enfein/mieru/v3/apis/client"
mierupb "github.com/enfein/mieru/v3/pkg/appctl/appctlpb"
"google.golang.org/protobuf/proto"
)
func TestNewMieru(t *testing.T) {
transportProtocol := mierupb.TransportProtocol_TCP.Enum()
testCases := []struct {
option MieruOption
wantBaseAddr string
wantConfig *mieruclient.ClientConfig
}{
{
option: MieruOption{
Name: "test",
Server: "1.2.3.4",
Port: 10000,
Port: "10000",
Transport: "TCP",
UserName: "test",
Password: "test",
},
wantBaseAddr: "1.2.3.4:10000",
wantConfig: &mieruclient.ClientConfig{
Profile: &mierupb.ClientProfile{
ProfileName: proto.String("test"),
User: &mierupb.User{
Name: proto.String("test"),
Password: proto.String("test"),
},
Servers: []*mierupb.ServerEndpoint{
{
IpAddress: proto.String("1.2.3.4"),
PortBindings: []*mierupb.PortBinding{
{
Port: proto.Int32(10000),
Protocol: transportProtocol,
},
},
},
},
},
},
},
{
option: MieruOption{
@@ -28,28 +57,212 @@ func TestNewMieru(t *testing.T) {
Password: "test",
},
wantBaseAddr: "[2001:db8::1]:10001",
wantConfig: &mieruclient.ClientConfig{
Profile: &mierupb.ClientProfile{
ProfileName: proto.String("test"),
User: &mierupb.User{
Name: proto.String("test"),
Password: proto.String("test"),
},
Servers: []*mierupb.ServerEndpoint{
{
IpAddress: proto.String("2001:db8::1"),
PortBindings: []*mierupb.PortBinding{
{
PortRange: proto.String("10001-10002"),
Protocol: transportProtocol,
},
},
},
},
},
},
},
{
option: MieruOption{
Name: "test",
Server: "example.com",
Port: 10003,
Port: "10003",
Transport: "TCP",
UserName: "test",
Password: "test",
},
wantBaseAddr: "example.com:10003",
wantConfig: &mieruclient.ClientConfig{
Profile: &mierupb.ClientProfile{
ProfileName: proto.String("test"),
User: &mierupb.User{
Name: proto.String("test"),
Password: proto.String("test"),
},
Servers: []*mierupb.ServerEndpoint{
{
DomainName: proto.String("example.com"),
PortBindings: []*mierupb.PortBinding{
{
Port: proto.Int32(10003),
Protocol: transportProtocol,
},
},
},
},
},
},
},
{
option: MieruOption{
Name: "test",
Server: "example.com",
Port: "10004,10005",
Transport: "TCP",
UserName: "test",
Password: "test",
},
wantBaseAddr: "example.com:10004",
wantConfig: &mieruclient.ClientConfig{
Profile: &mierupb.ClientProfile{
ProfileName: proto.String("test"),
User: &mierupb.User{
Name: proto.String("test"),
Password: proto.String("test"),
},
Servers: []*mierupb.ServerEndpoint{
{
DomainName: proto.String("example.com"),
PortBindings: []*mierupb.PortBinding{
{
Port: proto.Int32(10004),
Protocol: transportProtocol,
},
{
Port: proto.Int32(10005),
Protocol: transportProtocol,
},
},
},
},
},
},
},
{
option: MieruOption{
Name: "test",
Server: "example.com",
Port: "10006-10007,11000",
Transport: "TCP",
UserName: "test",
Password: "test",
},
wantBaseAddr: "example.com:10006",
wantConfig: &mieruclient.ClientConfig{
Profile: &mierupb.ClientProfile{
ProfileName: proto.String("test"),
User: &mierupb.User{
Name: proto.String("test"),
Password: proto.String("test"),
},
Servers: []*mierupb.ServerEndpoint{
{
DomainName: proto.String("example.com"),
PortBindings: []*mierupb.PortBinding{
{
PortRange: proto.String("10006-10007"),
Protocol: transportProtocol,
},
{
Port: proto.Int32(11000),
Protocol: transportProtocol,
},
},
},
},
},
},
},
{
option: MieruOption{
Name: "test",
Server: "example.com",
Port: "10008",
PortRange: "10009-10010",
Transport: "TCP",
UserName: "test",
Password: "test",
},
wantBaseAddr: "example.com:10008",
wantConfig: &mieruclient.ClientConfig{
Profile: &mierupb.ClientProfile{
ProfileName: proto.String("test"),
User: &mierupb.User{
Name: proto.String("test"),
Password: proto.String("test"),
},
Servers: []*mierupb.ServerEndpoint{
{
DomainName: proto.String("example.com"),
PortBindings: []*mierupb.PortBinding{
{
Port: proto.Int32(10008),
Protocol: transportProtocol,
},
{
PortRange: proto.String("10009-10010"),
Protocol: transportProtocol,
},
},
},
},
},
},
},
}
for _, testCase := range testCases {
mieru, err := NewMieru(testCase.option)
if err != nil {
t.Error(err)
t.Fatal(err)
}
config, err := mieru.client.Load()
if err != nil {
t.Fatal(err)
}
config.Dialer = nil
if mieru.addr != testCase.wantBaseAddr {
t.Errorf("got addr %q, want %q", mieru.addr, testCase.wantBaseAddr)
}
if !reflect.DeepEqual(config, testCase.wantConfig) {
t.Errorf("got config %+v, want %+v", config, testCase.wantConfig)
}
}
}
func TestNewMieruError(t *testing.T) {
testCases := []MieruOption{
{
Name: "test",
Server: "example.com",
Port: "invalid",
PortRange: "invalid",
Transport: "TCP",
UserName: "test",
Password: "test",
},
{
Name: "test",
Server: "example.com",
Port: "",
PortRange: "",
Transport: "TCP",
UserName: "test",
Password: "test",
},
}
for _, option := range testCases {
_, err := NewMieru(option)
if err == nil {
t.Errorf("expected error for option %+v, but got nil", option)
}
}
}
@@ -63,6 +276,7 @@ func TestBeginAndEndPortFromPortRange(t *testing.T) {
{"1-10", 1, 10, false},
{"1000-2000", 1000, 2000, false},
{"65535-65535", 65535, 65535, false},
{"2000-1000", 0, 0, true},
{"1", 0, 0, true},
{"1-", 0, 0, true},
{"-10", 0, 0, true},
@@ -13,6 +13,7 @@ import (
C "github.com/metacubex/mihomo/constant"
"github.com/metacubex/mihomo/ntp"
gost "github.com/metacubex/mihomo/transport/gost-plugin"
"github.com/metacubex/mihomo/transport/kcptun"
"github.com/metacubex/mihomo/transport/restls"
obfs "github.com/metacubex/mihomo/transport/simple-obfs"
shadowtls "github.com/metacubex/mihomo/transport/sing-shadowtls"
@@ -36,6 +37,7 @@ type ShadowSocks struct {
gostOption *gost.Option
shadowTLSOption *shadowtls.ShadowTLSOption
restlsConfig *restls.Config
kcptunClient *kcptun.Client
}
type ShadowSocksOption struct {
@@ -106,6 +108,32 @@ type restlsOption struct {
RestlsScript string `obfs:"restls-script,omitempty"`
}
type kcpTunOption struct {
Key string `obfs:"key,omitempty"`
Crypt string `obfs:"crypt,omitempty"`
Mode string `obfs:"mode,omitempty"`
Conn int `obfs:"conn,omitempty"`
AutoExpire int `obfs:"autoexpire,omitempty"`
ScavengeTTL int `obfs:"scavengettl,omitempty"`
MTU int `obfs:"mtu,omitempty"`
SndWnd int `obfs:"sndwnd,omitempty"`
RcvWnd int `obfs:"rcvwnd,omitempty"`
DataShard int `obfs:"datashard,omitempty"`
ParityShard int `obfs:"parityshard,omitempty"`
DSCP int `obfs:"dscp,omitempty"`
NoComp bool `obfs:"nocomp,omitempty"`
AckNodelay bool `obfs:"acknodelay,omitempty"`
NoDelay int `obfs:"nodelay,omitempty"`
Interval int `obfs:"interval,omitempty"`
Resend int `obfs:"resend,omitempty"`
NoCongestion int `obfs:"nc,omitempty"`
SockBuf int `obfs:"sockbuf,omitempty"`
SmuxVer int `obfs:"smuxver,omitempty"`
SmuxBuf int `obfs:"smuxbuf,omitempty"`
StreamBuf int `obfs:"streambuf,omitempty"`
KeepAlive int `obfs:"keepalive,omitempty"`
}
// StreamConnContext implements C.ProxyAdapter
func (ss *ShadowSocks) StreamConnContext(ctx context.Context, c net.Conn, metadata *C.Metadata) (_ net.Conn, err error) {
useEarly := false
@@ -174,7 +202,27 @@ func (ss *ShadowSocks) DialContextWithDialer(ctx context.Context, dialer C.Diale
return nil, err
}
}
c, err := dialer.DialContext(ctx, "tcp", ss.addr)
var c net.Conn
if ss.kcptunClient != nil {
c, err = ss.kcptunClient.OpenStream(ctx, func(ctx context.Context) (net.PacketConn, net.Addr, error) {
if err = ss.ResolveUDP(ctx, metadata); err != nil {
return nil, nil, err
}
addr, err := resolveUDPAddr(ctx, "udp", ss.addr, ss.prefer)
if err != nil {
return nil, nil, err
}
pc, err := dialer.ListenPacket(ctx, "udp", "", addr.AddrPort())
if err != nil {
return nil, nil, err
}
return pc, addr, nil
})
} else {
c, err = dialer.DialContext(ctx, "tcp", ss.addr)
}
if err != nil {
return nil, fmt.Errorf("%s connect error: %w", ss.addr, err)
}
@@ -256,6 +304,13 @@ func (ss *ShadowSocks) SupportUOT() bool {
return ss.option.UDPOverTCP
}
func (ss *ShadowSocks) Close() error {
if ss.kcptunClient != nil {
return ss.kcptunClient.Close()
}
return nil
}
func NewShadowSocks(option ShadowSocksOption) (*ShadowSocks, error) {
addr := net.JoinHostPort(option.Server, strconv.Itoa(option.Port))
method, err := shadowsocks.CreateMethod(option.Cipher, shadowsocks.MethodOptions{
@@ -271,6 +326,7 @@ func NewShadowSocks(option ShadowSocksOption) (*ShadowSocks, error) {
var obfsOption *simpleObfsOption
var shadowTLSOpt *shadowtls.ShadowTLSOption
var restlsConfig *restls.Config
var kcptunClient *kcptun.Client
obfsMode := ""
decoder := structure.NewDecoder(structure.Option{TagName: "obfs", WeaklyTypedInput: true})
@@ -384,6 +440,39 @@ func NewShadowSocks(option ShadowSocksOption) (*ShadowSocks, error) {
return nil, fmt.Errorf("ss %s initialize restls-plugin error: %w", addr, err)
}
} else if option.Plugin == kcptun.Mode {
obfsMode = kcptun.Mode
kcptunOpt := &kcpTunOption{}
if err := decoder.Decode(option.PluginOpts, kcptunOpt); err != nil {
return nil, fmt.Errorf("ss %s initialize kcptun-plugin error: %w", addr, err)
}
kcptunClient = kcptun.NewClient(kcptun.Config{
Key: kcptunOpt.Key,
Crypt: kcptunOpt.Crypt,
Mode: kcptunOpt.Mode,
Conn: kcptunOpt.Conn,
AutoExpire: kcptunOpt.AutoExpire,
ScavengeTTL: kcptunOpt.ScavengeTTL,
MTU: kcptunOpt.MTU,
SndWnd: kcptunOpt.SndWnd,
RcvWnd: kcptunOpt.RcvWnd,
DataShard: kcptunOpt.DataShard,
ParityShard: kcptunOpt.ParityShard,
DSCP: kcptunOpt.DSCP,
NoComp: kcptunOpt.NoComp,
AckNodelay: kcptunOpt.AckNodelay,
NoDelay: kcptunOpt.NoDelay,
Interval: kcptunOpt.Interval,
Resend: kcptunOpt.Resend,
NoCongestion: kcptunOpt.NoCongestion,
SockBuf: kcptunOpt.SockBuf,
SmuxVer: kcptunOpt.SmuxVer,
SmuxBuf: kcptunOpt.SmuxBuf,
StreamBuf: kcptunOpt.StreamBuf,
KeepAlive: kcptunOpt.KeepAlive,
})
option.UDPOverTCP = true // must open uot
}
switch option.UDPOverTCPVersion {
case uot.Version, uot.LegacyVersion:
@@ -414,5 +503,6 @@ func NewShadowSocks(option ShadowSocksOption) (*ShadowSocks, error) {
obfsOption: obfsOption,
shadowTLSOption: shadowTLSOpt,
restlsConfig: restlsConfig,
kcptunClient: kcptunClient,
}, nil
}
@@ -24,7 +24,6 @@ import (
"github.com/metacubex/randv2"
utls "github.com/metacubex/utls"
"golang.org/x/crypto/chacha20poly1305"
"golang.org/x/crypto/hkdf"
"golang.org/x/net/http2"
)
@@ -107,13 +106,8 @@ func GetRealityConn(ctx context.Context, conn net.Conn, fingerprint UClientHello
if err != nil {
return nil, err
}
var aeadCipher cipher.AEAD
if utls.AesgcmPreferred(hello.CipherSuites) {
aesBlock, _ := aes.NewCipher(authKey)
aeadCipher, _ = cipher.NewGCM(aesBlock)
} else {
aeadCipher, _ = chacha20poly1305.New(authKey)
}
aesBlock, _ := aes.NewCipher(authKey)
aeadCipher, _ := cipher.NewGCM(aesBlock)
aeadCipher.Seal(hello.SessionId[:0], hello.Random[20:], hello.SessionId[:16], hello.Raw)
copy(hello.Raw[39:], hello.SessionId)
//log.Debugln("REALITY hello.sessionId: %v", hello.SessionId)
@@ -534,6 +534,37 @@ proxies: # socks5
version-hint: "tls12"
restls-script: "1000?100<1,500~100,350~100,600~100,400~200"
- name: "ss-kcptun"
type: ss
server: [YOUR_SERVER_IP]
port: 443
cipher: chacha20-ietf-poly1305
password: [YOUR_SS_PASSWORD]
plugin: kcptun
plugin-opts:
key: it's a secrect # pre-shared secret between client and server
crypt: aes # aes, aes-128, aes-192, salsa20, blowfish, twofish, cast5, 3des, tea, xtea, xor, sm4, none, null
mode: fast # profiles: fast3, fast2, fast, normal, manual
conn: 1 # set num of UDP connections to server
autoexpire: 0 # set auto expiration time(in seconds) for a single UDP connection, 0 to disable
scavengettl: 600 # set how long an expired connection can live (in seconds)
mtu: 1350 # set maximum transmission unit for UDP packets
sndwnd: 128 # set send window size(num of packets)
rcvwnd: 512 # set receive window size(num of packets)
datashard: 10 # set reed-solomon erasure coding - datashard
parityshard: 3 # set reed-solomon erasure coding - parityshard
dscp: 0 # set DSCP(6bit)
nocomp: false # disable compression
acknodelay: false # flush ack immediately when a packet is received
nodelay: 0
interval: 50
resend: false
sockbuf: 4194304 # per-socket buffer in bytes
smuxver: 1 # specify smux version, available 1,2
smuxbuf: 4194304 # the overall de-mux buffer in bytes
streambuf: 2097152 # per stream receive buffer in bytes, smux v2+
keepalive: 10 # seconds between heartbeats
# vmess
# cipher 支持 auto/aes-128-gcm/chacha20-poly1305/none
- name: "vmess"
@@ -993,8 +1024,8 @@ proxies: # socks5
- name: mieru
type: mieru
server: 1.2.3.4
port: 2999
# port-range: 2090-2099 #(不可同时填写 port 和 port-range
port: 2999 # 支持使用 ports 格式,例如 2999,3999 或 2999-3010,3950,3995-3999
# port-range: 2090-2099 # 已废弃,请使用 port
transport: TCP # 只支持 TCP
udp: true # 支持 UDP over TCP
username: user
@@ -1336,6 +1367,30 @@ listeners:
# password: password
# handshake:
# dest: test.com:443
# kcp-tun:
# enable: false
# key: it's a secrect # pre-shared secret between client and server
# crypt: aes # aes, aes-128, aes-192, salsa20, blowfish, twofish, cast5, 3des, tea, xtea, xor, sm4, none, null
# mode: fast # profiles: fast3, fast2, fast, normal, manual
# conn: 1 # set num of UDP connections to server
# autoexpire: 0 # set auto expiration time(in seconds) for a single UDP connection, 0 to disable
# scavengettl: 600 # set how long an expired connection can live (in seconds)
# mtu: 1350 # set maximum transmission unit for UDP packets
# sndwnd: 128 # set send window size(num of packets)
# rcvwnd: 512 # set receive window size(num of packets)
# datashard: 10 # set reed-solomon erasure coding - datashard
# parityshard: 3 # set reed-solomon erasure coding - parityshard
# dscp: 0 # set DSCP(6bit)
# nocomp: false # disable compression
# acknodelay: false # flush ack immediately when a packet is received
# nodelay: 0
# interval: 50
# resend: false
# sockbuf: 4194304 # per-socket buffer in bytes
# smuxver: 1 # specify smux version, available 1,2
# smuxbuf: 4194304 # the overall de-mux buffer in bytes
# streambuf: 2097152 # per stream receive buffer in bytes, smux v2+
# keepalive: 10 # seconds between heartbeats
- name: vmess-in-1
type: vmess
@@ -11,6 +11,7 @@ require (
github.com/go-chi/render v1.0.3
github.com/gobwas/ws v1.4.0
github.com/gofrs/uuid/v5 v5.3.2
github.com/golang/snappy v1.0.0
github.com/insomniacslk/dhcp v0.0.0-20250109001534-8abf58130905
github.com/klauspost/compress v1.17.9 // lastest version compatible with golang1.20
github.com/mdlayher/netlink v1.7.2
@@ -21,6 +22,7 @@ require (
github.com/metacubex/chacha v0.1.5
github.com/metacubex/fswatch v0.1.1
github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759
github.com/metacubex/kcp-go v0.0.0-20250923001605-1ba6f691c45b
github.com/metacubex/quic-go v0.54.1-0.20250730114134-a1ae705fe295
github.com/metacubex/randv2 v0.2.0
github.com/metacubex/restls-client-go v0.1.7
@@ -33,9 +35,9 @@ require (
github.com/metacubex/sing-tun v0.4.8
github.com/metacubex/sing-vmess v0.2.4
github.com/metacubex/sing-wireguard v0.0.0-20250503063753-2dc62acc626f
github.com/metacubex/smux v0.0.0-20250503055512-501391591dee
github.com/metacubex/smux v0.0.0-20250922175018-15c9a6a78719
github.com/metacubex/tfo-go v0.0.0-20250921095601-b102db4216c0
github.com/metacubex/utls v1.8.1-0.20250921102910-221428e5d4b2
github.com/metacubex/utls v1.8.1-0.20250923145048-0a5bbc90dd3e
github.com/metacubex/wireguard-go v0.0.0-20250820062549-a6cecdd7f57f
github.com/miekg/dns v1.1.63 // lastest version compatible with golang1.20
github.com/mroth/weightedrand/v2 v2.1.0
@@ -83,6 +85,8 @@ require (
github.com/google/go-cmp v0.6.0 // indirect
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect
github.com/josharian/native v1.1.0 // indirect
github.com/klauspost/cpuid/v2 v2.2.6 // indirect
github.com/klauspost/reedsolomon v1.12.3 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
@@ -60,6 +60,8 @@ github.com/gofrs/uuid/v5 v5.3.2 h1:2jfO8j3XgSwlz/wHqemAEugfnTlikAYHhnqQ8Xh4fE0=
github.com/gofrs/uuid/v5 v5.3.2/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV+9bD8=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs=
github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg=
github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
@@ -77,6 +79,10 @@ github.com/josharian/native v1.1.0 h1:uuaP0hAbW7Y4l0ZRQ6C9zfb7Mg1mbFKry/xzDAfmtL
github.com/josharian/native v1.1.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc=
github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
github.com/klauspost/reedsolomon v1.12.3 h1:tzUznbfc3OFwJaTebv/QdhnFf2Xvb7gZ24XaHLBPmdc=
github.com/klauspost/reedsolomon v1.12.3/go.mod h1:3K5rXwABAvzGeR01r6pWZieUALXO/Tq7bFKGIb4m4WI=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
@@ -106,6 +112,8 @@ github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759 h1:cjd4biTvO
github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759/go.mod h1:UHOv2xu+RIgLwpXca7TLrXleEd4oR3sPatW6IF8wU88=
github.com/metacubex/gvisor v0.0.0-20250919004547-6122b699a301 h1:N5GExQJqYAH3gOCshpp2u/J3CtNYzMctmlb0xK9wtbQ=
github.com/metacubex/gvisor v0.0.0-20250919004547-6122b699a301/go.mod h1:8LpS0IJW1VmWzUm3ylb0e2SK5QDm5lO/2qwWLZgRpBU=
github.com/metacubex/kcp-go v0.0.0-20250923001605-1ba6f691c45b h1:z7JLKjugnQ1qvDOAD8yMA5C8AlJY3bG+VrrgRntRlUY=
github.com/metacubex/kcp-go v0.0.0-20250923001605-1ba6f691c45b/go.mod h1:HIJZW4QMhbBqXuqC1ly6Hn0TEYT2SzRw58ns1yGhXTs=
github.com/metacubex/nftables v0.0.0-20250503052935-30a69ab87793 h1:1Qpuy+sU3DmyX9HwI+CrBT/oLNJngvBorR2RbajJcqo=
github.com/metacubex/nftables v0.0.0-20250503052935-30a69ab87793/go.mod h1:RjRNb4G52yAgfR+Oe/kp9G4PJJ97Fnj89eY1BFO3YyA=
github.com/metacubex/quic-go v0.54.1-0.20250730114134-a1ae705fe295 h1:8JVlYuE8uSJAvmyCd4TjvDxs57xjb0WxEoaWafK5+qs=
@@ -133,12 +141,12 @@ github.com/metacubex/sing-vmess v0.2.4 h1:Tx6AGgCiEf400E/xyDuYyafsel6sGbR8oF7RkA
github.com/metacubex/sing-vmess v0.2.4/go.mod h1:21R5R1u90uUvBQF0owoooEu96/SAYYD56nDrwm6nFaM=
github.com/metacubex/sing-wireguard v0.0.0-20250503063753-2dc62acc626f h1:Sr/DYKYofKHKc4GF3qkRGNuj6XA6c0eqPgEDN+VAsYU=
github.com/metacubex/sing-wireguard v0.0.0-20250503063753-2dc62acc626f/go.mod h1:jpAkVLPnCpGSfNyVmj6Cq4YbuZsFepm/Dc+9BAOcR80=
github.com/metacubex/smux v0.0.0-20250503055512-501391591dee h1:lp6hJ+4wCLZu113awp7P6odM2okB5s60HUyF0FMqKmo=
github.com/metacubex/smux v0.0.0-20250503055512-501391591dee/go.mod h1:4bPD8HWx9jPJ9aE4uadgyN7D1/Wz3KmPy+vale8sKLE=
github.com/metacubex/smux v0.0.0-20250922175018-15c9a6a78719 h1:T6qCCfolRDAVJKeaPW/mXwNLjnlo65AYN7WS2jrBNaM=
github.com/metacubex/smux v0.0.0-20250922175018-15c9a6a78719/go.mod h1:4bPD8HWx9jPJ9aE4uadgyN7D1/Wz3KmPy+vale8sKLE=
github.com/metacubex/tfo-go v0.0.0-20250921095601-b102db4216c0 h1:Ui+/2s5Qz0lSnDUBmEL12M5Oi/PzvFxGTNohm8ZcsmE=
github.com/metacubex/tfo-go v0.0.0-20250921095601-b102db4216c0/go.mod h1:l9oLnLoEXyGZ5RVLsh7QCC5XsouTUyKk4F2nLm2DHLw=
github.com/metacubex/utls v1.8.1-0.20250921102910-221428e5d4b2 h1:5OGzQvoE5yuOe8AsZsFwhf32ZxKmKN9G+k06AVd+6jY=
github.com/metacubex/utls v1.8.1-0.20250921102910-221428e5d4b2/go.mod h1:GN/CB3TRwQ9LYquYpIFynDkvMTYmkjwI7+mkUIoHj88=
github.com/metacubex/utls v1.8.1-0.20250923145048-0a5bbc90dd3e h1:t9IxEaxSRp3YJ1ewQV4oGkKaJaMeSoUWjOV0boLVQo8=
github.com/metacubex/utls v1.8.1-0.20250923145048-0a5bbc90dd3e/go.mod h1:kncGGVhFaoGn5M3pFe3SXhZCzsbCJayNOH4UEqTKTko=
github.com/metacubex/wireguard-go v0.0.0-20250820062549-a6cecdd7f57f h1:FGBPRb1zUabhPhDrlKEjQ9lgIwQ6cHL4x8M9lrERhbk=
github.com/metacubex/wireguard-go v0.0.0-20250820062549-a6cecdd7f57f/go.mod h1:oPGcV994OGJedmmxrcK9+ni7jUEMGhR+uVQAdaduIP4=
github.com/metacubex/yamux v0.0.0-20250918083631-dd5f17c0be49 h1:lhlqpYHopuTLx9xQt22kSA9HtnyTDmk5XjjQVCGHe2E=
@@ -198,7 +206,6 @@ github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/tiendc/go-deepcopy v1.6.1 h1:uVRTItFeNHkMcLueHS7OCsxgxT9P8MzGB/taUa2Y4Tk=
github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=
github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=
@@ -216,6 +223,7 @@ github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAh
github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc=
github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw=
github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae h1:J0GxkO96kL4WF+AIT3M4mfUVinOCPgf2uUWYFUzN0sM=
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
gitlab.com/go-extension/aes-ccm v0.0.0-20230221065045-e58665ef23c7 h1:UNrDfkQqiEYzdMlNsVvBYOAJWZjdktqFE9tQh5BT2+4=
@@ -256,6 +264,7 @@ golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20220622161953-175b2fd9d664/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -0,0 +1,8 @@
package config
import "github.com/metacubex/mihomo/transport/kcptun"
type KcpTun struct {
Enable bool `json:"enable"`
kcptun.Config `json:",inline"`
}
@@ -14,6 +14,7 @@ type ShadowsocksServer struct {
Udp bool
MuxOption sing.MuxOption `yaml:"mux-option" json:"mux-option,omitempty"`
ShadowTLS ShadowTLS `yaml:"shadow-tls" json:"shadow-tls,omitempty"`
KcpTun KcpTun `yaml:"kcp-tun" json:"kcp-tun,omitempty"`
}
func (t ShadowsocksServer) String() string {
@@ -0,0 +1,64 @@
package inbound
import (
LC "github.com/metacubex/mihomo/listener/config"
"github.com/metacubex/mihomo/transport/kcptun"
)
type KcpTun struct {
Enable bool `inbound:"enable"`
Key string `inbound:"key,omitempty"`
Crypt string `inbound:"crypt,omitempty"`
Mode string `inbound:"mode,omitempty"`
Conn int `inbound:"conn,omitempty"`
AutoExpire int `inbound:"autoexpire,omitempty"`
ScavengeTTL int `inbound:"scavengettl,omitempty"`
MTU int `inbound:"mtu,omitempty"`
SndWnd int `inbound:"sndwnd,omitempty"`
RcvWnd int `inbound:"rcvwnd,omitempty"`
DataShard int `inbound:"datashard,omitempty"`
ParityShard int `inbound:"parityshard,omitempty"`
DSCP int `inbound:"dscp,omitempty"`
NoComp bool `inbound:"nocomp,omitempty"`
AckNodelay bool `inbound:"acknodelay,omitempty"`
NoDelay int `inbound:"nodelay,omitempty"`
Interval int `inbound:"interval,omitempty"`
Resend int `inbound:"resend,omitempty"`
NoCongestion int `inbound:"nc,omitempty"`
SockBuf int `inbound:"sockbuf,omitempty"`
SmuxVer int `inbound:"smuxver,omitempty"`
SmuxBuf int `inbound:"smuxbuf,omitempty"`
StreamBuf int `inbound:"streambuf,omitempty"`
KeepAlive int `inbound:"keepalive,omitempty"`
}
func (c KcpTun) Build() LC.KcpTun {
return LC.KcpTun{
Enable: c.Enable,
Config: kcptun.Config{
Key: c.Key,
Crypt: c.Crypt,
Mode: c.Mode,
Conn: c.Conn,
AutoExpire: c.AutoExpire,
ScavengeTTL: c.ScavengeTTL,
MTU: c.MTU,
SndWnd: c.SndWnd,
RcvWnd: c.RcvWnd,
DataShard: c.DataShard,
ParityShard: c.ParityShard,
DSCP: c.DSCP,
NoComp: c.NoComp,
AckNodelay: c.AckNodelay,
NoDelay: c.NoDelay,
Interval: c.Interval,
Resend: c.Resend,
NoCongestion: c.NoCongestion,
SockBuf: c.SockBuf,
SmuxVer: c.SmuxVer,
SmuxBuf: c.SmuxBuf,
StreamBuf: c.StreamBuf,
KeepAlive: c.KeepAlive,
},
}
}
@@ -16,6 +16,7 @@ type ShadowSocksOption struct {
UDP bool `inbound:"udp,omitempty"`
MuxOption MuxOption `inbound:"mux-option,omitempty"`
ShadowTLS ShadowTLS `inbound:"shadow-tls,omitempty"`
KcpTun KcpTun `inbound:"kcp-tun,omitempty"`
}
func (o ShadowSocksOption) Equal(config C.InboundConfig) bool {
@@ -45,6 +46,7 @@ func NewShadowSocks(options *ShadowSocksOption) (*ShadowSocks, error) {
Udp: options.UDP,
MuxOption: options.MuxOption.Build(),
ShadowTLS: options.ShadowTLS.Build(),
KcpTun: options.KcpTun.Build(),
},
}, nil
}
@@ -10,6 +10,7 @@ import (
"github.com/metacubex/mihomo/adapter/outbound"
"github.com/metacubex/mihomo/listener/inbound"
"github.com/metacubex/mihomo/transport/kcptun"
shadowtls "github.com/metacubex/mihomo/transport/sing-shadowtls"
shadowsocks "github.com/metacubex/sing-shadowsocks"
@@ -21,7 +22,7 @@ import (
var noneList = []string{shadowsocks.MethodNone}
var shadowsocksCipherLists = [][]string{noneList, shadowaead.List, shadowaead_2022.List, shadowstream.List}
var shadowsocksCipherShortLists = [][]string{noneList, shadowaead.List[:5]} // for test shadowTLS
var shadowsocksCipherShortLists = [][]string{noneList, shadowaead.List[:5]} // for test shadowTLS and kcptun
var shadowsocksPassword32 string
var shadowsocksPassword16 string
@@ -32,11 +33,11 @@ func init() {
shadowsocksPassword16 = base64.StdEncoding.EncodeToString(passwordBytes[:16])
}
func testInboundShadowSocks(t *testing.T, inboundOptions inbound.ShadowSocksOption, outboundOptions outbound.ShadowSocksOption, cipherLists [][]string) {
func testInboundShadowSocks(t *testing.T, inboundOptions inbound.ShadowSocksOption, outboundOptions outbound.ShadowSocksOption, cipherLists [][]string, enableSingMux bool) {
t.Parallel()
for _, cipherList := range cipherLists {
for i, cipher := range cipherList {
enableSingMux := i == 0
enableSingMux := enableSingMux && i == 0
cipher := cipher
t.Run(cipher, func(t *testing.T) {
inboundOptions, outboundOptions := inboundOptions, outboundOptions // don't modify outside options value
@@ -100,19 +101,19 @@ func testInboundShadowSocks0(t *testing.T, inboundOptions inbound.ShadowSocksOpt
func TestInboundShadowSocks_Basic(t *testing.T) {
inboundOptions := inbound.ShadowSocksOption{}
outboundOptions := outbound.ShadowSocksOption{}
testInboundShadowSocks(t, inboundOptions, outboundOptions, shadowsocksCipherLists)
testInboundShadowSocks(t, inboundOptions, outboundOptions, shadowsocksCipherLists, true)
}
func testInboundShadowSocksShadowTls(t *testing.T, inboundOptions inbound.ShadowSocksOption, outboundOptions outbound.ShadowSocksOption) {
t.Parallel()
t.Run("Conn", func(t *testing.T) {
inboundOptions, outboundOptions := inboundOptions, outboundOptions // don't modify outside options value
testInboundShadowSocks(t, inboundOptions, outboundOptions, shadowsocksCipherShortLists)
testInboundShadowSocks(t, inboundOptions, outboundOptions, shadowsocksCipherShortLists, true)
})
t.Run("UConn", func(t *testing.T) {
inboundOptions, outboundOptions := inboundOptions, outboundOptions // don't modify outside options value
outboundOptions.ClientFingerprint = "chrome"
testInboundShadowSocks(t, inboundOptions, outboundOptions, shadowsocksCipherShortLists)
testInboundShadowSocks(t, inboundOptions, outboundOptions, shadowsocksCipherShortLists, true)
})
}
@@ -163,3 +164,17 @@ func TestInboundShadowSocks_ShadowTlsv3(t *testing.T) {
}
testInboundShadowSocksShadowTls(t, inboundOptions, outboundOptions)
}
func TestInboundShadowSocks_KcpTun(t *testing.T) {
inboundOptions := inbound.ShadowSocksOption{
KcpTun: inbound.KcpTun{
Enable: true,
Key: shadowsocksPassword16,
},
}
outboundOptions := outbound.ShadowSocksOption{
Plugin: kcptun.Mode,
PluginOpts: map[string]any{"key": shadowsocksPassword16},
}
testInboundShadowSocks(t, inboundOptions, outboundOptions, shadowsocksCipherShortLists, false)
}
@@ -14,6 +14,7 @@ import (
"github.com/metacubex/mihomo/listener/sing"
"github.com/metacubex/mihomo/log"
"github.com/metacubex/mihomo/ntp"
"github.com/metacubex/mihomo/transport/kcptun"
shadowsocks "github.com/metacubex/sing-shadowsocks"
"github.com/metacubex/sing-shadowsocks/shadowaead"
@@ -138,6 +139,12 @@ func New(config LC.ShadowsocksServer, tunnel C.Tunnel, additions ...inbound.Addi
}
}
var kcptunServer *kcptun.Server
if config.KcpTun.Enable {
kcptunServer = kcptun.NewServer(config.KcpTun.Config)
config.Udp = true
}
for _, addr := range strings.Split(config.Listen, ",") {
addr := addr
@@ -154,6 +161,14 @@ func New(config LC.ShadowsocksServer, tunnel C.Tunnel, additions ...inbound.Addi
sl.udpListeners = append(sl.udpListeners, ul)
if kcptunServer != nil {
go kcptunServer.Serve(ul, func(c net.Conn) {
sl.HandleConn(c, tunnel)
})
continue // skip tcp listener
}
go func() {
conn := bufio.NewPacketConn(ul)
rwOptions := network.NewReadWaitOptions(conn, sl.service)
@@ -46,7 +46,7 @@ func NewClient(ctx context.Context, config ClientConfig) *Client {
}
// Initialize the padding state of this client
padding.UpdatePaddingScheme(padding.DefaultPaddingScheme, &c.padding)
c.sessionClient = session.NewClient(ctx, c.CreateOutboundTLSConnection, &c.padding, config.IdleSessionCheckInterval, config.IdleSessionTimeout, config.MinIdleSession)
c.sessionClient = session.NewClient(ctx, c.createOutboundTLSConnection, &c.padding, config.IdleSessionCheckInterval, config.IdleSessionTimeout, config.MinIdleSession)
return c
}
@@ -63,7 +63,7 @@ func (c *Client) CreateProxy(ctx context.Context, destination M.Socksaddr) (net.
return conn, nil
}
func (c *Client) CreateOutboundTLSConnection(ctx context.Context) (net.Conn, error) {
func (c *Client) createOutboundTLSConnection(ctx context.Context) (net.Conn, error) {
conn, err := c.dialer.DialContext(ctx, N.NetworkTCP, c.server)
if err != nil {
return nil, err
@@ -66,23 +66,21 @@ func (c *Client) CreateStream(ctx context.Context) (net.Conn, error) {
var stream *Stream
var err error
for i := 0; i < 3; i++ {
session, err = c.findSession(ctx)
if session == nil {
return nil, fmt.Errorf("failed to create session: %w", err)
}
stream, err = session.OpenStream()
if err != nil {
_ = session.Close()
continue
}
break
session = c.getIdleSession()
if session == nil {
session, err = c.createSession(ctx)
}
if session == nil || stream == nil {
return nil, fmt.Errorf("too many closed session: %w", err)
if session == nil {
return nil, fmt.Errorf("failed to create session: %w", err)
}
stream, err = session.OpenStream()
if err != nil {
session.Close()
return nil, fmt.Errorf("failed to create stream: %w", err)
}
stream.dieHook = func() {
// If Session is not closed, put this Stream to pool
if !session.IsClosed() {
select {
case <-c.die.Done():
@@ -100,9 +98,7 @@ func (c *Client) CreateStream(ctx context.Context) (net.Conn, error) {
return stream, nil
}
func (c *Client) findSession(ctx context.Context) (*Session, error) {
var idle *Session
func (c *Client) getIdleSession() (idle *Session) {
c.idleSessionLock.Lock()
if !c.idleSession.IsEmpty() {
it := c.idleSession.Iterate()
@@ -110,12 +106,7 @@ func (c *Client) findSession(ctx context.Context) (*Session, error) {
c.idleSession.Remove(it.Key())
}
c.idleSessionLock.Unlock()
if idle == nil {
s, err := c.createSession(ctx)
return s, err
}
return idle, nil
return
}
func (c *Client) createSession(ctx context.Context) (*Session, error) {
@@ -127,7 +118,6 @@ func (c *Client) createSession(ctx context.Context) (*Session, error) {
session := NewClientSession(underlying, c.padding)
session.seq = c.sessionCounter.Add(1)
session.dieHook = func() {
//logrus.Debugln("session died", session)
c.idleSessionLock.Lock()
c.idleSession.Remove(math.MaxUint64 - session.seq)
c.idleSessionLock.Unlock()
@@ -168,12 +158,11 @@ func (c *Client) idleCleanup() {
}
func (c *Client) idleCleanupExpTime(expTime time.Time) {
sessionToRemove := make([]*Session, 0, c.idleSession.Len())
activeCount := 0
sessionToClose := make([]*Session, 0, c.idleSession.Len())
c.idleSessionLock.Lock()
it := c.idleSession.Iterate()
activeCount := 0
for it.IsNotEnd() {
session := it.Value()
key := it.Key()
@@ -190,12 +179,12 @@ func (c *Client) idleCleanupExpTime(expTime time.Time) {
continue
}
sessionToRemove = append(sessionToRemove, session)
sessionToClose = append(sessionToClose, session)
c.idleSession.Remove(key)
}
c.idleSessionLock.Unlock()
for _, session := range sessionToRemove {
for _, session := range sessionToClose {
session.Close()
}
}
@@ -90,7 +90,7 @@ func (s *Session) Run() {
f := newFrame(cmdSettings, 0)
f.data = settings.ToBytes()
s.buffering = true
s.writeFrame(f)
s.writeControlFrame(f)
go s.recvLoop()
}
@@ -119,7 +119,7 @@ func (s *Session) Close() error {
}
s.streamLock.Lock()
for _, stream := range s.streams {
stream.Close()
stream.closeLocally()
}
s.streams = make(map[uint32]*Stream)
s.streamLock.Unlock()
@@ -138,8 +138,6 @@ func (s *Session) OpenStream() (*Stream, error) {
sid := s.streamId.Add(1)
stream := newStream(sid, s)
//logrus.Debugln("stream open", sid, s.streams)
if sid >= 2 && s.peerVersion >= 2 {
s.synDoneLock.Lock()
if s.synDone != nil {
@@ -151,7 +149,7 @@ func (s *Session) OpenStream() (*Stream, error) {
s.synDoneLock.Unlock()
}
if _, err := s.writeFrame(newFrame(cmdSYN, sid)); err != nil {
if _, err := s.writeControlFrame(newFrame(cmdSYN, sid)); err != nil {
return nil, err
}
@@ -207,7 +205,7 @@ func (s *Session) recvLoop() error {
if !s.isClient && !receivedSettingsFromClient {
f := newFrame(cmdAlert, 0)
f.data = []byte("client did not send its settings")
s.writeFrame(f)
s.writeControlFrame(f)
return nil
}
s.streamLock.Lock()
@@ -241,18 +239,18 @@ func (s *Session) recvLoop() error {
stream, ok := s.streams[sid]
s.streamLock.RUnlock()
if ok {
stream.CloseWithError(fmt.Errorf("remote: %s", string(buffer)))
stream.closeWithError(fmt.Errorf("remote: %s", string(buffer)))
}
pool.Put(buffer)
}
case cmdFIN:
s.streamLock.RLock()
s.streamLock.Lock()
stream, ok := s.streams[sid]
s.streamLock.RUnlock()
delete(s.streams, sid)
s.streamLock.Unlock()
if ok {
stream.Close()
stream.closeLocally()
}
//logrus.Debugln("stream fin", sid, s.streams)
case cmdWaste:
if hdr.Length() > 0 {
buffer := pool.Get(int(hdr.Length()))
@@ -274,10 +272,9 @@ func (s *Session) recvLoop() error {
m := util.StringMapFromBytes(buffer)
paddingF := s.padding.Load()
if m["padding-md5"] != paddingF.Md5 {
// logrus.Debugln("remote md5 is", m["padding-md5"])
f := newFrame(cmdUpdatePaddingScheme, 0)
f.data = paddingF.RawScheme
_, err = s.writeFrame(f)
_, err = s.writeControlFrame(f)
if err != nil {
pool.Put(buffer)
return err
@@ -291,7 +288,7 @@ func (s *Session) recvLoop() error {
f.data = util.StringMap{
"v": "2",
}.ToBytes()
_, err = s.writeFrame(f)
_, err = s.writeControlFrame(f)
if err != nil {
pool.Put(buffer)
return err
@@ -329,7 +326,7 @@ func (s *Session) recvLoop() error {
}
}
case cmdHeartRequest:
if _, err := s.writeFrame(newFrame(cmdHeartResponse, sid)); err != nil {
if _, err := s.writeControlFrame(newFrame(cmdHeartResponse, sid)); err != nil {
return err
}
case cmdHeartResponse:
@@ -364,14 +361,31 @@ func (s *Session) streamClosed(sid uint32) error {
if s.IsClosed() {
return io.ErrClosedPipe
}
_, err := s.writeFrame(newFrame(cmdFIN, sid))
_, err := s.writeControlFrame(newFrame(cmdFIN, sid))
s.streamLock.Lock()
delete(s.streams, sid)
s.streamLock.Unlock()
return err
}
func (s *Session) writeFrame(frame frame) (int, error) {
func (s *Session) writeDataFrame(sid uint32, data []byte) (int, error) {
dataLen := len(data)
buffer := buf.NewSize(dataLen + headerOverHeadSize)
buffer.WriteByte(cmdPSH)
binary.BigEndian.PutUint32(buffer.Extend(4), sid)
binary.BigEndian.PutUint16(buffer.Extend(2), uint16(dataLen))
buffer.Write(data)
_, err := s.writeConn(buffer.Bytes())
buffer.Release()
if err != nil {
return 0, err
}
return dataLen, nil
}
func (s *Session) writeControlFrame(frame frame) (int, error) {
dataLen := len(frame.data)
buffer := buf.NewSize(dataLen + headerOverHeadSize)
@@ -379,12 +393,18 @@ func (s *Session) writeFrame(frame frame) (int, error) {
binary.BigEndian.PutUint32(buffer.Extend(4), frame.sid)
binary.BigEndian.PutUint16(buffer.Extend(2), uint16(dataLen))
buffer.Write(frame.data)
s.conn.SetWriteDeadline(time.Now().Add(time.Second * 5))
_, err := s.writeConn(buffer.Bytes())
buffer.Release()
if err != nil {
s.Close()
return 0, err
}
s.conn.SetWriteDeadline(time.Time{})
return dataLen, nil
}
@@ -53,21 +53,35 @@ func (s *Stream) Write(b []byte) (n int, err error) {
return 0, os.ErrDeadlineExceeded
default:
}
f := newFrame(cmdPSH, s.id)
f.data = b
n, err = s.sess.writeFrame(f)
if s.dieErr != nil {
return 0, s.dieErr
}
n, err = s.sess.writeDataFrame(s.id, b)
return
}
// Close implements net.Conn
func (s *Stream) Close() error {
return s.CloseWithError(io.ErrClosedPipe)
return s.closeWithError(io.ErrClosedPipe)
}
func (s *Stream) CloseWithError(err error) error {
// if err != io.ErrClosedPipe {
// logrus.Debugln(err)
// }
// closeLocally only closes Stream and don't notify remote peer
func (s *Stream) closeLocally() {
var once bool
s.dieOnce.Do(func() {
s.dieErr = net.ErrClosed
s.pipeR.Close()
once = true
})
if once {
if s.dieHook != nil {
s.dieHook()
s.dieHook = nil
}
}
}
func (s *Stream) closeWithError(err error) error {
var once bool
s.dieOnce.Do(func() {
s.dieErr = err
@@ -128,7 +142,7 @@ func (s *Stream) HandshakeFailure(err error) error {
if once && err != nil && s.sess.peerVersion >= 2 {
f := newFrame(cmdSYNACK, s.id)
f.data = []byte(err.Error())
if _, err := s.sess.writeFrame(f); err != nil {
if _, err := s.sess.writeControlFrame(f); err != nil {
return err
}
}
@@ -142,7 +156,7 @@ func (s *Stream) HandshakeSuccess() error {
once = true
})
if once && s.sess.peerVersion >= 2 {
if _, err := s.sess.writeFrame(newFrame(cmdSYNACK, s.id)); err != nil {
if _, err := s.sess.writeControlFrame(newFrame(cmdSYNACK, s.id)); err != nil {
return err
}
}
@@ -0,0 +1,9 @@
The MIT License (MIT)
Copyright (c) 2016 xtaci
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,171 @@
package kcptun
import (
"context"
"net"
"sync"
"time"
"github.com/metacubex/mihomo/log"
"github.com/metacubex/kcp-go"
"github.com/metacubex/randv2"
"github.com/metacubex/smux"
)
const Mode = "kcptun"
type DialFn func(ctx context.Context) (net.PacketConn, net.Addr, error)
type Client struct {
once sync.Once
config Config
block kcp.BlockCrypt
ctx context.Context
cancel context.CancelFunc
numconn uint16
muxes []timedSession
rr uint16
connMu sync.Mutex
chScavenger chan timedSession
}
func NewClient(config Config) *Client {
config.FillDefaults()
block := config.NewBlock()
ctx, cancel := context.WithCancel(context.Background())
return &Client{
config: config,
block: block,
ctx: ctx,
cancel: cancel,
}
}
func (c *Client) Close() error {
c.cancel()
return nil
}
func (c *Client) createConn(ctx context.Context, dial DialFn) (*smux.Session, error) {
conn, addr, err := dial(ctx)
if err != nil {
return nil, err
}
config := c.config
convid := randv2.Uint32()
kcpconn, err := kcp.NewConn4(convid, addr, c.block, config.DataShard, config.ParityShard, true, conn)
if err != nil {
return nil, err
}
kcpconn.SetStreamMode(true)
kcpconn.SetWriteDelay(false)
kcpconn.SetNoDelay(config.NoDelay, config.Interval, config.Resend, config.NoCongestion)
kcpconn.SetWindowSize(config.SndWnd, config.RcvWnd)
kcpconn.SetMtu(config.MTU)
kcpconn.SetACKNoDelay(config.AckNodelay)
_ = kcpconn.SetDSCP(config.DSCP)
_ = kcpconn.SetReadBuffer(config.SockBuf)
_ = kcpconn.SetWriteBuffer(config.SockBuf)
smuxConfig := smux.DefaultConfig()
smuxConfig.Version = config.SmuxVer
smuxConfig.MaxReceiveBuffer = config.SmuxBuf
smuxConfig.MaxStreamBuffer = config.StreamBuf
smuxConfig.KeepAliveInterval = time.Duration(config.KeepAlive) * time.Second
if smuxConfig.KeepAliveInterval >= smuxConfig.KeepAliveTimeout {
smuxConfig.KeepAliveTimeout = 3 * smuxConfig.KeepAliveInterval
}
if err := smux.VerifyConfig(smuxConfig); err != nil {
return nil, err
}
var netConn net.Conn = kcpconn
if !config.NoComp {
netConn = NewCompStream(netConn)
}
// stream multiplex
return smux.Client(netConn, smuxConfig)
}
func (c *Client) OpenStream(ctx context.Context, dial DialFn) (*smux.Stream, error) {
c.once.Do(func() {
// start scavenger if autoexpire is set
c.chScavenger = make(chan timedSession, 128)
if c.config.AutoExpire > 0 {
go scavenger(c.ctx, c.chScavenger, &c.config)
}
c.numconn = uint16(c.config.Conn)
c.muxes = make([]timedSession, c.config.Conn)
c.rr = uint16(0)
})
c.connMu.Lock()
idx := c.rr % c.numconn
// do auto expiration && reconnection
if c.muxes[idx].session == nil || c.muxes[idx].session.IsClosed() ||
(c.config.AutoExpire > 0 && time.Now().After(c.muxes[idx].expiryDate)) {
var err error
c.muxes[idx].session, err = c.createConn(ctx, dial)
if err != nil {
c.connMu.Unlock()
return nil, err
}
c.muxes[idx].expiryDate = time.Now().Add(time.Duration(c.config.AutoExpire) * time.Second)
if c.config.AutoExpire > 0 { // only when autoexpire set
c.chScavenger <- c.muxes[idx]
}
}
c.rr++
session := c.muxes[idx].session
c.connMu.Unlock()
return session.OpenStream()
}
// timedSession is a wrapper for smux.Session with expiry date
type timedSession struct {
session *smux.Session
expiryDate time.Time
}
// scavenger goroutine is used to close expired sessions
func scavenger(ctx context.Context, ch chan timedSession, config *Config) {
ticker := time.NewTicker(scavengePeriod * time.Second)
defer ticker.Stop()
var sessionList []timedSession
for {
select {
case item := <-ch:
sessionList = append(sessionList, timedSession{
item.session,
item.expiryDate.Add(time.Duration(config.ScavengeTTL) * time.Second)})
case <-ticker.C:
var newList []timedSession
for k := range sessionList {
s := sessionList[k]
if s.session.IsClosed() {
log.Debugln("scavenger: session normally closed: %s", s.session.LocalAddr())
} else if time.Now().After(s.expiryDate) {
s.session.Close()
log.Debugln("scavenger: session closed due to ttl: %s", s.session.LocalAddr())
} else {
newList = append(newList, sessionList[k])
}
}
sessionList = newList
case <-ctx.Done():
return
}
}
}
@@ -0,0 +1,152 @@
package kcptun
import (
"crypto/sha1"
"github.com/metacubex/mihomo/log"
"github.com/metacubex/kcp-go"
"golang.org/x/crypto/pbkdf2"
)
const (
// SALT is use for pbkdf2 key expansion
SALT = "kcp-go"
// maximum supported smux version
maxSmuxVer = 2
// scavenger check period
scavengePeriod = 5
)
type Config struct {
Key string `json:"key"`
Crypt string `json:"crypt"`
Mode string `json:"mode"`
Conn int `json:"conn"`
AutoExpire int `json:"autoexpire"`
ScavengeTTL int `json:"scavengettl"`
MTU int `json:"mtu"`
SndWnd int `json:"sndwnd"`
RcvWnd int `json:"rcvwnd"`
DataShard int `json:"datashard"`
ParityShard int `json:"parityshard"`
DSCP int `json:"dscp"`
NoComp bool `json:"nocomp"`
AckNodelay bool `json:"acknodelay"`
NoDelay int `json:"nodelay"`
Interval int `json:"interval"`
Resend int `json:"resend"`
NoCongestion int `json:"nc"`
SockBuf int `json:"sockbuf"`
SmuxVer int `json:"smuxver"`
SmuxBuf int `json:"smuxbuf"`
StreamBuf int `json:"streambuf"`
KeepAlive int `json:"keepalive"`
}
func (config *Config) FillDefaults() {
if config.Key == "" {
config.Key = "it's a secrect"
}
if config.Crypt == "" {
config.Crypt = "aes"
}
if config.Mode == "" {
config.Mode = "fast"
}
if config.Conn == 0 {
config.Conn = 1
}
if config.ScavengeTTL == 0 {
config.ScavengeTTL = 600
}
if config.MTU == 0 {
config.MTU = 1350
}
if config.SndWnd == 0 {
config.SndWnd = 128
}
if config.RcvWnd == 0 {
config.RcvWnd = 512
}
if config.DataShard == 0 {
config.DataShard = 10
}
if config.ParityShard == 0 {
config.ParityShard = 3
}
if config.Interval == 0 {
config.Interval = 50
}
if config.SockBuf == 0 {
config.SockBuf = 4194304
}
if config.SmuxVer == 0 {
config.SmuxVer = 1
}
if config.SmuxBuf == 0 {
config.SmuxBuf = 4194304
}
if config.StreamBuf == 0 {
config.StreamBuf = 2097152
}
if config.KeepAlive == 0 {
config.KeepAlive = 10
}
switch config.Mode {
case "normal":
config.NoDelay, config.Interval, config.Resend, config.NoCongestion = 0, 40, 2, 1
case "fast":
config.NoDelay, config.Interval, config.Resend, config.NoCongestion = 0, 30, 2, 1
case "fast2":
config.NoDelay, config.Interval, config.Resend, config.NoCongestion = 1, 20, 2, 1
case "fast3":
config.NoDelay, config.Interval, config.Resend, config.NoCongestion = 1, 10, 2, 1
}
// SMUX Version check
if config.SmuxVer > maxSmuxVer {
log.Warnln("unsupported smux version: %d", config.SmuxVer)
config.SmuxVer = maxSmuxVer
}
// Scavenge parameters check
if config.AutoExpire != 0 && config.ScavengeTTL > config.AutoExpire {
log.Warnln("WARNING: scavengettl is bigger than autoexpire, connections may race hard to use bandwidth.")
log.Warnln("Try limiting scavengettl to a smaller value.")
}
}
func (config *Config) NewBlock() (block kcp.BlockCrypt) {
pass := pbkdf2.Key([]byte(config.Key), []byte(SALT), 4096, 32, sha1.New)
switch config.Crypt {
case "null":
block = nil
case "tea":
block, _ = kcp.NewTEABlockCrypt(pass[:16])
case "xor":
block, _ = kcp.NewSimpleXORBlockCrypt(pass)
case "none":
block, _ = kcp.NewNoneBlockCrypt(pass)
case "aes-128":
block, _ = kcp.NewAESBlockCrypt(pass[:16])
case "aes-192":
block, _ = kcp.NewAESBlockCrypt(pass[:24])
case "blowfish":
block, _ = kcp.NewBlowfishBlockCrypt(pass)
case "twofish":
block, _ = kcp.NewTwofishBlockCrypt(pass)
case "cast5":
block, _ = kcp.NewCast5BlockCrypt(pass[:16])
case "3des":
block, _ = kcp.NewTripleDESBlockCrypt(pass[:24])
case "xtea":
block, _ = kcp.NewXTEABlockCrypt(pass[:16])
case "salsa20":
block, _ = kcp.NewSalsa20BlockCrypt(pass)
default:
config.Crypt = "aes"
block, _ = kcp.NewAESBlockCrypt(pass)
}
return
}
@@ -0,0 +1,63 @@
package kcptun
import (
"net"
"time"
"github.com/golang/snappy"
)
// CompStream is a net.Conn wrapper that compresses data using snappy
type CompStream struct {
conn net.Conn
w *snappy.Writer
r *snappy.Reader
}
func (c *CompStream) Read(p []byte) (n int, err error) {
return c.r.Read(p)
}
func (c *CompStream) Write(p []byte) (n int, err error) {
if _, err := c.w.Write(p); err != nil {
return 0, err
}
if err := c.w.Flush(); err != nil {
return 0, err
}
return len(p), err
}
func (c *CompStream) Close() error {
return c.conn.Close()
}
func (c *CompStream) LocalAddr() net.Addr {
return c.conn.LocalAddr()
}
func (c *CompStream) RemoteAddr() net.Addr {
return c.conn.RemoteAddr()
}
func (c *CompStream) SetDeadline(t time.Time) error {
return c.conn.SetDeadline(t)
}
func (c *CompStream) SetReadDeadline(t time.Time) error {
return c.conn.SetReadDeadline(t)
}
func (c *CompStream) SetWriteDeadline(t time.Time) error {
return c.conn.SetWriteDeadline(t)
}
// NewCompStream creates a new stream that compresses data using snappy
func NewCompStream(conn net.Conn) *CompStream {
c := new(CompStream)
c.conn = conn
c.w = snappy.NewBufferedWriter(conn)
c.r = snappy.NewReader(conn)
return c
}
@@ -0,0 +1,5 @@
// Package kcptun copy and modify from:
// https://github.com/xtaci/kcptun/tree/52492c72592627d0005cbedbc4ba37fc36a95c3f
// adopt for mihomo
// without SM4,QPP,tcpraw support
package kcptun
@@ -0,0 +1,79 @@
package kcptun
import (
"net"
"time"
"github.com/metacubex/kcp-go"
"github.com/metacubex/smux"
)
type Server struct {
config Config
block kcp.BlockCrypt
}
func NewServer(config Config) *Server {
config.FillDefaults()
block := config.NewBlock()
return &Server{
config: config,
block: block,
}
}
func (s *Server) Serve(pc net.PacketConn, handler func(net.Conn)) error {
lis, err := kcp.ServeConn(s.block, s.config.DataShard, s.config.ParityShard, pc)
if err != nil {
return err
}
defer lis.Close()
_ = lis.SetDSCP(s.config.DSCP)
_ = lis.SetReadBuffer(s.config.SockBuf)
_ = lis.SetWriteBuffer(s.config.SockBuf)
for {
conn, err := lis.AcceptKCP()
if err != nil {
return err
}
conn.SetStreamMode(true)
conn.SetWriteDelay(false)
conn.SetNoDelay(s.config.NoDelay, s.config.Interval, s.config.Resend, s.config.NoCongestion)
conn.SetMtu(s.config.MTU)
conn.SetWindowSize(s.config.SndWnd, s.config.RcvWnd)
conn.SetACKNoDelay(s.config.AckNodelay)
var netConn net.Conn = conn
if !s.config.NoComp {
netConn = NewCompStream(netConn)
}
go func() {
// stream multiplex
smuxConfig := smux.DefaultConfig()
smuxConfig.Version = s.config.SmuxVer
smuxConfig.MaxReceiveBuffer = s.config.SmuxBuf
smuxConfig.MaxStreamBuffer = s.config.StreamBuf
smuxConfig.KeepAliveInterval = time.Duration(s.config.KeepAlive) * time.Second
if smuxConfig.KeepAliveInterval >= smuxConfig.KeepAliveTimeout {
smuxConfig.KeepAliveTimeout = 3 * smuxConfig.KeepAliveInterval
}
mux, err := smux.Server(netConn, smuxConfig)
if err != nil {
return
}
defer mux.Close()
for {
stream, err := mux.AcceptStream()
if err != nil {
return
}
go handler(stream)
}
}()
}
}
@@ -7,23 +7,12 @@ import (
"errors"
"io"
"net"
"runtime"
"sync"
"time"
"github.com/metacubex/blake3"
utls "github.com/metacubex/utls"
"github.com/metacubex/utls/mlkem"
"golang.org/x/sys/cpu"
)
var (
// Keep in sync with crypto/tls/cipher_suites.go.
hasGCMAsmAMD64 = cpu.X86.HasAES && cpu.X86.HasPCLMULQDQ && cpu.X86.HasSSE41 && cpu.X86.HasSSSE3
hasGCMAsmARM64 = cpu.ARM64.HasAES && cpu.ARM64.HasPMULL
hasGCMAsmS390X = cpu.S390X.HasAES && cpu.S390X.HasAESCTR && cpu.S390X.HasGHASH
hasGCMAsmPPC64 = runtime.GOARCH == "ppc64" || runtime.GOARCH == "ppc64le"
HasAESGCMHardwareSupport = hasGCMAsmAMD64 || hasGCMAsmARM64 || hasGCMAsmS390X || hasGCMAsmPPC64
)
type ClientInstance struct {
@@ -77,7 +66,7 @@ func (i *ClientInstance) Handshake(conn net.Conn) (*CommonConn, error) {
if i.NfsPKeys == nil {
return nil, errors.New("uninitialized")
}
c := NewCommonConn(conn, HasAESGCMHardwareSupport)
c := NewCommonConn(conn, utls.HasAESGCMHardwareSupport())
ivAndRealysLength := 16 + i.RelaysLength
pfsKeyExchangeLength := 18 + 1184 + 32 + 16
@@ -0,0 +1,21 @@
package encryption
import (
"fmt"
"runtime"
"testing"
utls "github.com/metacubex/utls"
)
func TestHasAESGCMHardwareSupport(t *testing.T) {
fmt.Println("HasAESGCMHardwareSupport:", utls.HasAESGCMHardwareSupport())
if runtime.GOARCH == "arm64" && runtime.GOOS == "darwin" {
// It should be supported starting from Apple Silicon M1
// https://github.com/golang/go/blob/go1.25.0/src/internal/cpu/cpu_arm64_darwin.go#L26-L30
if !utls.HasAESGCMHardwareSupport() {
t.Errorf("For ARM64 Darwin platforms (excluding iOS), AES GCM hardware acceleration should always be available.")
}
}
}
@@ -29,12 +29,15 @@ require (
github.com/gobwas/pool v0.2.1 // indirect
github.com/gobwas/ws v1.4.0 // indirect
github.com/gofrs/uuid/v5 v5.3.2 // indirect
github.com/golang/snappy v1.0.0 // indirect
github.com/google/btree v1.1.3 // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect
github.com/insomniacslk/dhcp v0.0.0-20250109001534-8abf58130905 // indirect
github.com/josharian/native v1.1.0 // indirect
github.com/klauspost/compress v1.17.9 // indirect
github.com/klauspost/cpuid/v2 v2.2.6 // indirect
github.com/klauspost/reedsolomon v1.12.3 // indirect
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mdlayher/netlink v1.7.2 // indirect
@@ -48,6 +51,7 @@ require (
github.com/metacubex/fswatch v0.1.1 // indirect
github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759 // indirect
github.com/metacubex/gvisor v0.0.0-20250919004547-6122b699a301 // indirect
github.com/metacubex/kcp-go v0.0.0-20250923001605-1ba6f691c45b // indirect
github.com/metacubex/mihomo v1.7.0 // indirect
github.com/metacubex/nftables v0.0.0-20250503052935-30a69ab87793 // indirect
github.com/metacubex/quic-go v0.54.1-0.20250730114134-a1ae705fe295 // indirect
@@ -62,9 +66,9 @@ require (
github.com/metacubex/sing-tun v0.4.8 // indirect
github.com/metacubex/sing-vmess v0.2.4 // indirect
github.com/metacubex/sing-wireguard v0.0.0-20250503063753-2dc62acc626f // indirect
github.com/metacubex/smux v0.0.0-20250503055512-501391591dee // indirect
github.com/metacubex/smux v0.0.0-20250922175018-15c9a6a78719 // indirect
github.com/metacubex/tfo-go v0.0.0-20250921095601-b102db4216c0 // indirect
github.com/metacubex/utls v1.8.1-0.20250921102910-221428e5d4b2 // indirect
github.com/metacubex/utls v1.8.1-0.20250923145048-0a5bbc90dd3e // indirect
github.com/metacubex/wireguard-go v0.0.0-20250820062549-a6cecdd7f57f // indirect
github.com/metacubex/yamux v0.0.0-20250918083631-dd5f17c0be49 // indirect
github.com/miekg/dns v1.1.63 // indirect
+14 -5
View File
@@ -59,6 +59,8 @@ github.com/gofrs/uuid/v5 v5.3.2 h1:2jfO8j3XgSwlz/wHqemAEugfnTlikAYHhnqQ8Xh4fE0=
github.com/gofrs/uuid/v5 v5.3.2/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV+9bD8=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs=
github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg=
github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
@@ -76,6 +78,10 @@ github.com/josharian/native v1.1.0 h1:uuaP0hAbW7Y4l0ZRQ6C9zfb7Mg1mbFKry/xzDAfmtL
github.com/josharian/native v1.1.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc=
github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
github.com/klauspost/reedsolomon v1.12.3 h1:tzUznbfc3OFwJaTebv/QdhnFf2Xvb7gZ24XaHLBPmdc=
github.com/klauspost/reedsolomon v1.12.3/go.mod h1:3K5rXwABAvzGeR01r6pWZieUALXO/Tq7bFKGIb4m4WI=
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4=
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
@@ -102,6 +108,8 @@ github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759 h1:cjd4biTvO
github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759/go.mod h1:UHOv2xu+RIgLwpXca7TLrXleEd4oR3sPatW6IF8wU88=
github.com/metacubex/gvisor v0.0.0-20250919004547-6122b699a301 h1:N5GExQJqYAH3gOCshpp2u/J3CtNYzMctmlb0xK9wtbQ=
github.com/metacubex/gvisor v0.0.0-20250919004547-6122b699a301/go.mod h1:8LpS0IJW1VmWzUm3ylb0e2SK5QDm5lO/2qwWLZgRpBU=
github.com/metacubex/kcp-go v0.0.0-20250923001605-1ba6f691c45b h1:z7JLKjugnQ1qvDOAD8yMA5C8AlJY3bG+VrrgRntRlUY=
github.com/metacubex/kcp-go v0.0.0-20250923001605-1ba6f691c45b/go.mod h1:HIJZW4QMhbBqXuqC1ly6Hn0TEYT2SzRw58ns1yGhXTs=
github.com/metacubex/nftables v0.0.0-20250503052935-30a69ab87793 h1:1Qpuy+sU3DmyX9HwI+CrBT/oLNJngvBorR2RbajJcqo=
github.com/metacubex/nftables v0.0.0-20250503052935-30a69ab87793/go.mod h1:RjRNb4G52yAgfR+Oe/kp9G4PJJ97Fnj89eY1BFO3YyA=
github.com/metacubex/quic-go v0.54.1-0.20250730114134-a1ae705fe295 h1:8JVlYuE8uSJAvmyCd4TjvDxs57xjb0WxEoaWafK5+qs=
@@ -129,12 +137,12 @@ github.com/metacubex/sing-vmess v0.2.4 h1:Tx6AGgCiEf400E/xyDuYyafsel6sGbR8oF7RkA
github.com/metacubex/sing-vmess v0.2.4/go.mod h1:21R5R1u90uUvBQF0owoooEu96/SAYYD56nDrwm6nFaM=
github.com/metacubex/sing-wireguard v0.0.0-20250503063753-2dc62acc626f h1:Sr/DYKYofKHKc4GF3qkRGNuj6XA6c0eqPgEDN+VAsYU=
github.com/metacubex/sing-wireguard v0.0.0-20250503063753-2dc62acc626f/go.mod h1:jpAkVLPnCpGSfNyVmj6Cq4YbuZsFepm/Dc+9BAOcR80=
github.com/metacubex/smux v0.0.0-20250503055512-501391591dee h1:lp6hJ+4wCLZu113awp7P6odM2okB5s60HUyF0FMqKmo=
github.com/metacubex/smux v0.0.0-20250503055512-501391591dee/go.mod h1:4bPD8HWx9jPJ9aE4uadgyN7D1/Wz3KmPy+vale8sKLE=
github.com/metacubex/smux v0.0.0-20250922175018-15c9a6a78719 h1:T6qCCfolRDAVJKeaPW/mXwNLjnlo65AYN7WS2jrBNaM=
github.com/metacubex/smux v0.0.0-20250922175018-15c9a6a78719/go.mod h1:4bPD8HWx9jPJ9aE4uadgyN7D1/Wz3KmPy+vale8sKLE=
github.com/metacubex/tfo-go v0.0.0-20250921095601-b102db4216c0 h1:Ui+/2s5Qz0lSnDUBmEL12M5Oi/PzvFxGTNohm8ZcsmE=
github.com/metacubex/tfo-go v0.0.0-20250921095601-b102db4216c0/go.mod h1:l9oLnLoEXyGZ5RVLsh7QCC5XsouTUyKk4F2nLm2DHLw=
github.com/metacubex/utls v1.8.1-0.20250921102910-221428e5d4b2 h1:5OGzQvoE5yuOe8AsZsFwhf32ZxKmKN9G+k06AVd+6jY=
github.com/metacubex/utls v1.8.1-0.20250921102910-221428e5d4b2/go.mod h1:GN/CB3TRwQ9LYquYpIFynDkvMTYmkjwI7+mkUIoHj88=
github.com/metacubex/utls v1.8.1-0.20250923145048-0a5bbc90dd3e h1:t9IxEaxSRp3YJ1ewQV4oGkKaJaMeSoUWjOV0boLVQo8=
github.com/metacubex/utls v1.8.1-0.20250923145048-0a5bbc90dd3e/go.mod h1:kncGGVhFaoGn5M3pFe3SXhZCzsbCJayNOH4UEqTKTko=
github.com/metacubex/wireguard-go v0.0.0-20250820062549-a6cecdd7f57f h1:FGBPRb1zUabhPhDrlKEjQ9lgIwQ6cHL4x8M9lrERhbk=
github.com/metacubex/wireguard-go v0.0.0-20250820062549-a6cecdd7f57f/go.mod h1:oPGcV994OGJedmmxrcK9+ni7jUEMGhR+uVQAdaduIP4=
github.com/metacubex/yamux v0.0.0-20250918083631-dd5f17c0be49 h1:lhlqpYHopuTLx9xQt22kSA9HtnyTDmk5XjjQVCGHe2E=
@@ -192,7 +200,6 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/tiendc/go-deepcopy v1.6.1 h1:uVRTItFeNHkMcLueHS7OCsxgxT9P8MzGB/taUa2Y4Tk=
github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=
github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=
@@ -210,6 +217,7 @@ github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAh
github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc=
github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw=
github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae h1:J0GxkO96kL4WF+AIT3M4mfUVinOCPgf2uUWYFUzN0sM=
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
gitlab.com/go-extension/aes-ccm v0.0.0-20230221065045-e58665ef23c7 h1:UNrDfkQqiEYzdMlNsVvBYOAJWZjdktqFE9tQh5BT2+4=
@@ -248,6 +256,7 @@ golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20220622161953-175b2fd9d664/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -36,12 +36,15 @@ require (
github.com/gobwas/ws v1.4.0 // indirect
github.com/gofrs/uuid/v5 v5.3.2 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/golang/snappy v1.0.0 // indirect
github.com/google/btree v1.1.3 // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect
github.com/insomniacslk/dhcp v0.0.0-20250109001534-8abf58130905 // indirect
github.com/josharian/native v1.1.0 // indirect
github.com/klauspost/compress v1.17.9 // indirect
github.com/klauspost/cpuid/v2 v2.2.6 // indirect
github.com/klauspost/reedsolomon v1.12.3 // indirect
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mdlayher/netlink v1.7.2 // indirect
@@ -55,6 +58,7 @@ require (
github.com/metacubex/fswatch v0.1.1 // indirect
github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759 // indirect
github.com/metacubex/gvisor v0.0.0-20250919004547-6122b699a301 // indirect
github.com/metacubex/kcp-go v0.0.0-20250923001605-1ba6f691c45b // indirect
github.com/metacubex/nftables v0.0.0-20250503052935-30a69ab87793 // indirect
github.com/metacubex/quic-go v0.54.1-0.20250730114134-a1ae705fe295 // indirect
github.com/metacubex/randv2 v0.2.0 // indirect
@@ -68,9 +72,9 @@ require (
github.com/metacubex/sing-tun v0.4.8 // indirect
github.com/metacubex/sing-vmess v0.2.4 // indirect
github.com/metacubex/sing-wireguard v0.0.0-20250503063753-2dc62acc626f // indirect
github.com/metacubex/smux v0.0.0-20250503055512-501391591dee // indirect
github.com/metacubex/smux v0.0.0-20250922175018-15c9a6a78719 // indirect
github.com/metacubex/tfo-go v0.0.0-20250921095601-b102db4216c0 // indirect
github.com/metacubex/utls v1.8.1-0.20250921102910-221428e5d4b2 // indirect
github.com/metacubex/utls v1.8.1-0.20250923145048-0a5bbc90dd3e // indirect
github.com/metacubex/wireguard-go v0.0.0-20250820062549-a6cecdd7f57f // indirect
github.com/metacubex/yamux v0.0.0-20250918083631-dd5f17c0be49 // indirect
github.com/miekg/dns v1.1.63 // indirect
+14 -5
View File
@@ -60,6 +60,8 @@ github.com/gofrs/uuid/v5 v5.3.2/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs=
github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg=
github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
@@ -77,6 +79,10 @@ github.com/josharian/native v1.1.0 h1:uuaP0hAbW7Y4l0ZRQ6C9zfb7Mg1mbFKry/xzDAfmtL
github.com/josharian/native v1.1.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc=
github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
github.com/klauspost/reedsolomon v1.12.3 h1:tzUznbfc3OFwJaTebv/QdhnFf2Xvb7gZ24XaHLBPmdc=
github.com/klauspost/reedsolomon v1.12.3/go.mod h1:3K5rXwABAvzGeR01r6pWZieUALXO/Tq7bFKGIb4m4WI=
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4=
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
@@ -103,6 +109,8 @@ github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759 h1:cjd4biTvO
github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759/go.mod h1:UHOv2xu+RIgLwpXca7TLrXleEd4oR3sPatW6IF8wU88=
github.com/metacubex/gvisor v0.0.0-20250919004547-6122b699a301 h1:N5GExQJqYAH3gOCshpp2u/J3CtNYzMctmlb0xK9wtbQ=
github.com/metacubex/gvisor v0.0.0-20250919004547-6122b699a301/go.mod h1:8LpS0IJW1VmWzUm3ylb0e2SK5QDm5lO/2qwWLZgRpBU=
github.com/metacubex/kcp-go v0.0.0-20250923001605-1ba6f691c45b h1:z7JLKjugnQ1qvDOAD8yMA5C8AlJY3bG+VrrgRntRlUY=
github.com/metacubex/kcp-go v0.0.0-20250923001605-1ba6f691c45b/go.mod h1:HIJZW4QMhbBqXuqC1ly6Hn0TEYT2SzRw58ns1yGhXTs=
github.com/metacubex/nftables v0.0.0-20250503052935-30a69ab87793 h1:1Qpuy+sU3DmyX9HwI+CrBT/oLNJngvBorR2RbajJcqo=
github.com/metacubex/nftables v0.0.0-20250503052935-30a69ab87793/go.mod h1:RjRNb4G52yAgfR+Oe/kp9G4PJJ97Fnj89eY1BFO3YyA=
github.com/metacubex/quic-go v0.54.1-0.20250730114134-a1ae705fe295 h1:8JVlYuE8uSJAvmyCd4TjvDxs57xjb0WxEoaWafK5+qs=
@@ -130,12 +138,12 @@ github.com/metacubex/sing-vmess v0.2.4 h1:Tx6AGgCiEf400E/xyDuYyafsel6sGbR8oF7RkA
github.com/metacubex/sing-vmess v0.2.4/go.mod h1:21R5R1u90uUvBQF0owoooEu96/SAYYD56nDrwm6nFaM=
github.com/metacubex/sing-wireguard v0.0.0-20250503063753-2dc62acc626f h1:Sr/DYKYofKHKc4GF3qkRGNuj6XA6c0eqPgEDN+VAsYU=
github.com/metacubex/sing-wireguard v0.0.0-20250503063753-2dc62acc626f/go.mod h1:jpAkVLPnCpGSfNyVmj6Cq4YbuZsFepm/Dc+9BAOcR80=
github.com/metacubex/smux v0.0.0-20250503055512-501391591dee h1:lp6hJ+4wCLZu113awp7P6odM2okB5s60HUyF0FMqKmo=
github.com/metacubex/smux v0.0.0-20250503055512-501391591dee/go.mod h1:4bPD8HWx9jPJ9aE4uadgyN7D1/Wz3KmPy+vale8sKLE=
github.com/metacubex/smux v0.0.0-20250922175018-15c9a6a78719 h1:T6qCCfolRDAVJKeaPW/mXwNLjnlo65AYN7WS2jrBNaM=
github.com/metacubex/smux v0.0.0-20250922175018-15c9a6a78719/go.mod h1:4bPD8HWx9jPJ9aE4uadgyN7D1/Wz3KmPy+vale8sKLE=
github.com/metacubex/tfo-go v0.0.0-20250921095601-b102db4216c0 h1:Ui+/2s5Qz0lSnDUBmEL12M5Oi/PzvFxGTNohm8ZcsmE=
github.com/metacubex/tfo-go v0.0.0-20250921095601-b102db4216c0/go.mod h1:l9oLnLoEXyGZ5RVLsh7QCC5XsouTUyKk4F2nLm2DHLw=
github.com/metacubex/utls v1.8.1-0.20250921102910-221428e5d4b2 h1:5OGzQvoE5yuOe8AsZsFwhf32ZxKmKN9G+k06AVd+6jY=
github.com/metacubex/utls v1.8.1-0.20250921102910-221428e5d4b2/go.mod h1:GN/CB3TRwQ9LYquYpIFynDkvMTYmkjwI7+mkUIoHj88=
github.com/metacubex/utls v1.8.1-0.20250923145048-0a5bbc90dd3e h1:t9IxEaxSRp3YJ1ewQV4oGkKaJaMeSoUWjOV0boLVQo8=
github.com/metacubex/utls v1.8.1-0.20250923145048-0a5bbc90dd3e/go.mod h1:kncGGVhFaoGn5M3pFe3SXhZCzsbCJayNOH4UEqTKTko=
github.com/metacubex/wireguard-go v0.0.0-20250820062549-a6cecdd7f57f h1:FGBPRb1zUabhPhDrlKEjQ9lgIwQ6cHL4x8M9lrERhbk=
github.com/metacubex/wireguard-go v0.0.0-20250820062549-a6cecdd7f57f/go.mod h1:oPGcV994OGJedmmxrcK9+ni7jUEMGhR+uVQAdaduIP4=
github.com/metacubex/yamux v0.0.0-20250918083631-dd5f17c0be49 h1:lhlqpYHopuTLx9xQt22kSA9HtnyTDmk5XjjQVCGHe2E=
@@ -193,7 +201,6 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/tiendc/go-deepcopy v1.6.1 h1:uVRTItFeNHkMcLueHS7OCsxgxT9P8MzGB/taUa2Y4Tk=
github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=
github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=
@@ -211,6 +218,7 @@ github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAh
github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc=
github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw=
github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae h1:J0GxkO96kL4WF+AIT3M4mfUVinOCPgf2uUWYFUzN0sM=
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
gitlab.com/go-extension/aes-ccm v0.0.0-20230221065045-e58665ef23c7 h1:UNrDfkQqiEYzdMlNsVvBYOAJWZjdktqFE9tQh5BT2+4=
@@ -249,6 +257,7 @@ golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20220622161953-175b2fd9d664/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+95 -74
View File
@@ -5,6 +5,7 @@ import (
"fmt"
"net"
"strconv"
"strings"
"sync"
CN "github.com/metacubex/mihomo/common/net"
@@ -30,8 +31,8 @@ type MieruOption struct {
BasicOption
Name string `proxy:"name"`
Server string `proxy:"server"`
Port int `proxy:"port,omitempty"`
PortRange string `proxy:"port-range,omitempty"`
Port string `proxy:"port,omitempty"`
PortRange string `proxy:"port-range,omitempty"` // deprecated
Transport string `proxy:"transport"`
UDP bool `proxy:"udp,omitempty"`
UserName string `proxy:"username"`
@@ -123,13 +124,19 @@ func NewMieru(option MieruOption) (*Mieru, error) {
}
// Client is started lazily on the first use.
// Use the first port to construct the address.
var addr string
if option.Port != 0 {
addr = net.JoinHostPort(option.Server, strconv.Itoa(option.Port))
var portStr string
if option.Port != "" {
portStr = option.Port
} else {
beginPort, _, _ := beginAndEndPortFromPortRange(option.PortRange)
addr = net.JoinHostPort(option.Server, strconv.Itoa(beginPort))
portStr = option.PortRange
}
firstPort, err := getFirstPort(portStr)
if err != nil {
return nil, fmt.Errorf("failed to get first port from port string %q: %w", portStr, err)
}
addr = net.JoinHostPort(option.Server, strconv.Itoa(firstPort))
outbound := &Mieru{
Base: &Base{
name: option.Name,
@@ -183,54 +190,62 @@ func buildMieruClientConfig(option MieruOption) (*mieruclient.ClientConfig, erro
}
transportProtocol := mierupb.TransportProtocol_TCP.Enum()
var server *mierupb.ServerEndpoint
if net.ParseIP(option.Server) != nil {
// server is an IP address
if option.PortRange != "" {
server = &mierupb.ServerEndpoint{
IpAddress: proto.String(option.Server),
PortBindings: []*mierupb.PortBinding{
{
PortRange: proto.String(option.PortRange),
portBindings := make([]*mierupb.PortBinding, 0)
if option.Port != "" {
parts := strings.Split(option.Port, ",")
for _, part := range parts {
part = strings.TrimSpace(part)
if strings.Contains(part, "-") {
_, _, err := beginAndEndPortFromPortRange(part)
if err == nil {
portBindings = append(portBindings, &mierupb.PortBinding{
PortRange: proto.String(part),
Protocol: transportProtocol,
},
},
}
} else {
server = &mierupb.ServerEndpoint{
IpAddress: proto.String(option.Server),
PortBindings: []*mierupb.PortBinding{
{
Port: proto.Int32(int32(option.Port)),
Protocol: transportProtocol,
},
},
}
}
} else {
// server is a domain name
if option.PortRange != "" {
server = &mierupb.ServerEndpoint{
DomainName: proto.String(option.Server),
PortBindings: []*mierupb.PortBinding{
{
PortRange: proto.String(option.PortRange),
Protocol: transportProtocol,
},
},
}
} else {
server = &mierupb.ServerEndpoint{
DomainName: proto.String(option.Server),
PortBindings: []*mierupb.PortBinding{
{
Port: proto.Int32(int32(option.Port)),
Protocol: transportProtocol,
},
},
})
} else {
return nil, err
}
} else {
p, err := strconv.Atoi(part)
if err != nil {
return nil, fmt.Errorf("invalid port value: %s", part)
}
portBindings = append(portBindings, &mierupb.PortBinding{
Port: proto.Int32(int32(p)),
Protocol: transportProtocol,
})
}
}
}
if option.PortRange != "" {
parts := strings.Split(option.PortRange, ",")
for _, part := range parts {
part = strings.TrimSpace(part)
if _, _, err := beginAndEndPortFromPortRange(part); err == nil {
portBindings = append(portBindings, &mierupb.PortBinding{
PortRange: proto.String(part),
Protocol: transportProtocol,
})
}
}
}
var server *mierupb.ServerEndpoint
if net.ParseIP(option.Server) != nil {
// server is an IP address
server = &mierupb.ServerEndpoint{
IpAddress: proto.String(option.Server),
PortBindings: portBindings,
}
} else {
// server is a domain name
server = &mierupb.ServerEndpoint{
DomainName: proto.String(option.Server),
PortBindings: portBindings,
}
}
config := &mieruclient.ClientConfig{
Profile: &mierupb.ClientProfile{
ProfileName: proto.String(option.Name),
@@ -259,31 +274,9 @@ func validateMieruOption(option MieruOption) error {
if option.Server == "" {
return fmt.Errorf("server is empty")
}
if option.Port == 0 && option.PortRange == "" {
return fmt.Errorf("either port or port-range must be set")
if option.Port == "" && option.PortRange == "" {
return fmt.Errorf("port must be set")
}
if option.Port != 0 && option.PortRange != "" {
return fmt.Errorf("port and port-range cannot be set at the same time")
}
if option.Port != 0 && (option.Port < 1 || option.Port > 65535) {
return fmt.Errorf("port must be between 1 and 65535")
}
if option.PortRange != "" {
begin, end, err := beginAndEndPortFromPortRange(option.PortRange)
if err != nil {
return fmt.Errorf("invalid port-range format")
}
if begin < 1 || begin > 65535 {
return fmt.Errorf("begin port must be between 1 and 65535")
}
if end < 1 || end > 65535 {
return fmt.Errorf("end port must be between 1 and 65535")
}
if begin > end {
return fmt.Errorf("begin port must be less than or equal to end port")
}
}
if option.Transport != "TCP" {
return fmt.Errorf("transport must be TCP")
}
@@ -306,8 +299,36 @@ func validateMieruOption(option MieruOption) error {
return nil
}
func getFirstPort(portStr string) (int, error) {
if portStr == "" {
return 0, fmt.Errorf("port string is empty")
}
parts := strings.Split(portStr, ",")
firstPart := parts[0]
if strings.Contains(firstPart, "-") {
begin, _, err := beginAndEndPortFromPortRange(firstPart)
if err != nil {
return 0, err
}
return begin, nil
}
port, err := strconv.Atoi(firstPart)
if err != nil {
return 0, fmt.Errorf("invalid port format: %s", firstPart)
}
return port, nil
}
func beginAndEndPortFromPortRange(portRange string) (int, int, error) {
var begin, end int
_, err := fmt.Sscanf(portRange, "%d-%d", &begin, &end)
if err != nil {
return 0, 0, fmt.Errorf("invalid port range format: %w", err)
}
if begin > end {
return 0, 0, fmt.Errorf("begin port is greater than end port: %s", portRange)
}
return begin, end, err
}
+218 -4
View File
@@ -1,22 +1,51 @@
package outbound
import "testing"
import (
"reflect"
"testing"
mieruclient "github.com/enfein/mieru/v3/apis/client"
mierupb "github.com/enfein/mieru/v3/pkg/appctl/appctlpb"
"google.golang.org/protobuf/proto"
)
func TestNewMieru(t *testing.T) {
transportProtocol := mierupb.TransportProtocol_TCP.Enum()
testCases := []struct {
option MieruOption
wantBaseAddr string
wantConfig *mieruclient.ClientConfig
}{
{
option: MieruOption{
Name: "test",
Server: "1.2.3.4",
Port: 10000,
Port: "10000",
Transport: "TCP",
UserName: "test",
Password: "test",
},
wantBaseAddr: "1.2.3.4:10000",
wantConfig: &mieruclient.ClientConfig{
Profile: &mierupb.ClientProfile{
ProfileName: proto.String("test"),
User: &mierupb.User{
Name: proto.String("test"),
Password: proto.String("test"),
},
Servers: []*mierupb.ServerEndpoint{
{
IpAddress: proto.String("1.2.3.4"),
PortBindings: []*mierupb.PortBinding{
{
Port: proto.Int32(10000),
Protocol: transportProtocol,
},
},
},
},
},
},
},
{
option: MieruOption{
@@ -28,28 +57,212 @@ func TestNewMieru(t *testing.T) {
Password: "test",
},
wantBaseAddr: "[2001:db8::1]:10001",
wantConfig: &mieruclient.ClientConfig{
Profile: &mierupb.ClientProfile{
ProfileName: proto.String("test"),
User: &mierupb.User{
Name: proto.String("test"),
Password: proto.String("test"),
},
Servers: []*mierupb.ServerEndpoint{
{
IpAddress: proto.String("2001:db8::1"),
PortBindings: []*mierupb.PortBinding{
{
PortRange: proto.String("10001-10002"),
Protocol: transportProtocol,
},
},
},
},
},
},
},
{
option: MieruOption{
Name: "test",
Server: "example.com",
Port: 10003,
Port: "10003",
Transport: "TCP",
UserName: "test",
Password: "test",
},
wantBaseAddr: "example.com:10003",
wantConfig: &mieruclient.ClientConfig{
Profile: &mierupb.ClientProfile{
ProfileName: proto.String("test"),
User: &mierupb.User{
Name: proto.String("test"),
Password: proto.String("test"),
},
Servers: []*mierupb.ServerEndpoint{
{
DomainName: proto.String("example.com"),
PortBindings: []*mierupb.PortBinding{
{
Port: proto.Int32(10003),
Protocol: transportProtocol,
},
},
},
},
},
},
},
{
option: MieruOption{
Name: "test",
Server: "example.com",
Port: "10004,10005",
Transport: "TCP",
UserName: "test",
Password: "test",
},
wantBaseAddr: "example.com:10004",
wantConfig: &mieruclient.ClientConfig{
Profile: &mierupb.ClientProfile{
ProfileName: proto.String("test"),
User: &mierupb.User{
Name: proto.String("test"),
Password: proto.String("test"),
},
Servers: []*mierupb.ServerEndpoint{
{
DomainName: proto.String("example.com"),
PortBindings: []*mierupb.PortBinding{
{
Port: proto.Int32(10004),
Protocol: transportProtocol,
},
{
Port: proto.Int32(10005),
Protocol: transportProtocol,
},
},
},
},
},
},
},
{
option: MieruOption{
Name: "test",
Server: "example.com",
Port: "10006-10007,11000",
Transport: "TCP",
UserName: "test",
Password: "test",
},
wantBaseAddr: "example.com:10006",
wantConfig: &mieruclient.ClientConfig{
Profile: &mierupb.ClientProfile{
ProfileName: proto.String("test"),
User: &mierupb.User{
Name: proto.String("test"),
Password: proto.String("test"),
},
Servers: []*mierupb.ServerEndpoint{
{
DomainName: proto.String("example.com"),
PortBindings: []*mierupb.PortBinding{
{
PortRange: proto.String("10006-10007"),
Protocol: transportProtocol,
},
{
Port: proto.Int32(11000),
Protocol: transportProtocol,
},
},
},
},
},
},
},
{
option: MieruOption{
Name: "test",
Server: "example.com",
Port: "10008",
PortRange: "10009-10010",
Transport: "TCP",
UserName: "test",
Password: "test",
},
wantBaseAddr: "example.com:10008",
wantConfig: &mieruclient.ClientConfig{
Profile: &mierupb.ClientProfile{
ProfileName: proto.String("test"),
User: &mierupb.User{
Name: proto.String("test"),
Password: proto.String("test"),
},
Servers: []*mierupb.ServerEndpoint{
{
DomainName: proto.String("example.com"),
PortBindings: []*mierupb.PortBinding{
{
Port: proto.Int32(10008),
Protocol: transportProtocol,
},
{
PortRange: proto.String("10009-10010"),
Protocol: transportProtocol,
},
},
},
},
},
},
},
}
for _, testCase := range testCases {
mieru, err := NewMieru(testCase.option)
if err != nil {
t.Error(err)
t.Fatal(err)
}
config, err := mieru.client.Load()
if err != nil {
t.Fatal(err)
}
config.Dialer = nil
if mieru.addr != testCase.wantBaseAddr {
t.Errorf("got addr %q, want %q", mieru.addr, testCase.wantBaseAddr)
}
if !reflect.DeepEqual(config, testCase.wantConfig) {
t.Errorf("got config %+v, want %+v", config, testCase.wantConfig)
}
}
}
func TestNewMieruError(t *testing.T) {
testCases := []MieruOption{
{
Name: "test",
Server: "example.com",
Port: "invalid",
PortRange: "invalid",
Transport: "TCP",
UserName: "test",
Password: "test",
},
{
Name: "test",
Server: "example.com",
Port: "",
PortRange: "",
Transport: "TCP",
UserName: "test",
Password: "test",
},
}
for _, option := range testCases {
_, err := NewMieru(option)
if err == nil {
t.Errorf("expected error for option %+v, but got nil", option)
}
}
}
@@ -63,6 +276,7 @@ func TestBeginAndEndPortFromPortRange(t *testing.T) {
{"1-10", 1, 10, false},
{"1000-2000", 1000, 2000, false},
{"65535-65535", 65535, 65535, false},
{"2000-1000", 0, 0, true},
{"1", 0, 0, true},
{"1-", 0, 0, true},
{"-10", 0, 0, true},
+2 -8
View File
@@ -24,7 +24,6 @@ import (
"github.com/metacubex/randv2"
utls "github.com/metacubex/utls"
"golang.org/x/crypto/chacha20poly1305"
"golang.org/x/crypto/hkdf"
"golang.org/x/net/http2"
)
@@ -107,13 +106,8 @@ func GetRealityConn(ctx context.Context, conn net.Conn, fingerprint UClientHello
if err != nil {
return nil, err
}
var aeadCipher cipher.AEAD
if utls.AesgcmPreferred(hello.CipherSuites) {
aesBlock, _ := aes.NewCipher(authKey)
aeadCipher, _ = cipher.NewGCM(aesBlock)
} else {
aeadCipher, _ = chacha20poly1305.New(authKey)
}
aesBlock, _ := aes.NewCipher(authKey)
aeadCipher, _ := cipher.NewGCM(aesBlock)
aeadCipher.Seal(hello.SessionId[:0], hello.Random[20:], hello.SessionId[:16], hello.Raw)
copy(hello.Raw[39:], hello.SessionId)
//log.Debugln("REALITY hello.sessionId: %v", hello.SessionId)
+2 -2
View File
@@ -1024,8 +1024,8 @@ proxies: # socks5
- name: mieru
type: mieru
server: 1.2.3.4
port: 2999
# port-range: 2090-2099 #(不可同时填写 port 和 port-range
port: 2999 # 支持使用 ports 格式,例如 2999,3999 或 2999-3010,3950,3995-3999
# port-range: 2090-2099 # 已废弃,请使用 port
transport: TCP # 只支持 TCP
udp: true # 支持 UDP over TCP
username: user
+2 -2
View File
@@ -22,7 +22,7 @@ require (
github.com/metacubex/chacha v0.1.5
github.com/metacubex/fswatch v0.1.1
github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759
github.com/metacubex/kcp-go v0.0.0-20250922034656-df9a2b90cdf7
github.com/metacubex/kcp-go v0.0.0-20250923001605-1ba6f691c45b
github.com/metacubex/quic-go v0.54.1-0.20250730114134-a1ae705fe295
github.com/metacubex/randv2 v0.2.0
github.com/metacubex/restls-client-go v0.1.7
@@ -37,7 +37,7 @@ require (
github.com/metacubex/sing-wireguard v0.0.0-20250503063753-2dc62acc626f
github.com/metacubex/smux v0.0.0-20250922175018-15c9a6a78719
github.com/metacubex/tfo-go v0.0.0-20250921095601-b102db4216c0
github.com/metacubex/utls v1.8.1-0.20250921102910-221428e5d4b2
github.com/metacubex/utls v1.8.1-0.20250923145048-0a5bbc90dd3e
github.com/metacubex/wireguard-go v0.0.0-20250820062549-a6cecdd7f57f
github.com/miekg/dns v1.1.63 // lastest version compatible with golang1.20
github.com/mroth/weightedrand/v2 v2.1.0
+4 -5
View File
@@ -112,8 +112,8 @@ github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759 h1:cjd4biTvO
github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759/go.mod h1:UHOv2xu+RIgLwpXca7TLrXleEd4oR3sPatW6IF8wU88=
github.com/metacubex/gvisor v0.0.0-20250919004547-6122b699a301 h1:N5GExQJqYAH3gOCshpp2u/J3CtNYzMctmlb0xK9wtbQ=
github.com/metacubex/gvisor v0.0.0-20250919004547-6122b699a301/go.mod h1:8LpS0IJW1VmWzUm3ylb0e2SK5QDm5lO/2qwWLZgRpBU=
github.com/metacubex/kcp-go v0.0.0-20250922034656-df9a2b90cdf7 h1:vGsrjQxlepSfkMALzJuvDzd+wp6NvKXpoyPuPb4SYCE=
github.com/metacubex/kcp-go v0.0.0-20250922034656-df9a2b90cdf7/go.mod h1:HIJZW4QMhbBqXuqC1ly6Hn0TEYT2SzRw58ns1yGhXTs=
github.com/metacubex/kcp-go v0.0.0-20250923001605-1ba6f691c45b h1:z7JLKjugnQ1qvDOAD8yMA5C8AlJY3bG+VrrgRntRlUY=
github.com/metacubex/kcp-go v0.0.0-20250923001605-1ba6f691c45b/go.mod h1:HIJZW4QMhbBqXuqC1ly6Hn0TEYT2SzRw58ns1yGhXTs=
github.com/metacubex/nftables v0.0.0-20250503052935-30a69ab87793 h1:1Qpuy+sU3DmyX9HwI+CrBT/oLNJngvBorR2RbajJcqo=
github.com/metacubex/nftables v0.0.0-20250503052935-30a69ab87793/go.mod h1:RjRNb4G52yAgfR+Oe/kp9G4PJJ97Fnj89eY1BFO3YyA=
github.com/metacubex/quic-go v0.54.1-0.20250730114134-a1ae705fe295 h1:8JVlYuE8uSJAvmyCd4TjvDxs57xjb0WxEoaWafK5+qs=
@@ -145,8 +145,8 @@ github.com/metacubex/smux v0.0.0-20250922175018-15c9a6a78719 h1:T6qCCfolRDAVJKea
github.com/metacubex/smux v0.0.0-20250922175018-15c9a6a78719/go.mod h1:4bPD8HWx9jPJ9aE4uadgyN7D1/Wz3KmPy+vale8sKLE=
github.com/metacubex/tfo-go v0.0.0-20250921095601-b102db4216c0 h1:Ui+/2s5Qz0lSnDUBmEL12M5Oi/PzvFxGTNohm8ZcsmE=
github.com/metacubex/tfo-go v0.0.0-20250921095601-b102db4216c0/go.mod h1:l9oLnLoEXyGZ5RVLsh7QCC5XsouTUyKk4F2nLm2DHLw=
github.com/metacubex/utls v1.8.1-0.20250921102910-221428e5d4b2 h1:5OGzQvoE5yuOe8AsZsFwhf32ZxKmKN9G+k06AVd+6jY=
github.com/metacubex/utls v1.8.1-0.20250921102910-221428e5d4b2/go.mod h1:GN/CB3TRwQ9LYquYpIFynDkvMTYmkjwI7+mkUIoHj88=
github.com/metacubex/utls v1.8.1-0.20250923145048-0a5bbc90dd3e h1:t9IxEaxSRp3YJ1ewQV4oGkKaJaMeSoUWjOV0boLVQo8=
github.com/metacubex/utls v1.8.1-0.20250923145048-0a5bbc90dd3e/go.mod h1:kncGGVhFaoGn5M3pFe3SXhZCzsbCJayNOH4UEqTKTko=
github.com/metacubex/wireguard-go v0.0.0-20250820062549-a6cecdd7f57f h1:FGBPRb1zUabhPhDrlKEjQ9lgIwQ6cHL4x8M9lrERhbk=
github.com/metacubex/wireguard-go v0.0.0-20250820062549-a6cecdd7f57f/go.mod h1:oPGcV994OGJedmmxrcK9+ni7jUEMGhR+uVQAdaduIP4=
github.com/metacubex/yamux v0.0.0-20250918083631-dd5f17c0be49 h1:lhlqpYHopuTLx9xQt22kSA9HtnyTDmk5XjjQVCGHe2E=
@@ -206,7 +206,6 @@ github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/tiendc/go-deepcopy v1.6.1 h1:uVRTItFeNHkMcLueHS7OCsxgxT9P8MzGB/taUa2Y4Tk=
github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=
github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=
+2 -4
View File
@@ -2,8 +2,6 @@ package kcptun
import (
"context"
"crypto/rand"
"encoding/binary"
"net"
"sync"
"time"
@@ -11,6 +9,7 @@ import (
"github.com/metacubex/mihomo/log"
"github.com/metacubex/kcp-go"
"github.com/metacubex/randv2"
"github.com/metacubex/smux"
)
@@ -60,8 +59,7 @@ func (c *Client) createConn(ctx context.Context, dial DialFn) (*smux.Session, er
}
config := c.config
var convid uint32
binary.Read(rand.Reader, binary.LittleEndian, &convid)
convid := randv2.Uint32()
kcpconn, err := kcp.NewConn4(convid, addr, c.block, config.DataShard, config.ParityShard, true, conn)
if err != nil {
return nil, err
@@ -7,23 +7,12 @@ import (
"errors"
"io"
"net"
"runtime"
"sync"
"time"
"github.com/metacubex/blake3"
utls "github.com/metacubex/utls"
"github.com/metacubex/utls/mlkem"
"golang.org/x/sys/cpu"
)
var (
// Keep in sync with crypto/tls/cipher_suites.go.
hasGCMAsmAMD64 = cpu.X86.HasAES && cpu.X86.HasPCLMULQDQ && cpu.X86.HasSSE41 && cpu.X86.HasSSSE3
hasGCMAsmARM64 = cpu.ARM64.HasAES && cpu.ARM64.HasPMULL
hasGCMAsmS390X = cpu.S390X.HasAES && cpu.S390X.HasAESCTR && cpu.S390X.HasGHASH
hasGCMAsmPPC64 = runtime.GOARCH == "ppc64" || runtime.GOARCH == "ppc64le"
HasAESGCMHardwareSupport = hasGCMAsmAMD64 || hasGCMAsmARM64 || hasGCMAsmS390X || hasGCMAsmPPC64
)
type ClientInstance struct {
@@ -77,7 +66,7 @@ func (i *ClientInstance) Handshake(conn net.Conn) (*CommonConn, error) {
if i.NfsPKeys == nil {
return nil, errors.New("uninitialized")
}
c := NewCommonConn(conn, HasAESGCMHardwareSupport)
c := NewCommonConn(conn, utls.HasAESGCMHardwareSupport())
ivAndRealysLength := 16 + i.RelaysLength
pfsKeyExchangeLength := 18 + 1184 + 32 + 16
@@ -0,0 +1,21 @@
package encryption
import (
"fmt"
"runtime"
"testing"
utls "github.com/metacubex/utls"
)
func TestHasAESGCMHardwareSupport(t *testing.T) {
fmt.Println("HasAESGCMHardwareSupport:", utls.HasAESGCMHardwareSupport())
if runtime.GOARCH == "arm64" && runtime.GOOS == "darwin" {
// It should be supported starting from Apple Silicon M1
// https://github.com/golang/go/blob/go1.25.0/src/internal/cpu/cpu_arm64_darwin.go#L26-L30
if !utls.HasAESGCMHardwareSupport() {
t.Errorf("For ARM64 Darwin platforms (excluding iOS), AES GCM hardware acceleration should always be available.")
}
}
}
+128
View File
@@ -0,0 +1,128 @@
# Contributor Covenant Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
- Demonstrating empathy and kindness toward other people
- Being respectful of differing opinions, viewpoints, and experiences
- Giving and gracefully accepting constructive feedback
- Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
- Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
- The use of sexualized language or imagery, and sexual attention or
advances of any kind
- Trolling, insulting or derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information, such as a physical or email
address, without their explicit permission
- Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
i@elaina.moe.
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series
of actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within
the community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.
+3 -2
View File
@@ -9735,11 +9735,12 @@ dependencies = [
[[package]]
name = "time"
version = "0.3.43"
version = "0.3.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83bde6f1ec10e72d583d91623c939f623002284ef622b87de38cfd546cbf2031"
checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d"
dependencies = [
"deranged",
"itoa",
"js-sys",
"libc",
"num-conv",
@@ -57,6 +57,9 @@ export const useClashConnections = () => {
]) || []
)
},
// Ensure the query is enabled and properly initialized
enabled: true,
staleTime: 0, // Data is always fresh as it comes from WebSocket
})
const deleteConnections = useMutation({
@@ -31,7 +31,7 @@
"country-code-emoji": "2.3.0",
"country-emoji": "1.5.6",
"dayjs": "1.11.18",
"framer-motion": "12.23.18",
"framer-motion": "12.23.16",
"i18next": "25.5.2",
"jotai": "2.14.0",
"json-schema": "0.4.0",
@@ -49,14 +49,14 @@
"react-use": "17.6.0",
"rxjs": "7.8.2",
"swr": "2.3.6",
"virtua": "0.43.2",
"virtua": "0.43.3",
"vite-bundle-visualizer": "1.2.1"
},
"devDependencies": {
"@csstools/normalize.css": "12.1.1",
"@emotion/babel-plugin": "11.13.5",
"@emotion/react": "11.14.0",
"@iconify/json": "2.2.386",
"@iconify/json": "2.2.387",
"@monaco-editor/react": "4.7.0",
"@tanstack/react-query": "5.87.4",
"@tanstack/react-router": "1.131.50",
@@ -83,12 +83,12 @@
"meta-json-schema": "1.19.13",
"monaco-yaml": "5.4.0",
"nanoid": "5.1.6",
"sass-embedded": "1.93.0",
"sass-embedded": "1.93.1",
"shiki": "2.5.0",
"unplugin-auto-import": "20.1.0",
"unplugin-icons": "22.3.0",
"validator": "13.15.15",
"vite": "7.1.6",
"vite": "7.1.7",
"vite-plugin-html": "3.2.2",
"vite-plugin-sass-dts": "1.3.31",
"vite-plugin-svgr": "4.5.0",
@@ -33,7 +33,7 @@ export const ConnectionsTable = ({ searchTerm }: { searchTerm?: string }) => {
const { t, i18n } = useTranslation()
const {
query: { data: clashConnections },
query: { data: clashConnections, isLoading },
} = useClashConnections()
const historyMessage = useRef<TableMessage | null>(null)
@@ -189,6 +189,12 @@ export const ConnectionsTable = ({ searchTerm }: { searchTerm?: string }) => {
columnVirtualizerOptions: { overscan: 2 },
})
// Show loading state while data is being fetched
if (isLoading && !connectionsMessage) {
// Don't show a separate loading indicator here since the parent component already handles it
return null
}
return connectionsMessage?.connections.length ? (
<>
<ConnectionDetailDialog
@@ -1,13 +1,13 @@
import { filesize } from 'filesize'
import { useEffect, useRef, useState } from 'react'
import { Download, Upload } from '@mui/icons-material'
import { Paper } from '@mui/material'
import { Paper, Skeleton } from '@mui/material'
import { useClashConnections } from '@nyanpasu/interface'
import { darken, lighten } from '@nyanpasu/ui'
export default function ConnectionTotal() {
const {
query: { data: clashConnections },
query: { data: clashConnections, isLoading },
} = useClashConnections()
const latestClashConnections = clashConnections?.at(-1)
@@ -48,8 +48,33 @@ export default function ConnectionTotal() {
}
}, [latestClashConnections?.uploadTotal])
if (!latestClashConnections) {
return null
// Show skeleton loading state while data is being fetched
if (isLoading || !latestClashConnections) {
return (
<div className="flex gap-2">
<Paper
elevation={0}
className="flex min-h-8 items-center justify-center gap-1 px-2"
sx={{
borderRadius: '1em',
}}
>
<Download className="scale-75" />
<Skeleton variant="text" width={60} height={20} />
</Paper>
<Paper
elevation={0}
className="flex min-h-8 items-center justify-center gap-1 px-2"
sx={{
borderRadius: '1em',
}}
>
<Upload className="scale-75" />
<Skeleton variant="text" width={60} height={20} />
</Paper>
</div>
)
}
return (
@@ -4,7 +4,7 @@ import { useTranslation } from 'react-i18next'
import { SearchTermCtx } from '@/components/connections/connection-search-term'
import HeaderSearch from '@/components/connections/header-search'
import { FilterAlt } from '@mui/icons-material'
import { IconButton } from '@mui/material'
import { Box, CircularProgress, IconButton } from '@mui/material'
import { BasePage } from '@nyanpasu/ui'
import { createFileRoute, useBlocker } from '@tanstack/react-router'
@@ -46,6 +46,21 @@ function Connections() {
}
}, [proceed, deferredMountTable])
// Loading fallback component
const LoadingFallback = () => (
<Box
sx={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
height: '100%',
minHeight: 200,
}}
>
<CircularProgress />
</Box>
)
return (
<SearchTermCtx.Provider value={throttledSearchTerm}>
<BasePage
@@ -53,7 +68,9 @@ function Connections() {
full
header={
<div className="flex max-h-96 w-full flex-1 items-center justify-between gap-2 pl-5">
<ConnectionTotal />
<Suspense fallback={null}>
<ConnectionTotal />
</Suspense>
<div className="flex items-center gap-1">
<Suspense fallback={null}>
<ColumnFilterDialog
@@ -72,7 +89,9 @@ function Connections() {
</div>
}
>
{mountTable && <Component />}
<Suspense fallback={<LoadingFallback />}>
{mountTable && <Component />}
</Suspense>
</BasePage>
</SearchTermCtx.Provider>
)
+3 -3
View File
@@ -23,14 +23,14 @@
"@vitejs/plugin-react": "5.0.3",
"ahooks": "3.9.5",
"d3": "7.9.0",
"framer-motion": "12.23.18",
"framer-motion": "12.23.16",
"react": "19.1.1",
"react-dom": "19.1.1",
"react-error-boundary": "6.0.0",
"react-i18next": "15.7.3",
"react-use": "17.6.0",
"tailwindcss": "4.1.13",
"vite": "7.1.6",
"vite": "7.1.7",
"vite-tsconfig-paths": "5.1.4"
},
"devDependencies": {
@@ -38,7 +38,7 @@
"@types/d3-interpolate-path": "2.0.3",
"clsx": "2.1.1",
"d3-interpolate-path": "2.3.0",
"sass-embedded": "1.93.0",
"sass-embedded": "1.93.1",
"tailwind-merge": "3.3.1",
"typescript-plugin-css-modules": "5.2.0",
"vite-plugin-dts": "4.5.4"
+2 -2
View File
@@ -2,7 +2,7 @@
"manifest_version": 1,
"latest": {
"mihomo": "v1.19.13",
"mihomo_alpha": "alpha-74a86f1",
"mihomo_alpha": "alpha-8a9300d",
"clash_rs": "v0.9.0",
"clash_premium": "2023-09-05-gdcc8d87",
"clash_rs_alpha": "0.9.0-alpha+sha.50f295d"
@@ -69,5 +69,5 @@
"linux-armv7hf": "clash-armv7-unknown-linux-gnueabihf"
}
},
"updated_at": "2025-09-21T22:20:53.338Z"
"updated_at": "2025-09-22T22:20:56.709Z"
}
+1 -1
View File
@@ -110,7 +110,7 @@
"typescript": "5.9.2",
"typescript-eslint": "8.44.0"
},
"packageManager": "pnpm@10.17.0",
"packageManager": "pnpm@10.17.1",
"engines": {
"node": "22.19.0"
},
+144 -144
View File
@@ -276,8 +276,8 @@ importers:
specifier: 1.11.18
version: 1.11.18
framer-motion:
specifier: 12.23.18
version: 12.23.18(@emotion/is-prop-valid@1.3.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
specifier: 12.23.16
version: 12.23.16(@emotion/is-prop-valid@1.3.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
i18next:
specifier: 25.5.2
version: 25.5.2(typescript@5.9.2)
@@ -330,8 +330,8 @@ importers:
specifier: 2.3.6
version: 2.3.6(react@19.1.1)
virtua:
specifier: 0.43.2
version: 0.43.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(solid-js@1.9.5)
specifier: 0.43.3
version: 0.43.3(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(solid-js@1.9.5)
vite-bundle-visualizer:
specifier: 1.2.1
version: 1.2.1(rollup@4.46.2)
@@ -346,8 +346,8 @@ importers:
specifier: 11.14.0
version: 11.14.0(@types/react@19.1.12)(react@19.1.1)
'@iconify/json':
specifier: 2.2.386
version: 2.2.386
specifier: 2.2.387
version: 2.2.387
'@monaco-editor/react':
specifier: 4.7.0
version: 4.7.0(monaco-editor@0.52.2)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
@@ -362,7 +362,7 @@ importers:
version: 1.131.50(@tanstack/react-router@1.131.50(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(@tanstack/router-core@1.131.50)(csstype@3.1.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(solid-js@1.9.5)(tiny-invariant@1.3.3)
'@tanstack/router-plugin':
specifier: 1.131.50
version: 1.131.50(@tanstack/react-router@1.131.50(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(vite@7.1.6(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.0)(sass@1.93.0)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1))
version: 1.131.50(@tanstack/react-router@1.131.50(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(vite@7.1.7(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.1)(sass@1.93.1)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1))
'@tauri-apps/plugin-clipboard-manager':
specifier: 2.3.0
version: 2.3.0
@@ -398,13 +398,13 @@ importers:
version: 13.15.3
'@vitejs/plugin-legacy':
specifier: 7.2.1
version: 7.2.1(terser@5.36.0)(vite@7.1.6(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.0)(sass@1.93.0)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1))
version: 7.2.1(terser@5.36.0)(vite@7.1.7(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.1)(sass@1.93.1)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1))
'@vitejs/plugin-react':
specifier: 5.0.3
version: 5.0.3(vite@7.1.6(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.0)(sass@1.93.0)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1))
version: 5.0.3(vite@7.1.7(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.1)(sass@1.93.1)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1))
'@vitejs/plugin-react-swc':
specifier: 4.1.0
version: 4.1.0(vite@7.1.6(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.0)(sass@1.93.0)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1))
version: 4.1.0(vite@7.1.7(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.1)(sass@1.93.1)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1))
change-case:
specifier: 5.4.4
version: 5.4.4
@@ -427,8 +427,8 @@ importers:
specifier: 5.1.6
version: 5.1.6
sass-embedded:
specifier: 1.93.0
version: 1.93.0
specifier: 1.93.1
version: 1.93.1
shiki:
specifier: 2.5.0
version: 2.5.0
@@ -442,20 +442,20 @@ importers:
specifier: 13.15.15
version: 13.15.15
vite:
specifier: 7.1.6
version: 7.1.6(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.0)(sass@1.93.0)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1)
specifier: 7.1.7
version: 7.1.7(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.1)(sass@1.93.1)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1)
vite-plugin-html:
specifier: 3.2.2
version: 3.2.2(vite@7.1.6(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.0)(sass@1.93.0)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1))
version: 3.2.2(vite@7.1.7(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.1)(sass@1.93.1)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1))
vite-plugin-sass-dts:
specifier: 1.3.31
version: 1.3.31(postcss@8.5.6)(prettier@3.6.2)(sass-embedded@1.93.0)(vite@7.1.6(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.0)(sass@1.93.0)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1))
version: 1.3.31(postcss@8.5.6)(prettier@3.6.2)(sass-embedded@1.93.1)(vite@7.1.7(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.1)(sass@1.93.1)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1))
vite-plugin-svgr:
specifier: 4.5.0
version: 4.5.0(rollup@4.46.2)(typescript@5.9.2)(vite@7.1.6(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.0)(sass@1.93.0)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1))
version: 4.5.0(rollup@4.46.2)(typescript@5.9.2)(vite@7.1.7(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.1)(sass@1.93.1)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1))
vite-tsconfig-paths:
specifier: 5.1.4
version: 5.1.4(typescript@5.9.2)(vite@7.1.6(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.0)(sass@1.93.0)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1))
version: 5.1.4(typescript@5.9.2)(vite@7.1.7(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.1)(sass@1.93.1)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1))
zod:
specifier: 4.1.11
version: 4.1.11
@@ -491,7 +491,7 @@ importers:
version: 19.1.12
'@vitejs/plugin-react':
specifier: 5.0.3
version: 5.0.3(vite@7.1.6(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.0)(sass@1.93.0)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1))
version: 5.0.3(vite@7.1.7(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.1)(sass@1.93.1)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1))
ahooks:
specifier: 3.9.5
version: 3.9.5(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
@@ -499,8 +499,8 @@ importers:
specifier: 7.9.0
version: 7.9.0
framer-motion:
specifier: 12.23.18
version: 12.23.18(@emotion/is-prop-valid@1.3.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
specifier: 12.23.16
version: 12.23.16(@emotion/is-prop-valid@1.3.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
react:
specifier: 19.1.1
version: 19.1.1
@@ -520,11 +520,11 @@ importers:
specifier: 4.1.13
version: 4.1.13
vite:
specifier: 7.1.6
version: 7.1.6(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.0)(sass@1.93.0)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1)
specifier: 7.1.7
version: 7.1.7(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.1)(sass@1.93.1)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1)
vite-tsconfig-paths:
specifier: 5.1.4
version: 5.1.4(typescript@5.9.2)(vite@7.1.6(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.0)(sass@1.93.0)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1))
version: 5.1.4(typescript@5.9.2)(vite@7.1.7(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.1)(sass@1.93.1)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1))
devDependencies:
'@emotion/react':
specifier: 11.14.0
@@ -539,8 +539,8 @@ importers:
specifier: 2.3.0
version: 2.3.0
sass-embedded:
specifier: 1.93.0
version: 1.93.0
specifier: 1.93.1
version: 1.93.1
tailwind-merge:
specifier: 3.3.1
version: 3.3.1
@@ -549,7 +549,7 @@ importers:
version: 5.2.0(typescript@5.9.2)
vite-plugin-dts:
specifier: 4.5.4
version: 4.5.4(@types/node@24.3.1)(rollup@4.46.2)(typescript@5.9.2)(vite@7.1.6(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.0)(sass@1.93.0)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1))
version: 4.5.4(@types/node@24.3.1)(rollup@4.46.2)(typescript@5.9.2)(vite@7.1.7(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.1)(sass@1.93.1)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1))
scripts:
dependencies:
@@ -1821,8 +1821,8 @@ packages:
prettier-plugin-ember-template-tag:
optional: true
'@iconify/json@2.2.386':
resolution: {integrity: sha512-qvSvaRBu4B1PXKLoXc2yme+eRy3NDTQh/CO3k1vmXjwDKFTFUEVmn8nTD4elPMJZEQa3OOVjh4NfYopnxiAabA==}
'@iconify/json@2.2.387':
resolution: {integrity: sha512-R1PTcM799jGSqHNfzggGqEQA+bQry/X/ckoISJIMKZdC9cz4pYWrWZsRGU50DmYkqTcC9aBQcSLOZxBFHTVT3Q==}
'@iconify/types@2.0.0':
resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==}
@@ -5255,8 +5255,8 @@ packages:
fraction.js@4.3.7:
resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==}
framer-motion@12.23.18:
resolution: {integrity: sha512-HBVXBL5x3nk/0WrYM5G4VgjBey99ytVYET5AX17s/pcnlH90cyaxVUqgoN8cpF4+PqZRVOhwWsv28F+hxA9Tzg==}
framer-motion@12.23.16:
resolution: {integrity: sha512-N81A8hiHqVsexOzI3wzkibyLURW1nEJsZaRuctPhG4AdbbciYu+bKJq9I2lQFzAO4Bx3h4swI6pBbF/Hu7f7BA==}
peerDependencies:
'@emotion/is-prop-valid': '*'
react: ^18.0.0 || ^19.0.0
@@ -6517,8 +6517,8 @@ packages:
peerDependencies:
monaco-editor: '>=0.36'
motion-dom@12.23.18:
resolution: {integrity: sha512-9piw3uOcP6DpS0qpnDF95bLDzmgMxLOg/jghLnHwYJ0YFizzuvbH/L8106dy39JNgHYmXFUTztoP9JQvUqlBwQ==}
motion-dom@12.23.12:
resolution: {integrity: sha512-RcR4fvMCTESQBD/uKQe49D5RUeDOokkGRmz4ceaJKDBgHYtZtntC/s2vLvY38gqGaytinij/yi3hMcWVcEF5Kw==}
motion-utils@12.23.6:
resolution: {integrity: sha512-eAWoPgr4eFEOFfg2WjIsMoqJTW6Z8MTUCgn/GZ3VRpClWBdnbjryiA3ZSNLyxCTmCQx4RmYX6jX1iWHbenUPNQ==}
@@ -7423,112 +7423,112 @@ packages:
safer-buffer@2.1.2:
resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
sass-embedded-all-unknown@1.93.0:
resolution: {integrity: sha512-fBTnh5qgOyw0CGVaF2iPsIIRj40D9Mnf19WerixjmWwmYKaGhxd62STsuMt6t1dWS5lkUZWRgrJ+2biQiEcCBg==}
sass-embedded-all-unknown@1.93.1:
resolution: {integrity: sha512-APlGAJhk/Twv1i8K/jHfkruMwTVV03M5+RZ2yxalYWhn0pouC+MIQ8I/xkiOPk2sNmCQ4M3EewMb0FUVyS/LMQ==}
cpu: ['!arm', '!arm64', '!riscv64', '!x64']
sass-embedded-android-arm64@1.93.0:
resolution: {integrity: sha512-bwU+0uWUVoATaYAb9mnDj7GCEnNAIrinzT4UlA6GlicH+ELEZlNwVjaPJfdCyyYs8iOKuzUPfZrFZuwRCsXXqw==}
sass-embedded-android-arm64@1.93.1:
resolution: {integrity: sha512-kWvCvNXnHjPmjSS4uYGcSRLZo9am8cNDdg+jIY4mZy62Q3nmz0h0p9if1GszBHl4H3eIBXJIEJQiDY5E26amdQ==}
engines: {node: '>=14.0.0'}
cpu: [arm64]
os: [android]
sass-embedded-android-arm@1.93.0:
resolution: {integrity: sha512-oMm6RafXdpWDejufUs+GcgBSS/wa/iG1zRhwsCrkIkMLhqa34oN7xLkNs9Ieg337nlIryUBijwAVMFlAs/mgIg==}
sass-embedded-android-arm@1.93.1:
resolution: {integrity: sha512-ysejojGThRhsnyYRQtNyAstQqqOP+W+EsEbxnhKVZRLBp4WxeAza/W5x1/GBzLjhk6HUJ7N1MwNkkpvF0eqnuQ==}
engines: {node: '>=14.0.0'}
cpu: [arm]
os: [android]
sass-embedded-android-riscv64@1.93.0:
resolution: {integrity: sha512-lKk7elql2abYeLY+wNBW8DB13W8An9JWlAr/BWOAtluz1RMsPVZwv0amQiP2PcR6HA02QDoLfRE/QpnPDHzCuw==}
sass-embedded-android-riscv64@1.93.1:
resolution: {integrity: sha512-EaNkWJ5IOMCZid3IZWl/Bvb3RkCFz0RBas6Ns05F7W3hls+ggaqiFB7RaVr4Wbr7Em8Ak6yYw5CuTgUiY58nDg==}
engines: {node: '>=14.0.0'}
cpu: [riscv64]
os: [android]
sass-embedded-android-x64@1.93.0:
resolution: {integrity: sha512-wuyphs1VMS/PRXtCBLhA0bVo5nyKFCXKaVKMbqPylOTvoTHe7u0zxjWRN4eF5LTPVuQp0A+LYgJz07duzxwJew==}
sass-embedded-android-x64@1.93.1:
resolution: {integrity: sha512-kyGNIgFTAgWPa79LI+vkbOUNV1DzCywSAayAHsvuK6NgPcq560ET7qekp/OlbZ97wgTjVRlj68UAP0jVhq4k4A==}
engines: {node: '>=14.0.0'}
cpu: [x64]
os: [android]
sass-embedded-darwin-arm64@1.93.0:
resolution: {integrity: sha512-lEb5J/jabesh16xdocRFgpzIa8GAZCLrdKtUnGbn9a4Y4WkEKHtUkvAm9ZtqE8YiuIm8PwHW/zBUKtZYoGYoYA==}
sass-embedded-darwin-arm64@1.93.1:
resolution: {integrity: sha512-GOD2Nt+BZZdBmg+BM2CozkhAZFGzaU8IK1lI2KP5C6HTuhQP7mTPA9UZWNN3c7iHj6JrkenfWd1ec/vsCZVr+Q==}
engines: {node: '>=14.0.0'}
cpu: [arm64]
os: [darwin]
sass-embedded-darwin-x64@1.93.0:
resolution: {integrity: sha512-mo9OfKyNF6MiFf711c+QGR7aPpFqAC9FttiLKPYH3RRBZQZU/UcG4mbg+yXfKbhZrJmYngbGiTzE9B+xiOz27Q==}
sass-embedded-darwin-x64@1.93.1:
resolution: {integrity: sha512-79UlR88nNDbsGqa/87yxOdShPL9Bqz0KnFzv8ioh1NkxYwKYUM9XuKwohFEBTyGg8KDw6h31oTFAvrEFR2qBzg==}
engines: {node: '>=14.0.0'}
cpu: [x64]
os: [darwin]
sass-embedded-linux-arm64@1.93.0:
resolution: {integrity: sha512-bJclpjTeP/qCu7zYLZQXROx4xIT3x+qfj/q92fripV9L9Oj2khfUm+2nW0Cq7DS6UrHphrWZ9QSnVYFhkCKtEA==}
sass-embedded-linux-arm64@1.93.1:
resolution: {integrity: sha512-F5ZHx1s5ce3NdjtwPAq6oTXpTC1bZUlHweFgqzbYH5rhVhdhkOemIdHHUG+3gl8YttYrqZ0KASVDtJKBrJMnSg==}
engines: {node: '>=14.0.0'}
cpu: [arm64]
os: [linux]
sass-embedded-linux-arm@1.93.0:
resolution: {integrity: sha512-wtO2vB8rMc5zF29xwC3AMgmBgNgm3i3/8zog5vQBD4yddqCJ93JcWDjdUqYmq0H/DLD/Z7q91j6X/YgPq1WuEg==}
sass-embedded-linux-arm@1.93.1:
resolution: {integrity: sha512-CdJXeZazBU1Ry1jG0T0ohZkoKHnUBIdniqw3o8ZzqHPzVY3A4svuQWj0WvGGM+YrZ+SV5HQ3nmzezS58dlandA==}
engines: {node: '>=14.0.0'}
cpu: [arm]
os: [linux]
sass-embedded-linux-musl-arm64@1.93.0:
resolution: {integrity: sha512-VH0zFGqsTy+lThHAm3y8Dpd/X4nC5DLJvk66+mJTg7rwblRhfPpsVO6n8QHeN5ZV1ATTnLh/PbZ7uEPiyAg2wg==}
sass-embedded-linux-musl-arm64@1.93.1:
resolution: {integrity: sha512-p7fxdQI+ev6KMkqRNgl1i7yG5PaUiPgudF4usfSE5NaQobORZYuFXt4m2XPd1h5xwP0ykYLyXjad1EMXTnGr7Q==}
engines: {node: '>=14.0.0'}
cpu: [arm64]
os: [linux]
sass-embedded-linux-musl-arm@1.93.0:
resolution: {integrity: sha512-mMGAy+2VLLTMDPDG/mfzMmoy09potXp/ZRPRsyJEYVjF0rQij6Iss3qsZbCjVJa4atLwBtPJ14M0NvqpAa2WIg==}
sass-embedded-linux-musl-arm@1.93.1:
resolution: {integrity: sha512-gMxRky1OjjVh8HHw/blgMggkmIu5a9l8iLAODuBIi+AOOuF9v7v20JXyUfXh2jT2HvdXjKfc/EvIuhhELnBPpg==}
engines: {node: '>=14.0.0'}
cpu: [arm]
os: [linux]
sass-embedded-linux-musl-riscv64@1.93.0:
resolution: {integrity: sha512-/a+MvExFEKvwPXyZsQ8b1DWYJMpTnXSdwpe9pDNkdTIcliMAtP952krCx14nBP0UqqNoU/TetyMR8H0WwyeJEA==}
sass-embedded-linux-musl-riscv64@1.93.1:
resolution: {integrity: sha512-iVtkoiwXxVcIjbOD3ctX1CxgkXMPUzkw3A/1Iok55lmLLDRKB6t4nny8vT8qiejKrQ9DF4Oz2/+q7Cj0S3mN+Q==}
engines: {node: '>=14.0.0'}
cpu: [riscv64]
os: [linux]
sass-embedded-linux-musl-x64@1.93.0:
resolution: {integrity: sha512-o168nV9QI5U+2LFBMmMecWzu6yJ7WJZZfQGlo4Frvg9vC3Em3W02GfAel+g9leJg+0PDnpJLqOsPdrngg25T/Q==}
sass-embedded-linux-musl-x64@1.93.1:
resolution: {integrity: sha512-UPtkoxgljB+Tz5TF8Pg/5EaMDlDRhqlqnA3cCOqj+bDoaAgTQcqYNpAz/6wJSXYTv7Jjs54kWjI+NDMSOPdh/Q==}
engines: {node: '>=14.0.0'}
cpu: [x64]
os: [linux]
sass-embedded-linux-riscv64@1.93.0:
resolution: {integrity: sha512-KYHED49coJQT633cBbqBfBOPmRe3yNbE+D2kqMONADBqzGyxHZpQRStCenhPmDabVLI4fgc3fn//6ubqH724jA==}
sass-embedded-linux-riscv64@1.93.1:
resolution: {integrity: sha512-gTzxKGPK1vwqO8ZOYlQIVh1BFI2dBW1GyMHmyjqM4Mc/orAjOmTN3aJYGafJjxiMmH424JwlUmCN5vARRJQsJg==}
engines: {node: '>=14.0.0'}
cpu: [riscv64]
os: [linux]
sass-embedded-linux-x64@1.93.0:
resolution: {integrity: sha512-9OD9OlZ61dmz/BbW4n29l3v74//ibiQCmWu8YBoXVgxxgcbi+2CFv+vRE8guA73BgEdPComw0tpgD1FkW3v12g==}
sass-embedded-linux-x64@1.93.1:
resolution: {integrity: sha512-x67rR5KmmjZrnqzKSqNFEEyQoybajFmWnsWvxt3Fn2BCewK40EThVjJAJwNdZtXKcc8y7CZrMF+kmxBDxFbv4g==}
engines: {node: '>=14.0.0'}
cpu: [x64]
os: [linux]
sass-embedded-unknown-all@1.93.0:
resolution: {integrity: sha512-Hh9OPBMg+i1g8OzQyOtQuJg/3ncup4Z+FHdXNzPIeFXcIeS+TVuVQyvJfnB+hYgvVGyBJ+9ekuUYzB+1zA82nw==}
sass-embedded-unknown-all@1.93.1:
resolution: {integrity: sha512-noDOdIJWRTXAW77J2bkrKGyoPWNuJ5G+JnXVHH+zLll1AlVcwPjVCKag9dNk6+o4cXDb0hx8b8Sg4ojdCzK8VA==}
os: ['!android', '!darwin', '!linux', '!win32']
sass-embedded-win32-arm64@1.93.0:
resolution: {integrity: sha512-3SNRTxBVk+c0Oyd4gCp4/KAQ+S6B9S5ihq5dxMMfWpvoQSUqn6mqhkEFrofG1oNlP7KsA2UzhTnFGDRid1An+A==}
sass-embedded-win32-arm64@1.93.1:
resolution: {integrity: sha512-B6seb+gjZ9XV/rXO2STkBkFLpsRnlLS1Hs9tqJyWe723VhuaOy/cyI8LSuUjNDolYVbo4YKb4vbx3+BNFNRGBQ==}
engines: {node: '>=14.0.0'}
cpu: [arm64]
os: [win32]
sass-embedded-win32-x64@1.93.0:
resolution: {integrity: sha512-6/RJGOdm3bwe71YJaYanQ81I6KA//T/a+MnKlRpP5zk5fy2ygAIGNeNr2ENEBu/KZCuFg7KY49g46v+hPKT6Ow==}
sass-embedded-win32-x64@1.93.1:
resolution: {integrity: sha512-tt4OxnQN2b1PbTWHeZHVFxnQTTSbzOZlSIVeZZ8T9hQmSWrAfzjuV0B96V1/YzhKfhSKtbCo7KD/JIgADKugqg==}
engines: {node: '>=14.0.0'}
cpu: [x64]
os: [win32]
sass-embedded@1.93.0:
resolution: {integrity: sha512-dQACVfrbwKtvnrA0xH67YAdUYi6k7XcPg8uNF3DPf/VaJMQzduE1z5w3NFa9oVjtqXM4+FA9P7Qdv06Bzf614g==}
sass-embedded@1.93.1:
resolution: {integrity: sha512-LgXSubbCngOUZ7sVhxtfREa/lHa+hkG0Pjul02I4gB4cb0PhsR+UTLH0GIMnEafoL4dhFM1x8tdtezB3Njv7ng==}
engines: {node: '>=16.0.0'}
hasBin: true
@@ -7537,8 +7537,8 @@ packages:
engines: {node: '>=14.0.0'}
hasBin: true
sass@1.93.0:
resolution: {integrity: sha512-CQi5/AzCwiubU3dSqRDJ93RfOfg/hhpW1l6wCIvolmehfwgCI35R/0QDs1+R+Ygrl8jFawwwIojE2w47/mf94A==}
sass@1.93.1:
resolution: {integrity: sha512-wLAeLB7IksO2u+cCfhHqcy7/2ZUMPp/X2oV6+LjmweTqgjhOKrkaE/Q1wljxtco5EcOcupZ4c981X0gpk5Tiag==}
engines: {node: '>=14.0.0'}
hasBin: true
@@ -8356,8 +8356,8 @@ packages:
vfile@6.0.1:
resolution: {integrity: sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==}
virtua@0.43.2:
resolution: {integrity: sha512-4Tv2qThKZ767PCkFbS5fz8Cy9JmqRV9hq24nGabFl+ddvw+iVdIx11tuWxKvWRhvOZOK5TUosNRUDjIkS6f3FA==}
virtua@0.43.3:
resolution: {integrity: sha512-KA4iLdc1ISLgeqWEdT++Y8zeRQxWMOsF0pMG8gXPGorfCC7xdVZS9R4/kRCkyrk9z52VoQBBOEAL48vrPnKSuw==}
peerDependencies:
react: '>=16.14.0'
react-dom: '>=16.14.0'
@@ -8417,8 +8417,8 @@ packages:
vite:
optional: true
vite@7.1.6:
resolution: {integrity: sha512-SRYIB8t/isTwNn8vMB3MR6E+EQZM/WG1aKmmIUCfDXfVvKfc20ZpamngWHKzAmmu9ppsgxsg4b2I7c90JZudIQ==}
vite@7.1.7:
resolution: {integrity: sha512-VbA8ScMvAISJNJVbRDTJdCwqQoAareR/wutevKanhR2/1EkoXVZVkkORaYm/tNVCjP/UDTKtcw3bAkwOUdedmA==}
engines: {node: ^20.19.0 || >=22.12.0}
hasBin: true
peerDependencies:
@@ -10190,7 +10190,7 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@iconify/json@2.2.386':
'@iconify/json@2.2.387':
dependencies:
'@iconify/types': 2.0.0
pathe: 1.1.2
@@ -11372,7 +11372,7 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@tanstack/router-plugin@1.131.50(@tanstack/react-router@1.131.50(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(vite@7.1.6(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.0)(sass@1.93.0)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1))':
'@tanstack/router-plugin@1.131.50(@tanstack/react-router@1.131.50(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(vite@7.1.7(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.1)(sass@1.93.1)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1))':
dependencies:
'@babel/core': 7.28.4
'@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.4)
@@ -11390,7 +11390,7 @@ snapshots:
zod: 3.25.76
optionalDependencies:
'@tanstack/react-router': 1.131.50(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
vite: 7.1.6(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.0)(sass@1.93.0)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1)
vite: 7.1.7(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.1)(sass@1.93.1)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1)
transitivePeerDependencies:
- supports-color
@@ -12005,7 +12005,7 @@ snapshots:
'@unrs/resolver-binding-win32-x64-msvc@1.10.1':
optional: true
'@vitejs/plugin-legacy@7.2.1(terser@5.36.0)(vite@7.1.6(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.0)(sass@1.93.0)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1))':
'@vitejs/plugin-legacy@7.2.1(terser@5.36.0)(vite@7.1.7(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.1)(sass@1.93.1)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1))':
dependencies:
'@babel/core': 7.28.0
'@babel/plugin-transform-dynamic-import': 7.27.1(@babel/core@7.28.0)
@@ -12020,19 +12020,19 @@ snapshots:
regenerator-runtime: 0.14.1
systemjs: 6.15.1
terser: 5.36.0
vite: 7.1.6(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.0)(sass@1.93.0)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1)
vite: 7.1.7(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.1)(sass@1.93.1)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1)
transitivePeerDependencies:
- supports-color
'@vitejs/plugin-react-swc@4.1.0(vite@7.1.6(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.0)(sass@1.93.0)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1))':
'@vitejs/plugin-react-swc@4.1.0(vite@7.1.7(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.1)(sass@1.93.1)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1))':
dependencies:
'@rolldown/pluginutils': 1.0.0-beta.35
'@swc/core': 1.13.5
vite: 7.1.6(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.0)(sass@1.93.0)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1)
vite: 7.1.7(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.1)(sass@1.93.1)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1)
transitivePeerDependencies:
- '@swc/helpers'
'@vitejs/plugin-react@5.0.3(vite@7.1.6(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.0)(sass@1.93.0)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1))':
'@vitejs/plugin-react@5.0.3(vite@7.1.7(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.1)(sass@1.93.1)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1))':
dependencies:
'@babel/core': 7.28.4
'@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.28.4)
@@ -12040,7 +12040,7 @@ snapshots:
'@rolldown/pluginutils': 1.0.0-beta.35
'@types/babel__core': 7.20.5
react-refresh: 0.17.0
vite: 7.1.6(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.0)(sass@1.93.0)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1)
vite: 7.1.7(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.1)(sass@1.93.1)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1)
transitivePeerDependencies:
- supports-color
@@ -13935,9 +13935,9 @@ snapshots:
fraction.js@4.3.7: {}
framer-motion@12.23.18(@emotion/is-prop-valid@1.3.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1):
framer-motion@12.23.16(@emotion/is-prop-valid@1.3.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1):
dependencies:
motion-dom: 12.23.18
motion-dom: 12.23.12
motion-utils: 12.23.6
tslib: 2.8.1
optionalDependencies:
@@ -15323,7 +15323,7 @@ snapshots:
vscode-uri: 3.0.8
yaml: 2.7.0
motion-dom@12.23.18:
motion-dom@12.23.12:
dependencies:
motion-utils: 12.23.6
@@ -16299,65 +16299,65 @@ snapshots:
safer-buffer@2.1.2: {}
sass-embedded-all-unknown@1.93.0:
sass-embedded-all-unknown@1.93.1:
dependencies:
sass: 1.93.0
sass: 1.93.1
optional: true
sass-embedded-android-arm64@1.93.0:
sass-embedded-android-arm64@1.93.1:
optional: true
sass-embedded-android-arm@1.93.0:
sass-embedded-android-arm@1.93.1:
optional: true
sass-embedded-android-riscv64@1.93.0:
sass-embedded-android-riscv64@1.93.1:
optional: true
sass-embedded-android-x64@1.93.0:
sass-embedded-android-x64@1.93.1:
optional: true
sass-embedded-darwin-arm64@1.93.0:
sass-embedded-darwin-arm64@1.93.1:
optional: true
sass-embedded-darwin-x64@1.93.0:
sass-embedded-darwin-x64@1.93.1:
optional: true
sass-embedded-linux-arm64@1.93.0:
sass-embedded-linux-arm64@1.93.1:
optional: true
sass-embedded-linux-arm@1.93.0:
sass-embedded-linux-arm@1.93.1:
optional: true
sass-embedded-linux-musl-arm64@1.93.0:
sass-embedded-linux-musl-arm64@1.93.1:
optional: true
sass-embedded-linux-musl-arm@1.93.0:
sass-embedded-linux-musl-arm@1.93.1:
optional: true
sass-embedded-linux-musl-riscv64@1.93.0:
sass-embedded-linux-musl-riscv64@1.93.1:
optional: true
sass-embedded-linux-musl-x64@1.93.0:
sass-embedded-linux-musl-x64@1.93.1:
optional: true
sass-embedded-linux-riscv64@1.93.0:
sass-embedded-linux-riscv64@1.93.1:
optional: true
sass-embedded-linux-x64@1.93.0:
sass-embedded-linux-x64@1.93.1:
optional: true
sass-embedded-unknown-all@1.93.0:
sass-embedded-unknown-all@1.93.1:
dependencies:
sass: 1.93.0
sass: 1.93.1
optional: true
sass-embedded-win32-arm64@1.93.0:
sass-embedded-win32-arm64@1.93.1:
optional: true
sass-embedded-win32-x64@1.93.0:
sass-embedded-win32-x64@1.93.1:
optional: true
sass-embedded@1.93.0:
sass-embedded@1.93.1:
dependencies:
'@bufbuild/protobuf': 2.5.2
buffer-builder: 0.2.0
@@ -16368,24 +16368,24 @@ snapshots:
sync-child-process: 1.0.2
varint: 6.0.0
optionalDependencies:
sass-embedded-all-unknown: 1.93.0
sass-embedded-android-arm: 1.93.0
sass-embedded-android-arm64: 1.93.0
sass-embedded-android-riscv64: 1.93.0
sass-embedded-android-x64: 1.93.0
sass-embedded-darwin-arm64: 1.93.0
sass-embedded-darwin-x64: 1.93.0
sass-embedded-linux-arm: 1.93.0
sass-embedded-linux-arm64: 1.93.0
sass-embedded-linux-musl-arm: 1.93.0
sass-embedded-linux-musl-arm64: 1.93.0
sass-embedded-linux-musl-riscv64: 1.93.0
sass-embedded-linux-musl-x64: 1.93.0
sass-embedded-linux-riscv64: 1.93.0
sass-embedded-linux-x64: 1.93.0
sass-embedded-unknown-all: 1.93.0
sass-embedded-win32-arm64: 1.93.0
sass-embedded-win32-x64: 1.93.0
sass-embedded-all-unknown: 1.93.1
sass-embedded-android-arm: 1.93.1
sass-embedded-android-arm64: 1.93.1
sass-embedded-android-riscv64: 1.93.1
sass-embedded-android-x64: 1.93.1
sass-embedded-darwin-arm64: 1.93.1
sass-embedded-darwin-x64: 1.93.1
sass-embedded-linux-arm: 1.93.1
sass-embedded-linux-arm64: 1.93.1
sass-embedded-linux-musl-arm: 1.93.1
sass-embedded-linux-musl-arm64: 1.93.1
sass-embedded-linux-musl-riscv64: 1.93.1
sass-embedded-linux-musl-x64: 1.93.1
sass-embedded-linux-riscv64: 1.93.1
sass-embedded-linux-x64: 1.93.1
sass-embedded-unknown-all: 1.93.1
sass-embedded-win32-arm64: 1.93.1
sass-embedded-win32-x64: 1.93.1
sass@1.83.0:
dependencies:
@@ -16395,7 +16395,7 @@ snapshots:
optionalDependencies:
'@parcel/watcher': 2.4.1
sass@1.93.0:
sass@1.93.1:
dependencies:
chokidar: 4.0.0
immutable: 5.0.2
@@ -17368,7 +17368,7 @@ snapshots:
unist-util-stringify-position: 4.0.0
vfile-message: 4.0.2
virtua@0.43.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(solid-js@1.9.5):
virtua@0.43.3(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(solid-js@1.9.5):
optionalDependencies:
react: 19.1.1
react-dom: 19.1.1(react@19.1.1)
@@ -17384,7 +17384,7 @@ snapshots:
- rollup
- supports-color
vite-plugin-dts@4.5.4(@types/node@24.3.1)(rollup@4.46.2)(typescript@5.9.2)(vite@7.1.6(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.0)(sass@1.93.0)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1)):
vite-plugin-dts@4.5.4(@types/node@24.3.1)(rollup@4.46.2)(typescript@5.9.2)(vite@7.1.7(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.1)(sass@1.93.1)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1)):
dependencies:
'@microsoft/api-extractor': 7.51.0(@types/node@24.3.1)
'@rollup/pluginutils': 5.1.4(rollup@4.46.2)
@@ -17397,13 +17397,13 @@ snapshots:
magic-string: 0.30.17
typescript: 5.9.2
optionalDependencies:
vite: 7.1.6(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.0)(sass@1.93.0)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1)
vite: 7.1.7(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.1)(sass@1.93.1)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1)
transitivePeerDependencies:
- '@types/node'
- rollup
- supports-color
vite-plugin-html@3.2.2(vite@7.1.6(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.0)(sass@1.93.0)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1)):
vite-plugin-html@3.2.2(vite@7.1.7(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.1)(sass@1.93.1)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1)):
dependencies:
'@rollup/pluginutils': 4.2.1
colorette: 2.0.20
@@ -17417,39 +17417,39 @@ snapshots:
html-minifier-terser: 6.1.0
node-html-parser: 5.4.2
pathe: 0.2.0
vite: 7.1.6(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.0)(sass@1.93.0)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1)
vite: 7.1.7(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.1)(sass@1.93.1)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1)
vite-plugin-sass-dts@1.3.31(postcss@8.5.6)(prettier@3.6.2)(sass-embedded@1.93.0)(vite@7.1.6(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.0)(sass@1.93.0)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1)):
vite-plugin-sass-dts@1.3.31(postcss@8.5.6)(prettier@3.6.2)(sass-embedded@1.93.1)(vite@7.1.7(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.1)(sass@1.93.1)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1)):
dependencies:
postcss: 8.5.6
postcss-js: 4.0.1(postcss@8.5.6)
prettier: 3.6.2
sass-embedded: 1.93.0
vite: 7.1.6(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.0)(sass@1.93.0)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1)
sass-embedded: 1.93.1
vite: 7.1.7(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.1)(sass@1.93.1)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1)
vite-plugin-svgr@4.5.0(rollup@4.46.2)(typescript@5.9.2)(vite@7.1.6(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.0)(sass@1.93.0)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1)):
vite-plugin-svgr@4.5.0(rollup@4.46.2)(typescript@5.9.2)(vite@7.1.7(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.1)(sass@1.93.1)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1)):
dependencies:
'@rollup/pluginutils': 5.2.0(rollup@4.46.2)
'@svgr/core': 8.1.0(typescript@5.9.2)
'@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0(typescript@5.9.2))
vite: 7.1.6(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.0)(sass@1.93.0)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1)
vite: 7.1.7(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.1)(sass@1.93.1)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1)
transitivePeerDependencies:
- rollup
- supports-color
- typescript
vite-tsconfig-paths@5.1.4(typescript@5.9.2)(vite@7.1.6(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.0)(sass@1.93.0)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1)):
vite-tsconfig-paths@5.1.4(typescript@5.9.2)(vite@7.1.7(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.1)(sass@1.93.1)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1)):
dependencies:
debug: 4.3.7
globrex: 0.1.2
tsconfck: 3.0.3(typescript@5.9.2)
optionalDependencies:
vite: 7.1.6(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.0)(sass@1.93.0)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1)
vite: 7.1.7(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.1)(sass@1.93.1)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1)
transitivePeerDependencies:
- supports-color
- typescript
vite@7.1.6(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.0)(sass@1.93.0)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1):
vite@7.1.7(@types/node@24.3.1)(jiti@2.5.1)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.93.1)(sass@1.93.1)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.5)(yaml@2.8.1):
dependencies:
esbuild: 0.25.0
fdir: 6.5.0(picomatch@4.0.3)
@@ -17463,8 +17463,8 @@ snapshots:
jiti: 2.5.1
less: 4.2.0
lightningcss: 1.30.1
sass: 1.93.0
sass-embedded: 1.93.0
sass: 1.93.1
sass-embedded: 1.93.1
stylus: 0.62.0
terser: 5.36.0
tsx: 4.20.5
+34
View File
@@ -0,0 +1,34 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=yt6801
PKG_VERSION:=1.0.30
PKG_RELEASE:=1
PKG_LICENSE:=GPL-2.0-only
PKG_MAINTAINER:=Lean <coolsnowwolf@gmail.com>
include $(INCLUDE_DIR)/kernel.mk
include $(INCLUDE_DIR)/package.mk
define KernelPackage/yt6801
SUBMENU:=Network Devices
TITLE:=Motorcomm YT6801 Gigabit Ethernet driver
DEPENDS:=@PCI_SUPPORT +kmod-libphy
FILES:=$(PKG_BUILD_DIR)/yt6801.ko
AUTOLOAD:=$(call AutoProbe,yt6801)
KCONFIG:=
endef
define KernelPackage/yt6801/description
Kernel module for Motorcomm YT6801 PCI Gigabit Ethernet controllers.
This driver supports the YT6801 chipset from Motorcomm.
endef
define Build/Compile
+$(KERNEL_MAKE) $(PKG_JOBS) \
M="$(PKG_BUILD_DIR)" \
EXTRA_CFLAGS="-DFXGMAC_DEBUG" \
modules
endef
$(eval $(call KernelPackage,yt6801))
+53
View File
@@ -0,0 +1,53 @@
# SPDX-License-Identifier: GPL-2.0-only
################################################################################
#
# Copyright (c) 2023 Motorcomm, Inc.
# Motorcomm Confidential and Proprietary.
#
# This is Motorcomm NIC driver relevant files. Please don't copy, modify,
# distribute without commercial permission.
#
################################################################################
SUBARCH := $(shell uname -m | sed -e s/i.86/x86/ -e s/x86_64/x86/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/ -e s/s390x/s390/ -e s/parisc64/parisc/ -e s/ppc.*/powerpc/ -e s/mips.*/mips/ -e s/sh[234].*/sh/ -e s/aarch64.*/arm64/ -e s/riscv.*/riscv/)
CURARCH ?= $(SUBARCH)
ARCH ?= $(SUBARCH)
CROSS_COMPILE ?=
#CONFIG_MODULE_SIG=n
PWD :=$(shell pwd)
EXTRA_CFLAGS = -Wall -g -I$(CURDIR) -I$(subst fuxi-linux-release-package/module_fuxi/src,common,$(PWD)) -I$(PWD)
EXTRA_CFLAGS += -DFXGMAC_DEBUG
KSRC_BASE = /lib/modules/$(shell uname -r)
KSRC = $(KSRC_BASE)/build
#KDST = /lib/modules/$(shell uname -r)/kernel/drivers/net/ethernet/motorcomm/
KDST = kernel/drivers/net/ethernet/motorcomm
ko_dir = $(KSRC_BASE)/$(KDST)/
KFILE = yt6801
ko_full = $(ko_dir)$(KFILE).ko
yt6801-objs := fuxi-gmac-common.o fuxi-gmac-desc.o fuxi-gmac-ethtool.o fuxi-gmac-hw.o fuxi-gmac-net.o fuxi-gmac-pci.o fuxi-gmac-phy.o fuxi-efuse.o fuxi-gmac-ioctl.o
obj-m += yt6801.o
modules:
make -C $(KSRC) M=$(PWD) modules
install:
@echo "KFILE: " $(KFILE)
@echo "KDST: " $(KDST)
make -C $(KSRC) M=$(PWD) INSTALL_MOD_DIR=$(KDST) modules_install
sudo ls -l $(ko_dir)
depmod $(shell uname -r)
modprobe $(KFILE)
@file $(ko_full)
@echo install done.
@modinfo $(ko_full)
uninstall:
sudo ls -l $(ko_dir)
sudo rm $(ko_full)
sudo ls -l $(ko_dir)
clean:
make -C $(KSRC) M=$(PWD) clean
.PHONY:modules install uninstall clean
+30
View File
@@ -0,0 +1,30 @@
=============================================================================
This file contains certain notices of software components included with
the software that Motorcomm, Inc. ("Motorcomm") is required to
provide you. Except where prohibited by the open source license, the
content of this file is provided solely to satisfy Motorcomm's attribution
and notice requirement; your use of these software components
together with the Motorcomm software ("Software") is subject to the terms
of your license from Motorcomm. Compliance with all copyright laws and
software license agreements included in the notice section of this
file are the responsibility of the user. Except as may be granted by
separate express written agreement, this file provides no license to
any patents, trademarks, copyrights, or other intellectual property
of Motorcomm or any of its subsidiaries.
Software provided with this notice is NOT A CONTRIBUTION to any open
source project. If alternative licensing is available for any of the
components with licenses or attributions provided below, a license
choice is made for receiving such code by Motorcomm.
Copyright (c) 2021 Motorcomm, Inc. All rights reserved.
Motorcomm is a trademark of Motorcomm Incorporated, registered in China
and other countries. All Motorcomm Incorporated trademarks
are used with permission. Other products and brand names may be
trademarks or registered trademarks of their respective owners.
=============================================================================
+8
View File
@@ -0,0 +1,8 @@
PACKAGE_NAME="yt6801"
PACKAGE_VERSION="1.0.30"
CLEAN="make clean"
MAKE[0]="make"
BUILT_MODULE_NAME[0]="yt6801"
DEST_MODULE_LOCATION[0]="/kernel/drivers/net/ethernet/motorcomm"
AUTOINSTALL="yes"
REMAKE_INITRD="yes"
+32
View File
@@ -0,0 +1,32 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/* Copyright (c) 2021 Motor-comm Corporation. All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#ifndef _MP_DBG_H
#define _MP_DBG_H
//
// Message verbosity: lower values indicate higher urgency
//
#define MP_OFF 0
#define MP_ERROR 1
#define MP_WARN 2
#define MP_TRACE 3
#define MP_INFO 4
#define MP_LOUD 5
#endif // _MP_DBG_H
+991
View File
@@ -0,0 +1,991 @@
// SPDX-License-Identifier: GPL-2.0+
/* Copyright (c) 2021 Motor-comm Corporation. All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#include "fuxi-gmac.h"
#include "fuxi-gmac-reg.h"
#include "fuxi-efuse.h"
#ifdef FXGMAC_USE_ADAPTER_HANDLE
#include "fuxi-mp.h"
#endif
bool fxgmac_read_patch_from_efuse_per_index(struct fxgmac_pdata* pdata, u8 index, u32 __far* offset, u32 __far* value) /* read patch per index. */
{
unsigned int wait, i;
u32 regval = 0;
bool succeed = false;
if (index >= FXGMAC_EFUSE_MAX_ENTRY) {
FXGMAC_PR("Reading efuse out of range, index %d\n", index);
return false;
}
if (offset) {
*offset = 0;
}
for (i = EFUSE_PATCH_ADDR_START_BYTE; i < EFUSE_PATCH_DATA_START_BYTE; i++) {
regval = 0;
regval = FXGMAC_SET_REG_BITS(regval, EFUSE_OP_ADDR_POS, EFUSE_OP_ADDR_LEN, EFUSE_REGION_A_B_LENGTH + index * EFUSE_EACH_PATH_SIZE + i);
regval = FXGMAC_SET_REG_BITS(regval, EFUSE_OP_START_POS, EFUSE_OP_START_LEN, 1);
regval = FXGMAC_SET_REG_BITS(regval, EFUSE_OP_MODE_POS, EFUSE_OP_MODE_LEN, EFUSE_OP_MODE_ROW_READ);
writereg(pdata->pAdapter, regval, pdata->base_mem + EFUSE_OP_CTRL_0);
wait = 1000;
while (wait--) {
usleep_range_ex(pdata->pAdapter, 20, 50);
regval = readreg(pdata->pAdapter, pdata->base_mem + EFUSE_OP_CTRL_1);
if (FXGMAC_GET_REG_BITS(regval, EFUSE_OP_DONE_POS, EFUSE_OP_DONE_LEN)) {
succeed = true;
break;
}
}
if (succeed) {
if (offset) {
*offset |= (FXGMAC_GET_REG_BITS(regval, EFUSE_OP_RD_DATA_POS, EFUSE_OP_RD_DATA_LEN) << (i << 3));
}
}
else {
FXGMAC_PR("Fail to reading efuse Byte%d\n", index * EFUSE_EACH_PATH_SIZE + i);
return succeed;
}
}
if (value) {
*value = 0;
}
for (i = EFUSE_PATCH_DATA_START_BYTE; i < EFUSE_EACH_PATH_SIZE; i++) {
regval = 0;
regval = FXGMAC_SET_REG_BITS(regval, EFUSE_OP_ADDR_POS, EFUSE_OP_ADDR_LEN, EFUSE_REGION_A_B_LENGTH + index * EFUSE_EACH_PATH_SIZE + i);
regval = FXGMAC_SET_REG_BITS(regval, EFUSE_OP_START_POS, EFUSE_OP_START_LEN, 1);
regval = FXGMAC_SET_REG_BITS(regval, EFUSE_OP_MODE_POS, EFUSE_OP_MODE_LEN, EFUSE_OP_MODE_ROW_READ);
writereg(pdata->pAdapter, regval, pdata->base_mem + EFUSE_OP_CTRL_0);
wait = 1000;
while (wait--) {
usleep_range_ex(pdata->pAdapter, 20, 50);
regval = readreg(pdata->pAdapter, pdata->base_mem + EFUSE_OP_CTRL_1);
if (FXGMAC_GET_REG_BITS(regval, EFUSE_OP_DONE_POS, EFUSE_OP_DONE_LEN)) {
succeed = true;
break;
}
}
if (succeed) {
if (value) {
*value |= (FXGMAC_GET_REG_BITS(regval, EFUSE_OP_RD_DATA_POS, EFUSE_OP_RD_DATA_LEN) << ((i - 2) << 3));
}
}
else {
FXGMAC_PR("Fail to reading efuse Byte%d\n", index * EFUSE_EACH_PATH_SIZE + i);
return succeed;
}
}
return succeed;
}
bool fxgmac_read_mac_subsys_from_efuse(struct fxgmac_pdata* pdata, u8* mac_addr, u32* subsys, u32* revid)
{
u32 offset = 0, value = 0;
u32 machr = 0, maclr = 0;
bool succeed = true;
u8 index = 0;
for (index = 0; index < FXGMAC_EFUSE_MAX_ENTRY; index++) {
if (!fxgmac_read_patch_from_efuse_per_index(pdata, index, &offset, &value)) {
succeed = false;
break; // reach the last item.
}
if (0x00 == offset) {
break; // reach the blank.
}
if (MACA0LR_FROM_EFUSE == offset) {
maclr = value;
}
if (MACA0HR_FROM_EFUSE == offset) {
machr = value;
}
if ((0x08 == offset) && revid) {
*revid = value;
}
if ((0x2C == offset) && subsys) {
*subsys = value;
}
}
if (mac_addr) {
mac_addr[5] = (u8)(maclr & 0xFF);
mac_addr[4] = (u8)((maclr >> 8) & 0xFF);
mac_addr[3] = (u8)((maclr >> 16) & 0xFF);
mac_addr[2] = (u8)((maclr >> 24) & 0xFF);
mac_addr[1] = (u8)(machr & 0xFF);
mac_addr[0] = (u8)((machr >> 8) & 0xFF);
}
return succeed;
}
bool fxgmac_efuse_read_data(struct fxgmac_pdata* pdata, u32 offset, u32 __far* value)
{
bool succeed = false;
unsigned int wait;
u32 reg_val = 0;
//if (reg >= EFUSE_REGION_A_B_LENGTH) {
// FXGMAC_PR("Read addr out of range %d", reg);
// return succeed;
//}
if (value) {
*value = 0;
}
reg_val = FXGMAC_SET_REG_BITS(reg_val, EFUSE_OP_ADDR_POS, EFUSE_OP_ADDR_LEN, offset);
reg_val = FXGMAC_SET_REG_BITS(reg_val, EFUSE_OP_START_POS, EFUSE_OP_START_LEN, 1);
reg_val = FXGMAC_SET_REG_BITS(reg_val, EFUSE_OP_MODE_POS, EFUSE_OP_MODE_LEN, EFUSE_OP_MODE_ROW_READ);
writereg(pdata->pAdapter, reg_val, pdata->base_mem + EFUSE_OP_CTRL_0);
wait = 1000;
while (wait--) {
usleep_range_ex(pdata->pAdapter, 20, 50);
reg_val = readreg(pdata->pAdapter, pdata->base_mem + EFUSE_OP_CTRL_1);
if (FXGMAC_GET_REG_BITS(reg_val, EFUSE_OP_DONE_POS, EFUSE_OP_DONE_LEN)) {
succeed = true;
break;
}
}
if (succeed) {
if (value) {
*value = FXGMAC_GET_REG_BITS(reg_val, EFUSE_OP_RD_DATA_POS, EFUSE_OP_RD_DATA_LEN);
}
}
else {
FXGMAC_PR("Fail to reading efuse Byte%d\n", offset);
}
return succeed;
}
#ifndef COMMENT_UNUSED_CODE_TO_REDUCE_SIZE
bool fxgmac_read_patch_from_efuse(struct fxgmac_pdata* pdata, u32 offset, u32* value)
{
u32 reg_offset, reg_val;
u32 cur_val = 0;
bool succeed = true;
u8 index = 0;
if(offset >> 16){
FXGMAC_PR("Reading efuse out of range, reg %d. reg must be 2bytes.\n", index);
return false;
}
for (index = 0; index < FXGMAC_EFUSE_MAX_ENTRY; index++) {
if (!fxgmac_read_patch_from_efuse_per_index(pdata, index, &reg_offset, &reg_val)) {
succeed = false;
break;
} else if (reg_offset == offset) {
cur_val = reg_val;
} else if (0 == reg_offset && 0 == reg_val) {
break; // first blank. We should write here.
}
}
if (value) {
*value = cur_val;
}
return succeed;
}
bool fxgmac_write_patch_to_efuse_per_index(struct fxgmac_pdata* pdata, u8 index, u32 offset, u32 value)
{
unsigned int wait, i;
u32 reg_val;
bool succeed = false;
u32 cur_reg, cur_val;
u8 max_index = FXGMAC_EFUSE_MAX_ENTRY;
if(offset >> 16){
FXGMAC_PR("Reading efuse out of range, reg %d. reg must be 2bytes.\n", index);
return false;
}
fxgmac_efuse_read_data(pdata, EFUSE_LED_ADDR, &reg_val);
if (EFUSE_LED_COMMON_SOLUTION == reg_val) {
max_index = FXGMAC_EFUSE_MAX_ENTRY_UNDER_LED_COMMON;
}
if (index >= max_index) {
FXGMAC_PR("Writing efuse out of range, index %d max index %d\n", index, max_index);
return false;
}
if (fxgmac_read_patch_from_efuse_per_index(pdata, index, &cur_reg, &cur_val)) {
if(cur_reg != 0 || cur_val != 0){
FXGMAC_PR(" The index %d has writed value, cannot rewrite it.\n", index);
return false;
}
}else{
FXGMAC_PR("Cannot read index %d.\n", index);
return false;
}
for (i = EFUSE_PATCH_ADDR_START_BYTE; i < EFUSE_PATCH_DATA_START_BYTE; i++) {
reg_val = 0;
reg_val = FXGMAC_SET_REG_BITS(reg_val, EFUSE_OP_ADDR_POS, EFUSE_OP_ADDR_LEN, EFUSE_REGION_A_B_LENGTH + index * EFUSE_EACH_PATH_SIZE + i);
reg_val = FXGMAC_SET_REG_BITS(reg_val, EFUSE_OP_WR_DATA_POS, EFUSE_OP_WR_DATA_LEN, (offset >> (i << 3)) & 0xFF);
reg_val = FXGMAC_SET_REG_BITS(reg_val, EFUSE_OP_START_POS, EFUSE_OP_START_LEN, 1);
reg_val = FXGMAC_SET_REG_BITS(reg_val, EFUSE_OP_MODE_POS, EFUSE_OP_MODE_LEN, EFUSE_OP_MODE_ROW_WRITE);
writereg(pdata->pAdapter, reg_val, pdata->base_mem + EFUSE_OP_CTRL_0);
succeed = false;
wait = 1000;
while (wait--) {
usleep_range_ex(pdata->pAdapter, 20, 50);
reg_val = readreg(pdata->pAdapter, pdata->base_mem + EFUSE_OP_CTRL_1);
if (FXGMAC_GET_REG_BITS(reg_val, EFUSE_OP_DONE_POS, EFUSE_OP_DONE_LEN)) {
succeed = true;
break;
}
}
if (!succeed) {
FXGMAC_PR("Fail to writing efuse Byte%d\n", index * EFUSE_EACH_PATH_SIZE + i);
return succeed;
}
}
for (i = 2; i < 6; i++) {
reg_val = 0;
reg_val = FXGMAC_SET_REG_BITS(reg_val, EFUSE_OP_ADDR_POS, EFUSE_OP_ADDR_LEN, 18 + index * 6 + i);
reg_val = FXGMAC_SET_REG_BITS(reg_val, EFUSE_OP_WR_DATA_POS, EFUSE_OP_WR_DATA_LEN, (value >> ((i - 2) << 3)) & 0xFF);
reg_val = FXGMAC_SET_REG_BITS(reg_val, EFUSE_OP_START_POS, EFUSE_OP_START_LEN, 1);
reg_val = FXGMAC_SET_REG_BITS(reg_val, EFUSE_OP_MODE_POS, EFUSE_OP_MODE_LEN, EFUSE_OP_MODE_ROW_WRITE);
writereg(pdata->pAdapter, reg_val, pdata->base_mem + EFUSE_OP_CTRL_0);
succeed = false;
wait = 1000;
while (wait--) {
usleep_range_ex(pdata->pAdapter, 20, 50);
reg_val = readreg(pdata->pAdapter, pdata->base_mem + EFUSE_OP_CTRL_1);
if (FXGMAC_GET_REG_BITS(reg_val, EFUSE_OP_DONE_POS, EFUSE_OP_DONE_LEN)) {
succeed = true;
break;
}
}
if (!succeed) {
FXGMAC_PR("Fail to writing efuse Byte%d\n", index * EFUSE_EACH_PATH_SIZE + i);
return succeed;
}
}
return succeed;
}
bool fxgmac_write_patch_to_efuse(struct fxgmac_pdata* pdata, u32 offset, u32 value)
{
unsigned int wait, i;
u32 reg_offset, reg_val;
u32 cur_offset = 0, cur_val = 0;
bool succeed = false;
u8 index = 0;
if(offset >> 16){
FXGMAC_PR("Reading efuse out of range, reg %d. reg must be 2bytes.\n", index);
return false;
}
for (index = 0; index < FXGMAC_EFUSE_MAX_ENTRY; index++) {
if (!fxgmac_read_patch_from_efuse_per_index(pdata, index, &reg_offset, &reg_val)) {
return false;
} else if (reg_offset == offset) {
cur_offset = reg_offset;
cur_val = reg_val;
} else if (0 == reg_offset && 0 == reg_val) {
break; // first blank. We should write here.
}
}
if (cur_offset == offset) {
if (cur_val == value) {
FXGMAC_PR("0x%x -> Reg0x%x already exists, ignore.\n", value, offset);
return true;
} else {
FXGMAC_PR("Reg0x%x entry current value 0x%x, reprogram.\n", offset, value);
}
}
for (i = EFUSE_PATCH_ADDR_START_BYTE; i < EFUSE_PATCH_DATA_START_BYTE; i++) {
reg_val = 0;
reg_val = FXGMAC_SET_REG_BITS(reg_val, EFUSE_OP_ADDR_POS, EFUSE_OP_ADDR_LEN, EFUSE_REGION_A_B_LENGTH + index * EFUSE_EACH_PATH_SIZE + i);
reg_val = FXGMAC_SET_REG_BITS(reg_val, EFUSE_OP_WR_DATA_POS, EFUSE_OP_WR_DATA_LEN, (offset >> (i << 3)) & 0xFF );
reg_val = FXGMAC_SET_REG_BITS(reg_val, EFUSE_OP_START_POS, EFUSE_OP_START_LEN, 1);
reg_val = FXGMAC_SET_REG_BITS(reg_val, EFUSE_OP_MODE_POS, EFUSE_OP_MODE_LEN, EFUSE_OP_MODE_ROW_WRITE);
writereg(pdata->pAdapter, reg_val, pdata->base_mem + EFUSE_OP_CTRL_0);
succeed = false;
wait = 1000;
while (wait--) {
usleep_range_ex(pdata->pAdapter, 20, 50);
reg_val = readreg(pdata->pAdapter, pdata->base_mem + EFUSE_OP_CTRL_1);
if (FXGMAC_GET_REG_BITS(reg_val, EFUSE_OP_DONE_POS, EFUSE_OP_DONE_LEN)) {
succeed = true;
break;
}
}
if (!succeed) {
FXGMAC_PR("Fail to writing efuse Byte%d\n", index * EFUSE_EACH_PATH_SIZE + i);
return succeed;
}
}
for (i = EFUSE_PATCH_DATA_START_BYTE; i < EFUSE_EACH_PATH_SIZE; i++) {
reg_val = 0;
reg_val = FXGMAC_SET_REG_BITS(reg_val, EFUSE_OP_ADDR_POS, EFUSE_OP_ADDR_LEN, EFUSE_REGION_A_B_LENGTH + index * EFUSE_EACH_PATH_SIZE + i);
reg_val = FXGMAC_SET_REG_BITS(reg_val, EFUSE_OP_WR_DATA_POS, EFUSE_OP_WR_DATA_LEN, (value >> ((i - 2) << 3)) & 0xFF);
reg_val = FXGMAC_SET_REG_BITS(reg_val, EFUSE_OP_START_POS, EFUSE_OP_START_LEN, 1);
reg_val = FXGMAC_SET_REG_BITS(reg_val, EFUSE_OP_MODE_POS, EFUSE_OP_MODE_LEN, EFUSE_OP_MODE_ROW_WRITE);
writereg(pdata->pAdapter, reg_val, pdata->base_mem + EFUSE_OP_CTRL_0);
succeed = false;
wait = 1000;
while (wait--) {
usleep_range_ex(pdata->pAdapter, 20, 50);
reg_val = readreg(pdata->pAdapter, pdata->base_mem + EFUSE_OP_CTRL_1);
if (FXGMAC_GET_REG_BITS(reg_val, EFUSE_OP_DONE_POS, EFUSE_OP_DONE_LEN)) {
succeed = true;
break;
}
}
if (!succeed) {
FXGMAC_PR("Fail to writing efuse Byte%d\n", index * EFUSE_EACH_PATH_SIZE + i);
return succeed;
}
}
return succeed;
}
bool fxgmac_write_mac_subsys_to_efuse(struct fxgmac_pdata* pdata, u8* mac_addr, u32* subsys, u32* revid)
{
#ifdef DBG
u32 machr = 0, maclr = 0;
#endif
u32 cur_subsysid = 0;
u32 pcie_cfg_ctrl= PCIE_CFG_CTRL_DEFAULT_VAL;
bool succeed = true;
if (mac_addr) {
#ifdef DBG
machr = readreg(pdata->pAdapter, pdata->base_mem + MACA0HR_FROM_EFUSE);
maclr = readreg(pdata->pAdapter, pdata->base_mem + MACA0LR_FROM_EFUSE);
DPRINTK("Current mac address from efuse is %02x-%02x-%02x-%02x-%02x-%02x.\n",
(machr >> 8) & 0xFF, machr & 0xFF, (maclr >> 24) & 0xFF, (maclr >> 16) & 0xFF, (maclr >> 8) & 0xFF, maclr & 0xFF);
#endif
if(!fxgmac_write_patch_to_efuse(pdata, MACA0HR_FROM_EFUSE, (((u32)mac_addr[0]) << 8) | mac_addr[1])){
succeed = false;
}
if(!fxgmac_write_patch_to_efuse(pdata, MACA0LR_FROM_EFUSE, (((u32)mac_addr[2]) << 24) | (((u32)mac_addr[3]) << 16) | (((u32)mac_addr[4]) << 8) | mac_addr[5])){
succeed = false;
}
}
if (revid) {
if(!fxgmac_write_patch_to_efuse(pdata, EFUSE_REVID_REGISTER, *revid)){
succeed = false;
}
}
if (subsys) {
if (!fxgmac_read_mac_subsys_from_efuse(pdata, NULL, &cur_subsysid, NULL))
return false;
if (cur_subsysid != *subsys)
{
pcie_cfg_ctrl = FXGMAC_SET_REG_BITS(pcie_cfg_ctrl, MGMT_PCIE_CFG_CTRL_CS_EN_POS, MGMT_PCIE_CFG_CTRL_CS_EN_LEN, 1);
if (!fxgmac_write_patch_to_efuse(pdata, MGMT_PCIE_CFG_CTRL, pcie_cfg_ctrl)) {
succeed = false;
}
if (!fxgmac_write_patch_to_efuse(pdata, EFUSE_SUBSYS_REGISTER, *subsys)) {
succeed = false;
}
pcie_cfg_ctrl = FXGMAC_SET_REG_BITS(pcie_cfg_ctrl, MGMT_PCIE_CFG_CTRL_CS_EN_POS, MGMT_PCIE_CFG_CTRL_CS_EN_LEN, 0);
if (!fxgmac_write_patch_to_efuse(pdata, MGMT_PCIE_CFG_CTRL, pcie_cfg_ctrl)) {
succeed = false;
}
}
}
return succeed;
}
bool fxgmac_write_mac_addr_to_efuse(struct fxgmac_pdata* pdata, u8* mac_addr)
{
#ifdef DBG
u32 machr = 0, maclr = 0;
#endif
bool succeed = true;
if (mac_addr) {
#ifdef DBG
machr = readreg(pdata->pAdapter, pdata->base_mem + MACA0HR_FROM_EFUSE);
maclr = readreg(pdata->pAdapter, pdata->base_mem + MACA0LR_FROM_EFUSE);
DPRINTK("Current mac address from efuse is %02x-%02x-%02x-%02x-%02x-%02x.\n",
(machr >> 8) & 0xFF, machr & 0xFF, (maclr >> 24) & 0xFF, (maclr >> 16) & 0xFF, (maclr >> 8) & 0xFF, maclr & 0xFF);
#endif
if(!fxgmac_write_patch_to_efuse(pdata, MACA0HR_FROM_EFUSE, (((u32)mac_addr[0]) << 8) | mac_addr[1])){
succeed = false;
}
if(!fxgmac_write_patch_to_efuse(pdata, MACA0LR_FROM_EFUSE, (((u32)mac_addr[2]) << 24) | (((u32)mac_addr[3]) << 16) | (((u32)mac_addr[4]) << 8) | mac_addr[5])){
succeed = false;
}
}
return succeed;
}
bool fxgmac_read_subsys_from_efuse(struct fxgmac_pdata* pdata, u32* subsys, u32* revid)
{
u32 offset = 0, value = 0;
u8 index;
bool succeed = true;
for (index = 0; index < FXGMAC_EFUSE_MAX_ENTRY; index++) {
if (!fxgmac_read_patch_from_efuse_per_index(pdata, index, &offset, &value)) {
succeed = false;
break; // reach the last item.
}
if (0x00 == offset) {
break; // reach the blank.
}
if ((EFUSE_REVID_REGISTER == offset) && revid) {
*revid = value;
}else{
succeed = false;
}
if ((EFUSE_SUBSYS_REGISTER == offset) && subsys) {
*subsys = value;
}else{
succeed = false;
}
}
return succeed;
}
bool fxgmac_write_subsys_to_efuse(struct fxgmac_pdata* pdata, u32* subsys, u32* revid)
{
bool succeed = true;
/* write subsys info */
if (revid) {
if(!fxgmac_write_patch_to_efuse(pdata, EFUSE_REVID_REGISTER, *revid)){
succeed = false;
}
}
if (subsys) {
if(!fxgmac_write_patch_to_efuse(pdata, EFUSE_SUBSYS_REGISTER, *subsys)){
succeed = false;
}
}
return succeed;
}
bool fxgmac_efuse_load(struct fxgmac_pdata* pdata)
{
bool succeed = false;
unsigned int wait;
u32 reg_val = 0;
reg_val = FXGMAC_SET_REG_BITS(reg_val, EFUSE_OP_START_POS, EFUSE_OP_START_LEN, 1);
reg_val = FXGMAC_SET_REG_BITS(reg_val, EFUSE_OP_MODE_POS, EFUSE_OP_MODE_LEN, EFUSE_OP_MODE_AUTO_LOAD);
writereg(pdata->pAdapter, reg_val, pdata->base_mem + EFUSE_OP_CTRL_0);
wait = 1000;
while (wait--) {
usleep_range_ex(pdata->pAdapter, 20, 50);
reg_val = readreg(pdata->pAdapter, pdata->base_mem + EFUSE_OP_CTRL_1);
if (FXGMAC_GET_REG_BITS(reg_val, EFUSE_OP_DONE_POS, EFUSE_OP_DONE_LEN)) {
succeed = true;
break;
}
}
if (!succeed) {
FXGMAC_PR("Fail to loading efuse, ctrl_1 0x%08x\n", reg_val);
}
return succeed;
}
bool fxgmac_efuse_write_oob(struct fxgmac_pdata* pdata)
{
bool succeed = false;
unsigned int wait;
u32 reg_val, value;
if (!fxgmac_efuse_read_data(pdata, EFUSE_OOB_ADDR, &reg_val)) {
return succeed;
}
if (FXGMAC_GET_REG_BITS(reg_val, EFUSE_OOB_POS, EFUSE_OOB_LEN)) {
FXGMAC_PR("OOB Ctrl bit already exists");
return true;
}
value = 0;
value = FXGMAC_SET_REG_BITS(value, EFUSE_OOB_POS, EFUSE_OOB_LEN, 1);
reg_val = 0;
reg_val = FXGMAC_SET_REG_BITS(reg_val, EFUSE_OP_ADDR_POS, EFUSE_OP_ADDR_LEN, EFUSE_OOB_ADDR);
reg_val = FXGMAC_SET_REG_BITS(reg_val, EFUSE_OP_WR_DATA_POS, EFUSE_OP_WR_DATA_LEN, value & 0xFF);
reg_val = FXGMAC_SET_REG_BITS(reg_val, EFUSE_OP_START_POS, EFUSE_OP_START_LEN, 1);
reg_val = FXGMAC_SET_REG_BITS(reg_val, EFUSE_OP_MODE_POS, EFUSE_OP_MODE_LEN, EFUSE_OP_MODE_ROW_WRITE);
writereg(pdata->pAdapter, reg_val, pdata->base_mem + EFUSE_OP_CTRL_0);
wait = 1000;
while (wait--) {
usleep_range_ex(pdata->pAdapter, 20, 50);
reg_val = readreg(pdata->pAdapter, pdata->base_mem + EFUSE_OP_CTRL_1);
if (FXGMAC_GET_REG_BITS(reg_val, EFUSE_OP_DONE_POS, EFUSE_OP_DONE_LEN)) {
succeed = true;
break;
}
}
if (!succeed) {
FXGMAC_PR("Fail to writing efuse Byte OOB");
}
return succeed;
}
bool fxgmac_efuse_write_led(struct fxgmac_pdata* pdata, u32 value)
{
bool succeed = false;
unsigned int wait;
u32 reg_val;
if (!fxgmac_efuse_read_data(pdata, EFUSE_LED_ADDR, &reg_val)) {
return succeed;
}
if (reg_val == value) {
FXGMAC_PR("Led Ctrl option already exists");
return true;
}
reg_val = 0;
reg_val = FXGMAC_SET_REG_BITS(reg_val, EFUSE_OP_ADDR_POS, EFUSE_OP_ADDR_LEN, EFUSE_LED_ADDR);
reg_val = FXGMAC_SET_REG_BITS(reg_val, EFUSE_OP_WR_DATA_POS, EFUSE_OP_WR_DATA_LEN, value & 0xFF);
reg_val = FXGMAC_SET_REG_BITS(reg_val, EFUSE_OP_START_POS, EFUSE_OP_START_LEN, 1);
reg_val = FXGMAC_SET_REG_BITS(reg_val, EFUSE_OP_MODE_POS, EFUSE_OP_MODE_LEN, EFUSE_OP_MODE_ROW_WRITE);
writereg(pdata->pAdapter, reg_val, pdata->base_mem + EFUSE_OP_CTRL_0);
wait = 1000;
while (wait--) {
usleep_range_ex(pdata->pAdapter, 20, 50);
reg_val = readreg(pdata->pAdapter, pdata->base_mem + EFUSE_OP_CTRL_1);
if (FXGMAC_GET_REG_BITS(reg_val, EFUSE_OP_DONE_POS, EFUSE_OP_DONE_LEN)) {
succeed = true;
break;
}
}
if (!succeed) {
FXGMAC_PR("Fail to writing efuse Byte LED");
}
return succeed;
}
bool fxgmac_efuse_write_data(struct fxgmac_pdata* pdata, u32 offset, u32 value)
{
bool succeed = false;
unsigned int wait;
u32 reg_val;
if (!fxgmac_efuse_read_data(pdata, offset, &reg_val)) {
return succeed;
}
if (reg_val == value) {
FXGMAC_PR("offset 0x%x already exists", offset);
return true;
}
reg_val = 0;
reg_val = FXGMAC_SET_REG_BITS(reg_val, EFUSE_OP_ADDR_POS, EFUSE_OP_ADDR_LEN, offset & 0xFF);
reg_val = FXGMAC_SET_REG_BITS(reg_val, EFUSE_OP_WR_DATA_POS, EFUSE_OP_WR_DATA_LEN, value & 0xFF);
reg_val = FXGMAC_SET_REG_BITS(reg_val, EFUSE_OP_START_POS, EFUSE_OP_START_LEN, 1);
reg_val = FXGMAC_SET_REG_BITS(reg_val, EFUSE_OP_MODE_POS, EFUSE_OP_MODE_LEN, EFUSE_OP_MODE_ROW_WRITE);
writereg(pdata->pAdapter, reg_val, pdata->base_mem + EFUSE_OP_CTRL_0);
wait = 1000;
while (wait--) {
usleep_range_ex(pdata->pAdapter, 20, 50);
reg_val = readreg(pdata->pAdapter, pdata->base_mem + EFUSE_OP_CTRL_1);
if (FXGMAC_GET_REG_BITS(reg_val, EFUSE_OP_DONE_POS, EFUSE_OP_DONE_LEN)) {
succeed = true;
break;
}
}
if (!succeed) {
FXGMAC_PR("Fail to writing efuse 0x%x Byte LED", offset);
}
return succeed;
}
static void fxgmac_read_led_efuse_config(struct fxgmac_pdata* pdata, struct led_setting* pfirst, struct led_setting* psecond)
{
u32 val_high = 0, val_low = 0;
//read first area
fxgmac_efuse_read_data(pdata, EFUSE_FISRT_UPDATE_ADDR, &val_high);
fxgmac_efuse_read_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 1), &val_low);
pfirst->disable_led_setting[4] = ((val_high << 8) + val_low);
fxgmac_efuse_read_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 2), &val_high);
fxgmac_efuse_read_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 3), &val_low);
pfirst->disable_led_setting[3] = ((val_high << 8) + val_low);
fxgmac_efuse_read_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 4), &val_high);
fxgmac_efuse_read_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 5), &val_low);
pfirst->disable_led_setting[2] = ((val_high << 8) + val_low);
fxgmac_efuse_read_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 6), &val_high);
fxgmac_efuse_read_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 7), &val_low);
pfirst->disable_led_setting[1] = ((val_high << 8) + val_low);
fxgmac_efuse_read_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 8), &val_high);
fxgmac_efuse_read_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 9), &val_low);
pfirst->disable_led_setting[0] = ((val_high << 8) + val_low);
fxgmac_efuse_read_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 10), &val_high);
fxgmac_efuse_read_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 11), &val_low);
pfirst->s5_led_setting[4] = ((val_high << 8) + val_low);
fxgmac_efuse_read_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 12), &val_high);
fxgmac_efuse_read_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 13), &val_low);
pfirst->s5_led_setting[3] = ((val_high << 8) + val_low);
fxgmac_efuse_read_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 14), &val_high);
fxgmac_efuse_read_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 15), &val_low);
pfirst->s5_led_setting[2] = ((val_high << 8) + val_low);
fxgmac_efuse_read_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 16), &val_high);
fxgmac_efuse_read_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 17), &val_low);
pfirst->s5_led_setting[1] = ((val_high << 8) + val_low);
fxgmac_efuse_read_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 18), &val_high);
fxgmac_efuse_read_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 19), &val_low);
pfirst->s5_led_setting[0] = ((val_high << 8) + val_low);
fxgmac_efuse_read_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 20), &val_high);
fxgmac_efuse_read_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 21), &val_low);
pfirst->s3_led_setting[4] = ((val_high << 8) + val_low);
fxgmac_efuse_read_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 22), &val_high);
fxgmac_efuse_read_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 23), &val_low);
pfirst->s3_led_setting[3] = ((val_high << 8) + val_low);
fxgmac_efuse_read_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 24), &val_high);
fxgmac_efuse_read_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 25), &val_low);
pfirst->s3_led_setting[2] = ((val_high << 8) + val_low);
fxgmac_efuse_read_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 26), &val_high);
fxgmac_efuse_read_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 27), &val_low);
pfirst->s3_led_setting[1] = ((val_high << 8) + val_low);
fxgmac_efuse_read_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 28), &val_high);
fxgmac_efuse_read_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 29), &val_low);
pfirst->s3_led_setting[0] = ((val_high << 8) + val_low);
fxgmac_efuse_read_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 30), &val_high);
fxgmac_efuse_read_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 31), &val_low);
pfirst->s0_led_setting[4] = ((val_high << 8) + val_low);
fxgmac_efuse_read_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 32), &val_high);
fxgmac_efuse_read_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 33), &val_low);
pfirst->s0_led_setting[3] = ((val_high << 8) + val_low);
fxgmac_efuse_read_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 34), &val_high);
fxgmac_efuse_read_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 35), &val_low);
pfirst->s0_led_setting[2] = ((val_high << 8) + val_low);
fxgmac_efuse_read_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 36), &val_high);
fxgmac_efuse_read_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 37), &val_low);
pfirst->s0_led_setting[1] = ((val_high << 8) + val_low);
fxgmac_efuse_read_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 38), &val_high);
fxgmac_efuse_read_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 39), &val_low);
pfirst->s0_led_setting[0] = ((val_high << 8) + val_low);
//read second area
fxgmac_efuse_read_data(pdata, EFUSE_SECOND_UPDATE_ADDR, &val_high);
fxgmac_efuse_read_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 1), &val_low);
psecond->disable_led_setting[4] = ((val_high << 8) + val_low);
fxgmac_efuse_read_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 2), &val_high);
fxgmac_efuse_read_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 3), &val_low);
psecond->disable_led_setting[3] = ((val_high << 8) + val_low);
fxgmac_efuse_read_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 4), &val_high);
fxgmac_efuse_read_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 5), &val_low);
psecond->disable_led_setting[2] = ((val_high << 8) + val_low);
fxgmac_efuse_read_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 6), &val_high);
fxgmac_efuse_read_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 7), &val_low);
psecond->disable_led_setting[1] = ((val_high << 8) + val_low);
fxgmac_efuse_read_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 8), &val_high);
fxgmac_efuse_read_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 9), &val_low);
psecond->disable_led_setting[0] = ((val_high << 8) + val_low);
fxgmac_efuse_read_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 10), &val_high);
fxgmac_efuse_read_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 11), &val_low);
psecond->s5_led_setting[4] = ((val_high << 8) + val_low);
fxgmac_efuse_read_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 12), &val_high);
fxgmac_efuse_read_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 13), &val_low);
psecond->s5_led_setting[3] = ((val_high << 8) + val_low);
fxgmac_efuse_read_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 14), &val_high);
fxgmac_efuse_read_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 15), &val_low);
psecond->s5_led_setting[2] = ((val_high << 8) + val_low);
fxgmac_efuse_read_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 16), &val_high);
fxgmac_efuse_read_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 17), &val_low);
psecond->s5_led_setting[1] = ((val_high << 8) + val_low);
fxgmac_efuse_read_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 18), &val_high);
fxgmac_efuse_read_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 19), &val_low);
psecond->s5_led_setting[0] = ((val_high << 8) + val_low);
fxgmac_efuse_read_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 20), &val_high);
fxgmac_efuse_read_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 21), &val_low);
psecond->s3_led_setting[4] = ((val_high << 8) + val_low);
fxgmac_efuse_read_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 22), &val_high);
fxgmac_efuse_read_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 23), &val_low);
psecond->s3_led_setting[3] = ((val_high << 8) + val_low);
fxgmac_efuse_read_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 24), &val_high);
fxgmac_efuse_read_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 25), &val_low);
psecond->s3_led_setting[2] = ((val_high << 8) + val_low);
fxgmac_efuse_read_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 26), &val_high);
fxgmac_efuse_read_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 27), &val_low);
psecond->s3_led_setting[1] = ((val_high << 8) + val_low);
fxgmac_efuse_read_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 28), &val_high);
fxgmac_efuse_read_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 29), &val_low);
psecond->s3_led_setting[0] = ((val_high << 8) + val_low);
fxgmac_efuse_read_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 30), &val_high);
fxgmac_efuse_read_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 31), &val_low);
psecond->s0_led_setting[4] = ((val_high << 8) + val_low);
fxgmac_efuse_read_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 32), &val_high);
fxgmac_efuse_read_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 33), &val_low);
psecond->s0_led_setting[3] = ((val_high << 8) + val_low);
fxgmac_efuse_read_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 34), &val_high);
fxgmac_efuse_read_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 35), &val_low);
psecond->s0_led_setting[2] = ((val_high << 8) + val_low);
fxgmac_efuse_read_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 36), &val_high);
fxgmac_efuse_read_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 37), &val_low);
psecond->s0_led_setting[1] = ((val_high << 8) + val_low);
fxgmac_efuse_read_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 38), &val_high);
fxgmac_efuse_read_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 39), &val_low);
psecond->s0_led_setting[0] = ((val_high << 8) + val_low);
}
bool fxgmac_write_led_setting_to_efuse(struct fxgmac_pdata* pdata)
{
struct led_setting led_config_first;
struct led_setting led_config_second;
bool bfirstflag = false, bsecondflag = false;
bool bsucceed = false;
fxgmac_read_led_efuse_config(pdata, &led_config_first, &led_config_second);
if (0x00 == led_config_first.s0_led_setting[0] && 0x00 == led_config_first.s0_led_setting[1] && 0x00 == led_config_first.s0_led_setting[2] && 0x00 == led_config_first.s0_led_setting[3] && 0x00 == led_config_first.s0_led_setting[4]
&& 0x00 == led_config_first.s3_led_setting[0] && 0x00 == led_config_first.s3_led_setting[1] && 0x00 == led_config_first.s3_led_setting[2] && 0x00 == led_config_first.s3_led_setting[3] && 0x00 == led_config_first.s3_led_setting[4]
&& 0x00 == led_config_first.s5_led_setting[0] && 0x00 == led_config_first.s5_led_setting[1] && 0x00 == led_config_first.s5_led_setting[2] && 0x00 == led_config_first.s5_led_setting[3] && 0x00 == led_config_first.s5_led_setting[4]
&& 0x00 == led_config_first.disable_led_setting[0] && 0x00 == led_config_first.disable_led_setting[1] && 0x00 == led_config_first.disable_led_setting[2] && 0x00 == led_config_first.disable_led_setting[3] && 0x00 == led_config_first.disable_led_setting[4]
) {
bfirstflag = true;
}
if (0x00 == led_config_second.s0_led_setting[0] && 0x00 == led_config_second.s0_led_setting[1] && 0x00 == led_config_second.s0_led_setting[2] && 0x00 == led_config_second.s0_led_setting[3] && 0x00 == led_config_second.s0_led_setting[4]
&& 0x00 == led_config_second.s3_led_setting[0] && 0x00 == led_config_second.s3_led_setting[1] && 0x00 == led_config_second.s3_led_setting[2] && 0x00 == led_config_second.s3_led_setting[3] && 0x00 == led_config_second.s3_led_setting[4]
&& 0x00 == led_config_second.s5_led_setting[0] && 0x00 == led_config_second.s5_led_setting[1] && 0x00 == led_config_second.s5_led_setting[2] && 0x00 == led_config_second.s5_led_setting[3] && 0x00 == led_config_second.s5_led_setting[4]
&& 0x00 == led_config_second.disable_led_setting[0] && 0x00 == led_config_second.disable_led_setting[1] && 0x00 == led_config_second.disable_led_setting[2] && 0x00 == led_config_second.disable_led_setting[3] && 0x00 == led_config_second.disable_led_setting[4]
) {
bsecondflag = true;
}
#ifndef LINUX
DbgPrintF(MP_TRACE, "%s s0 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x", __FUNCTION__, pdata->ledconfig.s0_led_setting[0], pdata->ledconfig.s0_led_setting[1], pdata->ledconfig.s0_led_setting[2], pdata->ledconfig.s0_led_setting[3], pdata->ledconfig.s0_led_setting[4]);
DbgPrintF(MP_TRACE, "%s s3 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x", __FUNCTION__, pdata->ledconfig.s3_led_setting[0], pdata->ledconfig.s3_led_setting[1], pdata->ledconfig.s3_led_setting[2], pdata->ledconfig.s3_led_setting[3], pdata->ledconfig.s3_led_setting[4]);
DbgPrintF(MP_TRACE, "%s s5 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x", __FUNCTION__, pdata->ledconfig.s5_led_setting[0], pdata->ledconfig.s5_led_setting[1], pdata->ledconfig.s5_led_setting[2], pdata->ledconfig.s5_led_setting[3], pdata->ledconfig.s5_led_setting[4]);
DbgPrintF(MP_TRACE, "%s disable 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x", __FUNCTION__, pdata->ledconfig.disable_led_setting[0], pdata->ledconfig.disable_led_setting[1], pdata->ledconfig.disable_led_setting[2], pdata->ledconfig.disable_led_setting[3], pdata->ledconfig.disable_led_setting[4]);
#endif
if (bfirstflag && bsecondflag) {
//update first area
fxgmac_efuse_write_data(pdata, EFUSE_FISRT_UPDATE_ADDR, (pdata->ledconfig.disable_led_setting[4]>>8)&0xFF);
fxgmac_efuse_write_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 1), pdata->ledconfig.disable_led_setting[4]);
fxgmac_efuse_write_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 2), (pdata->ledconfig.disable_led_setting[3] >> 8) & 0xFF);
fxgmac_efuse_write_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 3), pdata->ledconfig.disable_led_setting[3]);
fxgmac_efuse_write_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 4), (pdata->ledconfig.disable_led_setting[2] >> 8) & 0xFF);
fxgmac_efuse_write_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 5), pdata->ledconfig.disable_led_setting[2]);
fxgmac_efuse_write_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 6), (pdata->ledconfig.disable_led_setting[1] >> 8) & 0xFF);
fxgmac_efuse_write_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 7), pdata->ledconfig.disable_led_setting[1]);
fxgmac_efuse_write_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 8), (pdata->ledconfig.disable_led_setting[0] >> 8) & 0xFF);
fxgmac_efuse_write_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 9), pdata->ledconfig.disable_led_setting[0]);
fxgmac_efuse_write_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 10), (pdata->ledconfig.s5_led_setting[4] >> 8) & 0xFF);
fxgmac_efuse_write_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 11), pdata->ledconfig.s5_led_setting[4]);
fxgmac_efuse_write_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 12), (pdata->ledconfig.s5_led_setting[3] >> 8) & 0xFF);
fxgmac_efuse_write_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 13), pdata->ledconfig.s5_led_setting[3]);
fxgmac_efuse_write_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 14), (pdata->ledconfig.s5_led_setting[2] >> 8) & 0xFF);
fxgmac_efuse_write_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 15), pdata->ledconfig.s5_led_setting[2]);
fxgmac_efuse_write_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 16), (pdata->ledconfig.s5_led_setting[1] >> 8) & 0xFF);
fxgmac_efuse_write_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 17), pdata->ledconfig.s5_led_setting[1]);
fxgmac_efuse_write_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 18), (pdata->ledconfig.s5_led_setting[0] >> 8) & 0xFF);
fxgmac_efuse_write_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 19), pdata->ledconfig.s5_led_setting[0]);
fxgmac_efuse_write_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 20), (pdata->ledconfig.s3_led_setting[4] >> 8) & 0xFF);
fxgmac_efuse_write_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 21), pdata->ledconfig.s3_led_setting[4]);
fxgmac_efuse_write_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 22), (pdata->ledconfig.s3_led_setting[3] >> 8) & 0xFF);
fxgmac_efuse_write_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 23), pdata->ledconfig.s3_led_setting[3]);
fxgmac_efuse_write_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 24), (pdata->ledconfig.s3_led_setting[2] >> 8) & 0xFF);
fxgmac_efuse_write_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 25), pdata->ledconfig.s3_led_setting[2]);
fxgmac_efuse_write_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 26), (pdata->ledconfig.s3_led_setting[1] >> 8) & 0xFF);
fxgmac_efuse_write_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 27), pdata->ledconfig.s3_led_setting[1]);
fxgmac_efuse_write_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 28), (pdata->ledconfig.s3_led_setting[0] >> 8) & 0xFF);
fxgmac_efuse_write_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 29), pdata->ledconfig.s3_led_setting[0]);
fxgmac_efuse_write_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 30), (pdata->ledconfig.s0_led_setting[4] >> 8) & 0xFF);
fxgmac_efuse_write_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 31), pdata->ledconfig.s0_led_setting[4]);
fxgmac_efuse_write_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 32), (pdata->ledconfig.s0_led_setting[3] >> 8) & 0xFF);
fxgmac_efuse_write_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 33), pdata->ledconfig.s0_led_setting[3]);
fxgmac_efuse_write_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 34), (pdata->ledconfig.s0_led_setting[2] >> 8) & 0xFF);
fxgmac_efuse_write_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 35), pdata->ledconfig.s0_led_setting[2]);
fxgmac_efuse_write_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 36), (pdata->ledconfig.s0_led_setting[1] >> 8) & 0xFF);
fxgmac_efuse_write_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 37), pdata->ledconfig.s0_led_setting[1]);
fxgmac_efuse_write_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 38), (pdata->ledconfig.s0_led_setting[0] >> 8) & 0xFF);
fxgmac_efuse_write_data(pdata, (EFUSE_FISRT_UPDATE_ADDR - 39), pdata->ledconfig.s0_led_setting[0]);
bsucceed = true;
}
else if (!bfirstflag && bsecondflag) {
//update second area
fxgmac_efuse_write_data(pdata, EFUSE_SECOND_UPDATE_ADDR, (pdata->ledconfig.disable_led_setting[4] >> 8) & 0xFF);
fxgmac_efuse_write_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 1), pdata->ledconfig.disable_led_setting[4]);
fxgmac_efuse_write_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 2), (pdata->ledconfig.disable_led_setting[3] >> 8) & 0xFF);
fxgmac_efuse_write_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 3), pdata->ledconfig.disable_led_setting[3]);
fxgmac_efuse_write_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 4), (pdata->ledconfig.disable_led_setting[2] >> 8) & 0xFF);
fxgmac_efuse_write_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 5), pdata->ledconfig.disable_led_setting[2]);
fxgmac_efuse_write_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 6), (pdata->ledconfig.disable_led_setting[1] >> 8) & 0xFF);
fxgmac_efuse_write_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 7), pdata->ledconfig.disable_led_setting[1]);
fxgmac_efuse_write_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 8), (pdata->ledconfig.disable_led_setting[0] >> 8) & 0xFF);
fxgmac_efuse_write_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 9), pdata->ledconfig.disable_led_setting[0]);
fxgmac_efuse_write_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 10), (pdata->ledconfig.s5_led_setting[4] >> 8) & 0xFF);
fxgmac_efuse_write_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 11), pdata->ledconfig.s5_led_setting[4]);
fxgmac_efuse_write_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 12), (pdata->ledconfig.s5_led_setting[3] >> 8) & 0xFF);
fxgmac_efuse_write_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 13), pdata->ledconfig.s5_led_setting[3]);
fxgmac_efuse_write_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 14), (pdata->ledconfig.s5_led_setting[2] >> 8) & 0xFF);
fxgmac_efuse_write_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 15), pdata->ledconfig.s5_led_setting[2]);
fxgmac_efuse_write_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 16), (pdata->ledconfig.s5_led_setting[1] >> 8) & 0xFF);
fxgmac_efuse_write_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 17), pdata->ledconfig.s5_led_setting[1]);
fxgmac_efuse_write_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 18), (pdata->ledconfig.s5_led_setting[0] >> 8) & 0xFF);
fxgmac_efuse_write_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 19), pdata->ledconfig.s5_led_setting[0]);
fxgmac_efuse_write_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 20), (pdata->ledconfig.s3_led_setting[4] >> 8) & 0xFF);
fxgmac_efuse_write_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 21), pdata->ledconfig.s3_led_setting[4]);
fxgmac_efuse_write_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 22), (pdata->ledconfig.s3_led_setting[3] >> 8) & 0xFF);
fxgmac_efuse_write_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 23), pdata->ledconfig.s3_led_setting[3]);
fxgmac_efuse_write_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 24), (pdata->ledconfig.s3_led_setting[2] >> 8) & 0xFF);
fxgmac_efuse_write_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 25), pdata->ledconfig.s3_led_setting[2]);
fxgmac_efuse_write_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 26), (pdata->ledconfig.s3_led_setting[1] >> 8) & 0xFF);
fxgmac_efuse_write_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 27), pdata->ledconfig.s3_led_setting[1]);
fxgmac_efuse_write_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 28), (pdata->ledconfig.s3_led_setting[0] >> 8) & 0xFF);
fxgmac_efuse_write_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 29), pdata->ledconfig.s3_led_setting[0]);
fxgmac_efuse_write_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 30), (pdata->ledconfig.s0_led_setting[4] >> 8) & 0xFF);
fxgmac_efuse_write_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 31), pdata->ledconfig.s0_led_setting[4]);
fxgmac_efuse_write_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 32), (pdata->ledconfig.s0_led_setting[3] >> 8) & 0xFF);
fxgmac_efuse_write_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 33), pdata->ledconfig.s0_led_setting[3]);
fxgmac_efuse_write_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 34), (pdata->ledconfig.s0_led_setting[2] >> 8) & 0xFF);
fxgmac_efuse_write_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 35), pdata->ledconfig.s0_led_setting[2]);
fxgmac_efuse_write_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 36), (pdata->ledconfig.s0_led_setting[1] >> 8) & 0xFF);
fxgmac_efuse_write_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 37), pdata->ledconfig.s0_led_setting[1]);
fxgmac_efuse_write_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 38), (pdata->ledconfig.s0_led_setting[0] >> 8) & 0xFF);
fxgmac_efuse_write_data(pdata, (EFUSE_SECOND_UPDATE_ADDR - 39), pdata->ledconfig.s0_led_setting[0]);
bsucceed = true;
}
return bsucceed;
}
bool fxgmac_read_led_setting_from_efuse(struct fxgmac_pdata* pdata)
{
struct led_setting led_config_first;
struct led_setting led_config_second;
bool bfirstflag = false, bsecondflag = false;
bool bsucceed = false;
fxgmac_read_led_efuse_config(pdata, &led_config_first, &led_config_second);
if (0x00 == led_config_first.s0_led_setting[0] && 0x00 == led_config_first.s0_led_setting[1] && 0x00 == led_config_first.s0_led_setting[2] && 0x00 == led_config_first.s0_led_setting[3] && 0x00 == led_config_first.s0_led_setting[4]
&& 0x00 == led_config_first.s3_led_setting[0] && 0x00 == led_config_first.s3_led_setting[1] && 0x00 == led_config_first.s3_led_setting[2] && 0x00 == led_config_first.s3_led_setting[3] && 0x00 == led_config_first.s3_led_setting[4]
&& 0x00 == led_config_first.s5_led_setting[0] && 0x00 == led_config_first.s5_led_setting[1] && 0x00 == led_config_first.s5_led_setting[2] && 0x00 == led_config_first.s5_led_setting[3] && 0x00 == led_config_first.s5_led_setting[4]
&& 0x00 == led_config_first.disable_led_setting[0] && 0x00 == led_config_first.disable_led_setting[1] && 0x00 == led_config_first.disable_led_setting[2] && 0x00 == led_config_first.disable_led_setting[3] && 0x00 == led_config_first.disable_led_setting[4]
) {
bfirstflag = true;
}
if (0x00 == led_config_second.s0_led_setting[0] && 0x00 == led_config_second.s0_led_setting[1] && 0x00 == led_config_second.s0_led_setting[2] && 0x00 == led_config_second.s0_led_setting[3] && 0x00 == led_config_second.s0_led_setting[4]
&& 0x00 == led_config_second.s3_led_setting[0] && 0x00 == led_config_second.s3_led_setting[1] && 0x00 == led_config_second.s3_led_setting[2] && 0x00 == led_config_second.s3_led_setting[3] && 0x00 == led_config_second.s3_led_setting[4]
&& 0x00 == led_config_second.s5_led_setting[0] && 0x00 == led_config_second.s5_led_setting[1] && 0x00 == led_config_second.s5_led_setting[2] && 0x00 == led_config_second.s5_led_setting[3] && 0x00 == led_config_second.s5_led_setting[4]
&& 0x00 == led_config_second.disable_led_setting[0] && 0x00 == led_config_second.disable_led_setting[1] && 0x00 == led_config_second.disable_led_setting[2] && 0x00 == led_config_second.disable_led_setting[3] && 0x00 == led_config_second.disable_led_setting[4]
) {
bsecondflag = true;
}
if (!bfirstflag && bsecondflag) {
//read first area
memcpy(&pdata->led, &led_config_first, sizeof(struct led_setting));
bsucceed = true;
}
else if (!bfirstflag && !bsecondflag) {
//read second area
memcpy(&pdata->led, &led_config_second, sizeof(struct led_setting));
bsucceed = true;
}
#ifndef LINUX
DbgPrintF(MP_TRACE, "%s s0 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x", __FUNCTION__, pdata->led.s0_led_setting[0], pdata->led.s0_led_setting[1], pdata->led.s0_led_setting[2], pdata->led.s0_led_setting[3], pdata->led.s0_led_setting[4]);
DbgPrintF(MP_TRACE, "%s s3 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x", __FUNCTION__, pdata->led.s3_led_setting[0], pdata->led.s3_led_setting[1], pdata->led.s3_led_setting[2], pdata->led.s3_led_setting[3], pdata->led.s3_led_setting[4]);
DbgPrintF(MP_TRACE, "%s s5 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x", __FUNCTION__, pdata->led.s5_led_setting[0], pdata->led.s5_led_setting[1], pdata->led.s5_led_setting[2], pdata->led.s5_led_setting[3], pdata->led.s5_led_setting[4]);
DbgPrintF(MP_TRACE, "%s disable 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x", __FUNCTION__, pdata->led.disable_led_setting[0], pdata->led.disable_led_setting[1], pdata->led.disable_led_setting[2], pdata->led.disable_led_setting[3], pdata->led.disable_led_setting[4]);
#endif
return bsucceed;
}
#endif
@@ -0,0 +1,42 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/* Copyright (c) 2021 Motor-comm Corporation. All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#ifndef __FXGMAC_EFUSE_H__
#define __FXGMAC_EFUSE_H__
bool fxgmac_read_patch_from_efuse_per_index(struct fxgmac_pdata* pdata, u8 index, u32 __far* offset, u32 __far* value); /* read patch per 0-based index. */
bool fxgmac_read_mac_subsys_from_efuse(struct fxgmac_pdata* pdata, u8* mac_addr, u32* subsys, u32* revid);
bool fxgmac_efuse_read_data(struct fxgmac_pdata* pdata, u32 offset, u32 __far* value);
#ifndef COMMENT_UNUSED_CODE_TO_REDUCE_SIZE
bool fxgmac_read_patch_from_efuse(struct fxgmac_pdata* pdata, u32 offset, u32* value); /* read patch per register offset. */
bool fxgmac_write_patch_to_efuse(struct fxgmac_pdata* pdata, u32 offset, u32 value);
bool fxgmac_write_patch_to_efuse_per_index(struct fxgmac_pdata* pdata, u8 index, u32 offset, u32 value);
bool fxgmac_write_mac_subsys_to_efuse(struct fxgmac_pdata* pdata, u8* mac_addr, u32* subsys, u32* revid);
bool fxgmac_write_mac_addr_to_efuse(struct fxgmac_pdata* pdata, u8* mac_addr);
bool fxgmac_read_subsys_from_efuse(struct fxgmac_pdata* pdata, u32* subsys, u32* revid);
bool fxgmac_write_subsys_to_efuse(struct fxgmac_pdata* pdata, u32* subsys, u32* revid);
bool fxgmac_efuse_load(struct fxgmac_pdata* pdata);
bool fxgmac_efuse_write_data(struct fxgmac_pdata* pdata, u32 offset, u32 value);
bool fxgmac_efuse_write_oob(struct fxgmac_pdata* pdata);
bool fxgmac_efuse_write_led(struct fxgmac_pdata* pdata, u32 value);
bool fxgmac_read_led_setting_from_efuse(struct fxgmac_pdata* pdata);
bool fxgmac_write_led_setting_to_efuse(struct fxgmac_pdata* pdata);
#endif
#endif // __FXGMAC_EFUSE_H__
+179
View File
@@ -0,0 +1,179 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/* Copyright (c) 2021 Motor-comm Corporation. All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#ifndef __FXGMAC_ERROR_H__
#define __FXGMAC_ERROR_H__
#define EOK 0
/* ref linux https://elixir.bootlin.com/linux/v5.18-rc7/source/include/uapi/asm-generic/errno.h#L93 */
#define EPERM 1 /* Operation not permitted */
#define ENOENT 2 /* No such file or directory */
#define ESRCH 3 /* No such process */
#define EINTR 4 /* Interrupted system call */
#define EIO 5 /* I/O error */
#define ENXIO 6 /* No such device or address */
#define E2BIG 7 /* Argument list too long */
#define ENOEXEC 8 /* Exec format error */
#define EBADF 9 /* Bad file number */
#define ECHILD 10 /* No child processes */
#define EAGAIN 11 /* Try again */
#define ENOMEM 12 /* Out of memory */
#define EACCES 13 /* Permission denied */
#define EFAULT 14 /* Bad address */
#define ENOTBLK 15 /* Block device required */
#define EBUSY 16 /* Device or resource busy */
#define EEXIST 17 /* File exists */
#define EXDEV 18 /* Cross-device link */
#define ENODEV 19 /* No such device */
#define ENOTDIR 20 /* Not a directory */
#define EISDIR 21 /* Is a directory */
#define EINVAL 22 /* Invalid argument */
#define ENFILE 23 /* File table overflow */
#define EMFILE 24 /* Too many open files */
#define ENOTTY 25 /* Not a typewriter */
#define ETXTBSY 26 /* Text file busy */
#define EFBIG 27 /* File too large */
#define ENOSPC 28 /* No space left on device */
#define ESPIPE 29 /* Illegal seek */
#define EROFS 30 /* Read-only file system */
#define EMLINK 31 /* Too many links */
#define EPIPE 32 /* Broken pipe */
#define EDOM 33 /* Math argument out of domain of func */
#define ERANGE 34 /* Math result not representable */
#define EDEADLK 35 /* Resource deadlock would occur */
#define ENAMETOOLONG 36 /* File name too long */
#define ENOLCK 37 /* No record locks available */
/*
* This error code is special: arch syscall entry code will return
* -ENOSYS if users try to call a syscall that doesn't exist. To keep
* failures of syscalls that really do exist distinguishable from
* failures due to attempts to use a nonexistent syscall, syscall
* implementations should refrain from returning -ENOSYS.
*/
#define ENOSYS 38 /* Invalid system call number */
#define ENOTEMPTY 39 /* Directory not empty */
#define ELOOP 40 /* Too many symbolic links encountered */
#define EWOULDBLOCK EAGAIN /* Operation would block */
#define ENOMSG 42 /* No message of desired type */
#define EIDRM 43 /* Identifier removed */
#define ECHRNG 44 /* Channel number out of range */
#define EL2NSYNC 45 /* Level 2 not synchronized */
#define EL3HLT 46 /* Level 3 halted */
#define EL3RST 47 /* Level 3 reset */
#define ELNRNG 48 /* Link number out of range */
#define EUNATCH 49 /* Protocol driver not attached */
#define ENOCSI 50 /* No CSI structure available */
#define EL2HLT 51 /* Level 2 halted */
#define EBADE 52 /* Invalid exchange */
#define EBADR 53 /* Invalid request descriptor */
#define EXFULL 54 /* Exchange full */
#define ENOANO 55 /* No anode */
#define EBADRQC 56 /* Invalid request code */
#define EBADSLT 57 /* Invalid slot */
#define EDEADLOCK EDEADLK
#define EBFONT 59 /* Bad font file format */
#define ENOSTR 60 /* Device not a stream */
#define ENODATA 61 /* No data available */
#define ETIME 62 /* Timer expired */
#define ENOSR 63 /* Out of streams resources */
#define ENONET 64 /* Machine is not on the network */
#define ENOPKG 65 /* Package not installed */
#define EREMOTE 66 /* Object is remote */
#define ENOLINK 67 /* Link has been severed */
#define EADV 68 /* Advertise error */
#define ESRMNT 69 /* Srmount error */
#define ECOMM 70 /* Communication error on send */
#define EPROTO 71 /* Protocol error */
#define EMULTIHOP 72 /* Multihop attempted */
#define EDOTDOT 73 /* RFS specific error */
#define EBADMSG 74 /* Not a data message */
#define EOVERFLOW 75 /* Value too large for defined data type */
#define ENOTUNIQ 76 /* Name not unique on network */
#define EBADFD 77 /* File descriptor in bad state */
#define EREMCHG 78 /* Remote address changed */
#define ELIBACC 79 /* Can not access a needed shared library */
#define ELIBBAD 80 /* Accessing a corrupted shared library */
#define ELIBSCN 81 /* .lib section in a.out corrupted */
#define ELIBMAX 82 /* Attempting to link in too many shared libraries */
#define ELIBEXEC 83 /* Cannot exec a shared library directly */
#define EILSEQ 84 /* Illegal byte sequence */
#define ERESTART 85 /* Interrupted system call should be restarted */
#define ESTRPIPE 86 /* Streams pipe error */
#define EUSERS 87 /* Too many users */
#define ENOTSOCK 88 /* Socket operation on non-socket */
#define EDESTADDRREQ 89 /* Destination address required */
#define EMSGSIZE 90 /* Message too long */
#define EPROTOTYPE 91 /* Protocol wrong type for socket */
#define ENOPROTOOPT 92 /* Protocol not available */
#define EPROTONOSUPPORT 93 /* Protocol not supported */
#define ESOCKTNOSUPPORT 94 /* Socket type not supported */
#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
#define EPFNOSUPPORT 96 /* Protocol family not supported */
#define EAFNOSUPPORT 97 /* Address family not supported by protocol */
#define EADDRINUSE 98 /* Address already in use */
#define EADDRNOTAVAIL 99 /* Cannot assign requested address */
#define ENETDOWN 100 /* Network is down */
#define ENETUNREACH 101 /* Network is unreachable */
#define ENETRESET 102 /* Network dropped connection because of reset */
#define ECONNABORTED 103 /* Software caused connection abort */
#define ECONNRESET 104 /* Connection reset by peer */
#define ENOBUFS 105 /* No buffer space available */
#define EISCONN 106 /* Transport endpoint is already connected */
#define ENOTCONN 107 /* Transport endpoint is not connected */
#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */
#define ETOOMANYREFS 109 /* Too many references: cannot splice */
#define ETIMEDOUT 110 /* Connection timed out */
#define ECONNREFUSED 111 /* Connection refused */
#define EHOSTDOWN 112 /* Host is down */
#define EHOSTUNREACH 113 /* No route to host */
#define EALREADY 114 /* Operation already in progress */
#define EINPROGRESS 115 /* Operation now in progress */
#define ESTALE 116 /* Stale file handle */
#define EUCLEAN 117 /* Structure needs cleaning */
#define ENOTNAM 118 /* Not a XENIX named type file */
#define ENAVAIL 119 /* No XENIX semaphores available */
#define EISNAM 120 /* Is a named type file */
#define EREMOTEIO 121 /* Remote I/O error */
#define EDQUOT 122 /* Quota exceeded */
#define ENOMEDIUM 123 /* No medium found */
#define EMEDIUMTYPE 124 /* Wrong medium type */
#define ECANCELED 125 /* Operation Canceled */
#define ENOKEY 126 /* Required key not available */
#define EKEYEXPIRED 127 /* Key has expired */
#define EKEYREVOKED 128 /* Key has been revoked */
#define EKEYREJECTED 129 /* Key was rejected by service */
/* for robust mutexes */
#define EOWNERDEAD 130 /* Owner died */
#define ENOTRECOVERABLE 131 /* State not recoverable */
#define ERFKILL 132 /* Operation not possible due to RF-kill */
#define EHWPOISON 133 /* Memory page has hardware error */
#endif // __FXGMAC_ERROR_H__
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,563 @@
// SPDX-License-Identifier: GPL-2.0+
/* Copyright (c) 2021 Motor-comm Corporation. All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#include "fuxi-gmac.h"
#include "fuxi-gmac-reg.h"
static void fxgmac_dbg_tx_pkt(struct fxgmac_pdata *pdata, u8 *pcmd_data)
{
unsigned int pktLen = 0;
struct sk_buff *skb;
pfxgmac_test_packet pPkt;
u8 * pTx_data = NULL;
u8 * pSkb_data = NULL;
u32 offload_len = 0;
u8 ipHeadLen, tcpHeadLen, headTotalLen;
static u32 lastGsoSize = 806;//initial default value
//int i = 0;
/* get fxgmac_test_packet */
pPkt = (pfxgmac_test_packet)(pcmd_data + sizeof(struct ext_ioctl_data));
pktLen = pPkt->length;
/* get pkt data */
pTx_data = (u8 *)pPkt + sizeof(fxgmac_test_packet);
/* alloc sk_buff */
skb = alloc_skb(pktLen, GFP_ATOMIC);
if (!skb){
DPRINTK("alloc skb fail\n");
return;
}
/* copy data to skb */
pSkb_data = skb_put(skb, pktLen);
memset(pSkb_data, 0, pktLen);
memcpy(pSkb_data, pTx_data, pktLen);
/* set skb parameters */
skb->dev = pdata->netdev;
skb->pkt_type = PACKET_OUTGOING;
skb->protocol = ntohs(ETH_P_IP);
skb->no_fcs = 1;
skb->ip_summed = CHECKSUM_PARTIAL;
if(skb->len > 1514){
/* TSO packet */
/* set tso test flag */
pdata->expansion.fxgmac_test_tso_flag = true;
/* get protocol head length */
ipHeadLen = (pSkb_data[TEST_MAC_HEAD] & 0xF) * 4;
tcpHeadLen = (pSkb_data[TEST_MAC_HEAD + ipHeadLen + TEST_TCP_HEAD_LEN_OFFSET] >> 4 & 0xF) * 4;
headTotalLen = TEST_MAC_HEAD + ipHeadLen + tcpHeadLen;
offload_len = (pSkb_data[TEST_TCP_OFFLOAD_LEN_OFFSET] << 8 |
pSkb_data[TEST_TCP_OFFLOAD_LEN_OFFSET + 1]) & 0xFFFF;
/* set tso skb parameters */
//skb->ip_summed = CHECKSUM_PARTIAL;
skb->transport_header = ipHeadLen + TEST_MAC_HEAD;
skb->network_header = TEST_MAC_HEAD;
skb->inner_network_header = TEST_MAC_HEAD;
skb->mac_len = TEST_MAC_HEAD;
/* set skb_shinfo parameters */
if(tcpHeadLen > TEST_TCP_FIX_HEAD_LEN){
skb_shinfo(skb)->gso_size = (pSkb_data[TEST_TCP_MSS_OFFSET] << 8 |
pSkb_data[TEST_TCP_MSS_OFFSET + 1]) & 0xFFFF;
}else{
skb_shinfo(skb)->gso_size = 0;
}
if(skb_shinfo(skb)->gso_size != 0){
lastGsoSize = skb_shinfo(skb)->gso_size;
}else{
skb_shinfo(skb)->gso_size = lastGsoSize;
}
//DPRINTK("offload_len is %d, skb_shinfo(skb)->gso_size is %d", offload_len, skb_shinfo(skb)->gso_size);
/* get segment size */
if(offload_len % skb_shinfo(skb)->gso_size == 0){
skb_shinfo(skb)->gso_segs = offload_len / skb_shinfo(skb)->gso_size;
pdata->expansion.fxgmac_test_last_tso_len = skb_shinfo(skb)->gso_size + headTotalLen;
}else{
skb_shinfo(skb)->gso_segs = offload_len / skb_shinfo(skb)->gso_size + 1;
pdata->expansion.fxgmac_test_last_tso_len = offload_len % skb_shinfo(skb)->gso_size + headTotalLen;
}
pdata->expansion.fxgmac_test_tso_seg_num = skb_shinfo(skb)->gso_segs;
skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4 ;
skb_shinfo(skb)->frag_list = NULL;
skb->csum_start = skb_headroom(skb) + TEST_MAC_HEAD + ipHeadLen;
skb->csum_offset = skb->len - TEST_MAC_HEAD - ipHeadLen;
pdata->expansion.fxgmac_test_packet_len = skb_shinfo(skb)->gso_size + headTotalLen;
}else {
/* set non-TSO packet parameters */
pdata->expansion.fxgmac_test_packet_len = skb->len;
}
/* send data */
if(dev_queue_xmit(skb) != NET_XMIT_SUCCESS){
DPRINTK("xmit data fail \n");
}
}
static void fxgmac_dbg_rx_pkt(struct fxgmac_pdata *pdata, u8 *pcmd_data)
{
unsigned int totalLen = 0;
struct sk_buff *rx_skb;
struct ext_ioctl_data *pcmd;
fxgmac_test_packet pkt;
void* addr = 0;
u8 *rx_data = (u8*)kzalloc(FXGMAC_MAX_DBG_RX_DATA, GFP_KERNEL);
if (!rx_data)
return;
//int i;
/* initial dest data region */
pcmd = (struct ext_ioctl_data *)pcmd_data;
addr = pcmd->cmd_buf.buf;
while(pdata->expansion.fxgmac_test_skb_arr_in_index != pdata->expansion.fxgmac_test_skb_arr_out_index){
/* get received skb data */
rx_skb = pdata->expansion.fxgmac_test_skb_array[pdata->expansion.fxgmac_test_skb_arr_out_index];
if(rx_skb->len + sizeof(fxgmac_test_packet) + totalLen < 64000){
pkt.length = rx_skb->len;
pkt.type = 0x80;
pkt.buf[0].offset = totalLen + sizeof(fxgmac_test_packet);
pkt.buf[0].length = rx_skb->len;
/* get data from skb */
//DPRINTK("FXG:rx_skb->len=%d", rx_skb->len);
memcpy(rx_data, rx_skb->data, rx_skb->len);
/* update next pointer */
if((pdata->expansion.fxgmac_test_skb_arr_out_index + 1) % FXGMAC_MAX_DBG_TEST_PKT == pdata->expansion.fxgmac_test_skb_arr_in_index)
{
pkt.next = NULL;
}
else
{
pkt.next = (pfxgmac_test_packet)(addr + totalLen + sizeof(fxgmac_test_packet) + pkt.length);
}
/* copy data to user space */
if(copy_to_user((void *)(addr + totalLen), (void*)(&pkt), sizeof(fxgmac_test_packet)))
{
DPRINTK("cppy pkt data to user fail...");
}
//FXGMAC_PR("FXG:rx_skb->len=%d", rx_skb->len);
if(copy_to_user((void *)(addr + totalLen + sizeof(fxgmac_test_packet)), (void*)rx_data, rx_skb->len))
{
DPRINTK("cppy data to user fail...");
}
/* update total length */
totalLen += (sizeof(fxgmac_test_packet) + rx_skb->len);
/* free skb */
kfree_skb(rx_skb);
pdata->expansion.fxgmac_test_skb_array[pdata->expansion.fxgmac_test_skb_arr_out_index] = NULL;
/* update gCurSkbOutIndex */
pdata->expansion.fxgmac_test_skb_arr_out_index = (pdata->expansion.fxgmac_test_skb_arr_out_index + 1) % FXGMAC_MAX_DBG_TEST_PKT;
}else{
DPRINTK("receive data more receive buffer... \n");
break;
}
}
if (rx_data)
kfree(rx_data);
#if 0
pPkt = (pfxgmac_test_packet)buf;
DPRINTK("FXG: pPkt->Length is %d", pPkt->length);
DPRINTK("FXG: pPkt->Length is %d", pPkt->length);
DPRINTK("pPkt: %p, buf is %lx",pPkt, pcmd->cmd_buf.buf);
for(i = 0; i < 30; i++){
DPRINTK("%x",*(((u8*)pPkt + sizeof(fxgmac_test_packet)) + i));
}
#endif
}
// Based on the current application scenario,we only use CMD_DATA for data.
// if you use other struct, you should recalculate in_total_size
long fxgmac_netdev_ops_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
bool ret = true;
int regval = 0;
struct fxgmac_pdata *pdata = file->private_data;
struct fxgmac_hw_ops *hw_ops = &pdata->hw_ops;
FXGMAC_PDATA_OF_PLATFORM *ex = &pdata->expansion;
CMD_DATA ex_data;
struct ext_ioctl_data pcmd;
u8* data = NULL;
u8* buf = NULL;
int in_total_size, in_data_size, out_total_size;
int ioctl_cmd_size = sizeof(struct ext_ioctl_data);
u8 mac[ETH_ALEN] = {0};
struct sk_buff *tmpskb;
if (!arg) {
DPRINTK("[%s] command arg is %lx !\n", __func__, arg);
goto err;
}
/* check device type */
if (_IOC_TYPE(cmd) != IOC_MAGIC) {
DPRINTK("[%s] command type [%c] error!\n", __func__, _IOC_TYPE(cmd));
goto err;
}
/* check command number*/
if (_IOC_NR(cmd) > IOC_MAXNR) {
DPRINTK("[%s] command number [%d] exceeded!\n", __func__, _IOC_NR(cmd));
goto err;
}
//buf = (u8*)kzalloc(FXGMAC_MAX_DBG_BUF_LEN, GFP_KERNEL);
if(copy_from_user(&pcmd, (void*)arg, ioctl_cmd_size)) {
DPRINTK("copy data from user fail... \n");
goto err;
}
in_total_size = pcmd.cmd_buf.size_in;
in_data_size = in_total_size - ioctl_cmd_size;
out_total_size = pcmd.cmd_buf.size_out;
buf = (u8*)kzalloc(in_total_size, GFP_KERNEL);
if (!buf)
return -ENOMEM;
if(copy_from_user(buf, (void*)arg, in_total_size)) {
DPRINTK("copy data from user fail... \n");
goto err;
}
data = buf + ioctl_cmd_size;
if(arg != 0) {
switch(pcmd.cmd_type) {
/* ioctl diag begin */
case FXGMAC_DFS_IOCTL_DIAG_BEGIN:
DPRINTK("Debugfs received diag begin command.\n");
#ifdef FXGMAC_EPHY_LOOPBACK_DETECT_ENABLED
pdata->expansion.lb_test_flag = 1;
#endif
if (netif_running(pdata->netdev)){
fxgmac_restart_dev(pdata);
}
/* release last loopback test abnormal exit buffer */
while(ex->fxgmac_test_skb_arr_in_index !=
ex->fxgmac_test_skb_arr_out_index)
{
tmpskb = ex->fxgmac_test_skb_array[ex->fxgmac_test_skb_arr_out_index];
if(tmpskb)
{
kfree_skb(tmpskb);
ex->fxgmac_test_skb_array[ex->fxgmac_test_skb_arr_out_index] = NULL;
}
ex->fxgmac_test_skb_arr_out_index = (ex->fxgmac_test_skb_arr_out_index + 1) % FXGMAC_MAX_DBG_TEST_PKT;
}
/* init loopback test parameters */
ex->fxgmac_test_skb_arr_in_index = 0;
ex->fxgmac_test_skb_arr_out_index = 0;
ex->fxgmac_test_tso_flag = false;
ex->fxgmac_test_tso_seg_num = 0;
ex->fxgmac_test_last_tso_len = 0;
ex->fxgmac_test_packet_len = 0;
break;
/* ioctl diag end */
case FXGMAC_DFS_IOCTL_DIAG_END:
DPRINTK("Debugfs received diag end command.\n");
if (netif_running(pdata->netdev)){
fxgmac_restart_dev(pdata);
}
#ifdef FXGMAC_EPHY_LOOPBACK_DETECT_ENABLED
pdata->expansion.lb_test_flag = 0;
#endif
break;
/* ioctl diag tx pkt */
case FXGMAC_DFS_IOCTL_DIAG_TX_PKT:
fxgmac_dbg_tx_pkt(pdata, buf);
break;
/* ioctl diag rx pkt */
case FXGMAC_DFS_IOCTL_DIAG_RX_PKT:
fxgmac_dbg_rx_pkt(pdata, buf);
break;
/* ioctl device reset */
case FXGMAC_DFS_IOCTL_DEVICE_RESET:
DPRINTK("Debugfs received device reset command.\n");
if (netif_running(pdata->netdev)){
fxgmac_restart_dev(pdata);
}
break;
case FXGMAC_EFUSE_LED_TEST:
DPRINTK("Debugfs received device led test command.\n");
memcpy(&pdata->led, data, sizeof(struct led_setting));
fxgmac_restart_dev(pdata);
break;
case FXGMAC_EFUSE_UPDATE_LED_CFG:
DPRINTK("Debugfs received device led update command.\n");
memcpy(&pdata->ledconfig, data, sizeof(struct led_setting));
ret = hw_ops->write_led_config(pdata);
hw_ops->read_led_config(pdata);
hw_ops->led_under_active(pdata);
break;
case FXGMAC_EFUSE_WRITE_LED:
memcpy(&ex_data, data, sizeof(CMD_DATA));
DPRINTK("FXGMAC_EFUSE_WRITE_LED, val = 0x%x\n", ex_data.val0);
ret = hw_ops->write_led(pdata, ex_data.val0);
break;
case FXGMAC_EFUSE_WRITE_OOB:
DPRINTK("FXGMAC_EFUSE_WRITE_OOB.\n");
ret = hw_ops->write_oob(pdata);
break;
case FXGMAC_EFUSE_READ_REGIONABC:
memcpy(&ex_data, data, sizeof(CMD_DATA));
ret = hw_ops->read_efuse_data(pdata, ex_data.val0, &ex_data.val1);
/*
* DPRINTK("FXGMAC_EFUSE_READ_REGIONABC, address = 0x%x, val = 0x%x\n",
* ex_data.val0,
* ex_data.val1);
*/
if (ret) {
memcpy(data, &ex_data, sizeof(CMD_DATA));
out_total_size = ioctl_cmd_size + sizeof(CMD_DATA);
if (copy_to_user((void*)arg, (void*)buf, out_total_size))
goto err;
}
break;
case FXGMAC_EFUSE_WRITE_PATCH_REG:
memcpy(&ex_data, data, sizeof(CMD_DATA));
/*
* DPRINTK("FXGMAC_EFUSE_WRITE_PATCH_REG, address = 0x%x, val = 0x%x\n",
* ex_data.val0,
* ex_data.val1);
*/
ret = hw_ops->write_patch_to_efuse(pdata, ex_data.val0, ex_data.val1);
break;
case FXGMAC_EFUSE_READ_PATCH_REG:
memcpy(&ex_data, data, sizeof(CMD_DATA));
ret = hw_ops->read_patch_from_efuse(pdata, ex_data.val0, &ex_data.val1);
/*
* DPRINTK("FXGMAC_EFUSE_READ_PATCH_REG, address = 0x%x, val = 0x%x\n",
* ex_data.val0, ex_data.val1);
*/
if (ret) {
memcpy(data, &ex_data, sizeof(CMD_DATA));
out_total_size = ioctl_cmd_size + sizeof(CMD_DATA);
if (copy_to_user((void*)arg, (void*)buf, out_total_size))
goto err;
}
break;
case FXGMAC_EFUSE_WRITE_PATCH_PER_INDEX:
memcpy(&ex_data, data, sizeof(CMD_DATA));
ret = hw_ops->write_patch_to_efuse_per_index(pdata, ex_data.val0,
ex_data.val1,
ex_data.val2);
/*
* DPRINTK("FXGMAC_EFUSE_WRITE_PATCH_PER_INDEX, index = %d, address = 0x%x, val = 0x%x\n",
* ex_data.val0, ex_data.val1, ex_data.val2);
*/
break;
case FXGMAC_EFUSE_READ_PATCH_PER_INDEX:
memcpy(&ex_data, data, sizeof(CMD_DATA));
ret = hw_ops->read_patch_from_efuse_per_index(pdata,ex_data.val0,
&ex_data.val1,
&ex_data.val2);
/*
* DPRINTK("FXGMAC_EFUSE_READ_PATCH_PER_INDEX, address = 0x%x, val = 0x%x\n",
* ex_data.val1, ex_data.val2);
*/
if (ret) {
memcpy(data, &ex_data, sizeof(CMD_DATA));
out_total_size = ioctl_cmd_size + sizeof(CMD_DATA);
if (copy_to_user((void*)arg, (void*)buf, out_total_size))
goto err;
}
break;
case FXGMAC_EFUSE_LOAD:
DPRINTK("FXGMAC_EFUSE_LOAD.\n");
ret = hw_ops->efuse_load(pdata);
break;
case FXGMAC_GET_MAC_DATA:
ret = hw_ops->read_mac_subsys_from_efuse(pdata, mac, NULL, NULL);
if (ret) {
memcpy(data, mac, ETH_ALEN);
out_total_size = ioctl_cmd_size + ETH_ALEN;
if (copy_to_user((void*)arg, (void*)buf, out_total_size))
goto err;
}
break;
case FXGMAC_SET_MAC_DATA:
if (in_data_size != ETH_ALEN)
goto err;
memcpy(mac, data, ETH_ALEN);
ret = hw_ops->write_mac_subsys_to_efuse(pdata, mac, NULL, NULL);
if (ret) {
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,17,0))
eth_hw_addr_set(pdata->netdev, mac);
#else
memcpy(pdata->netdev->dev_addr, mac, ETH_ALEN);
#endif
memcpy(pdata->mac_addr, mac, ETH_ALEN);
hw_ops->set_mac_address(pdata, mac);
hw_ops->set_mac_hash(pdata);
}
break;
case FXGMAC_GET_SUBSYS_ID:
memcpy(&ex_data, data, sizeof(CMD_DATA));
ret = hw_ops->read_mac_subsys_from_efuse(pdata,
NULL,
&ex_data.val0,
NULL);
if (ret) {
ex_data.val1 = 0xFFFF; // invalid value
memcpy(data, &ex_data, sizeof(CMD_DATA));
out_total_size = ioctl_cmd_size + sizeof(CMD_DATA);
if (copy_to_user((void*)arg, (void*)buf, out_total_size))
goto err;
}
break;
case FXGMAC_SET_SUBSYS_ID:
memcpy(&ex_data, data, sizeof(CMD_DATA));
ret = hw_ops->write_mac_subsys_to_efuse(pdata,
NULL,
&ex_data.val0,
NULL);
break;
case FXGMAC_GET_REG:
memcpy(&ex_data, data, sizeof(CMD_DATA));
ex_data.val1 = hw_ops->get_gmac_register(pdata,
(u8*)(pdata->base_mem + ex_data.val0));
memcpy(data, &ex_data, sizeof(CMD_DATA));
out_total_size = ioctl_cmd_size + sizeof(CMD_DATA);
if (copy_to_user((void*)arg, (void*)buf, out_total_size))
goto err;
break;
case FXGMAC_SET_REG:
memcpy(&ex_data, data, sizeof(CMD_DATA));
regval = hw_ops->set_gmac_register(pdata,
(u8*)(pdata->base_mem + ex_data.val0),
ex_data.val1);
ret = (regval == 0 ? true : false);
break;
case FXGMAC_GET_PHY_REG:
memcpy(&ex_data, data, sizeof(CMD_DATA));
regval = hw_ops->read_ephy_reg(pdata, ex_data.val0, &ex_data.val1);
if (regval != -1) {
memcpy(data, &ex_data, sizeof(CMD_DATA));
out_total_size = ioctl_cmd_size + sizeof(CMD_DATA);
if (copy_to_user((void*)arg, (void*)buf, out_total_size))
goto err;
}
ret = (regval == -1 ? false : true);
break;
case FXGMAC_SET_PHY_REG:
memcpy(&ex_data, data, sizeof(CMD_DATA));
regval = hw_ops->write_ephy_reg(pdata, ex_data.val0, ex_data.val1);
ret = (regval == 0 ? true : false);
break;
case FXGMAC_GET_PCIE_LOCATION:
ex_data.val0 = pdata->pdev->bus->number;
ex_data.val1 = PCI_SLOT(pdata->pdev->devfn);
ex_data.val2 = PCI_FUNC(pdata->pdev->devfn);
memcpy(data, &ex_data, sizeof(CMD_DATA));
out_total_size = ioctl_cmd_size + sizeof(CMD_DATA);
if (copy_to_user((void*)arg, (void*)buf, out_total_size))
goto err;
break;
case FXGMAC_GET_GSO_SIZE:
ex_data.val0 = pdata->netdev->gso_max_size;
memcpy(data, &ex_data, sizeof(CMD_DATA));
out_total_size = ioctl_cmd_size + sizeof(CMD_DATA);
if (copy_to_user((void*)arg, (void*)buf, out_total_size))
goto err;
break;
case FXGMAC_SET_GSO_SIZE:
memcpy(&ex_data, data, sizeof(CMD_DATA));
pdata->netdev->gso_max_size = ex_data.val0;
break;
case FXGMAC_SET_RX_MODERATION:
memcpy(&ex_data, data, sizeof(CMD_DATA));
regval = readreg(pdata->pAdapter, pdata->base_mem + INT_MOD);
regval = FXGMAC_SET_REG_BITS(regval, INT_MOD_RX_POS, INT_MOD_RX_LEN, ex_data.val0);
writereg(pdata->pAdapter, regval, pdata->base_mem + INT_MOD);
break;
case FXGMAC_SET_TX_MODERATION:
memcpy(&ex_data, data, sizeof(CMD_DATA));
regval = readreg(pdata->pAdapter, pdata->base_mem + INT_MOD);
regval = FXGMAC_SET_REG_BITS(regval, INT_MOD_TX_POS, INT_MOD_TX_LEN, ex_data.val0);
writereg(pdata->pAdapter, regval, pdata->base_mem + INT_MOD);
break;
case FXGMAC_GET_TXRX_MODERATION:
regval = readreg(pdata->pAdapter, pdata->base_mem + INT_MOD);
ex_data.val0 = FXGMAC_GET_REG_BITS(regval, INT_MOD_RX_POS, INT_MOD_RX_LEN);
ex_data.val1 = FXGMAC_GET_REG_BITS(regval, INT_MOD_TX_POS, INT_MOD_TX_LEN);
memcpy(data, &ex_data, sizeof(CMD_DATA));
out_total_size = ioctl_cmd_size + sizeof(CMD_DATA);
if (copy_to_user((void*)arg, (void*)buf, out_total_size))
goto err;
break;
default:
DPRINTK("Debugfs received invalid command: %x.\n", pcmd.cmd_type);
ret = false;
break;
}
}
if (buf)
kfree(buf);
return ret ? FXGMAC_SUCCESS : FXGMAC_FAIL;
err:
if (buf)
kfree(buf);
return FXGMAC_FAIL;
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,267 @@
// SPDX-License-Identifier: GPL-2.0+
/* Copyright (c) 2021 Motor-comm Corporation. All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#include "fuxi-gmac.h"
#include "fuxi-gmac-reg.h"
/* declarations */
static void fxgmac_shutdown(struct pci_dev *pdev);
static int fxgmac_probe(struct pci_dev *pcidev, const struct pci_device_id *id)
{
struct device *dev = &pcidev->dev;
struct fxgmac_resources res;
int i, ret;
ret = pcim_enable_device(pcidev);
if (ret) {
dev_err(dev, "ERROR: fxgmac_probe failed to enable device\n");
return ret;
}
for (i = 0; i <= PCI_STD_RESOURCE_END; i++) {
if (pci_resource_len(pcidev, i) == 0)
continue;
ret = pcim_iomap_regions(pcidev, BIT(i), FXGMAC_DRV_NAME);
if (ret)
{
dev_err(dev, "fxgmac_probe pcim_iomap_regions failed\n");
return ret;
}
/* DPRINTK(KERN_INFO "fxgmac_probe iomap_region i=%#x,ret=%#x\n",(int)i,(int)ret); */
break;
}
pci_set_master(pcidev);
memset(&res, 0, sizeof(res));
res.irq = pcidev->irq;
res.addr = pcim_iomap_table(pcidev)[i];
return fxgmac_drv_probe(&pcidev->dev, &res);
}
static void fxgmac_remove(struct pci_dev *pcidev)
{
struct net_device *netdev;
struct fxgmac_pdata *pdata;
(void)pdata;
netdev = dev_get_drvdata(&pcidev->dev);
pdata = netdev_priv(netdev);
fxgmac_drv_remove(&pcidev->dev);
#ifdef CONFIG_PCI_MSI
if(FXGMAC_GET_REG_BITS(pdata->expansion.int_flags, FXGMAC_FLAG_MSIX_POS,
FXGMAC_FLAG_MSIX_LEN)){
pci_disable_msix(pcidev);
kfree(pdata->expansion.msix_entries);
pdata->expansion.msix_entries = NULL;
}
#endif
DPRINTK("%s has been removed\n", netdev->name);
}
/* for Power management, 20210628 */
static int __fxgmac_shutdown(struct pci_dev *pdev, bool *enable_wake)
{
struct net_device *netdev = dev_get_drvdata(&pdev->dev);
struct fxgmac_pdata *pdata = netdev_priv(netdev);
u32 wufc = pdata->expansion.wol;
#ifdef CONFIG_PM
int retval = 0;
#endif
DPRINTK("fxpm,_fxgmac_shutdown, callin\n");
rtnl_lock();
/* for linux shutdown, we just treat it as power off wol can be ignored
* for suspend, we do need recovery by wol
*/
fxgmac_net_powerdown(pdata, (unsigned int)!!wufc);
netif_device_detach(netdev);
rtnl_unlock();
#ifdef CONFIG_PM
retval = pci_save_state(pdev);
if (retval) {
DPRINTK("fxpm,_fxgmac_shutdown, save pci state failed.\n");
return retval;
}
#endif
DPRINTK("fxpm,_fxgmac_shutdown, save pci state done.\n");
pci_wake_from_d3(pdev, !!wufc);
*enable_wake = !!wufc;
pci_disable_device(pdev);
DPRINTK("fxpm,_fxgmac_shutdown callout, enable wake=%d.\n", *enable_wake);
return 0;
}
static void fxgmac_shutdown(struct pci_dev *pdev)
{
struct net_device *netdev = dev_get_drvdata(&pdev->dev);
struct fxgmac_pdata *pdata = netdev_priv(netdev);
struct fxgmac_hw_ops *hw_ops = &pdata->hw_ops;
bool wake;
DPRINTK("fxpm, fxgmac_shutdown callin\n");
fxgmac_lock(pdata);
__fxgmac_shutdown(pdev, &wake);
hw_ops->led_under_shutdown(pdata);
if (system_state == SYSTEM_POWER_OFF) {
pci_wake_from_d3(pdev, wake);
pci_set_power_state(pdev, PCI_D3hot);
}
DPRINTK("fxpm, fxgmac_shutdown callout, system power off=%d\n", (system_state == SYSTEM_POWER_OFF)? 1 : 0);
fxgmac_unlock(pdata);
}
#ifdef CONFIG_PM
/* yzhang, 20210628 for PM */
static int fxgmac_suspend(struct pci_dev *pdev,
pm_message_t __always_unused state)
{
struct net_device *netdev = dev_get_drvdata(&pdev->dev);
struct fxgmac_pdata *pdata = netdev_priv(netdev);
struct fxgmac_hw_ops *hw_ops = &pdata->hw_ops;
int retval = 0;
bool wake;
DPRINTK("fxpm, fxgmac_suspend callin\n");
fxgmac_lock(pdata);
if (pdata->expansion.dev_state != FXGMAC_DEV_START)
goto unlock;
if (netif_running(netdev)) {
#ifdef FXGMAC_ASPM_ENABLED
fxgmac_cancel_aspm_config_work(pdata);
pdata->expansion.aspm_en = false;
pdata->expansion.aspm_work_active = false;
pdata->expansion.recover_from_aspm = false;
#endif
retval = __fxgmac_shutdown(pdev, &wake);
if (retval)
goto unlock;
} else {
wake = !!(pdata->expansion.wol);
}
hw_ops->led_under_sleep(pdata);
if (wake) {
pci_prepare_to_sleep(pdev);
} else {
pci_wake_from_d3(pdev, false);
pci_set_power_state(pdev, PCI_D3hot);
}
pdata->expansion.recover_phy_state = 1;
pdata->expansion.dev_state = FXGMAC_DEV_SUSPEND;
DPRINTK("fxpm, fxgmac_suspend callout to %s\n", wake ? "sleep" : "D3hot");
unlock:
fxgmac_unlock(pdata);
return retval;
}
static int fxgmac_resume(struct pci_dev *pdev)
{
struct net_device *netdev = dev_get_drvdata(&pdev->dev);
struct fxgmac_pdata *pdata = netdev_priv(netdev);
u32 err = 0;
DPRINTK("fxpm, fxgmac_resume callin\n");
fxgmac_lock(pdata);
if (pdata->expansion.dev_state != FXGMAC_DEV_SUSPEND)
goto unlock;
pdata->expansion.dev_state = FXGMAC_DEV_RESUME;
pci_set_power_state(pdev, PCI_D0);
pci_restore_state(pdev);
/*
* pci_restore_state clears dev->state_saved so call
* pci_save_state to restore it.
*/
pci_save_state(pdev);
err = pci_enable_device_mem(pdev);
if (err) {
dev_err(pdata->dev, "fxgmac_resume, failed to enable PCI device from suspend\n");
goto unlock;
}
smp_mb__before_atomic();
__clear_bit(FXGMAC_POWER_STATE_DOWN, &pdata->expansion.powerstate);
pci_set_master(pdev);
pci_wake_from_d3(pdev, false);
rtnl_lock();
err = 0;
if (!err && netif_running(netdev))
fxgmac_net_powerup(pdata);
if (!err)
netif_device_attach(netdev);
rtnl_unlock();
DPRINTK("fxpm, fxgmac_resume callout\n");
unlock:
fxgmac_unlock(pdata);
return err;
}
#endif
static const struct pci_device_id fxgmac_pci_tbl[] = {
{ PCI_DEVICE(0x1f0a, 0x6801) },
{ 0 }
};
MODULE_DEVICE_TABLE(pci, fxgmac_pci_tbl);
static struct pci_driver fxgmac_pci_driver = {
.name = FXGMAC_DRV_NAME,
.id_table = fxgmac_pci_tbl,
.probe = fxgmac_probe,
.remove = fxgmac_remove,
#ifdef CONFIG_PM
/* currently, we only use USE_LEGACY_PM_SUPPORT */
.suspend = fxgmac_suspend,
.resume = fxgmac_resume,
#endif
.shutdown = fxgmac_shutdown,
};
module_pci_driver(fxgmac_pci_driver);
MODULE_DESCRIPTION(FXGMAC_DRV_DESC);
MODULE_VERSION(FXGMAC_DRV_VERSION);
MODULE_AUTHOR("Motorcomm Electronic Tech. Co., Ltd.");
MODULE_LICENSE("GPL");
@@ -0,0 +1,373 @@
// SPDX-License-Identifier: GPL-2.0+
/* Copyright (c) 2021 Motor-comm Corporation. All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#include "fuxi-gmac.h"
#include "fuxi-gmac-reg.h"
/*
* When in forced mode, set the speed, duplex, and auto-negotiation of the PHY
* all at once to avoid the problems caused by individual settings
* on some machines
*/
int fxgmac_phy_force_mode(struct fxgmac_pdata *pdata)
{
struct fxgmac_hw_ops* hw_ops = &pdata->hw_ops;
u32 regval = 0;
unsigned int high_bit = 0, low_bit = 0;
int ret = 0;
switch (pdata->phy_speed)
{
case SPEED_1000:
high_bit = 1, low_bit = 0;
break;
case SPEED_100:
high_bit = 0, low_bit = 1;
break;
case SPEED_10:
high_bit = 0, low_bit = 0;
break;
default:
break;
}
hw_ops->read_ephy_reg(pdata, REG_MII_BMCR, &regval);
regval = FXGMAC_SET_REG_BITS(regval, PHY_CR_AUTOENG_POS, PHY_CR_AUTOENG_LEN, pdata->phy_autoeng);
regval = FXGMAC_SET_REG_BITS(regval, PHY_CR_SPEED_SEL_H_POS, PHY_CR_SPEED_SEL_H_LEN, high_bit);
regval = FXGMAC_SET_REG_BITS(regval, PHY_CR_SPEED_SEL_L_POS, PHY_CR_SPEED_SEL_L_LEN, low_bit);
regval = FXGMAC_SET_REG_BITS(regval, PHY_CR_DUPLEX_POS, PHY_CR_DUPLEX_LEN, pdata->phy_duplex);
regval = FXGMAC_SET_REG_BITS(regval, PHY_CR_RESET_POS, PHY_CR_RESET_LEN, 1);
ret = hw_ops->write_ephy_reg(pdata, REG_MII_BMCR, regval);
return ret;
}
int fxgmac_phy_force_speed(struct fxgmac_pdata *pdata, int speed)
{
struct fxgmac_hw_ops* hw_ops = &pdata->hw_ops;
u32 regval = 0;
unsigned int high_bit = 0, low_bit = 0;
int ret = 0;
switch (speed)
{
case SPEED_1000:
high_bit = 1, low_bit = 0;
break;
case SPEED_100:
high_bit = 0, low_bit = 1;
break;
case SPEED_10:
high_bit = 0, low_bit = 0;
break;
default:
break;
}
hw_ops->read_ephy_reg(pdata, REG_MII_BMCR, &regval);
regval = FXGMAC_SET_REG_BITS(regval, PHY_CR_SPEED_SEL_H_POS, PHY_CR_SPEED_SEL_H_LEN, high_bit);
regval = FXGMAC_SET_REG_BITS(regval, PHY_CR_SPEED_SEL_L_POS, PHY_CR_SPEED_SEL_L_LEN, low_bit);
ret = hw_ops->write_ephy_reg(pdata, REG_MII_BMCR, regval);
return ret;
}
int fxgmac_phy_force_duplex(struct fxgmac_pdata *pdata, int duplex)
{
struct fxgmac_hw_ops* hw_ops = &pdata->hw_ops;
u32 regval = 0;
int ret = 0;
hw_ops->read_ephy_reg(pdata, REG_MII_BMCR, &regval);
regval = FXGMAC_SET_REG_BITS(regval, PHY_CR_DUPLEX_POS, PHY_CR_DUPLEX_LEN, (duplex ? 1 : 0));
hw_ops->write_ephy_reg(pdata, REG_MII_BMCR, regval);
return ret;
}
int fxgmac_phy_force_autoneg(struct fxgmac_pdata *pdata, int autoneg)
{
struct fxgmac_hw_ops* hw_ops = &pdata->hw_ops;
u32 regval = 0;
int ret = 0;
hw_ops->read_ephy_reg(pdata, REG_MII_BMCR, &regval);
regval = FXGMAC_SET_REG_BITS(regval, PHY_CR_AUTOENG_POS, PHY_CR_AUTOENG_LEN, (autoneg? 1 : 0));
ret = hw_ops->write_ephy_reg(pdata, REG_MII_BMCR, regval);
return ret;
}
void fxgmac_set_phy_link_ksettings(struct fxgmac_pdata *pdata)
{
struct fxgmac_hw_ops *hw_ops = &pdata->hw_ops;
pdata->phy_speed = pdata->expansion.pre_phy_speed;
pdata->phy_duplex = pdata->expansion.pre_phy_duplex;
pdata->phy_autoeng = pdata->expansion.pre_phy_autoneg;
if (pdata->phy_autoeng || (!pdata->phy_autoeng && pdata->phy_speed == SPEED_1000))
hw_ops->phy_config(pdata);
else
fxgmac_phy_force_mode(pdata);
}
int fxgmac_ephy_soft_reset(struct fxgmac_pdata *pdata)
{
struct fxgmac_hw_ops *hw_ops = &pdata->hw_ops;
int ret;
volatile unsigned int val;
int busy = 15;
ret = hw_ops->read_ephy_reg(pdata, REG_MII_BMCR, (unsigned int *)&val);
if (0 > ret)
goto busy_exit;
ret = hw_ops->write_ephy_reg(pdata, REG_MII_BMCR, (val | 0x8000));
if (0 > ret)
goto busy_exit;
do {
ret = hw_ops->read_ephy_reg(pdata, REG_MII_BMCR, (unsigned int *)&val);
busy--;
//DPRINTK("fxgmac_ephy_soft_reset, check busy=%d.\n", busy);
}while((ret == 0) && (0 != (val & 0x8000)) && (busy));
if(0 == (val & 0x8000)) return 0;
DPRINTK("fxgmac_ephy_soft_reset, timeout, busy=%d.\n", busy);
return -EBUSY;
busy_exit:
DPRINTK("fxgmac_ephy_soft_reset exit due to ephy reg access fail.\n");
return ret;
}
/* this function used to double check the speed. for fiber, to correct there is no 10M */
static int fxgmac_ephy_adjust_status(u32 lport, int val, int is_utp, int* speed, int* duplex)
{
int speed_mode;
*speed = -1;
*duplex = (val & BIT(FXGMAC_EPHY_DUPLEX_BIT)) >> FXGMAC_EPHY_DUPLEX_BIT;
speed_mode = (val & FXGMAC_EPHY_SPEED_MODE) >> FXGMAC_EPHY_SPEED_MODE_BIT;
switch (speed_mode) {
case 0:
if (is_utp)
*speed = SPEED_10M;
break;
case 1:
*speed = SPEED_100M;
break;
case 2:
*speed = SPEED_1000M;
break;
case 3:
break;
default:
break;
}
return 0;
}
/*
* this function for polling to get status of ephy link.
* output:
* speed: SPEED_10M, SPEED_100M, SPEED_1000M or -1;
* duplex: 0 or 1, see reg 0x11, bit YT8614_DUPLEX_BIT.
* ret_link: 0 or 1, link down or up.
* media: only valid when ret_link=1, (YT8614_SMI_SEL_SDS_SGMII + 1) for fiber; (YT8614_SMI_SEL_PHY + 1) for utp. -1 for link down.
*/
int fxgmac_ephy_status_get(struct fxgmac_pdata *pdata, int* speed, int* duplex, int* ret_link, int *media)
{
struct fxgmac_hw_ops *hw_ops = &pdata->hw_ops;
int ret;
u16 reg;
volatile unsigned int val;
volatile int link;
int link_utp = 0, link_fiber = 0;
reg = REG_MII_SPEC_STATUS;
ret = hw_ops->read_ephy_reg(pdata, reg, (unsigned int *)&val);
if (0 > ret)
goto busy_exit;
link = val & (BIT(FXGMAC_EPHY_LINK_STATUS_BIT));
if (link) {
link_utp = 1;
fxgmac_ephy_adjust_status(0, val, 1, speed, duplex);
} else {
link_utp = 0;
}
if (link_utp || link_fiber) {
/* case of fiber of priority */
if(link_utp) *media = (FXGMAC_EPHY_SMI_SEL_PHY + 1);
if(link_fiber) *media = (FXGMAC_EPHY_SMI_SEL_SDS_SGMII + 1);
*ret_link = 1;
} else
{
*ret_link = 0;
*media = -1;
*speed= -1;
*duplex = -1;
}
return 0;
busy_exit:
DPRINTK("fxgmac_ephy_status_get exit due to ephy reg access fail.\n");
return ret;
}
/*
* fxgmac_phy_update_link - update the phy link status
* @adapter: pointer to the device adapter structure
*/
void fxgmac_phy_update_link(struct net_device *netdev)
{
struct fxgmac_pdata *pdata = netdev_priv(netdev);
struct fxgmac_hw_ops *hw_ops = &pdata->hw_ops;
u32 regval, cur_link, cur_speed;
regval = hw_ops->get_ephy_state(pdata);
// We should make sure that PHY is done with the reset
if (!(regval & BIT(MGMT_EPHY_CTRL_RESET_POS)) &&
(pdata->expansion.dev_state != FXGMAC_DEV_CLOSE)) {
pdata->expansion.phy_link = false;
return;
}
cur_speed = FXGMAC_GET_REG_BITS(regval,
MGMT_EPHY_CTRL_STA_SPEED_POS,
MGMT_EPHY_CTRL_STA_SPEED_LEN);
pdata->phy_speed = (cur_speed == 2) ? SPEED_1000 :
(cur_speed == 1) ? SPEED_100 : SPEED_10;
pdata->phy_duplex = FXGMAC_GET_REG_BITS(regval,
MGMT_EPHY_CTRL_STA_EPHY_DUPLEX_POS,
MGMT_EPHY_CTRL_STA_EPHY_DUPLEX_LEN);
cur_link = FXGMAC_GET_REG_BITS(regval,
MGMT_EPHY_CTRL_STA_EPHY_LINKUP_POS,
MGMT_EPHY_CTRL_STA_EPHY_LINKUP_LEN);
if(pdata->expansion.phy_link != cur_link) {
hw_ops->read_ephy_reg(pdata, REG_MII_INT_STATUS, NULL);
hw_ops->read_ephy_reg(pdata, REG_MII_INT_STATUS, NULL);
if (cur_link) {
#ifdef FXGMAC_ASPM_ENABLED
if (fxgmac_aspm_action_linkup(pdata))
return;
#endif
hw_ops->config_mac_speed(pdata);
hw_ops->enable_rx(pdata);
hw_ops->enable_tx(pdata);
hw_ops->read_ephy_reg(pdata, REG_MII_LPA, &regval);
if (FXGMAC_GET_REG_BITS(regval, PHY_MII_LINK_PARNTNER_10FULL_POS, PHY_MII_LINK_PARNTNER_10FULL_LEN)
|| FXGMAC_GET_REG_BITS(regval, PHY_MII_LINK_PARNTNER_10HALF_POS, PHY_MII_LINK_PARNTNER_10HALF_LEN))
{
pdata->support_10m_link = true;
}
pdata->expansion.pre_phy_speed = pdata->phy_speed;
pdata->expansion.pre_phy_duplex = pdata->phy_duplex;
pdata->expansion.pre_phy_autoneg = pdata->phy_autoeng;
netif_carrier_on(pdata->netdev);
if (netif_running(pdata->netdev))
{
netif_tx_wake_all_queues(pdata->netdev);
dev_info(pdata->dev, "%s now is link up, mac_speed=%d.\n",
netdev_name(pdata->netdev),
pdata->phy_speed);
}
}else {
netif_carrier_off(pdata->netdev);
netif_tx_stop_all_queues(pdata->netdev);
pdata->phy_speed = SPEED_UNKNOWN;
pdata->phy_duplex = DUPLEX_UNKNOWN;
pdata->support_10m_link = false;
hw_ops->disable_rx(pdata);
hw_ops->disable_tx(pdata);
#ifdef FXGMAC_EPHY_LOOPBACK_DETECT_ENABLED
if (pdata->expansion.lb_cable_flag) {
hw_ops->clean_cable_loopback(pdata);
pdata->expansion.lb_cable_flag = 0;
}
#endif
#ifdef FXGMAC_ASPM_ENABLED
fxgmac_schedule_aspm_config_work(pdata);
#endif
dev_info(pdata->dev, "%s now is link down\n", netdev_name(pdata->netdev));
}
pdata->expansion.phy_link = cur_link;
}
}
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,15,0))
static void fxgmac_phy_link_poll(struct timer_list *t)
#else
static void fxgmac_phy_link_poll(unsigned long data)
#endif
{
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,15,0))
struct fxgmac_pdata *pdata = from_timer(pdata, t, expansion.phy_poll_tm);
#else
struct fxgmac_pdata *pdata = (struct fxgmac_pdata*)data;
#endif
if(NULL == pdata->netdev)
{
DPRINTK("fxgmac_phy_timer polling with NULL netdev %lx\n",(unsigned long)(pdata->netdev));
return;
}
pdata->stats.ephy_poll_timer_cnt++;
#if FXGMAC_PM_FEATURE_ENABLED
if(!test_bit(FXGMAC_POWER_STATE_DOWN, &pdata->expansion.powerstate))
#endif
{
mod_timer(&pdata->expansion.phy_poll_tm,jiffies + HZ / 2);
fxgmac_phy_update_link(pdata->netdev);
}else {
DPRINTK("fxgmac_phy_timer polling, powerstate changed, %ld, netdev=%lx, tm=%lx\n", pdata->expansion.powerstate, (unsigned long)(pdata->netdev), (unsigned long)&pdata->expansion.phy_poll_tm);
}
//DPRINTK("fxgmac_phy_timer polled,%d\n",cnt_polling);
}
int fxgmac_phy_timer_init(struct fxgmac_pdata *pdata)
{
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,15,0))
init_timer_key(&pdata->expansion.phy_poll_tm, NULL, 0, "fuxi_phy_link_update_timer", NULL);
#else
init_timer_key(&pdata->expansion.phy_poll_tm, 0, "fuxi_phy_link_update_timer", NULL);
#endif
pdata->expansion.phy_poll_tm.expires = jiffies + HZ / 2;
pdata->expansion.phy_poll_tm.function = (void *)(fxgmac_phy_link_poll);
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,15,0))
pdata->expansion.phy_poll_tm.data = (unsigned long)pdata;
#endif
add_timer(&pdata->expansion.phy_poll_tm);
DPRINTK("fxgmac_phy_timer started, %lx\n", jiffies);
return 0;
}
void fxgmac_phy_timer_destroy(struct fxgmac_pdata *pdata)
{
del_timer_sync(&pdata->expansion.phy_poll_tm);
DPRINTK("fxgmac_phy_timer removed\n");
}
File diff suppressed because it is too large Load Diff
+951
View File
@@ -0,0 +1,951 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/* Copyright (c) 2021 Motor-comm Corporation. All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#ifndef __FXGMAC_GMAC_H__
#define __FXGMAC_GMAC_H__
#include "fuxi-os.h"
#include "fuxi-errno.h"
// For fpga before 20210507
#define FXGMAC_FPGA_VER_B4_0507 0
#define FXGMAC_FPGA_VER_20210507 1
#define FXGMAC_DRV_NAME "yt6801"
#define FXGMAC_DRV_DESC "Motorcomm YT6801 Gigabit Ethernet Driver"
#define FXGMAC_MAC_REGS_OFFSET 0x2000
#define FXGMAC_EPHY_INTERRUPT_D0_OFF 0 //1: in normal D0 state, turn off ephy link change interrupt.
#define FXGMAC_ALLOC_NEW_RECBUFFER 0 //1:when rec buffer is not enough,to create rbd and rec buffer ,but the rdb need to be continus with the initialized rdb,so close the feature
#define RESUME_MAX_TIME 3000000
#define PHY_LINK_TIMEOUT 3000
#define ESD_RESET_MAXIMUM 0
#define REGWR_RETRY_MAXIMUM 2600
#define PCIE_LINKDOWN_VALUE 0xFFFFFFFF
#define FXGMAC_MSIX_Q_VECTORS 4
#define FXGMAC_IS_CHANNEL_WITH_TX_IRQ(chId) (0 == (chId) ? 1 : 0)
/* flags for ipv6 NS offload address, local link or Global unicast */
#define FXGMAC_NS_IFA_LOCAL_LINK 1
#define FXGMAC_NS_IFA_GLOBAL_UNICAST 2
#define FXGMAX_ASPM_WAR_EN
/* Descriptor related parameters */
#if FXGMAC_TX_HANG_TIMER_ENABLED
#define FXGMAC_TX_DESC_CNT 1024
#else
#define FXGMAC_TX_DESC_CNT 256 //256 to make sure the tx ring is in the 4k range when FXGMAC_TX_HANG_TIMER_ENABLED is 0
#endif
#define FXGMAC_TX_DESC_MIN_FREE (FXGMAC_TX_DESC_CNT >> 3)
#define FXGMAC_TX_DESC_MAX_PROC (FXGMAC_TX_DESC_CNT >> 1)
#define FXGMAC_RX_DESC_CNT 1024
#define FXGMAC_RX_DESC_MAX_DIRTY (FXGMAC_RX_DESC_CNT >> 3)
/* Descriptors required for maximum contiguous TSO/GSO packet */
#define FXGMAC_TX_MAX_SPLIT ((GSO_MAX_SIZE / FXGMAC_TX_MAX_BUF_SIZE) + 1)
/* Maximum possible descriptors needed for a SKB */
#define FXGMAC_TX_MAX_DESC_NR (MAX_SKB_FRAGS + FXGMAC_TX_MAX_SPLIT + 2)
#define FXGMAC_TX_MAX_BUF_SIZE (0x3fff & ~(64 - 1))
#define FXGMAC_RX_MIN_BUF_SIZE (ETH_FRAME_LEN + ETH_FCS_LEN + VLAN_HLEN)
#define FXGMAC_RX_BUF_ALIGN 64
/* Maximum Size for Splitting the Header Data
* Keep in sync with SKB_ALLOC_SIZE
* 3'b000: 64 bytes, 3'b001: 128 bytes
* 3'b010: 256 bytes, 3'b011: 512 bytes
* 3'b100: 1023 bytes , 3'b101'3'b111: Reserved
*/
#define FXGMAC_SPH_HDSMS_SIZE 3
#define FXGMAC_SKB_ALLOC_SIZE 512
#define FXGMAC_MAX_FIFO 81920
#define FXGMAC_MAX_DMA_CHANNELS FXGMAC_MSIX_Q_VECTORS
#define FXGMAC_DMA_STOP_TIMEOUT 5
#define FXGMAC_DMA_INTERRUPT_MASK 0x31c7
#define FXGMAC_MAX_DMA_CHANNELS_PLUS_1TX (FXGMAC_MAX_DMA_CHANNELS + 1)
/* Default coalescing parameters */
#define FXGMAC_INIT_DMA_TX_USECS INT_MOD_IN_US
#define FXGMAC_INIT_DMA_TX_FRAMES 25
#define FXGMAC_INIT_DMA_RX_USECS INT_MOD_IN_US /* 30 */
#define FXGMAC_INIT_DMA_RX_FRAMES 25
#define FXGMAC_MAX_DMA_RIWT 0xff
#define FXGMAC_MIN_DMA_RIWT 0x01
/* Flow control queue count */
#define FXGMAC_MAX_FLOW_CONTROL_QUEUES 8
/* System clock is 125 MHz */
#define FXGMAC_SYSCLOCK 125000000
/* Maximum MAC address hash table size (256 bits = 8 bytes) */
#define FXGMAC_MAC_HASH_TABLE_SIZE 8
/* wol pattern settings */
#define MAX_PATTERN_SIZE 128 // PATTERN length
#define MAX_PATTERN_COUNT 16 // pattern count
#define MAX_LPP_ARP_OFFLOAD_COUNT 1
#define MAX_LPP_NS_OFFLOAD_COUNT 2
#define MAX_WPI_LENGTH_SIZE 1536 // WPI packet.
#define PM_WAKE_PKT_ALIGN 8 // try use 64 bit boundary...
/* Receive Side Scaling */
#define FXGMAC_RSS_HASH_KEY_SIZE 40
#define FXGMAC_RSS_MAX_TABLE_SIZE 128
#define FXGMAC_RSS_LOOKUP_TABLE_TYPE 0
#define FXGMAC_RSS_HASH_KEY_TYPE 1
#define MAX_MSI_COUNT 16 // Max Msi/Msix supported.
#define FXGMAC_STD_PACKET_MTU 1500
#define FXGMAC_JUMBO_PACKET_MTU 9014
#define NIC_MAX_TCP_OFFLOAD_SIZE 7300
#define NIC_MIN_LSO_SEGMENT_COUNT 2
/* power management */
#define FXGMAC_POWER_STATE_DOWN 0
#define FXGMAC_POWER_STATE_UP 1
#define FXGMAC_DATA_WIDTH 128
#define FXGMAC_WOL_WAIT_TIME 2 // unit 1ms
// Don't change the member variables or types, this inherits from Windows OS.
struct wol_bitmap_pattern
{
u32 flags;
u32 pattern_size;
u32 mask_size;
u8 mask_info[MAX_PATTERN_SIZE / 8];
u8 pattern_info[MAX_PATTERN_SIZE];
u8 pattern_offset;
u16 pattern_crc;
};
struct led_setting
{
u32 s0_led_setting[5];
u32 s3_led_setting[5];
u32 s5_led_setting[5];
u32 disable_led_setting[5];
};
typedef struct led_setting LED_SETTING;
typedef struct wol_bitmap_pattern WOL_BITMAP_PATTERN;
typedef enum
{
WAKE_REASON_NONE = 0,
WAKE_REASON_MAGIC,
WAKE_REASON_PATTERNMATCH,
WAKE_REASON_LINK,
WAKE_REASON_TCPSYNV4,
WAKE_REASON_TCPSYNV6,
WAKE_REASON_TBD, //for wake up method like Link-change, for that, GMAC cannot identify and need more checking.
WAKE_REASON_HW_ERR,
} WAKE_REASON; //note, maybe we should refer to NDIS_PM_WAKE_REASON_TYPE to avoid duplication definition....
/* Helper macro for descriptor handling
* Always use FXGMAC_GET_DESC_DATA to access the descriptor data
*/
#if 0 //No need to round
#define FXGMAC_GET_DESC_DATA(ring, idx) ({ \
typeof(ring) _ring = (ring); \
((_ring)->desc_data_head + \
((idx) & ((_ring)->dma_desc_count - 1))); \
})
#endif
#define FXGMAC_GET_DESC_DATA(ring, idx) ((ring)->desc_data_head + (idx))
#define FXGMAC_GET_ENTRY(x, size) ((x + 1) & (size - 1))
struct fxgmac_pdata;
enum fxgmac_int {
FXGMAC_INT_DMA_CH_SR_TI,
FXGMAC_INT_DMA_CH_SR_TPS,
FXGMAC_INT_DMA_CH_SR_TBU,
FXGMAC_INT_DMA_CH_SR_RI,
FXGMAC_INT_DMA_CH_SR_RBU,
FXGMAC_INT_DMA_CH_SR_RPS,
FXGMAC_INT_DMA_CH_SR_TI_RI,
FXGMAC_INT_DMA_CH_SR_FBE,
FXGMAC_INT_DMA_ALL,
};
struct fxgmac_stats {
/* MMC TX counters */
u64 txoctetcount_gb;
u64 txframecount_gb;
u64 txbroadcastframes_g;
u64 txmulticastframes_g;
u64 tx64octets_gb;
u64 tx65to127octets_gb;
u64 tx128to255octets_gb;
u64 tx256to511octets_gb;
u64 tx512to1023octets_gb;
u64 tx1024tomaxoctets_gb;
u64 txunicastframes_gb;
u64 txmulticastframes_gb;
u64 txbroadcastframes_gb;
u64 txunderflowerror;
u64 txsinglecollision_g;
u64 txmultiplecollision_g;
u64 txdeferredframes;
u64 txlatecollisionframes;
u64 txexcessivecollisionframes;
u64 txcarriererrorframes;
u64 txoctetcount_g;
u64 txframecount_g;
u64 txexcessivedeferralerror;
u64 txpauseframes;
u64 txvlanframes_g;
u64 txoversize_g;
/* MMC RX counters */
u64 rxframecount_gb;
u64 rxoctetcount_gb;
u64 rxoctetcount_g;
u64 rxbroadcastframes_g;
u64 rxmulticastframes_g;
u64 rxcrcerror;
u64 rxalignerror;
u64 rxrunterror;
u64 rxjabbererror;
u64 rxundersize_g;
u64 rxoversize_g;
u64 rx64octets_gb;
u64 rx65to127octets_gb;
u64 rx128to255octets_gb;
u64 rx256to511octets_gb;
u64 rx512to1023octets_gb;
u64 rx1024tomaxoctets_gb;
u64 rxunicastframes_g;
u64 rxlengtherror;
u64 rxoutofrangetype;
u64 rxpauseframes;
u64 rxfifooverflow;
u64 rxvlanframes_gb;
u64 rxwatchdogerror;
u64 rxreceiveerrorframe;
u64 rxcontrolframe_g;
/* Extra counters */
u64 tx_tso_packets;
u64 rx_split_header_packets;
u64 tx_process_stopped;
u64 rx_process_stopped;
u64 tx_buffer_unavailable;
u64 rx_buffer_unavailable;
u64 fatal_bus_error;
u64 tx_vlan_packets;
u64 rx_vlan_packets;
u64 napi_poll_isr;
u64 napi_poll_txtimer;
u64 cnt_alive_txtimer;
u64 ephy_poll_timer_cnt;
u64 mgmt_int_isr;
};
struct fxgmac_ring_buf {
struct sk_buff* skb;
DMA_ADDR_T skb_dma;
unsigned int skb_len;
};
/* Common Tx and Rx DMA hardware descriptor */
struct fxgmac_dma_desc {
__le32 desc0;
__le32 desc1;
__le32 desc2;
__le32 desc3;
};
/* Page allocation related values */
struct fxgmac_page_alloc {
struct page* pages;
unsigned int pages_len;
unsigned int pages_offset;
DMA_ADDR_T pages_dma;
};
/* Ring entry buffer data */
struct fxgmac_buffer_data {
struct fxgmac_page_alloc pa;
struct fxgmac_page_alloc pa_unmap;
DMA_ADDR_T dma_base;
unsigned long dma_off;
unsigned int dma_len;
};
/* Tx-related desc data */
struct fxgmac_tx_desc_data {
unsigned int packets; /* BQL packet count */
unsigned int bytes; /* BQL byte count */
};
/* Rx-related desc data */
struct fxgmac_rx_desc_data {
struct fxgmac_buffer_data hdr; /* Header locations */
struct fxgmac_buffer_data buf; /* Payload locations */
unsigned short hdr_len; /* Length of received header */
unsigned short len; /* Length of received packet */
};
struct fxgmac_pkt_info {
struct sk_buff* skb;
unsigned int attributes;
unsigned int errors;
/* descriptors needed for this packet */
unsigned int desc_count;
unsigned int length;
unsigned int tx_packets;
unsigned int tx_bytes;
unsigned int header_len;
unsigned int tcp_header_len;
unsigned int tcp_payload_len;
unsigned short mss;
unsigned short vlan_ctag;
u64 rx_tstamp;
u32 rss_hash;
RSS_HASH_TYPE rss_hash_type;
};
struct fxgmac_desc_data {
/* dma_desc: Virtual address of descriptor
* dma_desc_addr: DMA address of descriptor
*/
struct fxgmac_dma_desc* dma_desc;
DMA_ADDR_T dma_desc_addr;
/* skb: Virtual address of SKB
* skb_dma: DMA address of SKB data
* skb_dma_len: Length of SKB DMA area
*/
struct sk_buff* skb;
DMA_ADDR_T skb_dma;
unsigned int skb_dma_len;
/* Tx/Rx -related data */
struct fxgmac_tx_desc_data tx;
struct fxgmac_rx_desc_data rx;
unsigned int mapped_as_page;
#if 0
/* Incomplete receive save location. If the budget is exhausted
* or the last descriptor (last normal descriptor or a following
* context descriptor) has not been DMA'd yet the current state
* of the receive processing needs to be saved.
*/
unsigned int state_saved;
struct {
struct sk_buff* skb;
unsigned int len;
unsigned int error;
} state;
#endif
};
struct fxgmac_ring {
/* Per packet related information */
struct fxgmac_pkt_info pkt_info;
/* Virtual/DMA addresses of DMA descriptor list and the total count */
struct fxgmac_dma_desc *dma_desc_head;
DMA_ADDR_T dma_desc_head_addr;
unsigned int dma_desc_count;
/* Array of descriptor data corresponding the DMA descriptor
* (always use the FXGMAC_GET_DESC_DATA macro to access this data)
*/
struct fxgmac_desc_data *desc_data_head;
/* Page allocation for RX buffers */
struct fxgmac_page_alloc rx_hdr_pa;
struct fxgmac_page_alloc rx_buf_pa;
/* Ring index values
* cur - Tx: index of descriptor to be used for current transfer
* Rx: index of descriptor to check for packet availability
* dirty - Tx: index of descriptor to check for transfer complete
* Rx: index of descriptor to check for buffer reallocation
*/
unsigned int cur;
unsigned int dirty;
/* Coalesce frame count used for interrupt bit setting */
unsigned int coalesce_count;
struct {
unsigned int xmit_more;
unsigned int queue_stopped;
unsigned short cur_mss;
unsigned short cur_vlan_ctag;
} tx;
} ____cacheline_aligned;
struct fxgmac_channel {
char name[16];
/* Address of private data area for device */
struct fxgmac_pdata* pdata;
/* Queue index and base address of queue's DMA registers */
unsigned int queue_index;
IOMEM dma_regs;
/* Per channel interrupt irq number */
u32 dma_irq;
FXGMAC_CHANNEL_OF_PLATFORM expansion;
u32 saved_ier;
unsigned int tx_timer_active;
struct fxgmac_ring *tx_ring;
struct fxgmac_ring *rx_ring;
} ____cacheline_aligned;
struct fxphy_ag_adv {
u8 auto_neg_en : 1;
u8 full_1000m : 1;
u8 half_1000m : 1;
u8 full_100m : 1;
u8 half_100m : 1;
u8 full_10m : 1;
u8 half_10m : 1;
};
struct fxgmac_desc_ops {
int (*alloc_channels_and_rings)(struct fxgmac_pdata* pdata);
void (*free_channels_and_rings)(struct fxgmac_pdata* pdata);
int (*map_tx_skb)(struct fxgmac_channel* channel,
struct sk_buff* skb);
int (*map_rx_buffer)(struct fxgmac_pdata* pdata,
struct fxgmac_ring* ring,
struct fxgmac_desc_data* desc_data);
void (*unmap_desc_data)(struct fxgmac_pdata* pdata,
struct fxgmac_desc_data* desc_data);
void (*tx_desc_init)(struct fxgmac_pdata* pdata);
int (*rx_desc_init)(struct fxgmac_pdata* pdata);
/* For descriptor related operation */
void (*tx_desc_init_channel)(struct fxgmac_channel* channel);
void (*rx_desc_init_channel)(struct fxgmac_channel* channel);
void (*tx_desc_reset)(struct fxgmac_desc_data* desc_data);
void (*rx_desc_reset)(struct fxgmac_pdata* pdata,
struct fxgmac_desc_data* desc_data,
unsigned int index);
};
struct fxgmac_hw_ops {
int (*init)(struct fxgmac_pdata* pdata);
int (*exit)(struct fxgmac_pdata* pdata);
void (*save_nonstick_reg)(struct fxgmac_pdata* pdata);
void (*restore_nonstick_reg)(struct fxgmac_pdata* pdata);
int (*set_gmac_register)(struct fxgmac_pdata* pdata, IOMEM address, unsigned int data);
u32 (*get_gmac_register)(struct fxgmac_pdata* pdata, IOMEM address);
void (*esd_restore_pcie_cfg)(struct fxgmac_pdata* pdata);
int (*tx_complete)(struct fxgmac_dma_desc* dma_desc);
void (*enable_tx)(struct fxgmac_pdata* pdata);
void (*disable_tx)(struct fxgmac_pdata* pdata);
void (*enable_rx)(struct fxgmac_pdata* pdata);
void (*disable_rx)(struct fxgmac_pdata* pdata);
void (*enable_channel_rx)(struct fxgmac_pdata* pdata, unsigned int queue);
void (*enable_rx_tx_ints)(struct fxgmac_pdata* pdata);
void (*disable_rx_tx_ints)(struct fxgmac_pdata* pdata);
int (*enable_int)(struct fxgmac_channel* channel,
enum fxgmac_int int_id);
int (*disable_int)(struct fxgmac_channel* channel,
enum fxgmac_int int_id);
void (*set_interrupt_moderation)(struct fxgmac_pdata* pdata);
void (*enable_msix_rxtxinterrupt)(struct fxgmac_pdata* pdata);
void (*disable_msix_interrupt)(struct fxgmac_pdata* pdata);
int (*enable_msix_rxtxphyinterrupt)(struct fxgmac_pdata* pdata);
void (*enable_msix_one_interrupt)(struct fxgmac_pdata* pdata, u32 intid);
void (*disable_msix_one_interrupt)(struct fxgmac_pdata* pdata, u32 intid);
bool (*enable_mgm_interrupt)(struct fxgmac_pdata* pdata);
bool (*disable_mgm_interrupt)(struct fxgmac_pdata* pdata);
bool (*enable_source_interrupt)(struct fxgmac_pdata* pdata);
bool (*disable_source_interrupt)(struct fxgmac_pdata* pdata);
int (*dismiss_all_int)(struct fxgmac_pdata* pdata);
void (*clear_misc_int_status)(struct fxgmac_pdata* pdata);
void (*dev_xmit)(struct fxgmac_channel* channel);
int (*dev_read)(struct fxgmac_channel* channel);
int (*set_mac_address)(struct fxgmac_pdata* pdata, u8* addr);
int (*set_mac_hash)(struct fxgmac_pdata* pdata);
int (*config_rx_mode)(struct fxgmac_pdata* pdata);
int (*enable_rx_csum)(struct fxgmac_pdata* pdata);
int (*disable_rx_csum)(struct fxgmac_pdata* pdata);
void (*config_tso)(struct fxgmac_pdata *pdata);
/* For MII speed configuration */
int (*config_mac_speed)(struct fxgmac_pdata* pdata);
int (*get_xlgmii_phy_status)(struct fxgmac_pdata *pdata, u32 *speed, bool *link_up, bool link_up_wait_to_complete);
/* For descriptor related operation */
//void (*tx_desc_init)(struct fxgmac_channel* channel);
//void (*rx_desc_init)(struct fxgmac_channel* channel);
//void (*tx_desc_reset)(struct fxgmac_desc_data* desc_data);
//void (*rx_desc_reset)(struct fxgmac_pdata* pdata,
// struct fxgmac_desc_data* desc_data,
// unsigned int index);
int (*is_last_desc)(struct fxgmac_dma_desc* dma_desc);
int (*is_context_desc)(struct fxgmac_dma_desc* dma_desc);
/* For Flow Control */
int (*config_tx_flow_control)(struct fxgmac_pdata* pdata);
int (*config_rx_flow_control)(struct fxgmac_pdata* pdata);
/* For Jumbo Frames */
int (*config_mtu)(struct fxgmac_pdata* pdata);
int (*enable_jumbo)(struct fxgmac_pdata* pdata);
/* For Vlan related config */
int (*enable_tx_vlan)(struct fxgmac_pdata* pdata);
int (*disable_tx_vlan)(struct fxgmac_pdata* pdata);
int (*enable_rx_vlan_stripping)(struct fxgmac_pdata* pdata);
int (*disable_rx_vlan_stripping)(struct fxgmac_pdata* pdata);
int (*enable_rx_vlan_filtering)(struct fxgmac_pdata* pdata);
int (*disable_rx_vlan_filtering)(struct fxgmac_pdata* pdata);
int (*update_vlan_hash_table)(struct fxgmac_pdata* pdata);
/* For RX coalescing */
int (*config_rx_coalesce)(struct fxgmac_pdata* pdata);
int (*config_tx_coalesce)(struct fxgmac_pdata* pdata);
unsigned long (*usec_to_riwt)(struct fxgmac_pdata* pdata,
unsigned int usec);
unsigned long (*riwt_to_usec)(struct fxgmac_pdata* pdata,
unsigned int riwt);
/* For RX and TX threshold config */
int (*config_rx_threshold)(struct fxgmac_pdata* pdata,
unsigned int val);
int (*config_tx_threshold)(struct fxgmac_pdata* pdata,
unsigned int val);
/* For RX and TX Store and Forward Mode config */
int (*config_rsf_mode)(struct fxgmac_pdata* pdata,
unsigned int val);
int (*config_tsf_mode)(struct fxgmac_pdata* pdata,
unsigned int val);
/* For TX DMA Operate on Second Frame config */
int (*config_osp_mode)(struct fxgmac_pdata* pdata);
/* For RX and TX PBL config */
u32 (*calculate_max_checksum_size)(struct fxgmac_pdata* pdata);
int (*config_rx_pbl_val)(struct fxgmac_pdata* pdata);
u32 (*get_rx_pbl_val)(struct fxgmac_pdata* pdata);
int (*config_tx_pbl_val)(struct fxgmac_pdata* pdata);
u32 (*get_tx_pbl_val)(struct fxgmac_pdata* pdata);
int (*config_pblx8)(struct fxgmac_pdata* pdata);
/* For MMC statistics */
void (*rx_mmc_int)(struct fxgmac_pdata* pdata);
void (*tx_mmc_int)(struct fxgmac_pdata* pdata);
void (*read_mmc_stats)(struct fxgmac_pdata* pdata);
bool (*update_stats_counters)(struct fxgmac_pdata* pdata, bool ephy_check_en);
/* For Receive Side Scaling */
int (*enable_rss)(struct fxgmac_pdata* pdata);
int (*disable_rss)(struct fxgmac_pdata* pdata);
u32 (*get_rss_options)(struct fxgmac_pdata* pdata);
int (*set_rss_options)(struct fxgmac_pdata* pdata);
int (*set_rss_hash_key)(struct fxgmac_pdata* pdata, const u8* key);
int (*set_rss_lookup_table)(struct fxgmac_pdata* pdata, const u32* table);
/*For Offload*/
#ifdef FXGMAC_POWER_MANAGEMENT
void (*set_arp_offload)(struct fxgmac_pdata* pdata, unsigned char* ip_addr);
int (*enable_arp_offload)(struct fxgmac_pdata* pdata);
int (*disable_arp_offload)(struct fxgmac_pdata* pdata);
/*NS offload*/
int (*set_ns_offload)(
struct fxgmac_pdata* pdata,
unsigned int index,
unsigned char* remote_addr,
unsigned char* solicited_addr,
unsigned char* target_addr1,
unsigned char* target_addr2,
unsigned char* mac_addr);
int (*enable_ns_offload)(struct fxgmac_pdata* pdata);
int (*disable_ns_offload)(struct fxgmac_pdata* pdata);
int (*enable_wake_magic_pattern)(struct fxgmac_pdata* pdata);
int (*disable_wake_magic_pattern)(struct fxgmac_pdata* pdata);
int (*enable_wake_link_change)(struct fxgmac_pdata* pdata);
int (*disable_wake_link_change)(struct fxgmac_pdata* pdata);
int (*check_wake_pattern_fifo_pointer)(struct fxgmac_pdata* pdata);
int (*set_wake_pattern)(struct fxgmac_pdata* pdata, struct wol_bitmap_pattern* wol_pattern, u32 pattern_cnt);
int (*enable_wake_pattern)(struct fxgmac_pdata* pdata);//int XlgmacEnableArpload(struct fxgmac_pdata* pdata,unsigned char *ip_addr)
int (*disable_wake_pattern)(struct fxgmac_pdata* pdata);
int (*set_wake_pattern_mask)(struct fxgmac_pdata* pdata, u32 filter_index, u8 register_index, u32 Data);
#if FXGMAC_PM_WPI_READ_FEATURE_ENABLED
void (*get_wake_packet_indication)(struct fxgmac_pdata* pdata, int* wake_reason, u32* wake_pattern_number, u8* wpi_buf, u32 buf_size, u32* packet_size);
void (*enable_wake_packet_indication)(struct fxgmac_pdata* pdata, int en);
#endif
#endif
void (*reset_phy)(struct fxgmac_pdata* pdata);
/*for release phy,phy write and read, and provide clock to GMAC. */
void (*release_phy)(struct fxgmac_pdata* pdata);
void (*enable_phy_check)(struct fxgmac_pdata* pdata);
void (*disable_phy_check)(struct fxgmac_pdata* pdata);
void (*setup_cable_loopback)(struct fxgmac_pdata* pdata);
void (*clean_cable_loopback)(struct fxgmac_pdata* pdata);
void (*disable_phy_sleep)(struct fxgmac_pdata* pdata);
void (*enable_phy_sleep)(struct fxgmac_pdata* pdata);
void (*phy_green_ethernet)(struct fxgmac_pdata* pdata);
void (*phy_eee_feature)(struct fxgmac_pdata* pdata);
u32 (*get_ephy_state)(struct fxgmac_pdata* pdata);
int (*write_ephy_reg)(struct fxgmac_pdata* pdata, u32 val, u32 data);
int (*read_ephy_reg)(struct fxgmac_pdata* pdata, u32 val, u32 __far* data);
int (*set_ephy_autoneg_advertise)(struct fxgmac_pdata* pdata, struct fxphy_ag_adv phy_ag_adv);
int (*phy_config)(struct fxgmac_pdata* pdata);
void (*close_phy_led)(struct fxgmac_pdata* pdata);
void (*led_under_active)(struct fxgmac_pdata* pdata);
void (*led_under_sleep)(struct fxgmac_pdata* pdata);
void (*led_under_shutdown)(struct fxgmac_pdata* pdata);
void (*led_under_disable)(struct fxgmac_pdata* pdata);
/* For power management */
void (*pre_power_down)(struct fxgmac_pdata* pdata, bool phyloopback);
int (*diag_sanity_check)(struct fxgmac_pdata *pdata);
int (*write_rss_lookup_table)(struct fxgmac_pdata *pdata);
int (*get_rss_hash_key)(struct fxgmac_pdata *pdata, u8 *key_buf);
#ifdef FXGMAC_WOL_INTEGRATED_WOL_PARAMETER
void (*config_power_down)(struct fxgmac_pdata *pdata, unsigned int wol);
#else
void (*config_power_down)(struct fxgmac_pdata* pdata, unsigned int offloadcount, bool magic_en, bool remote_pattern_en);
#endif
void (*config_power_up)(struct fxgmac_pdata* pdata);
unsigned char (*set_suspend_int)(void* pdata);
void (*set_resume_int)(struct fxgmac_pdata* pdata);
int (*set_suspend_txrx)(struct fxgmac_pdata* pdata);
void (*set_pwr_clock_gate)(struct fxgmac_pdata* pdata);
void (*set_pwr_clock_ungate)(struct fxgmac_pdata* pdata);
/* for multicast address list */
int (*set_all_multicast_mode)(struct fxgmac_pdata* pdata, unsigned int enable);
void (*config_multicast_mac_hash_table)(struct fxgmac_pdata* pdata, unsigned char* pmc_mac, int b_add);
/* for packet filter-promiscuous and broadcast */
int (*set_promiscuous_mode)(struct fxgmac_pdata* pdata, unsigned int enable);
int (*enable_rx_broadcast)(struct fxgmac_pdata* pdata, unsigned int enable);
/* efuse relevant operation. */
bool (*read_patch_from_efuse_per_index)(struct fxgmac_pdata* pdata, u8 index, u32 __far* offset, u32 __far* value); /* read patch per index. */
bool (*read_mac_subsys_from_efuse)(struct fxgmac_pdata* pdata, u8* mac_addr, u32* subsys, u32* revid);
bool (*read_efuse_data)(struct fxgmac_pdata* pdata, u32 offset, u32 __far* value);
#ifndef COMMENT_UNUSED_CODE_TO_REDUCE_SIZE
bool (*read_patch_from_efuse)(struct fxgmac_pdata* pdata, u32 offset, u32* value); /* read patch per index. */
bool (*write_patch_to_efuse)(struct fxgmac_pdata* pdata, u32 offset, u32 value);
bool (*write_patch_to_efuse_per_index)(struct fxgmac_pdata* pdata, u8 index, u32 offset, u32 value);
bool (*write_mac_subsys_to_efuse)(struct fxgmac_pdata* pdata, u8* mac_addr, u32* subsys, u32* revid);
bool (*read_mac_addr_from_efuse)(struct fxgmac_pdata* pdata, u8* mac_addr);
bool (*write_mac_addr_to_efuse)(struct fxgmac_pdata* pdata, u8* mac_addr);
bool (*efuse_load)(struct fxgmac_pdata* pdata);
bool (*write_oob)(struct fxgmac_pdata* pdata);
bool (*write_led)(struct fxgmac_pdata* pdata, u32 value);
bool (*read_led_config)(struct fxgmac_pdata* pdata);
bool (*write_led_config)(struct fxgmac_pdata* pdata);
#endif
int (*pcie_init)(struct fxgmac_pdata* pdata, bool ltr_en, bool aspm_l1ss_en, bool aspm_l1_en, bool aspm_l0s_en);
void (*trigger_pcie)(struct fxgmac_pdata* pdata, u32 code); // To trigger pcie sniffer for analysis.
};
/* This structure contains flags that indicate what hardware features
* or configurations are present in the device.
*/
struct fxgmac_hw_features {
/* HW Version */
u32 version;
/* HW Feature Register0 */
u32 phyifsel; /* PHY interface support */
u32 vlhash; /* VLAN Hash Filter */
u32 sma; /* SMA(MDIO) Interface */
u32 rwk; /* PMT remote wake-up packet */
u32 mgk; /* PMT magic packet */
u32 mmc; /* RMON module */
u32 aoe; /* ARP Offload */
u32 ts; /* IEEE 1588-2008 Advanced Timestamp */
u32 eee; /* Energy Efficient Ethernet */
u32 tx_coe; /* Tx Checksum Offload */
u32 rx_coe; /* Rx Checksum Offload */
u32 addn_mac; /* Additional MAC Addresses */
u32 ts_src; /* Timestamp Source */
u32 sa_vlan_ins;/* Source Address or VLAN Insertion */
/* HW Feature Register1 */
u32 rx_fifo_size; /* MTL Receive FIFO Size */
u32 tx_fifo_size; /* MTL Transmit FIFO Size */
u32 adv_ts_hi; /* Advance Timestamping High Word */
u32 dma_width; /* DMA width */
u32 dcb; /* DCB Feature */
u32 sph; /* Split Header Feature */
u32 tso; /* TCP Segmentation Offload */
u32 dma_debug; /* DMA Debug Registers */
u32 rss; /* Receive Side Scaling */
u32 tc_cnt; /* Number of Traffic Classes */
u32 avsel; /* AV Feature Enable */
u32 ravsel; /* Rx Side Only AV Feature Enable */
u32 hash_table_size;/* Hash Table Size */
u32 l3l4_filter_num;/* Number of L3-L4 Filters */
/* HW Feature Register2 */
u32 rx_q_cnt; /* Number of MTL Receive Queues */
u32 tx_q_cnt; /* Number of MTL Transmit Queues */
u32 rx_ch_cnt; /* Number of DMA Receive Channels */
u32 tx_ch_cnt; /* Number of DMA Transmit Channels */
u32 pps_out_num; /* Number of PPS outputs */
u32 aux_snap_num; /* Number of Aux snapshot inputs */
/* HW Feature Register3 */
u32 hwfr3;
};
struct fxgmac_resources {
IOMEM addr;
int irq;
};
struct fxgmac_pdata {
struct net_device *netdev;
struct device *dev;
PCI_DEV *pdev;
void *pAdapter;
struct fxgmac_hw_ops hw_ops;
struct fxgmac_desc_ops desc_ops;
/* Device statistics */
struct fxgmac_stats stats;
u32 msg_enable;
u32 reg_nonstick[0x300 >> 2];
/* MAC registers base */
IOMEM mac_regs;
IOMEM base_mem;
/* Hardware features of the device */
struct fxgmac_hw_features hw_feat;
/* Rings for Tx/Rx on a DMA channel */
struct fxgmac_channel *channel_head;
unsigned int channel_count;
unsigned int tx_ring_count;
unsigned int rx_ring_count;
unsigned int tx_desc_count;
unsigned int rx_desc_count;
unsigned int tx_q_count;
unsigned int rx_q_count;
/* Tx/Rx common settings */
unsigned int pblx8;
/* Tx settings */
unsigned int tx_sf_mode;
unsigned int tx_threshold;
unsigned int tx_pbl;
unsigned int tx_osp_mode;
#if FXGMAC_TX_HANG_TIMER_ENABLED
/* for tx hang checking. 20211227 */
unsigned int tx_hang_restart_queuing;
#endif
/* Rx settings */
unsigned int rx_sf_mode;
unsigned int rx_threshold;
unsigned int rx_pbl;
/* Tx coalescing settings */
unsigned int tx_usecs;
unsigned int tx_frames;
/* Rx coalescing settings */
unsigned long rx_riwt;
unsigned int rx_usecs;
unsigned int rx_frames;
/* Current Rx buffer size */
unsigned int rx_buf_size;
/* Flow control settings */
unsigned int tx_pause;
unsigned int rx_pause;
/* Jumbo frames */
unsigned int mtu;
unsigned int jumbo;
/* CRC checking */
unsigned int crc_check;
/* MSIX */
unsigned int msix;
/* RSS */
unsigned int rss;
/* VlanID */
unsigned int vlan;
unsigned int vlan_exist;
unsigned int vlan_filter;
unsigned int vlan_strip;
/* Interrupt Moderation */
unsigned int intr_mod;
unsigned int intr_mod_timer;
/* Device interrupt number */
int dev_irq;
unsigned int per_channel_irq;
u32 channel_irq[FXGMAC_MAX_DMA_CHANNELS_PLUS_1TX]; // change type from int to u32 to match MSIx, p_msix_entry.vector;
/* Netdev related settings */
unsigned char mac_addr[ETH_ALEN];
/* Filtering support */
#if FXGMAC_FILTER_MULTIPLE_VLAN_ENABLED
unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
#endif
/* Device clocks */
unsigned long sysclk_rate;
/* Receive Side Scaling settings */
u8 rss_key[FXGMAC_RSS_HASH_KEY_SIZE];
u32 rss_table[FXGMAC_RSS_MAX_TABLE_SIZE];
u32 rss_options;
int phy_speed;
int phy_duplex;
int phy_autoeng;
#ifndef COMMENT_UNUSED_CODE_TO_REDUCE_SIZE
char drv_name[32];
char drv_ver[32];
struct wol_bitmap_pattern pattern[MAX_PATTERN_COUNT];
#endif
struct led_setting led;
struct led_setting ledconfig;
FXGMAC_PDATA_OF_PLATFORM expansion;
u32 pcie_link_status;
u32 mgmt_phy_val;
u32 support_10m_link;
};
#if 1
#define FXGMAC_FLAG_MSI_CAPABLE (u32)(1 << 0)
#define FXGMAC_FLAG_MSI_ENABLED (u32)(1 << 1)
#define FXGMAC_FLAG_MSIX_CAPABLE (u32)(1 << 2)
#define FXGMAC_FLAG_MSIX_ENABLED (u32)(1 << 3)
#define FXGMAC_FLAG_LEGACY_ENABLED (u32)(1 << 4)
#define FXGMAC_FLAG_INTERRUPT_POS 0
#define FXGMAC_FLAG_INTERRUPT_LEN 5
#define FXGMAC_FLAG_MSI_POS 1
#define FXGMAC_FLAG_MSI_LEN 1
#define FXGMAC_FLAG_MSIX_POS 3
#define FXGMAC_FLAG_MSIX_LEN 1
#define FXGMAC_FLAG_LEGACY_POS 4
#define FXGMAC_FLAG_LEGACY_LEN 1
#define FXGMAC_FLAG_LEGACY_IRQ_FREE_POS 31
#define FXGMAC_FLAG_LEGACY_IRQ_FREE_LEN 1
#define FXGMAC_FLAG_LEGACY_NAPI_FREE_POS 30
#define FXGMAC_FLAG_LEGACY_NAPI_FREE_LEN 1
#define FXGMAC_FLAG_MISC_IRQ_FREE_POS 29
#define FXGMAC_FLAG_MISC_IRQ_FREE_LEN 1
#define FXGMAC_FLAG_MISC_NAPI_FREE_POS 28
#define FXGMAC_FLAG_MISC_NAPI_FREE_LEN 1
#define FXGMAC_FLAG_TX_IRQ_FREE_POS 27
#define FXGMAC_FLAG_TX_IRQ_FREE_LEN 1
#define FXGMAC_FLAG_TX_NAPI_FREE_POS 26
#define FXGMAC_FLAG_TX_NAPI_FREE_LEN 1
#define FXGMAC_FLAG_RX_IRQ_FREE_POS 22
#define FXGMAC_FLAG_RX_IRQ_FREE_LEN 4
#define FXGMAC_FLAG_PER_CHAN_RX_IRQ_FREE_LEN 1
#define FXGMAC_FLAG_RX_NAPI_FREE_POS 18
#define FXGMAC_FLAG_RX_NAPI_FREE_LEN 4
#define FXGMAC_FLAG_PER_CHAN_RX_NAPI_FREE_LEN 1
#endif
#ifndef FXGMAC_FAKE_4_TX_QUEUE_ENABLED
#define FXGMAC_FAKE_4_TX_QUEUE_ENABLED 0
#endif
void fxgmac_init_desc_ops(struct fxgmac_desc_ops *desc_ops);
void fxgmac_init_hw_ops(struct fxgmac_hw_ops *hw_ops);
const struct net_device_ops *fxgmac_get_netdev_ops(void);
const struct ethtool_ops *fxgmac_get_ethtool_ops(void);
void fxgmac_dump_tx_desc(struct fxgmac_pdata *pdata,
struct fxgmac_ring *ring,
unsigned int idx,
unsigned int count,
unsigned int flag);
void fxgmac_dump_rx_desc(struct fxgmac_pdata *pdata,
struct fxgmac_ring *ring,
unsigned int idx);
void fxgmac_dbg_pkt(struct net_device *netdev,
struct sk_buff *skb, bool tx_rx);
void fxgmac_get_all_hw_features(struct fxgmac_pdata *pdata);
void fxgmac_print_all_hw_features(struct fxgmac_pdata *pdata);
int fxgmac_drv_probe(struct device *dev,
struct fxgmac_resources *res);
int fxgmac_drv_remove(struct device *dev);
#endif /* __FXGMAC_GMAC_H__ */
+825
View File
@@ -0,0 +1,825 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/* Copyright (c) 2021 Motor-comm Corporation. All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#ifndef __FXGMAC_OS_H__
#define __FXGMAC_OS_H__
#include <linux/dma-mapping.h>
//#include <linux/timecounter.h>
#include <linux/etherdevice.h>
#include <linux/inetdevice.h>
#include <linux/pm_wakeup.h>
#include <linux/netdevice.h>
#include <linux/workqueue.h>
#include <linux/interrupt.h>
#include <linux/ethtool.h>
#include <linux/if_vlan.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/bitrev.h>
#include <net/addrconf.h>
#include <linux/bitops.h>
#include <linux/socket.h>
#include <linux/skbuff.h>
#include <linux/if_arp.h>
#include <linux/fcntl.h>
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/crc32.h>
#include <linux/dcbnl.h>
#include <linux/timer.h>
#include <linux/inet.h>
#include <linux/init.h>
#include <linux/mdio.h>
#include <linux/phy.h>
#include <linux/udp.h>
#include <linux/tcp.h>
#include <linux/clk.h>
#include <linux/mm.h>
#include <linux/in.h>
#include <linux/ip.h>
#ifdef CONFIG_PCI_MSI
#include <linux/pci.h>
#endif
#define LINUX
#ifndef LINUX_VERSION_CODE
#include <linux/version.h>
#else
#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
#endif
#ifndef RHEL_MAJOR
//must used like : if ( RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(a,b) )
#ifndef RHEL_RELEASE_VERSION
#define RHEL_RELEASE_VERSION(a,b) (((a) << 8) + (b))
#define RHEL_RELEASE_CODE (0)
#endif
#include <linux/timecounter.h>
#else
#if (RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,8))
#include <linux/timecounter.h>
#endif
#endif
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,19,0))
#include <linux/crc32poly.h>
#endif
#include "fuxi-dbg.h"
struct fxgmac_ring;
struct fxgmac_pdata;
struct fxgmac_channel;
#define FXGMAC_DRV_VERSION "1.0.30"
#ifdef CONFIG_PCI_MSI
/* undefined for legacy interrupt mode */
/* #undef CONFIG_PCI_MSI */
#endif
#define FXGMAC_INT_MODERATION_ENABLED 1
#define PCIE_LP_ASPM_L0S 1
#define PCIE_LP_ASPM_L1 2
#define PCIE_LP_ASPM_L1SS 4
#define PCIE_LP_ASPM_LTR 8
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,19,0))
/*
* There are multiple 16-bit CRC polynomials in common use, but this is
* *the* standard CRC-32 polynomial, first popularized by Ethernet.
* x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x^1+x^0
*/
#define CRC32_POLY_LE 0xedb88320
#define CRC32_POLY_BE 0x04c11db7
/*
* This is the CRC32c polynomial, as outlined by Castagnoli.
* x^32+x^28+x^27+x^26+x^25+x^23+x^22+x^20+x^19+x^18+x^14+x^13+x^11+x^10+x^9+
* x^8+x^6+x^0
*/
#define CRC32C_POLY_LE 0x82F63B78
#endif
#define FXGMAC_FAIL -1
#define FXGMAC_SUCCESS 0
#define FXGMAC_DEV_CMD (SIOCDEVPRIVATE + 1)
#define FXGMAC_IOCTL_DFS_COMMAND _IOWR('M', 0x80, struct ext_ioctl_data)
#define FXGMAC_MAX_DBG_TEST_PKT 150
#define FXGMAC_MAX_DBG_BUF_LEN 64000
#define FXGMAC_MAX_DBG_RX_DATA 1600
#define FXGMAC_NETDEV_OPS_BUF_LEN 256
#define FXGMAC_TEST_MAC_HEAD_LEN 14
#define FXGMAC_PM_WPI_READ_FEATURE_ENABLED 1
#define RSS_Q_COUNT 4
/* #define FXGMAC_TX_INTERRUPT_ENABLED 1 */
#define FXGMAC_TX_HANG_TIMER_ENABLED 0
/* 1 to trigger(write reg 0x1000) for sniffer stop */
#define FXGMAC_TRIGGER_TX_HANG 0
/* driver feature configuration */
#if FXGMAC_TX_HANG_TIMER_ENABLED
/* 0: check hw current desc; 1: check software dirty */
#define FXGMAC_TX_HANG_CHECH_DIRTY 0
#endif
#define FXGMAC_DMA_BIT_MASK64 64
#define FXGMAC_DMA_BIT_MASK32 32
#ifdef CONFIG_PCI_MSI
/* should be same as FXGMAC_MAX_DMA_CHANNELS + 1 tx_irq */
#define FXGMAC_MAX_MSIX_Q_VECTORS (FXGMAC_MSIX_Q_VECTORS + 1)
#define FXGMAC_MSIX_CH0RXDIS_ENABLED 0 //set to 1 for ch0 unbalance fix;
#define FXGMAC_MSIX_INTCTRL_EN 1
#ifdef FXGMAC_MISC_NOT_ENABLED
#define FXGMAC_MISC_INT_NUM 0
#else
#define FXGMAC_MISC_INT_NUM 1
#endif
#define FXGMAC_MSIX_INT_NUMS (FXGMAC_MAX_MSIX_Q_VECTORS + FXGMAC_MISC_INT_NUM)
#else
#define FXGMAC_MSIX_CH0RXDIS_ENABLED 0 /* NO modification needed! for non-MSI, set to 0 always */
#define FXGMAC_MSIX_INTCTRL_EN 0
#endif
/* RSS features */
#ifdef FXGMAC_ONE_CHANNEL
#define FXGMAC_RSS_FEATURE_ENABLED 0 /* 1:enable rss ; 0: rss not included. */
#else
#define FXGMAC_RSS_FEATURE_ENABLED 1 /* 1:enable rss ; 0: rss not included. */
#endif
#define FXGMAC_RSS_HASH_KEY_LINUX 1 /* 0:hard to default rss key ;1: normal hash key process from Linux. */
/* WOL features */
#define FXGMAC_WOL_FEATURE_ENABLED 1 /* 1:enable wol ; 0: wol not included. */
/* since wol upon link will cause issue, disabled it always. */
#define FXGMAC_WOL_UPON_EPHY_LINK 1 /* 1:enable ephy link change wol ; 0: ephy link change wol is not supported. */
/* Pause features */
#define FXGMAC_PAUSE_FEATURE_ENABLED 1 /* 1:enable flow control/pause framce ; 0: flow control/pause frame not included. */
/* ARP offload engine (AOE) */
#define FXGMAC_AOE_FEATURE_ENABLED 1 /* 1:enable arp offload engine ; 0: aoe is not included. */
/* NS offload engine */
#define FXGMAC_NS_OFFLOAD_ENABLED 1 /* 1:enable NS offload for IPv6 ; 0: NS is not included. */
/* for fpga ver after, which needs release phy before set of MAC tx/rx */
#define FXGMAC_TXRX_EN_AFTER_PHY_RELEASE 1 /* 1:release ephy before mac tx/rx bits are set. */
/* power management features */
#define FXGMAC_PM_FEATURE_ENABLED 1 /* 1:enable PM ; 0: PM not included. */
/* sanity check */
#define FXGMAC_SANITY_CHECK_ENABLED 0 /* 1:enable health checking ; */
/* vlan id filter */
#define FXGMAC_FILTER_SINGLE_VLAN_ENABLED 0
/* Linux driver implement VLAN HASH Table feature to support mutliple VLAN feautre */
#define FXGMAC_FILTER_MULTIPLE_VLAN_ENABLED 1
/* Linux driver implement MAC HASH Table feature */
#define FXGMAC_MAC_HASH_TABLE 1
/* Linux driver implement write multiple mac addr */
#define FXGMAC_FILTER_MULTIPLE_MAC_ADDR_ENABLED 1
/* Linux driver disable MISC Interrupt */
#define FXGMAC_MISC_INT_HANDLE_FEATURE_ENABLED 1
#define FXGMAC_ESD_RESTORE_PCIE_CFG
#define FXGMAC_WOL_INTEGRATED_WOL_PARAMETER
#define FXGMAC_LINK_SPEED_CHECK_PHY_LINK
#define FXGMAC_FLUSH_TX_CHECK_ENABLED
#define FXGMAC_POWER_MANAGEMENT
#define FXGMAC_INTERRUPT_TX_INTERVAL
#define FXGMAC_INTERRUPT_RX_INTERVAL
#define FXGMAC_WAIT_TX_STOP
#define FXGMAC_WAIT_RX_STOP_BY_PRXQ_RXQSTS
#define FXGMAC_USE_DEFAULT_RSS_KEY_TBALE
#define FXGMAC_MISC_NOT_ENABLED
#define FXGMAC_RX_VLAN_FILTERING_ENABLED (pdata->netdev->features & NETIF_F_HW_VLAN_CTAG_FILTER)
#define FXGMAC_NETDEV_PR_MODE_ENABLED ((pdata->netdev->flags & IFF_PROMISC) != 0)
#define FXGMAC_NETDEV_AM_MODE_ENABLED ((pdata->netdev->flags & IFF_ALLMULTI) != 0)
#define FXGMAC_NETDEV_MU_MODE_ENABLED ((pdata->netdev->flags & IFF_MULTICAST) != 0)
#define FXGMAC_NETDEV_BD_MODE_ENABLED ((pdata->netdev->flags & IFF_BROADCAST) != 0)
#define FXGMAC_RX_CHECKSUM_ENABLED (pdata->netdev->features & NETIF_F_RXCSUM)
#define TEST_MAC_HEAD 14
#define TEST_TCP_HEAD_LEN_OFFSET 12
#define TEST_TCP_OFFLOAD_LEN_OFFSET 48
#define TEST_TCP_FIX_HEAD_LEN 24
#define TEST_TCP_MSS_OFFSET 56
#define DF_MAX_NIC_NUM 16
#ifndef offsetof
#define offsetof(TYPE, MEMBER) ((size_t) &(((TYPE*)0)->MEMBER))
#endif
#define ETH_IS_ZEROADDRESS(Address) \
((((u8*)(Address))[0] == ((u8)0x00)) \
&& (((u8*)(Address))[1] == ((u8)0x00)) \
&& (((u8*)(Address))[2] == ((u8)0x00)) \
&& (((u8*)(Address))[3] == ((u8)0x00)) \
&& (((u8*)(Address))[4] == ((u8)0x00)) \
&& (((u8*)(Address))[5] == ((u8)0x00)))
/* centos 7 define start */
#ifndef dma_rmb
#define dma_rmb() barrier()
#endif
#ifndef dma_wmb
#define dma_wmb() barrier()
#endif
#ifndef smp_mb__before_atomic
#define smp_mb__before_atomic() barrier()
#endif
#ifndef smp_mb__after_atomic
#define smp_mb__after_atomic() barrier()
#endif
#ifndef skb_vlan_tag_present
#define skb_vlan_tag_present(__skb) ((__skb)->vlan_tci & VLAN_TAG_PRESENT)
#endif
#ifndef skb_vlan_tag_get
#define skb_vlan_tag_get(__skb) ((__skb)->vlan_tci & ~VLAN_TAG_PRESENT)
#endif
#ifndef GENMASK
/* Create a contiguous bitmask starting at bit position @l and ending at
* position @h. For example
* GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000.
*/
#define GENMASK(h, l) \
(((~0UL) << (l)) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
#endif
#ifndef ETH_RSS_HASH_TOP
#define __ETH_RSS_HASH_BIT(bit) ((u32)1 << (bit))
#define __ETH_RSS_HASH(name) __ETH_RSS_HASH_BIT(ETH_RSS_HASH_##name##_BIT)
#define ETH_RSS_HASH_TOP __ETH_RSS_HASH(TOP)
#endif
/* centos 7 needs set these definitions to 0
* 1. FXGMAC_RSS_FEATURE_ENABLED
* 2. FXGMAC_RSS_HASH_KEY_LINUX
* 3. FXGMAC_PAUSE_FEATURE_ENABLED
* #undef CONFIG_PCI_MSI
*/
#if (RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,0)) && (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,8))
#define strscpy strlcpy
#undef FXGMAC_RSS_FEATURE_ENABLED
#define FXGMAC_RSS_FEATURE_ENABLED 0
#undef FXGMAC_RSS_HASH_KEY_LINUX
#define FXGMAC_RSS_HASH_KEY_LINUX 0
#undef FXGMAC_PAUSE_FEATURE_ENABLED
#define FXGMAC_PAUSE_FEATURE_ENABLED 0
#undef CONFIG_PCI_MSI
#endif
/* centos 7 define end */
/* read from 8bit register via pci config space */
#define cfg_r8(_pdata, reg, pdat) pci_read_config_byte((_pdata)->pdev, (reg), (u8 *)(pdat))
/* read from 16bit register via pci config space */
#define cfg_r16(_pdata, reg, pdat) pci_read_config_word((_pdata)->pdev, (reg), (u16 *)(pdat))
/* read from 32bit register via pci config space */
#define cfg_r32(_pdata, reg, pdat) pci_read_config_dword((_pdata)->pdev, (reg), (u32 *)(pdat))
/* write to 8bit register via pci config space */
#define cfg_w8(_pdata, reg, val) pci_write_config_byte((_pdata)->pdev, (reg), (u8)(val))
/* write to 16bit register via pci config space */
#define cfg_w16(_pdata, reg, val) pci_write_config_word((_pdata)->pdev, (reg), (u16)(val))
/* write to 32bit register via pci config space */
#define cfg_w32(_pdata, reg, val) pci_write_config_dword((_pdata)->pdev, (reg), (u32)(val))
#define readreg(pAdapter, addr) (readl(addr))
#define writereg(pAdapter, val, addr) (writel(val, addr))
#define usleep_range_ex(pAdapter, a, b) (usleep_range(a, b))
#define _CR(Record, TYPE, Field) ((TYPE *) ((char *) (Record) - (char *) &(((TYPE *) 0)->Field)))
#define FXGMAC_GET_REG_BITS(var, pos, len) ({ \
typeof(pos) _pos = (pos); \
typeof(len) _len = (len); \
((var) & GENMASK(_pos + _len - 1, _pos)) >> (_pos); \
})
#define FXGMAC_GET_REG_BITS_LE(var, pos, len) ({ \
typeof(pos) _pos = (pos); \
typeof(len) _len = (len); \
typeof(var) _var = le32_to_cpu((var)); \
((_var) & GENMASK(_pos + _len - 1, _pos)) >> (_pos); \
})
#define FXGMAC_SET_REG_BITS(var, pos, len, val) ({ \
typeof(var) _var = (var); \
typeof(pos) _pos = (pos); \
typeof(len) _len = (len); \
typeof(val) _val = (val); \
_val = (_val << _pos) & GENMASK(_pos + _len - 1, _pos); \
_var = (_var & ~GENMASK(_pos + _len - 1, _pos)) | _val; \
})
#define FXGMAC_SET_REG_BITS_LE(var, pos, len, val) ({ \
typeof(var) _var = (var); \
typeof(pos) _pos = (pos); \
typeof(len) _len = (len); \
typeof(val) _val = (val); \
_val = (_val << _pos) & GENMASK(_pos + _len - 1, _pos); \
_var = (_var & ~GENMASK(_pos + _len - 1, _pos)) | _val; \
cpu_to_le32(_var); \
})
#define STR_FORMAT "%s"
#define DbgPrintF(level, fmt, ...)
#define DBGPRINT(Level, Fmt)
#define DBGPRINT_RAW(Level, Fmt)
#define DBGPRINT_S(Status, Fmt)
#define DBGPRINT_UNICODE(Level, UString)
#define Dump(p,cb,fAddress,ulGroup)
#undef ASSERT
#define ASSERT(x)
#define DbgPrintOidName(_Oid)
#define DbgPrintAddress(_pAddress)
// #define fxgmac_dump_buffer(_skb, _len, _tx_rx)
#define DumpLine(_p, _cbLine, _fAddress, _ulGroup )
#ifndef __far
#define __far
#endif
#ifndef FXGMAC_DEBUG
/* #define FXGMAC_DEBUG */
#endif
/* For debug prints */
#ifdef FXGMAC_DEBUG
#define FXGMAC_PR(fmt, args...) \
pr_alert("[%s,%d]:" fmt, __func__, __LINE__, ## args)
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,9,0))
/*
* If you want to continue a line, you NEED to use KERN_CONT.
* That has always been true. It hasn't always been enforced, though.
* If you do two printk's and the second one doesn't say "I'm a continuation",
* the printk logic assumes you're just confused and wanted two lines.
*/
#define DPRINTK(fmt, args...) \
printk(KERN_CONT fmt, ## args)
#else
#define DPRINTK printk
#endif
#else
#define FXGMAC_PR(x...) do { } while (0)
#define DPRINTK(x...)
#endif
#define IOC_MAGIC 'M'
#define IOC_MAXNR (0x80 + 5)
#define FXGMAC_DFS_IOCTL_DEVICE_INACTIVE 0x10001
#define FXGMAC_DFS_IOCTL_DEVICE_RESET 0x10002
#define FXGMAC_DFS_IOCTL_DIAG_BEGIN 0x10003
#define FXGMAC_DFS_IOCTL_DIAG_END 0x10004
#define FXGMAC_DFS_IOCTL_DIAG_TX_PKT 0x10005
#define FXGMAC_DFS_IOCTL_DIAG_RX_PKT 0x10006
#define FXGMAC_EFUSE_UPDATE_LED_CFG 0x10007
#define FXGMAC_EFUSE_WRITE_LED 0x10008
#define FXGMAC_EFUSE_WRITE_PATCH_REG 0x10009
#define FXGMAC_EFUSE_WRITE_PATCH_PER_INDEX 0x1000A
#define FXGMAC_EFUSE_WRITE_OOB 0x1000B
#define FXGMAC_EFUSE_LOAD 0x1000C
#define FXGMAC_EFUSE_READ_REGIONABC 0x1000D
#define FXGMAC_EFUSE_READ_PATCH_REG 0x1000E
#define FXGMAC_EFUSE_READ_PATCH_PER_INDEX 0x1000F
#define FXGMAC_EFUSE_LED_TEST 0x10010
#define FXGMAC_GET_MAC_DATA 0x10011
#define FXGMAC_SET_MAC_DATA 0x10012
#define FXGMAC_GET_SUBSYS_ID 0x10013
#define FXGMAC_SET_SUBSYS_ID 0x10014
#define FXGMAC_GET_REG 0x10015
#define FXGMAC_SET_REG 0x10016
#define FXGMAC_GET_PHY_REG 0x10017
#define FXGMAC_SET_PHY_REG 0x10018
#define FXGMAC_EPHY_STATISTICS 0x10019
#define FXGMAC_GET_STATISTICS 0x1001A
#define FXGMAC_GET_PCIE_LOCATION 0x1001B
#define FXGMAC_GET_GSO_SIZE 0x1001C
#define FXGMAC_SET_GSO_SIZE 0x1001D
#define FXGMAC_SET_RX_MODERATION 0x1001E
#define FXGMAC_SET_TX_MODERATION 0x1001F
#define FXGMAC_GET_TXRX_MODERATION 0x10020
#define MAX_PKT_BUF 1
#define FXGAMC_MAX_DATA_SIZE (1024 * 4 + 16)
#ifndef PCI_CAP_ID_MSI
#define PCI_CAP_ID_MSI 0x05 /* Message Signalled Interrupts */
#endif
#ifndef PCI_CAP_ID_MSIX
#define PCI_CAP_ID_MSIX 0x11 /* MSI-X */
#endif
#define PCI_CAP_ID_MSI_ENABLE_POS 0x10
#define PCI_CAP_ID_MSI_ENABLE_LEN 0x1
#define PCI_CAP_ID_MSIX_ENABLE_POS 0x1F
#define PCI_CAP_ID_MSIX_ENABLE_LEN 0x1
#define FXGMAC_IRQ_ENABLE 0x1
#define FXGMAC_IRQ_DISABLE 0x0
#define FXGMAC_NAPI_ENABLE 0x1
#define FXGMAC_NAPI_DISABLE 0x0
#ifndef fallthrough
#ifdef __has_attribute
#if __has_attribute(__fallthrough__)
# define fallthrough __attribute__((__fallthrough__))
#else
# define fallthrough do {} while (0) /* fallthrough */
#endif
#else
# define fallthrough do {} while (0) /* fallthrough */
#endif
#endif
#define PHY_POWER_DOWN 1
#define PHY_POWER_UP 0
#define FXGMAC_MMC_IER_ALL_DEFAULT 0
/* #define FXGMAC_ESD_CHECK_ENABLED */
#ifdef FXGMAC_ESD_CHECK_ENABLED
#define FXGMAC_ESD_INTERVAL (5 * HZ)
#define FXGMAC_ESD_ERROR_THRESHOLD (u64)4000000000
#define FXGMAC_PCIE_LINK_DOWN 0xFFFFFFFF
#define FXGMAC_PCIE_RECOVER_TIMES 5000
#define FXGMAC_PCIE_IO_MEM_MASTER_ENABLE 0x7
#endif
//#define FXGMAC_EPHY_LOOPBACK_DETECT_ENABLED
#ifdef FXGMAC_EPHY_LOOPBACK_DETECT_ENABLED
#define FXGMAC_LOOPBACK_CHECK_INTERVAL (5 * HZ)
#define FXGMAC_PHY_LOOPBACK_DETECT_THRESOLD 2
#endif
//#define FXGMAC_ASPM_ENABLED
#ifdef FXGMAC_ASPM_ENABLED
#define FXGMAC_CHECK_DEV_STATE
#define FXGMAC_ASPM_INTERVAL (20 * HZ)
#endif
#ifndef BIT
#define BIT(n) (0x1<<(n))
#endif
#define UDP_RSS_FLAGS (BIT(MAC_RSSCR_UDP4TE_POS) | \
BIT(MAC_RSSCR_UDP6TE_POS))
#define MF90_SUB_VENTOR_ID 0x17aa
#define MF90_SUB_DEVICE_ID 0x3509
#pragma pack(1)
/* it's better to make this struct's size to 128byte. */
struct pattern_packet{
u8 ether_daddr[ETH_ALEN];
u8 ether_saddr[ETH_ALEN];
u16 ether_type;
__be16 ar_hrd; /* format of hardware address */
__be16 ar_pro; /* format of protocol */
unsigned char ar_hln; /* length of hardware address */
unsigned char ar_pln; /* length of protocol address */
__be16 ar_op; /* ARP opcode (command) */
unsigned char ar_sha[ETH_ALEN]; /* sender hardware address */
unsigned char ar_sip[4]; /* sender IP address */
unsigned char ar_tha[ETH_ALEN]; /* target hardware address */
unsigned char ar_tip[4]; /* target IP address */
u8 reverse[86];
};
#pragma pack()
typedef dma_addr_t DMA_ADDR_T;
typedef enum pkt_hash_types RSS_HASH_TYPE;
typedef void __iomem* IOMEM;
typedef struct pci_dev PCI_DEV;
struct ext_command_buf {
void* buf;
u32 size_in;
u32 size_out;
};
struct ext_command_mac {
u32 num;
union {
u32 val32;
u16 val16;
u8 val8;
};
};
struct ext_command_mii {
u16 dev;
u16 num;
u16 val;
};
struct ext_ioctl_data {
u32 cmd_type;
struct ext_command_buf cmd_buf;
};
typedef struct _fxgmac_test_buf {
u8* addr;
u32 offset;
u32 length;
} fxgmac_test_buf, *pfxgmac_test_buf;
typedef struct _fxgmac_test_packet {
struct _fxgmac_test_packet * next;
u32 length; /* total length of the packet(buffers) */
u32 type; /* packet type, vlan, ip checksum, TSO, etc. */
fxgmac_test_buf buf[MAX_PKT_BUF];
fxgmac_test_buf sGList[MAX_PKT_BUF];
u16 vlanID;
u16 mss;
u32 hash;
u16 cpuNum;
u16 xsum; /* rx, ip-payload checksum */
u16 csumStart; /* custom checksum offset to the mac-header */
u16 csumPos; /* custom checksom position (to the mac_header) */
void* upLevelReserved[4];
void* lowLevelReserved[4];
} fxgmac_test_packet, *pfxgmac_test_packet;
typedef struct fxgmac_channel_of_platform
{
char dma_irq_name[IFNAMSIZ + 32];
u32 dma_irq_tx; //for MSIx to match the type of struct msix_entry.vector
char dma_irq_name_tx[IFNAMSIZ + 32];
/* Netdev related settings */
struct napi_struct napi_tx;
/* Netdev related settings */
struct napi_struct napi_rx;
struct timer_list tx_timer;
#if FXGMAC_TX_HANG_TIMER_ENABLED
unsigned int tx_hang_timer_active;
struct timer_list tx_hang_timer;
unsigned int tx_hang_hw_cur;
#endif
}FXGMAC_CHANNEL_OF_PLATFORM;
typedef struct per_regisiter_info
{
unsigned int size;
unsigned int address;
unsigned int value;
unsigned char data[FXGAMC_MAX_DATA_SIZE];
}PER_REG_INFO;
/*
* for FXGMAC_EFUSE_WRITE_PATCH_PER_INDEX,val0 is index, val1 is offset,
* val2 is value
*/
typedef struct ext_command_data {
u32 val0;
u32 val1;
u32 val2;
}CMD_DATA;
enum fxgmac_task_flag {
FXGMAC_FLAG_TASK_DOWN = 0,
FXGMAC_FLAG_TASK_RESET_PENDING,
FXGMAC_FLAG_TASK_ESD_CHECK_PENDING,
FXGMAC_FLAG_TASK_LINKCHG_CHECK_PENDING,
FXGMAC_FLAG_TASK_MAX
};
typedef struct fxgmac_esd_stats {
u32 tx_abort_excess_collisions;
u32 tx_dma_underrun;
u32 tx_lost_crs;
u32 tx_late_collisions;
u32 rx_crc_errors;
u32 rx_align_errors;
u32 rx_runt_errors;
u32 single_collisions;
u32 multi_collisions;
u32 tx_deferred_frames;
}FXGMAC_ESD_STATS;
typedef enum fxgmac_dev_state {
FXGMAC_DEV_OPEN = 0x0,
FXGMAC_DEV_CLOSE = 0x1,
FXGMAC_DEV_STOP = 0x2,
FXGMAC_DEV_START = 0x3,
FXGMAC_DEV_SUSPEND = 0x4,
FXGMAC_DEV_RESUME = 0x5,
FXGMAC_DEV_PROBE = 0xFF,
}DEV_STATE;
typedef struct fxgmac_pdata_of_platform
{
u32 cfg_pci_cmd;
u32 cfg_cache_line_size;
u32 cfg_mem_base;
u32 cfg_mem_base_hi;
u32 cfg_io_base;
u32 cfg_int_line;
u32 cfg_device_ctrl1;
u32 cfg_pci_link_ctrl;
u32 cfg_device_ctrl2;
u32 cfg_msix_capability;
int pre_phy_speed;
int pre_phy_duplex;
int pre_phy_autoneg;
struct work_struct restart_work;
#ifdef FXGMAC_ESD_CHECK_ENABLED
struct delayed_work esd_work;
FXGMAC_ESD_STATS esd_stats;
DECLARE_BITMAP(task_flags, FXGMAC_FLAG_TASK_MAX);
#endif
#ifdef FXGMAC_EPHY_LOOPBACK_DETECT_ENABLED
struct delayed_work loopback_work;
u32 lb_test_flag; // for tool
u32 lb_cable_flag; // for driver
u32 lb_cable_detect_count; // for driver
#endif
#ifdef FXGMAC_ASPM_ENABLED
struct delayed_work aspm_config_work;
bool aspm_en;
bool aspm_work_active;
#endif
bool recover_from_aspm;
u32 int_flags; /* legacy, msi or msix */
int misc_irq;
#ifdef CONFIG_PCI_MSI
struct msix_entry *msix_entries;
#endif
/* power management and wol*/
u32 wol;
unsigned long powerstate;
/*for ns-offload table. 2 entries supported. */
unsigned int ns_offload_tab_idx;
netdev_features_t netdev_features;
struct napi_struct napi;
#ifndef FXGMAC_MISC_NOT_ENABLED
struct napi_struct napi_misc;
#endif
u8 recover_phy_state;
char misc_irq_name[IFNAMSIZ + 32];
bool phy_link;
bool fxgmac_test_tso_flag;
u32 fxgmac_test_tso_seg_num;
u32 fxgmac_test_last_tso_len;
u32 fxgmac_test_packet_len;
volatile u32 fxgmac_test_skb_arr_in_index;
volatile u32 fxgmac_test_skb_arr_out_index;
/* CMD_DATA ex_cmd_data; */
/* PER_REG_INFO per_reg_data; */
struct sk_buff *fxgmac_test_skb_array[FXGMAC_MAX_DBG_TEST_PKT];
DEV_STATE dev_state;
struct mutex mutex;
struct timer_list phy_poll_tm;
}FXGMAC_PDATA_OF_PLATFORM;
void fxgmac_restart_dev(struct fxgmac_pdata *pdata);
long fxgmac_netdev_ops_ioctl(struct file *file, unsigned int cmd,
unsigned long arg);
int fxgmac_init(struct fxgmac_pdata *pdata, bool save_private_reg);
/* for phy interface */
#if 0
int fxgmac_ephy_autoneg_ability_get(struct fxgmac_pdata *pdata,
unsigned int *cap_mask);
#endif
int fxgmac_ephy_status_get(struct fxgmac_pdata *pdata, int* speed,
int* duplex, int* ret_link, int *media);
int fxgmac_ephy_soft_reset(struct fxgmac_pdata *pdata);
int fxgmac_phy_force_mode(struct fxgmac_pdata *pdata);
int fxgmac_phy_force_speed(struct fxgmac_pdata *pdata, int speed);
int fxgmac_phy_force_duplex(struct fxgmac_pdata *pdata, int duplex);
int fxgmac_phy_force_autoneg(struct fxgmac_pdata *pdata, int autoneg);
//void fxgmac_act_phy_link(struct fxgmac_pdata *pdata);
int fxgmac_phy_timer_init(struct fxgmac_pdata *pdata);
void fxgmac_phy_timer_destroy(struct fxgmac_pdata *pdata);
void fxgmac_phy_update_link(struct net_device *netdev);
unsigned int fxgmac_get_netdev_ip4addr(struct fxgmac_pdata *pdata);
unsigned char * fxgmac_get_netdev_ip6addr(struct fxgmac_pdata *pdata,
unsigned char *ipval,
unsigned char *ip6addr_solicited,
unsigned int ifa_flag);
#if FXGMAC_PM_FEATURE_ENABLED
void fxgmac_net_powerdown(struct fxgmac_pdata *pdata, unsigned int wol);
void fxgmac_net_powerup(struct fxgmac_pdata *pdata);
#endif
inline unsigned int fxgmac_tx_avail_desc(struct fxgmac_ring *ring);
inline unsigned int fxgmac_rx_dirty_desc(struct fxgmac_ring *ring);
int fxgmac_start(struct fxgmac_pdata *pdata);
void fxgmac_stop(struct fxgmac_pdata *pdata);
void fxgmac_free_rx_data(struct fxgmac_pdata *pdata);
void fxgmac_free_tx_data(struct fxgmac_pdata *pdata);
void fxgmac_tx_start_xmit(struct fxgmac_channel *channel, struct fxgmac_ring *ring);
void fxgmac_dev_xmit(struct fxgmac_channel *channel);
void fxgmac_config_wol(struct fxgmac_pdata *pdata, int en);
void fxgmac_print_pkt(struct net_device *netdev, struct sk_buff *skb, bool tx_rx);
void fxgmac_lock(struct fxgmac_pdata * pdata);
void fxgmac_unlock(struct fxgmac_pdata * pdata);
void fxgmac_set_phy_link_ksettings(struct fxgmac_pdata *pdata);
#ifdef FXGMAC_ASPM_ENABLED
void fxgmac_schedule_aspm_config_work(struct fxgmac_pdata *pdata);
void fxgmac_cancel_aspm_config_work(struct fxgmac_pdata *pdata);
bool fxgmac_aspm_action_linkup(struct fxgmac_pdata *pdata);
#endif
#endif /* __FXGMAC_OS_H__ */
+49
View File
@@ -0,0 +1,49 @@
#!/bin/sh
#
# yt6801 initramfs-tools hook script
#
# Installs copies of firmware files for the yt6801 driver
# to the early initramfs
PREREQ=""
prereqs()
{
echo "$PREREQ"
}
case $1 in
prereqs)
prereqs
exit 0
;;
esac
. /usr/share/initramfs-tools/hook-functions
#
# Copy yt6801 driver to /lib/modules/<KERNEL_VERSION> to be seen
# by mkinitramfs tool during initrd.img creation
#
copy_yt6801_driver() {
local dir="/lib/modules/$version/kernel/kylin/yt6801"
mkdir -p $dir
cp -a $dir/yt6801.ko $dir
}
#
# Remove yt6801 driver at /lib/modules/<KERNEL_VERSION> location
#
clean_yt6801_driver() {
local dir="/lib/modules/$version/kernel/kylin/yt6801"
rm -rf $dir
# if [ -z "$(ls -A $dir)" ]; then
# rm -rf $dir
# fi
}
copy_yt6801_driver
manual_add_modules yt6801
#clean_yt6801_driver
+3 -3
View File
@@ -10,14 +10,14 @@ BOARDNAME:=Loongson LoongArch
FEATURES:=audio display ext4 pcie boot-part rootfs-part rtc usb targz
SUBTARGETS:=generic
KERNEL_PATCHVER:=6.6
KERNEL_TESTING_PATCHVER:=6.12
KERNEL_PATCHVER:=6.12
KERNEL_TESTING_PATCHVER:=6.6
KERNELNAME:=vmlinuz.efi dtbs
include $(INCLUDE_DIR)/target.mk
DEFAULT_PACKAGES += \
partx-utils blkid e2fsprogs grub2-efi-loongarch64
partx-utils blkid e2fsprogs grub2-efi-loongarch64 kmod-yt6801
$(eval $(call BuildTarget))
+95 -74
View File
@@ -5,6 +5,7 @@ import (
"fmt"
"net"
"strconv"
"strings"
"sync"
CN "github.com/metacubex/mihomo/common/net"
@@ -30,8 +31,8 @@ type MieruOption struct {
BasicOption
Name string `proxy:"name"`
Server string `proxy:"server"`
Port int `proxy:"port,omitempty"`
PortRange string `proxy:"port-range,omitempty"`
Port string `proxy:"port,omitempty"`
PortRange string `proxy:"port-range,omitempty"` // deprecated
Transport string `proxy:"transport"`
UDP bool `proxy:"udp,omitempty"`
UserName string `proxy:"username"`
@@ -123,13 +124,19 @@ func NewMieru(option MieruOption) (*Mieru, error) {
}
// Client is started lazily on the first use.
// Use the first port to construct the address.
var addr string
if option.Port != 0 {
addr = net.JoinHostPort(option.Server, strconv.Itoa(option.Port))
var portStr string
if option.Port != "" {
portStr = option.Port
} else {
beginPort, _, _ := beginAndEndPortFromPortRange(option.PortRange)
addr = net.JoinHostPort(option.Server, strconv.Itoa(beginPort))
portStr = option.PortRange
}
firstPort, err := getFirstPort(portStr)
if err != nil {
return nil, fmt.Errorf("failed to get first port from port string %q: %w", portStr, err)
}
addr = net.JoinHostPort(option.Server, strconv.Itoa(firstPort))
outbound := &Mieru{
Base: &Base{
name: option.Name,
@@ -183,54 +190,62 @@ func buildMieruClientConfig(option MieruOption) (*mieruclient.ClientConfig, erro
}
transportProtocol := mierupb.TransportProtocol_TCP.Enum()
var server *mierupb.ServerEndpoint
if net.ParseIP(option.Server) != nil {
// server is an IP address
if option.PortRange != "" {
server = &mierupb.ServerEndpoint{
IpAddress: proto.String(option.Server),
PortBindings: []*mierupb.PortBinding{
{
PortRange: proto.String(option.PortRange),
portBindings := make([]*mierupb.PortBinding, 0)
if option.Port != "" {
parts := strings.Split(option.Port, ",")
for _, part := range parts {
part = strings.TrimSpace(part)
if strings.Contains(part, "-") {
_, _, err := beginAndEndPortFromPortRange(part)
if err == nil {
portBindings = append(portBindings, &mierupb.PortBinding{
PortRange: proto.String(part),
Protocol: transportProtocol,
},
},
}
} else {
server = &mierupb.ServerEndpoint{
IpAddress: proto.String(option.Server),
PortBindings: []*mierupb.PortBinding{
{
Port: proto.Int32(int32(option.Port)),
Protocol: transportProtocol,
},
},
}
}
} else {
// server is a domain name
if option.PortRange != "" {
server = &mierupb.ServerEndpoint{
DomainName: proto.String(option.Server),
PortBindings: []*mierupb.PortBinding{
{
PortRange: proto.String(option.PortRange),
Protocol: transportProtocol,
},
},
}
} else {
server = &mierupb.ServerEndpoint{
DomainName: proto.String(option.Server),
PortBindings: []*mierupb.PortBinding{
{
Port: proto.Int32(int32(option.Port)),
Protocol: transportProtocol,
},
},
})
} else {
return nil, err
}
} else {
p, err := strconv.Atoi(part)
if err != nil {
return nil, fmt.Errorf("invalid port value: %s", part)
}
portBindings = append(portBindings, &mierupb.PortBinding{
Port: proto.Int32(int32(p)),
Protocol: transportProtocol,
})
}
}
}
if option.PortRange != "" {
parts := strings.Split(option.PortRange, ",")
for _, part := range parts {
part = strings.TrimSpace(part)
if _, _, err := beginAndEndPortFromPortRange(part); err == nil {
portBindings = append(portBindings, &mierupb.PortBinding{
PortRange: proto.String(part),
Protocol: transportProtocol,
})
}
}
}
var server *mierupb.ServerEndpoint
if net.ParseIP(option.Server) != nil {
// server is an IP address
server = &mierupb.ServerEndpoint{
IpAddress: proto.String(option.Server),
PortBindings: portBindings,
}
} else {
// server is a domain name
server = &mierupb.ServerEndpoint{
DomainName: proto.String(option.Server),
PortBindings: portBindings,
}
}
config := &mieruclient.ClientConfig{
Profile: &mierupb.ClientProfile{
ProfileName: proto.String(option.Name),
@@ -259,31 +274,9 @@ func validateMieruOption(option MieruOption) error {
if option.Server == "" {
return fmt.Errorf("server is empty")
}
if option.Port == 0 && option.PortRange == "" {
return fmt.Errorf("either port or port-range must be set")
if option.Port == "" && option.PortRange == "" {
return fmt.Errorf("port must be set")
}
if option.Port != 0 && option.PortRange != "" {
return fmt.Errorf("port and port-range cannot be set at the same time")
}
if option.Port != 0 && (option.Port < 1 || option.Port > 65535) {
return fmt.Errorf("port must be between 1 and 65535")
}
if option.PortRange != "" {
begin, end, err := beginAndEndPortFromPortRange(option.PortRange)
if err != nil {
return fmt.Errorf("invalid port-range format")
}
if begin < 1 || begin > 65535 {
return fmt.Errorf("begin port must be between 1 and 65535")
}
if end < 1 || end > 65535 {
return fmt.Errorf("end port must be between 1 and 65535")
}
if begin > end {
return fmt.Errorf("begin port must be less than or equal to end port")
}
}
if option.Transport != "TCP" {
return fmt.Errorf("transport must be TCP")
}
@@ -306,8 +299,36 @@ func validateMieruOption(option MieruOption) error {
return nil
}
func getFirstPort(portStr string) (int, error) {
if portStr == "" {
return 0, fmt.Errorf("port string is empty")
}
parts := strings.Split(portStr, ",")
firstPart := parts[0]
if strings.Contains(firstPart, "-") {
begin, _, err := beginAndEndPortFromPortRange(firstPart)
if err != nil {
return 0, err
}
return begin, nil
}
port, err := strconv.Atoi(firstPart)
if err != nil {
return 0, fmt.Errorf("invalid port format: %s", firstPart)
}
return port, nil
}
func beginAndEndPortFromPortRange(portRange string) (int, int, error) {
var begin, end int
_, err := fmt.Sscanf(portRange, "%d-%d", &begin, &end)
if err != nil {
return 0, 0, fmt.Errorf("invalid port range format: %w", err)
}
if begin > end {
return 0, 0, fmt.Errorf("begin port is greater than end port: %s", portRange)
}
return begin, end, err
}
+218 -4
View File
@@ -1,22 +1,51 @@
package outbound
import "testing"
import (
"reflect"
"testing"
mieruclient "github.com/enfein/mieru/v3/apis/client"
mierupb "github.com/enfein/mieru/v3/pkg/appctl/appctlpb"
"google.golang.org/protobuf/proto"
)
func TestNewMieru(t *testing.T) {
transportProtocol := mierupb.TransportProtocol_TCP.Enum()
testCases := []struct {
option MieruOption
wantBaseAddr string
wantConfig *mieruclient.ClientConfig
}{
{
option: MieruOption{
Name: "test",
Server: "1.2.3.4",
Port: 10000,
Port: "10000",
Transport: "TCP",
UserName: "test",
Password: "test",
},
wantBaseAddr: "1.2.3.4:10000",
wantConfig: &mieruclient.ClientConfig{
Profile: &mierupb.ClientProfile{
ProfileName: proto.String("test"),
User: &mierupb.User{
Name: proto.String("test"),
Password: proto.String("test"),
},
Servers: []*mierupb.ServerEndpoint{
{
IpAddress: proto.String("1.2.3.4"),
PortBindings: []*mierupb.PortBinding{
{
Port: proto.Int32(10000),
Protocol: transportProtocol,
},
},
},
},
},
},
},
{
option: MieruOption{
@@ -28,28 +57,212 @@ func TestNewMieru(t *testing.T) {
Password: "test",
},
wantBaseAddr: "[2001:db8::1]:10001",
wantConfig: &mieruclient.ClientConfig{
Profile: &mierupb.ClientProfile{
ProfileName: proto.String("test"),
User: &mierupb.User{
Name: proto.String("test"),
Password: proto.String("test"),
},
Servers: []*mierupb.ServerEndpoint{
{
IpAddress: proto.String("2001:db8::1"),
PortBindings: []*mierupb.PortBinding{
{
PortRange: proto.String("10001-10002"),
Protocol: transportProtocol,
},
},
},
},
},
},
},
{
option: MieruOption{
Name: "test",
Server: "example.com",
Port: 10003,
Port: "10003",
Transport: "TCP",
UserName: "test",
Password: "test",
},
wantBaseAddr: "example.com:10003",
wantConfig: &mieruclient.ClientConfig{
Profile: &mierupb.ClientProfile{
ProfileName: proto.String("test"),
User: &mierupb.User{
Name: proto.String("test"),
Password: proto.String("test"),
},
Servers: []*mierupb.ServerEndpoint{
{
DomainName: proto.String("example.com"),
PortBindings: []*mierupb.PortBinding{
{
Port: proto.Int32(10003),
Protocol: transportProtocol,
},
},
},
},
},
},
},
{
option: MieruOption{
Name: "test",
Server: "example.com",
Port: "10004,10005",
Transport: "TCP",
UserName: "test",
Password: "test",
},
wantBaseAddr: "example.com:10004",
wantConfig: &mieruclient.ClientConfig{
Profile: &mierupb.ClientProfile{
ProfileName: proto.String("test"),
User: &mierupb.User{
Name: proto.String("test"),
Password: proto.String("test"),
},
Servers: []*mierupb.ServerEndpoint{
{
DomainName: proto.String("example.com"),
PortBindings: []*mierupb.PortBinding{
{
Port: proto.Int32(10004),
Protocol: transportProtocol,
},
{
Port: proto.Int32(10005),
Protocol: transportProtocol,
},
},
},
},
},
},
},
{
option: MieruOption{
Name: "test",
Server: "example.com",
Port: "10006-10007,11000",
Transport: "TCP",
UserName: "test",
Password: "test",
},
wantBaseAddr: "example.com:10006",
wantConfig: &mieruclient.ClientConfig{
Profile: &mierupb.ClientProfile{
ProfileName: proto.String("test"),
User: &mierupb.User{
Name: proto.String("test"),
Password: proto.String("test"),
},
Servers: []*mierupb.ServerEndpoint{
{
DomainName: proto.String("example.com"),
PortBindings: []*mierupb.PortBinding{
{
PortRange: proto.String("10006-10007"),
Protocol: transportProtocol,
},
{
Port: proto.Int32(11000),
Protocol: transportProtocol,
},
},
},
},
},
},
},
{
option: MieruOption{
Name: "test",
Server: "example.com",
Port: "10008",
PortRange: "10009-10010",
Transport: "TCP",
UserName: "test",
Password: "test",
},
wantBaseAddr: "example.com:10008",
wantConfig: &mieruclient.ClientConfig{
Profile: &mierupb.ClientProfile{
ProfileName: proto.String("test"),
User: &mierupb.User{
Name: proto.String("test"),
Password: proto.String("test"),
},
Servers: []*mierupb.ServerEndpoint{
{
DomainName: proto.String("example.com"),
PortBindings: []*mierupb.PortBinding{
{
Port: proto.Int32(10008),
Protocol: transportProtocol,
},
{
PortRange: proto.String("10009-10010"),
Protocol: transportProtocol,
},
},
},
},
},
},
},
}
for _, testCase := range testCases {
mieru, err := NewMieru(testCase.option)
if err != nil {
t.Error(err)
t.Fatal(err)
}
config, err := mieru.client.Load()
if err != nil {
t.Fatal(err)
}
config.Dialer = nil
if mieru.addr != testCase.wantBaseAddr {
t.Errorf("got addr %q, want %q", mieru.addr, testCase.wantBaseAddr)
}
if !reflect.DeepEqual(config, testCase.wantConfig) {
t.Errorf("got config %+v, want %+v", config, testCase.wantConfig)
}
}
}
func TestNewMieruError(t *testing.T) {
testCases := []MieruOption{
{
Name: "test",
Server: "example.com",
Port: "invalid",
PortRange: "invalid",
Transport: "TCP",
UserName: "test",
Password: "test",
},
{
Name: "test",
Server: "example.com",
Port: "",
PortRange: "",
Transport: "TCP",
UserName: "test",
Password: "test",
},
}
for _, option := range testCases {
_, err := NewMieru(option)
if err == nil {
t.Errorf("expected error for option %+v, but got nil", option)
}
}
}
@@ -63,6 +276,7 @@ func TestBeginAndEndPortFromPortRange(t *testing.T) {
{"1-10", 1, 10, false},
{"1000-2000", 1000, 2000, false},
{"65535-65535", 65535, 65535, false},
{"2000-1000", 0, 0, true},
{"1", 0, 0, true},
{"1-", 0, 0, true},
{"-10", 0, 0, true},
+2 -8
View File
@@ -24,7 +24,6 @@ import (
"github.com/metacubex/randv2"
utls "github.com/metacubex/utls"
"golang.org/x/crypto/chacha20poly1305"
"golang.org/x/crypto/hkdf"
"golang.org/x/net/http2"
)
@@ -107,13 +106,8 @@ func GetRealityConn(ctx context.Context, conn net.Conn, fingerprint UClientHello
if err != nil {
return nil, err
}
var aeadCipher cipher.AEAD
if utls.AesgcmPreferred(hello.CipherSuites) {
aesBlock, _ := aes.NewCipher(authKey)
aeadCipher, _ = cipher.NewGCM(aesBlock)
} else {
aeadCipher, _ = chacha20poly1305.New(authKey)
}
aesBlock, _ := aes.NewCipher(authKey)
aeadCipher, _ := cipher.NewGCM(aesBlock)
aeadCipher.Seal(hello.SessionId[:0], hello.Random[20:], hello.SessionId[:16], hello.Raw)
copy(hello.Raw[39:], hello.SessionId)
//log.Debugln("REALITY hello.sessionId: %v", hello.SessionId)
+2 -2
View File
@@ -1024,8 +1024,8 @@ proxies: # socks5
- name: mieru
type: mieru
server: 1.2.3.4
port: 2999
# port-range: 2090-2099 #(不可同时填写 port 和 port-range
port: 2999 # 支持使用 ports 格式,例如 2999,3999 或 2999-3010,3950,3995-3999
# port-range: 2090-2099 # 已废弃,请使用 port
transport: TCP # 只支持 TCP
udp: true # 支持 UDP over TCP
username: user
+2 -2
View File
@@ -22,7 +22,7 @@ require (
github.com/metacubex/chacha v0.1.5
github.com/metacubex/fswatch v0.1.1
github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759
github.com/metacubex/kcp-go v0.0.0-20250922034656-df9a2b90cdf7
github.com/metacubex/kcp-go v0.0.0-20250923001605-1ba6f691c45b
github.com/metacubex/quic-go v0.54.1-0.20250730114134-a1ae705fe295
github.com/metacubex/randv2 v0.2.0
github.com/metacubex/restls-client-go v0.1.7
@@ -37,7 +37,7 @@ require (
github.com/metacubex/sing-wireguard v0.0.0-20250503063753-2dc62acc626f
github.com/metacubex/smux v0.0.0-20250922175018-15c9a6a78719
github.com/metacubex/tfo-go v0.0.0-20250921095601-b102db4216c0
github.com/metacubex/utls v1.8.1-0.20250921102910-221428e5d4b2
github.com/metacubex/utls v1.8.1-0.20250923145048-0a5bbc90dd3e
github.com/metacubex/wireguard-go v0.0.0-20250820062549-a6cecdd7f57f
github.com/miekg/dns v1.1.63 // lastest version compatible with golang1.20
github.com/mroth/weightedrand/v2 v2.1.0
+4 -5
View File
@@ -112,8 +112,8 @@ github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759 h1:cjd4biTvO
github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759/go.mod h1:UHOv2xu+RIgLwpXca7TLrXleEd4oR3sPatW6IF8wU88=
github.com/metacubex/gvisor v0.0.0-20250919004547-6122b699a301 h1:N5GExQJqYAH3gOCshpp2u/J3CtNYzMctmlb0xK9wtbQ=
github.com/metacubex/gvisor v0.0.0-20250919004547-6122b699a301/go.mod h1:8LpS0IJW1VmWzUm3ylb0e2SK5QDm5lO/2qwWLZgRpBU=
github.com/metacubex/kcp-go v0.0.0-20250922034656-df9a2b90cdf7 h1:vGsrjQxlepSfkMALzJuvDzd+wp6NvKXpoyPuPb4SYCE=
github.com/metacubex/kcp-go v0.0.0-20250922034656-df9a2b90cdf7/go.mod h1:HIJZW4QMhbBqXuqC1ly6Hn0TEYT2SzRw58ns1yGhXTs=
github.com/metacubex/kcp-go v0.0.0-20250923001605-1ba6f691c45b h1:z7JLKjugnQ1qvDOAD8yMA5C8AlJY3bG+VrrgRntRlUY=
github.com/metacubex/kcp-go v0.0.0-20250923001605-1ba6f691c45b/go.mod h1:HIJZW4QMhbBqXuqC1ly6Hn0TEYT2SzRw58ns1yGhXTs=
github.com/metacubex/nftables v0.0.0-20250503052935-30a69ab87793 h1:1Qpuy+sU3DmyX9HwI+CrBT/oLNJngvBorR2RbajJcqo=
github.com/metacubex/nftables v0.0.0-20250503052935-30a69ab87793/go.mod h1:RjRNb4G52yAgfR+Oe/kp9G4PJJ97Fnj89eY1BFO3YyA=
github.com/metacubex/quic-go v0.54.1-0.20250730114134-a1ae705fe295 h1:8JVlYuE8uSJAvmyCd4TjvDxs57xjb0WxEoaWafK5+qs=
@@ -145,8 +145,8 @@ github.com/metacubex/smux v0.0.0-20250922175018-15c9a6a78719 h1:T6qCCfolRDAVJKea
github.com/metacubex/smux v0.0.0-20250922175018-15c9a6a78719/go.mod h1:4bPD8HWx9jPJ9aE4uadgyN7D1/Wz3KmPy+vale8sKLE=
github.com/metacubex/tfo-go v0.0.0-20250921095601-b102db4216c0 h1:Ui+/2s5Qz0lSnDUBmEL12M5Oi/PzvFxGTNohm8ZcsmE=
github.com/metacubex/tfo-go v0.0.0-20250921095601-b102db4216c0/go.mod h1:l9oLnLoEXyGZ5RVLsh7QCC5XsouTUyKk4F2nLm2DHLw=
github.com/metacubex/utls v1.8.1-0.20250921102910-221428e5d4b2 h1:5OGzQvoE5yuOe8AsZsFwhf32ZxKmKN9G+k06AVd+6jY=
github.com/metacubex/utls v1.8.1-0.20250921102910-221428e5d4b2/go.mod h1:GN/CB3TRwQ9LYquYpIFynDkvMTYmkjwI7+mkUIoHj88=
github.com/metacubex/utls v1.8.1-0.20250923145048-0a5bbc90dd3e h1:t9IxEaxSRp3YJ1ewQV4oGkKaJaMeSoUWjOV0boLVQo8=
github.com/metacubex/utls v1.8.1-0.20250923145048-0a5bbc90dd3e/go.mod h1:kncGGVhFaoGn5M3pFe3SXhZCzsbCJayNOH4UEqTKTko=
github.com/metacubex/wireguard-go v0.0.0-20250820062549-a6cecdd7f57f h1:FGBPRb1zUabhPhDrlKEjQ9lgIwQ6cHL4x8M9lrERhbk=
github.com/metacubex/wireguard-go v0.0.0-20250820062549-a6cecdd7f57f/go.mod h1:oPGcV994OGJedmmxrcK9+ni7jUEMGhR+uVQAdaduIP4=
github.com/metacubex/yamux v0.0.0-20250918083631-dd5f17c0be49 h1:lhlqpYHopuTLx9xQt22kSA9HtnyTDmk5XjjQVCGHe2E=
@@ -206,7 +206,6 @@ github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/tiendc/go-deepcopy v1.6.1 h1:uVRTItFeNHkMcLueHS7OCsxgxT9P8MzGB/taUa2Y4Tk=
github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=
github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=
+2 -4
View File
@@ -2,8 +2,6 @@ package kcptun
import (
"context"
"crypto/rand"
"encoding/binary"
"net"
"sync"
"time"
@@ -11,6 +9,7 @@ import (
"github.com/metacubex/mihomo/log"
"github.com/metacubex/kcp-go"
"github.com/metacubex/randv2"
"github.com/metacubex/smux"
)
@@ -60,8 +59,7 @@ func (c *Client) createConn(ctx context.Context, dial DialFn) (*smux.Session, er
}
config := c.config
var convid uint32
binary.Read(rand.Reader, binary.LittleEndian, &convid)
convid := randv2.Uint32()
kcpconn, err := kcp.NewConn4(convid, addr, c.block, config.DataShard, config.ParityShard, true, conn)
if err != nil {
return nil, err
+2 -13
View File
@@ -7,23 +7,12 @@ import (
"errors"
"io"
"net"
"runtime"
"sync"
"time"
"github.com/metacubex/blake3"
utls "github.com/metacubex/utls"
"github.com/metacubex/utls/mlkem"
"golang.org/x/sys/cpu"
)
var (
// Keep in sync with crypto/tls/cipher_suites.go.
hasGCMAsmAMD64 = cpu.X86.HasAES && cpu.X86.HasPCLMULQDQ && cpu.X86.HasSSE41 && cpu.X86.HasSSSE3
hasGCMAsmARM64 = cpu.ARM64.HasAES && cpu.ARM64.HasPMULL
hasGCMAsmS390X = cpu.S390X.HasAES && cpu.S390X.HasAESCTR && cpu.S390X.HasGHASH
hasGCMAsmPPC64 = runtime.GOARCH == "ppc64" || runtime.GOARCH == "ppc64le"
HasAESGCMHardwareSupport = hasGCMAsmAMD64 || hasGCMAsmARM64 || hasGCMAsmS390X || hasGCMAsmPPC64
)
type ClientInstance struct {
@@ -77,7 +66,7 @@ func (i *ClientInstance) Handshake(conn net.Conn) (*CommonConn, error) {
if i.NfsPKeys == nil {
return nil, errors.New("uninitialized")
}
c := NewCommonConn(conn, HasAESGCMHardwareSupport)
c := NewCommonConn(conn, utls.HasAESGCMHardwareSupport())
ivAndRealysLength := 16 + i.RelaysLength
pfsKeyExchangeLength := 18 + 1184 + 32 + 16
@@ -0,0 +1,21 @@
package encryption
import (
"fmt"
"runtime"
"testing"
utls "github.com/metacubex/utls"
)
func TestHasAESGCMHardwareSupport(t *testing.T) {
fmt.Println("HasAESGCMHardwareSupport:", utls.HasAESGCMHardwareSupport())
if runtime.GOARCH == "arm64" && runtime.GOOS == "darwin" {
// It should be supported starting from Apple Silicon M1
// https://github.com/golang/go/blob/go1.25.0/src/internal/cpu/cpu_arm64_darwin.go#L26-L30
if !utls.HasAESGCMHardwareSupport() {
t.Errorf("For ARM64 Darwin platforms (excluding iOS), AES GCM hardware acceleration should always be available.")
}
}
}
@@ -1,12 +1,12 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=UnblockNeteaseMusic
PKG_VERSION:=0.27.10
PKG_VERSION:=0.28.0
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/UnblockNeteaseMusic/server/tar.gz/v${PKG_VERSION}?
PKG_HASH:=49fc91f83485f29c4ac0f4867ebd473778639ac3f7ec526786577a10ca189b53
PKG_HASH:=0a1e843ffaa7b8ce65cc221daec07b63754473f0430019acb228f5b254602318
PKG_SOURCE_SUBDIR:=$(PKG_NAME)
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_SOURCE_SUBDIR)
@@ -163,7 +163,7 @@ start_service() {
ipset create "acl_neteasemusic_http" hash:ip
ipset create "acl_neteasemusic_https" hash:ip
ipset create "neteasemusic" hash:ip
ipset create "neteasemusic" hash:ip timeout 7200
config_foreach append_filter_client "acl_rule"
local netease_music_ips="$(wget -qO- "http://httpdns.n.netease.com/httpdns/v2/d?domain=music.163.com,interface.music.163.com,interface3.music.163.com,apm.music.163.com,apm3.music.163.com,clientlog.music.163.com,clientlog3.music.163.com" |jsonfilter -e '@.data.*.ip.*')"
+1 -1
View File
@@ -6,7 +6,7 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-passwall
PKG_VERSION:=25.9.19
PKG_VERSION:=25.9.23
PKG_RELEASE:=1
PKG_CONFIG_DEPENDS:= \
@@ -130,6 +130,11 @@ if #hysteria2_type > 0 then
end
end
if #ss_type > 0 or #trojan_type > 0 or #vmess_type > 0 or #vless_type > 0 or #hysteria2_type > 0 then
o.description = string.format("<font color='red'>%s</font>",
translate("The configured type also applies to the core specified when manually importing nodes."))
end
o = s:option(ListValue, "domain_strategy", "Sing-box " .. translate("Domain Strategy"), translate("Set the default domain resolution strategy for the sing-box node."))
o.default = ""
o:value("", translate("Auto"))
@@ -1336,16 +1336,13 @@ local hysteria2_type = get_core("hysteria2_type", {{has_hysteria2,"hysteria2"},{
dom_prefix = "xray_"
opt.set('type', "Xray");
}
opt.set(dom_prefix + 'protocol', "vless");
var m = parseNodeUrl(ssrurl);
var password = m.passwd;
if (password === "") {
s.innerHTML = "<font color='red'><%:Invalid Share URL Format%></font>";
return false;
}
opt.set(dom_prefix + 'uuid', password);
opt.set(dom_prefix + 'address', unbracketIP(m.hostname));
opt.set(dom_prefix + 'port', m.port || "443");
var queryParam = {};
if (m.search.length > 1) {
var query = m.search.replace('/?', '?').split('?')
@@ -1358,6 +1355,16 @@ local hysteria2_type = get_core("hysteria2_type", {{has_hysteria2,"hysteria2"},{
}
}
queryParam.type = queryParam.type.toLowerCase();
if (["xhttp", "kcp", "mkcp"].includes(queryParam.type) && vless_type !== "xray" && has_xray) {
dom_prefix = "xray_"
opt.set('type', "Xray");
}
opt.set(dom_prefix + 'protocol', "vless");
opt.set(dom_prefix + 'uuid', password);
opt.set(dom_prefix + 'address', unbracketIP(m.hostname));
opt.set(dom_prefix + 'port', m.port || "443");
opt.set(dom_prefix + 'encryption', queryParam.encryption || "none");
if (queryParam.security) {
if (queryParam.security == "tls") {
@@ -1397,7 +1404,6 @@ local hysteria2_type = get_core("hysteria2_type", {{has_hysteria2,"hysteria2"},{
}
queryParam.type = queryParam.type.toLowerCase();
if (queryParam.type === "kcp") {
queryParam.type = "mkcp";
}
@@ -1986,3 +1986,6 @@ msgstr "客户端版本"
msgid "Random version will be used if empty."
msgstr "如留空,则使用随机版本。"
msgid "The configured type also applies to the core specified when manually importing nodes."
msgstr "配置的类型同样适用于手动导入节点时所指定的核心程序。"
@@ -2280,8 +2280,8 @@ get_config() {
RESOLVFILE=/tmp/resolv.conf.d/resolv.conf.auto
[ -f "${RESOLVFILE}" ] && [ -s "${RESOLVFILE}" ] || RESOLVFILE=/tmp/resolv.conf.auto
ISP_DNS=$(cat $RESOLVFILE 2>/dev/null | grep -E -o "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+" | sort -u | grep -v 0.0.0.0 | grep -v 127.0.0.1)
ISP_DNS6=$(cat $RESOLVFILE 2>/dev/null | grep -E "([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}" | awk -F % '{print $1}' | awk -F " " '{print $2}'| sort -u | grep -v -Fx ::1 | grep -v -Fx ::)
ISP_DNS=$(cat $RESOLVFILE 2>/dev/null | grep -E -o "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+" | grep -v -E '^(0\.0\.0\.0|127\.0\.0\.1)$' | awk '!seen[$0]++')
ISP_DNS6=$(cat $RESOLVFILE 2>/dev/null | grep -E "([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}" | awk -F % '{print $1}' | awk -F " " '{print $2}' | grep -v -Fx ::1 | grep -v -Fx :: | awk '!seen[$0]++')
DEFAULT_DNS=$(uci show dhcp.@dnsmasq[0] | grep "\.server=" | awk -F '=' '{print $2}' | sed "s/'//g" | tr ' ' '\n' | grep -v "\/" | head -2 | sed ':label;N;s/\n/,/;b label')
[ -z "${DEFAULT_DNS}" ] && [ "$(echo $ISP_DNS | tr ' ' '\n' | wc -l)" -le 2 ] && DEFAULT_DNS=$(echo -n $ISP_DNS | tr ' ' '\n' | head -2 | tr '\n' ',' | sed 's/,$//')
File diff suppressed because it is too large Load Diff
@@ -53,6 +53,7 @@
101.198.0.0/22
101.198.160.0/19
101.198.192.0/19
101.198.4.0/24
101.199.112.0/24
101.199.128.0/23
101.199.196.0/22
@@ -89,6 +90,8 @@
101.248.0.0/15
101.251.0.0/22
101.251.128.0/19
101.251.160.0/20
101.251.176.0/22
101.251.192.0/18
101.251.80.0/20
101.254.0.0/20
@@ -207,7 +210,7 @@
103.126.101.0/24
103.126.102.0/23
103.126.124.0/22
103.126.18.0/23
103.126.19.0/24
103.13.12.0/24
103.13.244.0/22
103.130.160.0/23
@@ -253,6 +256,7 @@
103.145.92.0/24
103.146.126.0/23
103.147.124.0/24
103.149.111.0/24
103.149.181.0/24
103.149.242.0/24
103.149.244.0/22
@@ -264,6 +268,7 @@
103.150.212.0/24
103.150.24.0/23
103.151.148.0/23
103.151.179.0/24
103.151.216.0/23
103.151.228.0/23
103.151.5.0/24
@@ -281,6 +286,7 @@
103.154.30.0/23
103.154.41.0/24
103.155.110.0/23
103.155.120.0/23
103.155.76.0/23
103.156.174.0/23
103.156.186.0/23
@@ -311,8 +317,8 @@
103.175.197.0/24
103.177.28.0/23
103.179.78.0/23
103.18.186.0/24
103.180.108.0/23
103.181.164.0/23
103.181.234.0/24
103.183.122.0/23
103.183.124.0/23
@@ -387,7 +393,7 @@
103.21.140.0/22
103.21.176.0/22
103.210.160.0/22
103.210.170.0/23
103.210.171.0/24
103.211.220.0/22
103.211.44.0/22
103.212.1.0/24
@@ -655,6 +661,7 @@
103.42.8.0/22
103.43.132.0/24
103.43.134.0/23
103.43.175.0/24
103.43.184.0/22
103.43.240.0/23
103.44.144.0/22
@@ -685,7 +692,7 @@
103.49.196.0/24
103.49.198.0/23
103.5.192.0/22
103.50.36.0/22
103.50.38.0/24
103.51.62.0/23
103.52.100.0/22
103.52.104.0/23
@@ -744,6 +751,7 @@
103.71.232.0/22
103.71.68.0/22
103.72.113.0/24
103.72.120.0/22
103.72.172.0/24
103.73.116.0/22
103.73.136.0/21
@@ -768,7 +776,7 @@
103.78.60.0/22
103.79.120.0/22
103.79.200.0/22
103.79.228.0/23
103.79.228.0/24
103.79.24.0/22
103.8.220.0/22
103.8.32.0/22
@@ -957,6 +965,7 @@
110.218.192.0/20
110.218.224.0/20
110.218.32.0/20
110.219.128.0/17
110.219.64.0/22
110.219.68.0/24
110.228.0.0/14
@@ -1028,7 +1037,6 @@
111.235.178.0/23
111.235.180.0/23
111.235.182.0/24
111.67.192.0/20
111.72.0.0/13
111.85.0.0/16
112.0.0.0/10
@@ -1220,7 +1228,8 @@
115.175.64.0/19
115.182.0.0/15
115.190.0.0/17
115.190.128.0/19
115.190.128.0/18
115.190.192.0/20
115.192.0.0/11
115.224.0.0/12
115.24.0.0/14
@@ -1229,6 +1238,7 @@
115.32.0.0/19
115.32.32.0/21
115.32.56.0/21
115.32.64.0/20
115.44.0.0/14
115.48.0.0/12
115.84.0.0/18
@@ -1419,7 +1429,8 @@
118.178.0.0/16
118.180.0.0/14
118.184.0.0/22
118.184.104.0/22
118.184.105.0/24
118.184.106.0/23
118.184.128.0/17
118.184.30.0/24
118.184.40.0/21
@@ -1427,7 +1438,6 @@
118.184.52.0/24
118.184.64.0/24
118.184.66.0/23
118.184.69.0/24
118.184.76.0/22
118.184.81.0/24
118.184.82.0/23
@@ -1474,8 +1484,7 @@
118.192.70.0/24
118.192.96.0/19
118.193.128.0/23
118.193.138.0/24
118.193.144.0/23
118.193.144.0/24
118.193.152.0/22
118.193.160.0/23
118.193.162.0/24
@@ -1488,8 +1497,8 @@
118.194.240.0/21
118.194.32.0/19
118.195.0.0/16
118.196.0.0/19
118.196.32.0/20
118.196.0.0/18
118.196.64.0/19
118.199.0.0/16
118.202.0.0/15
118.212.0.0/15
@@ -1588,7 +1597,6 @@
119.255.128.0/17
119.255.63.0/24
119.27.160.0/19
119.27.64.0/18
119.28.28.0/24
119.29.0.0/16
119.3.0.0/16
@@ -1985,11 +1993,7 @@
124.172.0.0/15
124.192.0.0/15
124.196.0.0/24
124.196.10.0/23
124.196.12.0/23
124.196.17.0/24
124.196.18.0/23
124.196.20.0/24
124.196.25.0/24
124.196.26.0/23
124.196.28.0/24
@@ -2002,12 +2006,9 @@
124.196.56.0/23
124.196.58.0/24
124.196.66.0/24
124.196.72.0/24
124.196.76.0/23
124.196.78.0/24
124.196.77.0/24
124.196.80.0/22
124.196.84.0/24
124.196.9.0/24
124.200.0.0/16
124.202.0.0/16
124.203.176.0/20
@@ -2030,7 +2031,6 @@
124.40.128.0/18
124.42.0.0/16
124.47.0.0/18
124.6.64.0/18
124.64.0.0/15
124.66.0.0/17
124.67.0.0/16
@@ -2190,8 +2190,7 @@
150.138.0.0/15
150.158.0.0/16
150.223.0.0/16
150.242.120.0/24
150.242.122.0/23
150.242.120.0/22
150.242.156.0/22
150.242.168.0/22
150.242.184.0/22
@@ -2205,7 +2204,6 @@
150.242.96.0/22
150.255.0.0/16
151.241.174.0/24
151.242.65.0/24
152.104.128.0/17
152.136.0.0/16
153.0.0.0/16
@@ -2221,6 +2219,7 @@
154.208.160.0/21
154.208.172.0/23
154.213.4.0/23
154.218.6.0/23
154.223.168.0/24
154.223.179.0/24
154.223.180.0/24
@@ -2232,11 +2231,14 @@
154.8.128.0/17
154.91.158.0/23
155.117.164.0/24
155.117.188.0/24
155.126.176.0/23
156.107.160.0/24
156.107.170.0/24
156.107.179.0/24
156.107.181.0/24
156.227.1.0/24
156.227.24.0/22
156.230.11.0/24
156.231.163.0/24
156.236.116.0/24
@@ -2315,10 +2317,6 @@
167.148.46.0/24
167.189.0.0/16
167.220.244.0/22
168.159.144.0/21
168.159.152.0/22
168.159.156.0/23
168.159.158.0/24
168.160.0.0/17
168.160.152.0/24
168.160.158.0/23
@@ -2366,6 +2364,7 @@
175.42.0.0/15
175.44.0.0/16
175.46.0.0/15
178.219.5.0/24
178.253.239.0/24
180.129.128.0/17
180.130.0.0/16
@@ -2449,7 +2448,7 @@
182.61.128.0/19
182.61.192.0/22
182.61.200.0/21
182.61.216.0/21
182.61.208.0/20
182.61.224.0/19
182.80.0.0/13
182.88.0.0/14
@@ -2479,14 +2478,12 @@
185.75.173.0/24
185.75.174.0/24
188.131.128.0/17
192.102.204.0/22
192.140.160.0/19
192.140.208.0/21
192.144.128.0/17
192.163.11.0/24
192.232.97.0/24
192.55.46.0/24
192.55.68.0/22
193.112.0.0/16
193.119.10.0/23
193.119.12.0/23
@@ -2494,6 +2491,7 @@
193.119.17.0/24
193.119.19.0/24
193.119.20.0/23
193.119.22.0/24
193.119.25.0/24
193.119.28.0/24
193.119.30.0/24
@@ -2507,7 +2505,6 @@
194.138.245.0/24
194.15.39.0/24
195.114.203.0/24
198.175.100.0/22
198.208.112.0/23
198.208.17.0/24
198.208.19.0/24
@@ -2573,7 +2570,6 @@
202.153.48.0/20
202.158.160.0/19
202.160.140.0/22
202.164.0.0/20
202.164.25.0/24
202.168.160.0/19
202.170.128.0/19
@@ -2688,7 +2684,7 @@
203.119.26.0/23
203.119.28.0/22
203.119.33.0/24
203.119.80.0/23
203.119.80.0/24
203.119.83.0/24
203.12.204.0/23
203.12.91.0/24
@@ -2932,7 +2928,6 @@
203.83.56.0/21
203.86.0.0/19
203.86.112.0/24
203.86.116.0/24
203.86.254.0/23
203.86.43.0/24
203.86.44.0/23
@@ -3223,7 +3218,7 @@
211.97.0.0/17
211.97.128.0/19
211.97.160.0/21
211.97.190.0/24
211.97.176.0/20
211.97.192.0/18
211.98.0.0/16
211.99.128.0/18
@@ -3233,6 +3228,7 @@
211.99.32.0/19
211.99.64.0/18
211.99.8.0/21
212.100.186.0/24
212.129.128.0/17
212.64.0.0/17
218.0.0.0/11
@@ -3537,7 +3533,6 @@
223.240.0.0/13
223.248.0.0/14
223.252.194.0/24
223.252.196.0/24
223.252.199.0/24
223.252.200.0/23
223.252.202.0/24
@@ -3601,6 +3596,7 @@
36.213.192.0/20
36.213.208.0/23
36.213.210.0/24
36.221.0.0/17
36.248.0.0/14
36.255.116.0/22
36.255.128.0/22
@@ -3620,6 +3616,7 @@
36.56.0.0/13
36.96.0.0/12
38.111.220.0/23
38.211.199.0/24
39.104.0.0/14
39.108.0.0/16
39.128.0.0/10
@@ -3661,7 +3658,8 @@
42.240.12.0/24
42.240.128.0/17
42.240.16.0/24
42.240.20.0/24
42.240.20.0/23
42.240.22.0/24
42.240.8.0/22
42.242.0.0/15
42.244.0.0/14
@@ -3681,7 +3679,6 @@
42.83.189.0/24
42.83.190.0/24
42.83.200.0/23
42.83.255.0/24
42.84.0.0/14
42.88.0.0/13
42.96.128.0/17
@@ -3741,7 +3738,8 @@
43.229.216.0/22
43.229.48.0/22
43.230.136.0/22
43.230.220.0/22
43.230.221.0/24
43.230.222.0/23
43.230.72.0/22
43.231.144.0/20
43.231.160.0/21
@@ -3887,8 +3885,7 @@
45.116.208.0/22
45.116.32.0/22
45.116.52.0/22
45.117.68.0/24
45.117.70.0/23
45.117.68.0/22
45.117.8.0/22
45.119.105.0/24
45.119.116.0/22
@@ -3934,7 +3931,7 @@
45.248.8.0/22
45.249.208.0/23
45.249.212.0/22
45.250.152.0/24
45.250.152.0/23
45.250.180.0/23
45.250.184.0/22
45.250.188.0/24
@@ -4194,6 +4191,7 @@
66.102.248.0/22
66.102.252.0/24
66.102.254.0/23
66.92.248.0/24
68.79.0.0/18
69.163.104.0/24
69.163.106.0/24
@@ -4207,6 +4205,7 @@
71.132.0.0/18
71.136.64.0/18
71.137.0.0/18
74.122.24.0/24
77.107.118.0/24
8.128.32.0/19
8.128.64.0/19
@@ -4228,7 +4227,7 @@
8.150.64.0/23
8.152.0.0/13
8.160.0.0/15
8.162.0.0/19
8.162.0.0/18
8.163.0.0/16
8.164.0.0/16
81.173.18.0/23
@@ -4236,9 +4235,7 @@
81.173.28.0/24
81.68.0.0/14
82.156.0.0/15
82.206.108.0/24
84.247.114.0/24
84.54.2.0/23
85.237.205.0/24
89.149.17.0/24
94.191.0.0/17
@@ -30,6 +30,7 @@
2400:5f60::/32
2400:6000::/32
2400:6460:300::/40
2400:6460:500::/40
2400:6460::/39
2400:6600::/32
2400:6e60:1301::/48
@@ -162,7 +163,6 @@
2401:7e00::/32
2401:800::/32
2401:8be0::/48
2401:8d00:10::/48
2401:8d00:12::/48
2401:8d00:14::/48
2401:8d00:4::/48
@@ -204,10 +204,11 @@
2401:f860:86::/47
2401:f860:88::/47
2401:f860:90::/46
2401:f860:94::/48
2401:f860:c::/48
2401:f860:e::/48
2401:f860:94::/47
2401:f860:a::/47
2401:f860:c::/46
2401:f860:f100::/40
2401:f860:f6::/48
2401:fa00:40::/43
2402:1440::/32
2402:2000::/32
@@ -349,7 +350,7 @@
2404:e280::/47
2404:e5c0::/32
2404:e8c0::/32
2404:f4c0:f000::/44
2404:f4c0::/32
2405:1480:1000::/48
2405:1480:2000::/48
2405:1480:3000::/47
@@ -452,7 +453,8 @@
2406:840:fda0::/43
2406:840:fdc0::/44
2406:840:fdd1::/48
2406:840:fde1::/48
2406:840:fde5::/48
2406:840:fde6::/47
2406:840:fe27::/48
2406:840:fe90::/46
2406:840:fe94::/48
@@ -473,7 +475,7 @@
2406:840:fed1::/48
2406:840:fed8::/48
2406:840:fedb::/48
2406:840:fedc::/48
2406:840:fedc::/47
2406:840:fedf::/48
2406:840:fef0::/48
2406:840:fef3::/48
@@ -575,6 +577,7 @@
2408:8181:a000::/40
2408:8181:a220::/44
2408:8181:e000::/40
2408:8182:6000::/40
2408:8182:c000::/40
2408:8183:4000::/40
2408:8183:8000::/40
@@ -1100,7 +1103,6 @@
240a:4020:883a::/48
240a:4021:83a::/48
240a:4021:883a::/48
240a:4083::/35
240a:4084:2000::/35
240a:4088:a000::/35
240a:408c:2000::/35
@@ -1118,7 +1120,6 @@
240a:4090:5200::/40
240a:4090:7000::/39
240a:4090:7200::/40
240a:4090:a000::/35
240a:4093::/35
240a:4094:2000::/35
240a:409c:2000::/35
@@ -1171,6 +1172,7 @@
240a:41f2::/31
240a:420a::/31
240a:4224:9000::/44
240a:4224:a000::/44
240a:4224:d000::/44
240a:4224:e000::/44
240a:4230::/31
@@ -1197,8 +1199,10 @@
240e::/20
2602:2e0:ff::/48
2602:f7ee:ee::/48
2602:f92a:a478::/48
2602:f92a:d1ff::/48
2602:f92a:dead::/48
2602:f92a:e100::/44
2602:f92a:f000::/48
2602:f93b:400::/38
2602:f9ba:10c::/48
2602:f9ba:a8::/48
@@ -1224,6 +1228,7 @@
2620:57:4004::/48
2804:1e48:9001::/48
2804:1e48:9002::/48
2a01:f100:100::/48
2a01:f100:1f8::/48
2a01:ffc7:100::/40
2a03:5840:126::/48
@@ -1316,6 +1321,7 @@
2a0e:aa07:e162::/48
2a0e:aa07:e16a::/48
2a0e:aa07:e1a0::/44
2a0e:aa07:e1e1::/48
2a0e:aa07:e1e2::/47
2a0e:aa07:e1e4::/47
2a0e:aa07:e1e6::/48
@@ -1356,15 +1362,18 @@
2a0f:7803:fe82::/48
2a0f:7804:f650::/44
2a0f:7804:f9f0::/44
2a0f:7807::/32
2a0f:7d07::/32
2a0f:85c1:ba5::/48
2a0f:85c1:ca0::/44
2a0f:85c1:ce1::/48
2a0f:85c1:cf1::/48
2a0f:9400:6110::/48
2a0f:9400:7700::/48
2a0f:ac00::/29
2a0f:ea47:fc1d::/48
2a10:2f00:15a::/48
2a10:67c2:2::/48
2a10:ccc0:d00::/46
2a10:ccc0:d0a::/47
2a10:ccc0:d0c::/47
@@ -1387,12 +1396,16 @@
2a13:a5c7:2102::/48
2a13:a5c7:2121::/48
2a13:a5c7:2301::/48
2a13:a5c7:2302::/48
2a13:a5c7:23c0::/42
2a13:a5c7:2600::/40
2a13:a5c7:2801::/48
2a13:a5c7:2803::/48
2a13:a5c7:3108::/48
2a13:a5c7:31a0::/43
2a13:a5c7:3307::/48
2a13:a5c7:3301::/48
2a13:a5c7:3304::/48
2a13:a5c7:3306::/47
2a13:aac4:f000::/44
2a14:4c41::/32
2a14:67c1:20::/44
@@ -1410,14 +1423,12 @@
2a14:67c1:a040::/47
2a14:67c1:a061::/48
2a14:67c1:a064::/48
2a14:67c1:a090::/46
2a14:67c1:a094::/47
2a14:67c1:a096::/48
2a14:67c1:a090::/45
2a14:67c1:a099::/48
2a14:67c1:a100::/43
2a14:67c1:a125::/48
2a14:67c1:a127::/48
2a14:67c1:a144::/48
2a14:67c1:a150::/44
2a14:67c1:b000::/48
2a14:67c1:b065::/48
2a14:67c1:b066::/48
@@ -1441,10 +1452,10 @@
2a14:67c1:b581::/48
2a14:67c1:b582::/48
2a14:67c1:b588::/47
2a14:67c1:b590::/48
2a14:67c1:b590::/47
2a14:67c1:b599::/48
2a14:67c5:1900::/40
2a14:7580:72f::/48
2a14:7580:740::/44
2a14:7580:750::/47
2a14:7580:9200::/40
2a14:7580:9400::/39
@@ -1458,6 +1469,7 @@
2a14:7580:fe00::/40
2a14:7580:fff4::/48
2a14:7580:fff7::/48
2a14:7580:fffa::/48
2a14:7581:3100::/40
2a14:7581:3400::/47
2a14:7581:9010::/44
@@ -1484,9 +1496,20 @@
2a14:7581:bcd::/48
2a14:7581:bff::/48
2a14:7581:ffb::/48
2a14:7581:ffd::/48
2a14:7583:f201::/48
2a14:7583:f203::/48
2a14:7583:f300::/40
2a14:7583:f300::/46
2a14:7583:f304::/48
2a14:7583:f4fe::/48
2a14:7583:f500::/48
2a14:7583:f701::/48
2a14:7583:f702::/47
2a14:7583:f704::/47
2a14:7583:f707::/48
2a14:7583:f708::/48
2a14:7583:f743::/48
2a14:7583:f764::/48
2a14:7584::/36
2a14:7c0:4a01::/48
2c0f:f7a8:8011::/48
@@ -138,6 +138,7 @@ abematv.akamaized.net
abitno.linpie.com
ablwang.com
aboluowang.com
about.gitlab.com
about.me
abplive.com
abs.edu
@@ -734,6 +735,8 @@ brutaltgp.com
bsky.app
bsky.network
bsky.social
bt4g.org
bt4gprx.com
bt95.com
btaia.com
btbit.net
@@ -1898,6 +1901,7 @@ gaopi.net
gardennetworks.com
gardennetworks.org
gartlive.com
garudalinux.org
gate.io
gatecoin.com
gather.com
@@ -2700,6 +2704,7 @@ iphone4hongkong.com
iphonetaiwan.org
iphonix.fr
ipicture.ru
ipify.org
ipjetable.net
ipobar.com
ipoock.com
@@ -3176,6 +3181,7 @@ mcadforums.com
mcaf.ee
mcfog.com
mcreasite.com
mcusercontent.com
md-t.org
me.me
me.ns.ci
@@ -3550,6 +3556,7 @@ ninecommentaries.com
ninjacloak.com
ninjaproxy.ninja
nintendium.com
nirsoft.net
nitter.cc
nitter.net
niu.moe
@@ -4368,6 +4375,7 @@ simplecd.org
simpleproductivityblog.com
simpleswap.io
simplex.chat
sina.com.hk
sinchew.com.my
singaporepools.com.sg
singfortibet.com
@@ -4667,11 +4675,13 @@ taiwantt.org.tw
taiwanus.net
taiwanyes.ning.com
talk853.com
talkatone.com
talkboxapp.com
talkcc.com
talkonly.net
tanc.org
tangren.us
tanks.gg
taoism.net
tapanwap.com
tapatalk.com
@@ -5141,7 +5151,6 @@ ubddns.org
uberproxy.net
uc-japan.org
uchicago.edu
uderzo.it
udn.com
udn.com.tw
udnbkk.com
@@ -5378,6 +5387,7 @@ vpnvip.com
vpnworldwide.com
vporn.com
vpser.net
vpsxb.net
vraiesagesse.net
vrchat.com
vrmtr.com
@@ -1122,6 +1122,9 @@ local function processData(szType, content, add_mode, add_from)
if not params.type then params.type = "tcp" end
params.type = string.lower(params.type)
if ({ xhttp=true, kcp=true, mkcp=true })[params.type] and result.type ~= "Xray" and has_xray then
result.type = "Xray"
end
if result.type == "sing-box" and params.type == "raw" then
params.type = "tcp"
elseif result.type == "Xray" and params.type == "tcp" then
@@ -5,7 +5,7 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-passwall2
PKG_VERSION:=25.9.20
PKG_VERSION:=25.9.24
PKG_RELEASE:=1
PKG_CONFIG_DEPENDS:= \
@@ -124,6 +124,11 @@ if #hysteria2_type > 0 then
end
end
if #ss_type > 0 or #trojan_type > 0 or #vmess_type > 0 or #vless_type > 0 or #hysteria2_type > 0 then
o.description = string.format("<font color='red'>%s</font>",
translate("The configured type also applies to the core specified when manually importing nodes."))
end
o = s:option(ListValue, "domain_strategy", "Sing-box " .. translate("Domain Strategy"), translate("Set the default domain resolution strategy for the sing-box node."))
o.default = ""
o:value("", translate("Auto"))
@@ -122,7 +122,7 @@ function o.custom_write(self, section, value)
else
result = { value }
end
api.uci:set_list(appname, section, "balancing_node", result)
m.uci:set_list(appname, section, "balancing_node", result)
end
o = s:option(ListValue, _n("balancingStrategy"), translate("Balancing Strategy"))
@@ -132,7 +132,7 @@ function o.custom_write(self, section, value)
else
result = { value }
end
api.uci:set_list(appname, section, "urltest_node", result)
m.uci:set_list(appname, section, "urltest_node", result)
end
o = s:option(Value, _n("urltest_url"), translate("Probe URL"))
@@ -793,6 +793,7 @@ local hysteria2_type = get_core("hysteria2_type", {{has_hysteria2,"hysteria2"},{
if (ssrurl === null || ssrurl === "") {
return false;
}
ssrurl = ssrurl.replace(/&amp;/gi, '&').replace(/\s*#\s*/, '#').trim(); //一些奇葩的链接用"&amp;"当做"&""#"前后带空格
s.innerHTML = "";
var ssu = ssrurl.split('://');
var event = document.createEvent("HTMLEvents");
@@ -870,6 +871,8 @@ local hysteria2_type = get_core("hysteria2_type", {{has_hysteria2,"hysteria2"},{
if (userInfoSplitIndex !== -1) {
method = userInfo.substr(0, userInfoSplitIndex);
password = userInfo.substr(userInfoSplitIndex + 1);
} else {
password = url0.substr(0, sipIndex); //一些链接用明文uuid做密码
}
} else {
// base64(method:pass@host:port)
@@ -908,14 +911,14 @@ local hysteria2_type = get_core("hysteria2_type", {{has_hysteria2,"hysteria2"},{
pluginOpts = pluginParams.join(";");
}
if (ss_type == "sing-box" && has_singbox) {
dom_prefix = "singbox_"
opt.set('type', "sing-box");
opt.set(dom_prefix + 'protocol', "shadowsocks");
} else if (ss_type == "xray" && has_xray) {
if (has_xray && ((ss_type !== "xray" && ss_type !== "sing-box" && queryParam.type) || ss_type == "xray")) {
dom_prefix = "xray_"
opt.set('type', "Xray");
opt.set(dom_prefix + 'protocol', "shadowsocks");
} else if (has_singbox && ((ss_type !== "xray" && ss_type !== "sing-box" && queryParam.type) || ss_type == "sing-box")) {
dom_prefix = "singbox_"
opt.set('type', "sing-box");
opt.set(dom_prefix + 'protocol', "shadowsocks");
} else if (ss_type == "shadowsocks-rust") {
dom_prefix = "ssrust_"
opt.set('type', "SS-Rust");
@@ -928,10 +931,14 @@ local hysteria2_type = get_core("hysteria2_type", {{has_hysteria2,"hysteria2"},{
opt.set('type', "SS");
}
}
if (ss_type !== "xray") {
method = method.toLowerCase() === "chacha20-poly1305" ? "chacha20-ietf-poly1305" : method;
method = method.toLowerCase() === "xchacha20-poly1305" ? "xchacha20-ietf-poly1305" : method;
}
const _method = (method || "none").toLowerCase();
const mapping = {
"chacha20-poly1305": "chacha20-ietf-poly1305",
"xchacha20-poly1305": "xchacha20-ietf-poly1305",
};
method = mapping[_method] || _method;
opt.set(dom_prefix + 'address', unbracketIP(server));
opt.set(dom_prefix + 'port', port);
opt.set(dom_prefix + 'password', password || "");
@@ -1324,16 +1331,13 @@ local hysteria2_type = get_core("hysteria2_type", {{has_hysteria2,"hysteria2"},{
dom_prefix = "xray_"
opt.set('type', "Xray");
}
opt.set(dom_prefix + 'protocol', "vless");
var m = parseNodeUrl(ssrurl);
var password = m.passwd;
if (password === "") {
s.innerHTML = "<font color='red'><%:Invalid Share URL Format%></font>";
return false;
}
opt.set(dom_prefix + 'uuid', password);
opt.set(dom_prefix + 'address', unbracketIP(m.hostname));
opt.set(dom_prefix + 'port', m.port || "443");
var queryParam = {};
if (m.search.length > 1) {
var query = m.search.replace('/?', '?').split('?')
@@ -1346,6 +1350,16 @@ local hysteria2_type = get_core("hysteria2_type", {{has_hysteria2,"hysteria2"},{
}
}
queryParam.type = queryParam.type.toLowerCase();
if (["xhttp", "kcp", "mkcp"].includes(queryParam.type) && vless_type !== "xray" && has_xray) {
dom_prefix = "xray_"
opt.set('type', "Xray");
}
opt.set(dom_prefix + 'protocol', "vless");
opt.set(dom_prefix + 'uuid', password);
opt.set(dom_prefix + 'address', unbracketIP(m.hostname));
opt.set(dom_prefix + 'port', m.port || "443");
opt.set(dom_prefix + 'encryption', queryParam.encryption || "none");
if (queryParam.security) {
if (queryParam.security == "tls") {
@@ -1385,7 +1399,6 @@ local hysteria2_type = get_core("hysteria2_type", {{has_hysteria2,"hysteria2"},{
}
queryParam.type = queryParam.type.toLowerCase();
if (queryParam.type === "kcp" || queryParam.type === "mkcp") {
queryParam.type = "mkcp";
}
@@ -1833,3 +1833,6 @@ msgstr "客户端版本"
msgid "Random version will be used if empty."
msgstr "如留空,则使用随机版本。"
msgid "The configured type also applies to the core specified when manually importing nodes."
msgstr "配置的类型同样适用于手动导入节点时所指定的核心程序。"
@@ -688,8 +688,13 @@ local function processData(szType, content, add_mode, add_from)
else
userinfo = base64Decode(hostInfo[1])
end
local method = userinfo:sub(1, userinfo:find(":") - 1)
local password = userinfo:sub(userinfo:find(":") + 1, #userinfo)
local method, password
if userinfo:find(":") then
method = userinfo:sub(1, userinfo:find(":") - 1)
password = userinfo:sub(userinfo:find(":") + 1, #userinfo)
else
password = hostInfo[1] --一些链接用明文uuid做密码
end
-- 判断密码是否经过url编码
local function isURLEncodedPassword(pwd)
@@ -704,12 +709,20 @@ local function processData(szType, content, add_mode, add_from)
if isURLEncodedPassword(password) and decoded then
password = decoded
end
local _method = (method or "none"):lower()
method = (_method == "chacha20-poly1305" and "chacha20-ietf-poly1305") or
(_method == "xchacha20-poly1305" and "xchacha20-ietf-poly1305") or _method
result.method = method
result.password = password
if result.type ~= "Xray" then
result.method = (method:lower() == "chacha20-poly1305" and "chacha20-ietf-poly1305") or
(method:lower() == "xchacha20-poly1305" and "xchacha20-ietf-poly1305") or method
if has_xray and (result.type ~= 'Xray' and result.type ~= 'sing-box' and params.type) then
result.type = 'Xray'
result.protocol = 'shadowsocks'
elseif has_singbox and (result.type ~= 'Xray' and result.type ~= 'sing-box' and params.type) then
result.type = 'sing-box'
result.protocol = 'shadowsocks'
end
if result.plugin then
@@ -1115,6 +1128,9 @@ local function processData(szType, content, add_mode, add_from)
if not params.type then params.type = "tcp" end
params.type = string.lower(params.type)
if ({ xhttp=true, kcp=true, mkcp=true })[params.type] and result.type ~= "Xray" and has_xray then
result.type = "Xray"
end
if result.type == "sing-box" and params.type == "raw" then
params.type = "tcp"
elseif result.type == "Xray" and params.type == "tcp" then
@@ -1810,9 +1826,9 @@ local function parse_link(raw, add_mode, add_from, cfgid)
else
-- ssd 外的格式
if add_mode == "1" then
nodes = split(raw:gsub(" ", "\n"), "\n")
nodes = split(raw, "\n")
else
nodes = split(base64Decode(raw):gsub(" ", "\n"), "\n")
nodes = split(base64Decode(raw):gsub("\r\n", "\n"), "\n")
end
end
@@ -1830,7 +1846,8 @@ local function parse_link(raw, add_mode, add_from, cfgid)
local link = api.trim(dat[2]:gsub("#.*$", ""))
result = processData(dat[1], base64Decode(link), add_mode, add_from)
else
result = processData(dat[1], dat[2], add_mode, add_from)
local link = dat[2]:gsub("&amp;", "&"):gsub("%s*#%s*", "#") -- 一些奇葩的链接用"&amp;"当做"&""#"前后带空格
result = processData(dat[1], link, add_mode, add_from)
end
end
else
+40 -25
View File
@@ -554,7 +554,7 @@ dependencies = [
"android-tzdata",
"iana-time-zone",
"num-traits",
"windows-link",
"windows-link 0.1.3",
]
[[package]]
@@ -1592,7 +1592,7 @@ dependencies = [
"libc",
"percent-encoding",
"pin-project-lite",
"socket2 0.5.10",
"socket2 0.6.0",
"system-configuration",
"tokio",
"tower-service",
@@ -1942,9 +1942,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]]
name = "libc"
version = "0.2.175"
version = "0.2.176"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543"
checksum = "58f929b4d672ea937a23a1ab494143d968337a5f47e56d0815df1e0890ddf174"
[[package]]
name = "libloading"
@@ -1953,7 +1953,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667"
dependencies = [
"cfg-if",
"windows-targets 0.48.5",
"windows-targets 0.53.3",
]
[[package]]
@@ -2678,7 +2678,7 @@ dependencies = [
"quinn-udp",
"rustc-hash",
"rustls",
"socket2 0.5.10",
"socket2 0.6.0",
"thiserror 2.0.16",
"tokio",
"tracing",
@@ -2715,7 +2715,7 @@ dependencies = [
"cfg_aliases",
"libc",
"once_cell",
"socket2 0.5.10",
"socket2 0.6.0",
"tracing",
"windows-sys 0.60.2",
]
@@ -3167,9 +3167,9 @@ dependencies = [
[[package]]
name = "serde"
version = "1.0.223"
version = "1.0.226"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a505d71960adde88e293da5cb5eda57093379f64e61cf77bf0e6a63af07a7bac"
checksum = "0dca6411025b24b60bfa7ec1fe1f8e710ac09782dca409ee8237ba74b51295fd"
dependencies = [
"serde_core",
"serde_derive",
@@ -3196,18 +3196,18 @@ dependencies = [
[[package]]
name = "serde_core"
version = "1.0.223"
version = "1.0.226"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "20f57cbd357666aa7b3ac84a90b4ea328f1d4ddb6772b430caa5d9e1309bb9e9"
checksum = "ba2ba63999edb9dac981fb34b3e5c0d111a69b0924e253ed29d83f7c99e966a4"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.223"
version = "1.0.226"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d428d07faf17e306e699ec1e91996e5a165ba5d6bce5b5155173e91a8a01a56"
checksum = "8db53ae22f34573731bafa1db20f04027b2d25e02d8205921b569171699cdb33"
dependencies = [
"proc-macro2",
"quote",
@@ -3310,7 +3310,7 @@ dependencies = [
"tokio-tfo",
"trait-variant",
"url",
"windows-sys 0.60.2",
"windows-sys 0.61.0",
]
[[package]]
@@ -3428,7 +3428,7 @@ dependencies = [
"trait-variant",
"tun",
"webpki-roots 1.0.2",
"windows-sys 0.60.2",
"windows-sys 0.61.0",
"zstd",
]
@@ -4358,7 +4358,7 @@ version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0978bf7171b3d90bac376700cb56d606feb40f251a475a5d6634613564460b22"
dependencies = [
"windows-sys 0.48.0",
"windows-sys 0.60.2",
]
[[package]]
@@ -4376,7 +4376,7 @@ dependencies = [
"windows-collections",
"windows-core",
"windows-future",
"windows-link",
"windows-link 0.1.3",
"windows-numerics",
]
@@ -4397,7 +4397,7 @@ checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3"
dependencies = [
"windows-implement",
"windows-interface",
"windows-link",
"windows-link 0.1.3",
"windows-result",
"windows-strings",
]
@@ -4409,7 +4409,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e"
dependencies = [
"windows-core",
"windows-link",
"windows-link 0.1.3",
"windows-threading",
]
@@ -4441,6 +4441,12 @@ version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a"
[[package]]
name = "windows-link"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65"
[[package]]
name = "windows-numerics"
version = "0.2.0"
@@ -4448,7 +4454,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1"
dependencies = [
"windows-core",
"windows-link",
"windows-link 0.1.3",
]
[[package]]
@@ -4457,7 +4463,7 @@ version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b8a9ed28765efc97bbc954883f4e6796c33a06546ebafacbabee9696967499e"
dependencies = [
"windows-link",
"windows-link 0.1.3",
"windows-result",
"windows-strings",
]
@@ -4468,7 +4474,7 @@ version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6"
dependencies = [
"windows-link",
"windows-link 0.1.3",
]
[[package]]
@@ -4488,7 +4494,7 @@ version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57"
dependencies = [
"windows-link",
"windows-link 0.1.3",
]
[[package]]
@@ -4527,6 +4533,15 @@ dependencies = [
"windows-targets 0.53.3",
]
[[package]]
name = "windows-sys"
version = "0.61.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e201184e40b2ede64bc2ea34968b28e33622acdbbf37104f0e4a33f7abe657aa"
dependencies = [
"windows-link 0.2.0",
]
[[package]]
name = "windows-targets"
version = "0.48.5"
@@ -4564,7 +4579,7 @@ version = "0.53.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91"
dependencies = [
"windows-link",
"windows-link 0.1.3",
"windows_aarch64_gnullvm 0.53.0",
"windows_aarch64_msvc 0.53.0",
"windows_i686_gnu 0.53.0",
@@ -4581,7 +4596,7 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6"
dependencies = [
"windows-link",
"windows-link 0.1.3",
]
[[package]]

Some files were not shown because too many files have changed in this diff Show More