Update On Thu Nov 13 19:41:28 CET 2025

This commit is contained in:
github-action[bot]
2025-11-13 19:41:28 +01:00
parent cd9974abe8
commit 3642b6d22d
350 changed files with 6388 additions and 63252 deletions
+1
View File
@@ -1180,3 +1180,4 @@ Update On Sun Nov 9 19:36:09 CET 2025
Update On Mon Nov 10 19:41:15 CET 2025
Update On Tue Nov 11 19:39:14 CET 2025
Update On Wed Nov 12 19:37:25 CET 2025
Update On Thu Nov 13 19:41:20 CET 2025
+268 -96
View File
@@ -1,16 +1,17 @@
package xsync
// copy and modified from https://github.com/puzpuzpuz/xsync/blob/v4.1.0/map.go
// copy and modified from https://github.com/puzpuzpuz/xsync/blob/v4.2.0/map.go
// which is licensed under Apache v2.
//
// mihomo modified:
// 1. parallel Map resize has been removed to decrease the memory using.
// 1. restore xsync/v3's LoadOrCompute api and rename to LoadOrStoreFn.
// 2. the zero Map is ready for use.
import (
"fmt"
"math"
"math/bits"
"runtime"
"strings"
"sync"
"sync/atomic"
@@ -41,8 +42,28 @@ const (
metaMask uint64 = 0xffffffffff
defaultMetaMasked uint64 = defaultMeta & metaMask
emptyMetaSlot uint8 = 0x80
// minimal number of buckets to transfer when participating in cooperative
// resize; should be at least defaultMinMapTableLen
minResizeTransferStride = 64
// upper limit for max number of additional goroutines that participate
// in cooperative resize; must be changed simultaneously with resizeCtl
// and the related code
maxResizeHelpersLimit = (1 << 5) - 1
)
// max number of additional goroutines that participate in cooperative resize;
// "resize owner" goroutine isn't counted
var maxResizeHelpers = func() int32 {
v := int32(parallelism() - 1)
if v < 1 {
v = 1
}
if v > maxResizeHelpersLimit {
v = maxResizeHelpersLimit
}
return v
}()
type mapResizeHint int
const (
@@ -100,16 +121,25 @@ type Map[K comparable, V any] struct {
initOnce sync.Once
totalGrowths atomic.Int64
totalShrinks atomic.Int64
resizing atomic.Bool // resize in progress flag
resizeMu sync.Mutex // only used along with resizeCond
resizeCond sync.Cond // used to wake up resize waiters (concurrent modifications)
table atomic.Pointer[mapTable[K, V]]
minTableLen int
growOnly bool
// table being transferred to
nextTable atomic.Pointer[mapTable[K, V]]
// resize control state: combines resize sequence number (upper 59 bits) and
// the current number of resize helpers (lower 5 bits);
// odd values of resize sequence mean in-progress resize
resizeCtl atomic.Uint64
// only used along with resizeCond
resizeMu sync.Mutex
// used to wake up resize waiters (concurrent writes)
resizeCond sync.Cond
// transfer progress index for resize
resizeIdx atomic.Int64
minTableLen int
growOnly bool
}
type mapTable[K comparable, V any] struct {
buckets []bucketPadded[K, V]
buckets []bucketPadded
// striped counter for number of table entries;
// used to determine if a table shrinking is needed
// occupies min(buckets_memory/1024, 64KB) of memory
@@ -125,16 +155,16 @@ type counterStripe struct {
// bucketPadded is a CL-sized map bucket holding up to
// entriesPerMapBucket entries.
type bucketPadded[K comparable, V any] struct {
type bucketPadded struct {
//lint:ignore U1000 ensure each bucket takes two cache lines on both 32 and 64-bit archs
pad [cacheLineSize - unsafe.Sizeof(bucket[K, V]{})]byte
bucket[K, V]
pad [cacheLineSize - unsafe.Sizeof(bucket{})]byte
bucket
}
type bucket[K comparable, V any] struct {
meta atomic.Uint64
entries [entriesPerMapBucket]atomic.Pointer[entry[K, V]] // *entry
next atomic.Pointer[bucketPadded[K, V]] // *bucketPadded
type bucket struct {
meta uint64
entries [entriesPerMapBucket]unsafe.Pointer // *entry
next unsafe.Pointer // *bucketPadded
mu sync.Mutex
}
@@ -194,15 +224,15 @@ func (m *Map[K, V]) init() {
m.minTableLen = defaultMinMapTableLen
}
m.resizeCond = *sync.NewCond(&m.resizeMu)
table := newMapTable[K, V](m.minTableLen)
table := newMapTable[K, V](m.minTableLen, maphash.MakeSeed())
m.minTableLen = len(table.buckets)
m.table.Store(table)
}
func newMapTable[K comparable, V any](minTableLen int) *mapTable[K, V] {
buckets := make([]bucketPadded[K, V], minTableLen)
func newMapTable[K comparable, V any](minTableLen int, seed maphash.Seed) *mapTable[K, V] {
buckets := make([]bucketPadded, minTableLen)
for i := range buckets {
buckets[i].meta.Store(defaultMeta)
buckets[i].meta = defaultMeta
}
counterLen := minTableLen >> 10
if counterLen < minMapCounterLen {
@@ -214,7 +244,7 @@ func newMapTable[K comparable, V any](minTableLen int) *mapTable[K, V] {
t := &mapTable[K, V]{
buckets: buckets,
size: counter,
seed: maphash.MakeSeed(),
seed: seed,
}
return t
}
@@ -246,22 +276,24 @@ func (m *Map[K, V]) Load(key K) (value V, ok bool) {
bidx := uint64(len(table.buckets)-1) & h1
b := &table.buckets[bidx]
for {
metaw := b.meta.Load()
metaw := atomic.LoadUint64(&b.meta)
markedw := markZeroBytes(metaw^h2w) & metaMask
for markedw != 0 {
idx := firstMarkedByteIndex(markedw)
e := b.entries[idx].Load()
if e != nil {
eptr := atomic.LoadPointer(&b.entries[idx])
if eptr != nil {
e := (*entry[K, V])(eptr)
if e.key == key {
return e.value, true
}
}
markedw &= markedw - 1
}
b = b.next.Load()
if b == nil {
bptr := atomic.LoadPointer(&b.next)
if bptr == nil {
return
}
b = (*bucketPadded)(bptr)
}
}
@@ -399,7 +431,7 @@ func (m *Map[K, V]) doCompute(
for {
compute_attempt:
var (
emptyb *bucketPadded[K, V]
emptyb *bucketPadded
emptyidx int
)
table := m.table.Load()
@@ -415,12 +447,13 @@ func (m *Map[K, V]) doCompute(
b := rootb
load:
for {
metaw := b.meta.Load()
metaw := atomic.LoadUint64(&b.meta)
markedw := markZeroBytes(metaw^h2w) & metaMask
for markedw != 0 {
idx := firstMarkedByteIndex(markedw)
e := b.entries[idx].Load()
if e != nil {
eptr := atomic.LoadPointer(&b.entries[idx])
if eptr != nil {
e := (*entry[K, V])(eptr)
if e.key == key {
if loadOp == loadOrComputeOp {
return e.value, true
@@ -430,23 +463,24 @@ func (m *Map[K, V]) doCompute(
}
markedw &= markedw - 1
}
b = b.next.Load()
if b == nil {
bptr := atomic.LoadPointer(&b.next)
if bptr == nil {
if loadOp == loadAndDeleteOp {
return *new(V), false
}
break load
}
b = (*bucketPadded)(bptr)
}
}
rootb.mu.Lock()
// The following two checks must go in reverse to what's
// in the resize method.
if m.resizeInProgress() {
// Resize is in progress. Wait, then go for another attempt.
if seq := resizeSeq(m.resizeCtl.Load()); seq&1 == 1 {
// Resize is in progress. Help with the transfer, then go for another attempt.
rootb.mu.Unlock()
m.waitForResize()
m.helpResize(seq)
goto compute_attempt
}
if m.newerTableExists(table) {
@@ -456,12 +490,13 @@ func (m *Map[K, V]) doCompute(
}
b := rootb
for {
metaw := b.meta.Load()
metaw := b.meta
markedw := markZeroBytes(metaw^h2w) & metaMask
for markedw != 0 {
idx := firstMarkedByteIndex(markedw)
e := b.entries[idx].Load()
if e != nil {
eptr := b.entries[idx]
if eptr != nil {
e := (*entry[K, V])(eptr)
if e.key == key {
// In-place update/delete.
// We get a copy of the value via an interface{} on each call,
@@ -475,8 +510,8 @@ func (m *Map[K, V]) doCompute(
// Deletion.
// First we update the hash, then the entry.
newmetaw := setByte(metaw, emptyMetaSlot, idx)
b.meta.Store(newmetaw)
b.entries[idx].Store(nil)
atomic.StoreUint64(&b.meta, newmetaw)
atomic.StorePointer(&b.entries[idx], nil)
rootb.mu.Unlock()
table.addSize(bidx, -1)
// Might need to shrink the table if we left bucket empty.
@@ -488,7 +523,7 @@ func (m *Map[K, V]) doCompute(
newe := new(entry[K, V])
newe.key = key
newe.value = newv
b.entries[idx].Store(newe)
atomic.StorePointer(&b.entries[idx], unsafe.Pointer(newe))
case CancelOp:
newv = oldv
}
@@ -512,7 +547,7 @@ func (m *Map[K, V]) doCompute(
emptyidx = idx
}
}
if b.next.Load() == nil {
if b.next == nil {
if emptyb != nil {
// Insertion into an existing bucket.
var zeroV V
@@ -526,8 +561,8 @@ func (m *Map[K, V]) doCompute(
newe.key = key
newe.value = newValue
// First we update meta, then the entry.
emptyb.meta.Store(setByte(emptyb.meta.Load(), h2, emptyidx))
emptyb.entries[emptyidx].Store(newe)
atomic.StoreUint64(&emptyb.meta, setByte(emptyb.meta, h2, emptyidx))
atomic.StorePointer(&emptyb.entries[emptyidx], unsafe.Pointer(newe))
rootb.mu.Unlock()
table.addSize(bidx, 1)
return newValue, computeOnly
@@ -549,19 +584,19 @@ func (m *Map[K, V]) doCompute(
return newValue, false
default:
// Create and append a bucket.
newb := new(bucketPadded[K, V])
newb.meta.Store(setByte(defaultMeta, h2, 0))
newb := new(bucketPadded)
newb.meta = setByte(defaultMeta, h2, 0)
newe := new(entry[K, V])
newe.key = key
newe.value = newValue
newb.entries[0].Store(newe)
b.next.Store(newb)
newb.entries[0] = unsafe.Pointer(newe)
atomic.StorePointer(&b.next, unsafe.Pointer(newb))
rootb.mu.Unlock()
table.addSize(bidx, 1)
return newValue, computeOnly
}
}
b = b.next.Load()
b = (*bucketPadded)(b.next)
}
}
}
@@ -570,13 +605,21 @@ func (m *Map[K, V]) newerTableExists(table *mapTable[K, V]) bool {
return table != m.table.Load()
}
func (m *Map[K, V]) resizeInProgress() bool {
return m.resizing.Load()
func resizeSeq(ctl uint64) uint64 {
return ctl >> 5
}
func resizeHelpers(ctl uint64) uint64 {
return ctl & maxResizeHelpersLimit
}
func resizeCtl(seq uint64, helpers uint64) uint64 {
return (seq << 5) | (helpers & maxResizeHelpersLimit)
}
func (m *Map[K, V]) waitForResize() {
m.resizeMu.Lock()
for m.resizeInProgress() {
for resizeSeq(m.resizeCtl.Load())&1 == 1 {
m.resizeCond.Wait()
}
m.resizeMu.Unlock()
@@ -593,9 +636,9 @@ func (m *Map[K, V]) resize(knownTable *mapTable[K, V], hint mapResizeHint) {
}
}
// Slow path.
if !m.resizing.CompareAndSwap(false, true) {
// Someone else started resize. Wait for it to finish.
m.waitForResize()
seq := resizeSeq(m.resizeCtl.Load())
if seq&1 == 1 || !m.resizeCtl.CompareAndSwap(resizeCtl(seq, 0), resizeCtl(seq+1, 0)) {
m.helpResize(seq)
return
}
var newTable *mapTable[K, V]
@@ -604,64 +647,189 @@ func (m *Map[K, V]) resize(knownTable *mapTable[K, V], hint mapResizeHint) {
switch hint {
case mapGrowHint:
// Grow the table with factor of 2.
// We must keep the same table seed here to keep the same hash codes
// allowing us to avoid locking destination buckets when resizing.
m.totalGrowths.Add(1)
newTable = newMapTable[K, V](tableLen << 1)
newTable = newMapTable[K, V](tableLen<<1, table.seed)
case mapShrinkHint:
shrinkThreshold := int64((tableLen * entriesPerMapBucket) / mapShrinkFraction)
if tableLen > m.minTableLen && table.sumSize() <= shrinkThreshold {
// Shrink the table with factor of 2.
// It's fine to generate a new seed since full locking
// is required anyway.
m.totalShrinks.Add(1)
newTable = newMapTable[K, V](tableLen >> 1)
newTable = newMapTable[K, V](tableLen>>1, maphash.MakeSeed())
} else {
// No need to shrink. Wake up all waiters and give up.
m.resizeMu.Lock()
m.resizing.Store(false)
m.resizeCtl.Store(resizeCtl(seq+2, 0))
m.resizeCond.Broadcast()
m.resizeMu.Unlock()
return
}
case mapClearHint:
newTable = newMapTable[K, V](m.minTableLen)
newTable = newMapTable[K, V](m.minTableLen, maphash.MakeSeed())
default:
panic(fmt.Sprintf("unexpected resize hint: %d", hint))
}
// Copy the data only if we're not clearing the map.
if hint != mapClearHint {
for i := 0; i < tableLen; i++ {
copied := copyBucket(&table.buckets[i], newTable)
newTable.addSizePlain(uint64(i), copied)
}
// Set up cooperative transfer state.
// Next table must be published as the last step.
m.resizeIdx.Store(0)
m.nextTable.Store(newTable)
// Copy the buckets.
m.transfer(table, newTable)
}
// We're about to publish the new table, but before that
// we must wait for all helpers to finish.
for resizeHelpers(m.resizeCtl.Load()) != 0 {
runtime.Gosched()
}
// Publish the new table and wake up all waiters.
m.table.Store(newTable)
m.nextTable.Store(nil)
ctl := resizeCtl(seq+1, 0)
newCtl := resizeCtl(seq+2, 0)
// Increment the sequence number and wake up all waiters.
m.resizeMu.Lock()
m.resizing.Store(false)
// There may be slowpoke helpers who have just incremented
// the helper counter. This CAS loop makes sure to wait
// for them to back off.
for !m.resizeCtl.CompareAndSwap(ctl, newCtl) {
runtime.Gosched()
}
m.resizeCond.Broadcast()
m.resizeMu.Unlock()
}
func copyBucket[K comparable, V any](
b *bucketPadded[K, V],
func (m *Map[K, V]) helpResize(seq uint64) {
for {
table := m.table.Load()
nextTable := m.nextTable.Load()
if resizeSeq(m.resizeCtl.Load()) == seq {
if nextTable == nil || nextTable == table {
// Carry on until the next table is set by the main
// resize goroutine or until the resize finishes.
runtime.Gosched()
continue
}
// The resize is still in-progress, so let's try registering
// as a helper.
for {
ctl := m.resizeCtl.Load()
if resizeSeq(ctl) != seq || resizeHelpers(ctl) >= uint64(maxResizeHelpers) {
// The resize has ended or there are too many helpers.
break
}
if m.resizeCtl.CompareAndSwap(ctl, ctl+1) {
// Yay, we're a resize helper!
m.transfer(table, nextTable)
// Don't forget to unregister as a helper.
m.resizeCtl.Add(^uint64(0))
break
}
}
m.waitForResize()
}
break
}
}
func (m *Map[K, V]) transfer(table, newTable *mapTable[K, V]) {
tableLen := len(table.buckets)
newTableLen := len(newTable.buckets)
stride := (tableLen >> 3) / int(maxResizeHelpers)
if stride < minResizeTransferStride {
stride = minResizeTransferStride
}
for {
// Claim work by incrementing resizeIdx.
nextIdx := m.resizeIdx.Add(int64(stride))
start := int(nextIdx) - stride
if start < 0 {
start = 0
}
if start > tableLen {
break
}
end := int(nextIdx)
if end > tableLen {
end = tableLen
}
// Transfer buckets in this range.
total := 0
if newTableLen > tableLen {
// We're growing the table with 2x multiplier, so entries from a N bucket can
// only be transferred to N and 2*N buckets in the new table. Thus, destination
// buckets written by the resize helpers don't intersect, so we don't need to
// acquire locks in the destination buckets.
for i := start; i < end; i++ {
total += transferBucketUnsafe(&table.buckets[i], newTable)
}
} else {
// We're shrinking the table, so all locks must be acquired.
for i := start; i < end; i++ {
total += transferBucket(&table.buckets[i], newTable)
}
}
// The exact counter stripe doesn't matter here, so pick up the one
// that corresponds to the start value to avoid contention.
newTable.addSize(uint64(start), total)
}
}
// Doesn't acquire dest bucket lock.
func transferBucketUnsafe[K comparable, V any](
b *bucketPadded,
destTable *mapTable[K, V],
) (copied int) {
rootb := b
rootb.mu.Lock()
for {
for i := 0; i < entriesPerMapBucket; i++ {
if e := b.entries[i].Load(); e != nil {
if eptr := b.entries[i]; eptr != nil {
e := (*entry[K, V])(eptr)
hash := maphash.Comparable(destTable.seed, e.key)
bidx := uint64(len(destTable.buckets)-1) & h1(hash)
destb := &destTable.buckets[bidx]
appendToBucket(h2(hash), b.entries[i].Load(), destb)
appendToBucket(h2(hash), e, destb)
copied++
}
}
if next := b.next.Load(); next == nil {
if b.next == nil {
rootb.mu.Unlock()
return
} else {
b = next
}
b = (*bucketPadded)(b.next)
}
}
func transferBucket[K comparable, V any](
b *bucketPadded,
destTable *mapTable[K, V],
) (copied int) {
rootb := b
rootb.mu.Lock()
for {
for i := 0; i < entriesPerMapBucket; i++ {
if eptr := b.entries[i]; eptr != nil {
e := (*entry[K, V])(eptr)
hash := maphash.Comparable(destTable.seed, e.key)
bidx := uint64(len(destTable.buckets)-1) & h1(hash)
destb := &destTable.buckets[bidx]
destb.mu.Lock()
appendToBucket(h2(hash), e, destb)
destb.mu.Unlock()
copied++
}
}
if b.next == nil {
rootb.mu.Unlock()
return
}
b = (*bucketPadded)(b.next)
}
}
@@ -691,16 +859,15 @@ func (m *Map[K, V]) Range(f func(key K, value V) bool) {
rootb.mu.Lock()
for {
for i := 0; i < entriesPerMapBucket; i++ {
if entry := b.entries[i].Load(); entry != nil {
bentries = append(bentries, entry)
if b.entries[i] != nil {
bentries = append(bentries, (*entry[K, V])(b.entries[i]))
}
}
if next := b.next.Load(); next == nil {
if b.next == nil {
rootb.mu.Unlock()
break
} else {
b = next
}
b = (*bucketPadded)(b.next)
}
// Call the function for all copied entries.
for j, e := range bentries {
@@ -727,24 +894,25 @@ func (m *Map[K, V]) Size() int {
return int(m.table.Load().sumSize())
}
func appendToBucket[K comparable, V any](h2 uint8, e *entry[K, V], b *bucketPadded[K, V]) {
// It is safe to use plain stores here because the destination bucket must be
// either locked or exclusively written to by the helper during resize.
func appendToBucket[K comparable, V any](h2 uint8, e *entry[K, V], b *bucketPadded) {
for {
for i := 0; i < entriesPerMapBucket; i++ {
if b.entries[i].Load() == nil {
b.meta.Store(setByte(b.meta.Load(), h2, i))
b.entries[i].Store(e)
if b.entries[i] == nil {
b.meta = setByte(b.meta, h2, i)
b.entries[i] = unsafe.Pointer(e)
return
}
}
if next := b.next.Load(); next == nil {
newb := new(bucketPadded[K, V])
newb.meta.Store(setByte(defaultMeta, h2, 0))
newb.entries[0].Store(e)
b.next.Store(newb)
if b.next == nil {
newb := new(bucketPadded)
newb.meta = setByte(defaultMeta, h2, 0)
newb.entries[0] = unsafe.Pointer(e)
b.next = unsafe.Pointer(newb)
return
} else {
b = next
}
b = (*bucketPadded)(b.next)
}
}
@@ -753,11 +921,6 @@ func (table *mapTable[K, V]) addSize(bucketIdx uint64, delta int) {
atomic.AddInt64(&table.size[cidx].c, int64(delta))
}
func (table *mapTable[K, V]) addSizePlain(bucketIdx uint64, delta int) {
cidx := uint64(len(table.size)-1) & bucketIdx
table.size[cidx].c += int64(delta)
}
func (table *mapTable[K, V]) sumSize() int64 {
sum := int64(0)
for i := range table.size {
@@ -856,7 +1019,7 @@ func (m *Map[K, V]) Stats() MapStats {
nentriesLocal := 0
stats.Capacity += entriesPerMapBucket
for i := 0; i < entriesPerMapBucket; i++ {
if b.entries[i].Load() != nil {
if atomic.LoadPointer(&b.entries[i]) != nil {
stats.Size++
nentriesLocal++
}
@@ -865,11 +1028,10 @@ func (m *Map[K, V]) Stats() MapStats {
if nentriesLocal == 0 {
stats.EmptyBuckets++
}
if next := b.next.Load(); next == nil {
if b.next == nil {
break
} else {
b = next
}
b = (*bucketPadded)(atomic.LoadPointer(&b.next))
stats.TotalBuckets++
}
if nentries < stats.MinEntries {
@@ -906,6 +1068,15 @@ func nextPowOf2(v uint32) uint32 {
return v
}
func parallelism() uint32 {
maxProcs := uint32(runtime.GOMAXPROCS(0))
numCores := uint32(runtime.NumCPU())
if maxProcs < numCores {
return maxProcs
}
return numCores
}
func broadcast(b uint8) uint64 {
return 0x101010101010101 * uint64(b)
}
@@ -920,6 +1091,7 @@ func markZeroBytes(w uint64) uint64 {
return ((w - 0x0101010101010101) & (^w) & 0x8080808080808080)
}
// Sets byte of the input word at the specified index to the given value.
func setByte(w uint64, b uint8, idx int) uint64 {
shift := idx << 3
return (w &^ (0xff << shift)) | (uint64(b) << shift)
+197 -7
View File
@@ -3,6 +3,7 @@ package xsync
import (
"math"
"math/rand"
"runtime"
"strconv"
"sync"
"sync/atomic"
@@ -53,11 +54,11 @@ func runParallel(b *testing.B, benchFn func(pb *testing.PB)) {
}
func TestMap_BucketStructSize(t *testing.T) {
size := unsafe.Sizeof(bucketPadded[string, int64]{})
size := unsafe.Sizeof(bucketPadded{})
if size != 64 {
t.Fatalf("size of 64B (one cache line) is expected, got: %d", size)
}
size = unsafe.Sizeof(bucketPadded[struct{}, int32]{})
size = unsafe.Sizeof(bucketPadded{})
if size != 64 {
t.Fatalf("size of 64B (one cache line) is expected, got: %d", size)
}
@@ -743,10 +744,7 @@ func TestNewMapGrowOnly_OnlyShrinksOnClear(t *testing.T) {
}
func TestMapResize(t *testing.T) {
testMapResize(t, NewMap[string, int]())
}
func testMapResize(t *testing.T, m *Map[string, int]) {
m := NewMap[string, int]()
const numEntries = 100_000
for i := 0; i < numEntries; i++ {
@@ -810,6 +808,147 @@ func TestMapResize_CounterLenLimit(t *testing.T) {
}
}
func testParallelResize(t *testing.T, numGoroutines int) {
m := NewMap[int, int]()
// Fill the map to trigger resizing
const initialEntries = 10000
const newEntries = 5000
for i := 0; i < initialEntries; i++ {
m.Store(i, i*2)
}
// Start concurrent operations that should trigger helping behavior
var wg sync.WaitGroup
// Launch goroutines that will encounter resize operations
for g := 0; g < numGoroutines; g++ {
wg.Add(1)
go func(goroutineID int) {
defer wg.Done()
// Perform many operations to trigger resize and helping
for i := 0; i < newEntries; i++ {
key := goroutineID*newEntries + i + initialEntries
m.Store(key, key*2)
// Verify the value
if val, ok := m.Load(key); !ok || val != key*2 {
t.Errorf("Failed to load key %d: got %v, %v", key, val, ok)
return
}
}
}(g)
}
wg.Wait()
// Verify all entries are present
finalSize := m.Size()
expectedSize := initialEntries + numGoroutines*newEntries
if finalSize != expectedSize {
t.Errorf("Expected size %d, got %d", expectedSize, finalSize)
}
stats := m.Stats()
if stats.TotalGrowths == 0 {
t.Error("Expected at least one table growth due to concurrent operations")
}
}
func TestMapParallelResize(t *testing.T) {
testParallelResize(t, 1)
testParallelResize(t, runtime.GOMAXPROCS(0))
testParallelResize(t, 100)
}
func testParallelResizeWithSameKeys(t *testing.T, numGoroutines int) {
m := NewMap[int, int]()
// Fill the map to trigger resizing
const entries = 1000
for i := 0; i < entries; i++ {
m.Store(2*i, 2*i)
}
// Start concurrent operations that should trigger helping behavior
var wg sync.WaitGroup
// Launch goroutines that will encounter resize operations
for g := 0; g < numGoroutines; g++ {
wg.Add(1)
go func(goroutineID int) {
defer wg.Done()
for i := 0; i < 10*entries; i++ {
m.Store(i, i)
}
}(g)
}
wg.Wait()
// Verify all entries are present
finalSize := m.Size()
expectedSize := 10 * entries
if finalSize != expectedSize {
t.Errorf("Expected size %d, got %d", expectedSize, finalSize)
}
stats := m.Stats()
if stats.TotalGrowths == 0 {
t.Error("Expected at least one table growth due to concurrent operations")
}
}
func TestMapParallelResize_IntersectingKeys(t *testing.T) {
testParallelResizeWithSameKeys(t, 1)
testParallelResizeWithSameKeys(t, runtime.GOMAXPROCS(0))
testParallelResizeWithSameKeys(t, 100)
}
func testParallelShrinking(t *testing.T, numGoroutines int) {
m := NewMap[int, int]()
// Fill the map to trigger resizing
const entries = 100000
for i := 0; i < entries; i++ {
m.Store(i, i)
}
// Start concurrent operations that should trigger helping behavior
var wg sync.WaitGroup
// Launch goroutines that will encounter resize operations
for g := 0; g < numGoroutines; g++ {
wg.Add(1)
go func(goroutineID int) {
defer wg.Done()
for i := 0; i < entries; i++ {
m.Delete(i)
}
}(g)
}
wg.Wait()
// Verify all entries are present
finalSize := m.Size()
if finalSize != 0 {
t.Errorf("Expected size 0, got %d", finalSize)
}
stats := m.Stats()
if stats.TotalShrinks == 0 {
t.Error("Expected at least one table shrinking due to concurrent operations")
}
}
func TestMapParallelShrinking(t *testing.T) {
testParallelShrinking(t, 1)
testParallelShrinking(t, runtime.GOMAXPROCS(0))
testParallelShrinking(t, 100)
}
func parallelSeqMapGrower(m *Map[int, int], numEntries int, positive bool, cdone chan bool) {
for i := 0; i < numEntries; i++ {
if positive {
@@ -1459,7 +1598,7 @@ func BenchmarkMapRange(b *testing.B) {
}
// Benchmarks noop performance of Compute
func BenchmarkCompute(b *testing.B) {
func BenchmarkMapCompute(b *testing.B) {
tests := []struct {
Name string
Op ComputeOp
@@ -1487,6 +1626,57 @@ func BenchmarkCompute(b *testing.B) {
}
}
func BenchmarkMapParallelRehashing(b *testing.B) {
tests := []struct {
name string
goroutines int
numEntries int
}{
{"1goroutine_10M", 1, 10_000_000},
{"4goroutines_10M", 4, 10_000_000},
{"8goroutines_10M", 8, 10_000_000},
}
for _, test := range tests {
b.Run(test.name, func(b *testing.B) {
for i := 0; i < b.N; i++ {
m := NewMap[int, int]()
var wg sync.WaitGroup
entriesPerGoroutine := test.numEntries / test.goroutines
start := time.Now()
for g := 0; g < test.goroutines; g++ {
wg.Add(1)
go func(goroutineID int) {
defer wg.Done()
base := goroutineID * entriesPerGoroutine
for j := 0; j < entriesPerGoroutine; j++ {
key := base + j
m.Store(key, key)
}
}(g)
}
wg.Wait()
duration := time.Since(start)
b.ReportMetric(float64(test.numEntries)/duration.Seconds(), "entries/s")
finalSize := m.Size()
if finalSize != test.numEntries {
b.Fatalf("Expected size %d, got %d", test.numEntries, finalSize)
}
stats := m.Stats()
if stats.TotalGrowths == 0 {
b.Error("Expected at least one table growth during rehashing")
}
}
})
}
}
func TestNextPowOf2(t *testing.T) {
if nextPowOf2(0) != 1 {
t.Error("nextPowOf2 failed")
@@ -1,4 +1,4 @@
name: main
name: Continuous Integration
on:
push:
@@ -9,8 +9,8 @@ on:
pull_request:
jobs:
# linters
lint-frontend:
name: Lint Frontend
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
@@ -19,57 +19,39 @@ jobs:
package_json_file: "frontend/package.json"
- uses: actions/setup-node@v6
with:
node-version: "22.x"
node-version: "24.x"
cache: "pnpm"
cache-dependency-path: "frontend/pnpm-lock.yaml"
- run: make lint-frontend
- working-directory: frontend
run: |
pnpm install --frozen-lockfile
pnpm run lint
lint-backend:
name: Lint Backend
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/setup-go@v6
with:
go-version: '1.25'
- run: make lint-backend
lint:
runs-on: ubuntu-latest
needs: [lint-frontend, lint-backend]
steps:
- run: echo "done"
go-version: "1.25.x"
- uses: golangci/golangci-lint-action@v9
with:
version: "latest"
# tests
test-frontend:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: pnpm/action-setup@v4
with:
package_json_file: "frontend/package.json"
- uses: actions/setup-node@v6
with:
node-version: "22.x"
cache: "pnpm"
cache-dependency-path: "frontend/pnpm-lock.yaml"
- run: make test-frontend
test-backend:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/setup-go@v6
with:
go-version: '1.25'
- run: make test-backend
test:
name: Test
runs-on: ubuntu-latest
needs: [test-frontend, test-backend]
steps:
- run: echo "done"
- uses: actions/checkout@v5
- uses: actions/setup-go@v6
with:
go-version: "1.25.x"
- run: go test --race ./...
# release
release:
build:
name: Build
runs-on: ubuntu-latest
needs: [lint, test]
if: startsWith(github.event.ref, 'refs/tags/v')
steps:
- uses: actions/checkout@v5
with:
@@ -82,24 +64,52 @@ jobs:
package_json_file: "frontend/package.json"
- uses: actions/setup-node@v6
with:
node-version: "22.x"
node-version: "24.x"
cache: "pnpm"
cache-dependency-path: "frontend/pnpm-lock.yaml"
- name: Install Task
uses: go-task/setup-task@v1
- run: task build
release:
name: Release
needs: ["lint-frontend", "lint-backend", "test", "build"]
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
with:
fetch-depth: 0
- uses: actions/setup-go@v6
with:
go-version: '1.25'
- uses: pnpm/action-setup@v4
with:
package_json_file: "frontend/package.json"
- uses: actions/setup-node@v6
with:
node-version: "24.x"
cache: "pnpm"
cache-dependency-path: "frontend/pnpm-lock.yaml"
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
- name: Build frontend
run: make build-frontend
uses: docker/setup-buildx-action@v3
- name: Install Task
uses: go-task/setup-task@v1
- run: task build-frontend
- name: Login to Docker Hub
uses: docker/login-action@v1
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v2
uses: goreleaser/goreleaser-action@v6
with:
version: latest
args: release --clean
env:
GITHUB_TOKEN: ${{ secrets.GH_PAT }}
+52
View File
@@ -0,0 +1,52 @@
name: Docs
on:
pull_request:
paths:
- 'www'
- '*.md'
push:
branches:
- master
jobs:
build:
name: Build Docs
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Install Task
uses: go-task/setup-task@v1
- name: Build site
run: task docs
build-and-release:
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
name: Build and Release Docs
permissions:
contents: read
deployments: write
pull-requests: write
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Install Task
uses: go-task/setup-task@v1
- name: Build site
run: task docs
- name: Deploy to Cloudflare Pages
uses: cloudflare/wrangler-action@v3
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
command: pages deploy www/public --project-name=${{ secrets.CLOUDFLARE_PROJECT_NAME }}
gitHubToken: ${{ secrets.GITHUB_TOKEN }}
@@ -13,10 +13,10 @@ permissions:
jobs:
main:
name: Validate PR title
name: Validate Title
runs-on: ubuntu-latest
steps:
- uses: amannn/action-semantic-pull-request@v5
- uses: amannn/action-semantic-pull-request@v6
id: lint_pr_title
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -43,4 +43,4 @@ jobs:
uses: marocchino/sticky-pull-request-comment@v2
with:
header: pr-title-lint-error
delete: true
delete: true
-20
View File
@@ -1,20 +0,0 @@
name: Build Site
on:
pull_request:
paths:
- 'www'
- '*.md'
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Build site
run: make site
-32
View File
@@ -1,32 +0,0 @@
name: Build and Deploy Site
on:
push:
branches:
- master
jobs:
deploy:
permissions:
contents: read
deployments: write
pull-requests: write
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Build site
run: make site
- name: Deploy to Cloudflare Pages
uses: cloudflare/wrangler-action@v3
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
command: pages deploy www/public --project-name=${{ secrets.CLOUDFLARE_PROJECT_NAME }}
gitHubToken: ${{ secrets.GITHUB_TOKEN }}
-5
View File
@@ -35,10 +35,5 @@ build/
/frontend/dist/*
!/frontend/dist/.gitkeep
# Playwright files
/frontend/test-results/
/frontend/playwright-report/
/frontend/playwright/.cache/
default.nix
Dockerfile.dev
+13 -1
View File
@@ -1,6 +1,18 @@
# Changelog
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
All notable changes to this project will be documented in this file. See [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version) for commit guidelines.
## [2.45.3](https://github.com/filebrowser/filebrowser/compare/v2.45.2...v2.45.3) (2025-11-13)
This is a test release to ensure the updated workflow works.
## [2.45.2](https://github.com/filebrowser/filebrowser/compare/v2.45.1...v2.45.2) (2025-11-13)
### Bug Fixes
* **deps:** update module github.com/shirou/gopsutil/v3 to v4 ([#5536](https://github.com/filebrowser/filebrowser/issues/5536)) ([fdff7a3](https://github.com/filebrowser/filebrowser/commit/fdff7a38f4711f2b58dfdd60bebbb057bd3a478d))
* **deps:** update module gopkg.in/yaml.v2 to v3 ([#5537](https://github.com/filebrowser/filebrowser/issues/5537)) ([f26a685](https://github.com/filebrowser/filebrowser/commit/f26a68587d8432b536453093f42dc255d19d10fa))
### [2.45.1](https://github.com/filebrowser/filebrowser/compare/v2.45.0...v2.45.1) (2025-11-11)
+46 -9
View File
@@ -15,11 +15,23 @@ We encourage you to use git to manage your fork. To clone the main repository, j
git clone https://github.com/filebrowser/filebrowser
```
We use [Taskfile](https://taskfile.dev/) to manage the different processes (building, releasing, etc) automatically.
## Build
You can fully build the project in order to produce a binary by running:
```bash
task build
```
## Development
For development, there are a few things to have in mind.
### Frontend
We are using [Node.js](https://nodejs.org/en/) on the frontend to manage the build process. The steps to build it are:
We use [Node.js](https://nodejs.org/en/) on the frontend to manage the build process. Prepare the frontend environment:
```bash
# From the root of the repo, go to frontend/
@@ -27,37 +39,62 @@ cd frontend
# Install the dependencies
pnpm install
```
# Build the frontend
If you just want to develop the backend, you can create a static build of the frontend:
```bash
pnpm run build
```
This will install the dependencies and build the frontend so you can then embed it into the Go app. Although, if you want to play with it, you'll get bored of building it after every change you do. So, you can run the command below to watch for changes:
If you want to develop the frontend, start a development server which watches for changes:
```bash
pnpm run dev
```
Please note that you need to access File Browser's interface through the development server of the frontend.
### Backend
First of all, you need to download the required dependencies. We are using the built-in `go mod` tool for dependency management. To get the modules, run:
First prepare the backend environment by downloading all required dependencies:
```bash
go mod download
```
The magic of File Browser is that the static assets are bundled into the final binary. For that, we use [Go embed.FS](https://golang.org/pkg/embed/). The files from `frontend/dist` will be embedded during the build process.
To build File Browser is just like any other Go program:
You can now build or run File Browser as any other Go project:
```bash
# Build
go build
# Run
go run .
```
To create a development build use the "dev" tag, this way the content inside the frontend folder will not be embedded in the binary but will be reloaded at every change:
## Documentation
We rely on Docker to abstract all the dependencies required for building the documentation.
To build the documentation to `www/public`:
```bash
go build -tags dev
task docs
```
To start a local server on port `8000` to view the built documentation:
```bash
task docs-serve
```
## Release
To make a release, just run:
```bash
task release
```
## Translations
-88
View File
@@ -1,88 +0,0 @@
include common.mk
include tools.mk
LDFLAGS += -X "$(MODULE)/version.Version=$(VERSION)" -X "$(MODULE)/version.CommitSHA=$(VERSION_HASH)"
SITE_DOCKER_FLAGS = \
-v $(CURDIR)/www:/docs \
-v $(CURDIR)/LICENSE:/docs/docs/LICENSE \
-v $(CURDIR)/SECURITY.md:/docs/docs/security.md \
-v $(CURDIR)/CHANGELOG.md:/docs/docs/changelog.md \
-v $(CURDIR)/CODE-OF-CONDUCT.md:/docs/docs/code-of-conduct.md \
-v $(CURDIR)/CONTRIBUTING.md:/docs/docs/contributing.md
## Build:
.PHONY: build
build: | build-frontend build-backend ## Build binary
.PHONY: build-frontend
build-frontend: ## Build frontend
$Q cd frontend && pnpm install --frozen-lockfile && pnpm run build
.PHONY: build-backend
build-backend: ## Build backend
$Q $(go) build -ldflags '$(LDFLAGS)' -o .
.PHONY: test
test: | test-frontend test-backend ## Run all tests
.PHONY: test-frontend
test-frontend: ## Run frontend tests
$Q cd frontend && pnpm install --frozen-lockfile && pnpm run typecheck
.PHONY: test-backend
test-backend: ## Run backend tests
$Q $(go) test -v ./...
.PHONY: lint
lint: lint-frontend lint-backend ## Run all linters
.PHONY: lint-frontend
lint-frontend: ## Run frontend linters
$Q cd frontend && pnpm install --frozen-lockfile && pnpm run lint
.PHONY: lint-backend
lint-backend: | $(golangci-lint) ## Run backend linters
$Q $(golangci-lint) run -v
.PHONY: lint-commits
lint-commits: $(commitlint) ## Run commit linters
$Q ./scripts/commitlint.sh
fmt: $(goimports) ## Format source files
$Q $(goimports) -local $(MODULE) -w $$(find . -type f -name '*.go' -not -path "./vendor/*")
clean: clean-tools ## Clean
## Release:
.PHONY: bump-version
bump-version: $(standard-version) ## Bump app version
$Q ./scripts/bump_version.sh
.PHONY: site
site: ## Build site
@rm -rf www/public
docker build -f www/Dockerfile --progress=plain -t filebrowser.site www
docker run --rm $(SITE_DOCKER_FLAGS) filebrowser.site build -d "public"
.PHONY: site-serve
site-serve: ## Serve site for development
docker build -f www/Dockerfile --progress=plain -t filebrowser.site www
docker run --rm -it -p 8000:8000 $(SITE_DOCKER_FLAGS) filebrowser.site
## Help:
help: ## Show this help
@echo ''
@echo 'Usage:'
@echo ' ${YELLOW}make${RESET} ${GREEN}<target> [options]${RESET}'
@echo ''
@echo 'Options:'
@$(call global_option, "V [0|1]", "enable verbose mode (default:0)")
@echo ''
@echo 'Targets:'
@awk 'BEGIN {FS = ":.*?## "} { \
if (/^[a-zA-Z_-]+:.*?##.*$$/) {printf " ${YELLOW}%-20s${GREEN}%s${RESET}\n", $$1, $$2} \
else if (/^## .*$$/) {printf " ${CYAN}%s${RESET}\n", substr($$1,4)} \
}' $(MAKEFILE_LIST)
+6 -12
View File
@@ -2,7 +2,7 @@
<img src="https://raw.githubusercontent.com/filebrowser/filebrowser/master/branding/banner.png" width="550"/>
</p>
[![Build](https://github.com/filebrowser/filebrowser/actions/workflows/main.yaml/badge.svg)](https://github.com/filebrowser/filebrowser/actions/workflows/main.yaml)
[![Build](https://github.com/filebrowser/filebrowser/actions/workflows/ci.yaml/badge.svg)](https://github.com/filebrowser/filebrowser/actions/workflows/ci.yaml)
[![Go Report Card](https://goreportcard.com/badge/github.com/filebrowser/filebrowser/v2)](https://goreportcard.com/report/github.com/filebrowser/filebrowser/v2)
[![Version](https://img.shields.io/github/release/filebrowser/filebrowser.svg)](https://github.com/filebrowser/filebrowser/releases/latest)
@@ -14,18 +14,12 @@ Documentation on how to install, configure, and contribute to this project is ho
## Project Status
> [!WARNING]
>
> This project is currently on **maintenance-only** mode, and is looking for new maintainers. For more information, please read the [discussion #4906](https://github.com/filebrowser/filebrowser/discussions/4906). Therefore, please note the following:
>
> - It can take a while until someone gets back to you. Please be patient.
> - [Issues][issues] are only being used to track bugs. Any unrelated issues will be converted into a [discussion][discussions].
> - No new features will be implemented until further notice. The priority is on triaging issues and merge bug fixes.
>
> If you're interested in maintaining this project, please reach out via the discussion above.
This project is a finished product which fulfills its goal: be a single binary web File Browser which can be run by anyone anywhere. That means that File Browser is currently on **maintenance-only** mode. Therefore, please note the following:
[issues]: https://github.com/filebrowser/filebrowser/issues
[discussions]: https://github.com/filebrowser/filebrowser/discussions
- It can take a while until someone gets back to you. Please be patient.
- [Issues](https://github.com/filebrowser/filebrowser/issues) are meant to track bugs. Unrelated issues will be converted into [discussions](https://github.com/filebrowser/filebrowser/discussions).
- No new features will be implemented by maintainers. Pull requests for new features will be reviewed on a case by case basis.
- The priority is triaging issues, addressing security issues, and fixing bug fixes.
## Contributing
+69
View File
@@ -0,0 +1,69 @@
version: '3'
vars:
SITE_DOCKER_FLAGS: >-
-v ./www:/docs
-v ./LICENSE:/docs/docs/LICENSE
-v ./SECURITY.md:/docs/docs/security.md
-v ./CHANGELOG.md:/docs/docs/changelog.md
-v ./CODE-OF-CONDUCT.md:/docs/docs/code-of-conduct.md
-v ./CONTRIBUTING.md:/docs/docs/contributing.md
tasks:
build-frontend:
desc: Build frontend assets
dir: frontend
cmds:
- pnpm install --frozen-lockfile
- pnpm run build
build-backend:
desc: Build backend binary
cmds:
- go build -ldflags='-s -w -X "github.com/filebrowser/filebrowser/v2/version.Version={{.VERSION}}" -X "github.com/filebrowser/filebrowser/v2/version.CommitSHA={{.GIT_COMMIT}}"' -o filebrowser .
vars:
GIT_COMMIT:
sh: git log -n 1 --format=%h
VERSION:
sh: git describe --tags --abbrev=0 --match=v* | cut -c 2-
build:
desc: Build both frontend and backend
cmds:
- task: build-frontend
- task: build-backend
release-make:
internal: true
prompt: Do you wish to proceed?
cmds:
- pnpm dlx commit-and-tag-version -s
release-dry-run:
internal: true
cmds:
- pnpm dlx commit-and-tag-version --dry-run --skip
release:
desc: Create a new release
cmds:
- task: release-dry-run
- task: release-make
docs-image-make:
internal: true
cmds:
- docker build -f www/Dockerfile --progress=plain -t filebrowser.site www
docs:
desc: Generate documentation
cmds:
- rm -rf www/public
- task: docs-image-make
- docker run --rm {{.SITE_DOCKER_FLAGS}} filebrowser.site build -d "public"
docs-serve:
desc: Serve documentation
cmds:
- task: docs-image-make
- docker run --rm -it -p 8000:8000 {{.SITE_DOCKER_FLAGS}} filebrowser.site
+1 -1
View File
@@ -14,7 +14,7 @@ import (
"github.com/asdine/storm/v3"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
yaml "gopkg.in/yaml.v2"
yaml "gopkg.in/yaml.v3"
"github.com/filebrowser/filebrowser/v2/settings"
"github.com/filebrowser/filebrowser/v2/storage"
-34
View File
@@ -1,34 +0,0 @@
module.exports = {
rules: {
'body-leading-blank': [1, 'always'],
'body-max-line-length': [2, 'always', 100],
'footer-leading-blank': [1, 'always'],
'footer-max-line-length': [2, 'always', 100],
'header-max-length': [2, 'always', 100],
'scope-case': [2, 'always', 'lower-case'],
'subject-case': [
2,
'never',
['sentence-case', 'start-case', 'pascal-case', 'upper-case'],
],
'subject-full-stop': [2, 'never', '.'],
'type-case': [2, 'always', 'lower-case'],
'type-empty': [2, 'never'],
'type-enum': [
2,
'always',
[
'feat',
'fix',
'perf',
'revert',
'refactor',
'build',
'ci',
'test',
'chore',
'docs',
],
],
},
};
-28
View File
@@ -1,28 +0,0 @@
SHELL := /usr/bin/env bash
DATE ?= $(shell date +%FT%T%z)
BASE_PATH := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
VERSION ?= $(shell git describe --tags --always --match=v* 2> /dev/null || \
cat $(CURDIR)/.version 2> /dev/null || echo v0)
VERSION_HASH = $(shell git rev-parse HEAD)
BRANCH = $(shell git rev-parse --abbrev-ref HEAD)
go = GOGC=off go
MODULE = $(shell env GO111MODULE=on go list -m)
# printing
# $Q (quiet) is used in the targets as a replacer for @.
# This macro helps to print the command for debugging by setting V to 1. Example `make test-unit V=1`
V = 0
Q = $(if $(filter 1,$V),,@)
# $M is a macro to print a colored ▶ character. Example `$(info $(M) running coverage tests…)` will print "▶ running coverage tests…"
M = $(shell printf "\033[34;1m▶\033[0m")
GREEN := $(shell tput -Txterm setaf 2)
YELLOW := $(shell tput -Txterm setaf 3)
WHITE := $(shell tput -Txterm setaf 7)
CYAN := $(shell tput -Txterm setaf 6)
RESET := $(shell tput -Txterm sgr0)
define global_option
printf " ${YELLOW}%-20s${GREEN}%s${RESET}\n" $(1) $(2)
endef
-14
View File
@@ -1,14 +0,0 @@
//go:build dev
package frontend
import (
"io/fs"
"os"
)
var assets fs.FS = os.DirFS("frontend")
func Assets() fs.FS {
return assets
}
+5 -1
View File
@@ -12,7 +12,11 @@
<link rel="icon" type="image/svg+xml" href="/img/icons/favicon.svg" />
<link rel="shortcut icon" href="/img/icons/favicon.ico" />
<link rel="apple-touch-icon" sizes="180x180" href="/img/icons/apple-touch-icon.png" />
<link
rel="apple-touch-icon"
sizes="180x180"
href="/img/icons/apple-touch-icon.png"
/>
<meta name="apple-mobile-web-app-title" content="File Browser" />
<!-- Add to home screen for Android and modern mobile browsers -->
+22 -26
View File
@@ -4,37 +4,35 @@
"private": true,
"type": "module",
"engines": {
"node": ">=22.0.0",
"pnpm": ">=9.0.0"
"node": ">=24.0.0",
"pnpm": ">=10.0.0"
},
"scripts": {
"dev": "vite dev",
"build": "pnpm run typecheck && vite build",
"clean": "find ./dist -maxdepth 1 -mindepth 1 ! -name '.gitkeep' -exec rm -r {} +",
"typecheck": "vue-tsc -p ./tsconfig.tsc.json --noEmit",
"typecheck": "vue-tsc -p ./tsconfig.app.json --noEmit",
"lint": "eslint src/",
"lint:fix": "eslint --fix src/",
"format": "prettier --write .",
"test": "playwright test"
"format": "prettier --write ."
},
"dependencies": {
"@chenfengyuan/vue-number-input": "^2.0.1",
"@vueuse/core": "^12.5.0",
"@vueuse/integrations": "^12.5.0",
"@vueuse/core": "^14.0.0",
"@vueuse/integrations": "^14.0.0",
"ace-builds": "^1.43.2",
"core-js": "^3.44.0",
"dayjs": "^1.11.13",
"dompurify": "^3.2.6",
"epubjs": "^0.3.93",
"filesize": "^10.1.1",
"filesize": "^11.0.13",
"js-base64": "^3.7.7",
"jwt-decode": "^4.0.0",
"lodash-es": "^4.17.21",
"marked": "^15.0.6",
"marked": "^17.0.0",
"material-icons": "^1.13.14",
"normalize.css": "^8.0.1",
"pinia": "^2.3.1",
"pretty-bytes": "^6.1.1",
"pinia": "^3.0.4",
"pretty-bytes": "^7.1.0",
"qrcode.vue": "^3.6.0",
"tus-js-client": "^4.3.1",
"utif": "^3.1.0",
@@ -50,30 +48,28 @@
"vue-toastification": "^2.0.0-rc.5"
},
"devDependencies": {
"@intlify/unplugin-vue-i18n": "^6.0.8",
"@playwright/test": "^1.54.1",
"@tsconfig/node22": "^22.0.2",
"@intlify/unplugin-vue-i18n": "^11.0.1",
"@tsconfig/node24": "^24.0.2",
"@types/lodash-es": "^4.17.12",
"@types/node": "^22.10.10",
"@types/node": "^24.10.1",
"@typescript-eslint/eslint-plugin": "^8.37.0",
"@vitejs/plugin-legacy": "^6.0.0",
"@vitejs/plugin-vue": "^5.0.4",
"@vitejs/plugin-legacy": "^7.2.1",
"@vitejs/plugin-vue": "^6.0.1",
"@vue/eslint-config-prettier": "^10.2.0",
"@vue/eslint-config-typescript": "^14.6.0",
"@vue/tsconfig": "^0.7.0",
"@vue/tsconfig": "^0.8.1",
"autoprefixer": "^10.4.21",
"concurrently": "^9.2.0",
"eslint": "^9.31.0",
"eslint-config-prettier": "^10.1.5",
"eslint-plugin-prettier": "^5.5.1",
"eslint-plugin-vue": "^9.24.0",
"jsdom": "^26.1.0",
"eslint-plugin-vue": "^10.5.1",
"postcss": "^8.5.6",
"prettier": "^3.6.2",
"terser": "^5.43.1",
"vite": "^6.4.1",
"vite-plugin-compression2": "^1.0.0",
"vue-tsc": "^2.2.0"
"typescript": "^5.9.3",
"vite": "^7.2.2",
"vite-plugin-compression2": "^2.3.1",
"vue-tsc": "^3.1.3"
},
"packageManager": "pnpm@9.15.9+sha512.68046141893c66fad01c079231128e9afb89ef87e2691d69e4d40eee228988295fd4682181bae55b58418c3a253bde65a505ec7c5f9403ece5cc3cd37dcf2531"
"packageManager": "pnpm@10.22.0+sha512.bf049efe995b28f527fd2b41ae0474ce29186f7edcb3bf545087bd61fbbebb2bf75362d1307fda09c2d288e1e499787ac12d4fcb617a974718a6051f2eee741c"
}
-80
View File
@@ -1,80 +0,0 @@
import { defineConfig, devices } from "@playwright/test";
/**
* Read environment variables from file.
* https://github.com/motdotla/dotenv
*/
// require('dotenv').config();
/**
* See https://playwright.dev/docs/test-configuration.
*/
export default defineConfig({
testDir: "./tests",
/* Run tests in files in parallel */
fullyParallel: true,
/* Fail the build on CI if you accidentally left test.only in the source code. */
forbidOnly: !!process.env.CI,
/* Retry on CI only */
retries: process.env.CI ? 2 : 0,
/* Opt out of parallel tests on CI. */
workers: process.env.CI ? 1 : undefined,
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
reporter: "html",
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
use: {
/* Base URL to use in actions like `await page.goto('/')`. */
baseURL: "http://127.0.0.1:5173",
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
trace: "on-first-retry",
/* Set default locale to English (US) */
locale: "en-US",
},
/* Configure projects for major browsers */
projects: [
{
name: "chromium",
use: { ...devices["Desktop Chrome"] },
},
{
name: "firefox",
use: { ...devices["Desktop Firefox"] },
},
// {
// name: "webkit",
// use: { ...devices["Desktop Safari"] },
// },
/* Test against mobile viewports. */
// {
// name: 'Mobile Chrome',
// use: { ...devices['Pixel 5'] },
// },
// {
// name: 'Mobile Safari',
// use: { ...devices['iPhone 12'] },
// },
/* Test against branded browsers. */
// {
// name: 'Microsoft Edge',
// use: { ...devices['Desktop Edge'], channel: 'msedge' },
// },
// {
// name: 'Google Chrome',
// use: { ...devices['Desktop Chrome'], channel: 'chrome' },
// },
],
/* Run your local dev server before starting the tests */
webServer: {
command: "npm run dev",
url: "http://127.0.0.1:5173",
reuseExistingServer: !process.env.CI,
},
});
+378 -987
View File
File diff suppressed because it is too large Load Diff
+10 -2
View File
@@ -18,9 +18,17 @@
<meta name="robots" content="noindex,nofollow" />
<link rel="icon" type="image/svg+xml" href="[{[ .StaticURL ]}]/img/icons/favicon.svg" />
<link
rel="icon"
type="image/svg+xml"
href="[{[ .StaticURL ]}]/img/icons/favicon.svg"
/>
<link rel="shortcut icon" href="[{[ .StaticURL ]}]/img/icons/favicon.ico" />
<link rel="apple-touch-icon" sizes="180x180" href="[{[ .StaticURL ]}]/img/icons/apple-touch-icon.png" />
<link
rel="apple-touch-icon"
sizes="180x180"
href="[{[ .StaticURL ]}]/img/icons/apple-touch-icon.png"
/>
<meta name="apple-mobile-web-app-title" content="File Browser" />
<!-- Add to home screen for Android and modern mobile browsers -->
+15 -12
View File
@@ -63,8 +63,8 @@
local("Roboto"),
local("Roboto-Regular"),
url(../assets/fonts/roboto/normal-latin-ext.woff2) format("woff2");
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF,
U+2C60-2C7F, U+A720-A7FF;
unicode-range:
U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
@@ -75,8 +75,9 @@
local("Roboto"),
local("Roboto-Regular"),
url(../assets/fonts/roboto/normal-latin.woff2) format("woff2");
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC,
U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
unicode-range:
U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F,
U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
}
@font-face {
@@ -142,8 +143,8 @@
local("Roboto Medium"),
local("Roboto-Medium"),
url(../assets/fonts/roboto/medium-latin-ext.woff2) format("woff2");
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF,
U+2C60-2C7F, U+A720-A7FF;
unicode-range:
U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
@@ -154,8 +155,9 @@
local("Roboto Medium"),
local("Roboto-Medium"),
url(../assets/fonts/roboto/medium-latin.woff2) format("woff2");
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC,
U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
unicode-range:
U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F,
U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
}
@font-face {
@@ -221,8 +223,8 @@
local("Roboto Bold"),
local("Roboto-Bold"),
url(../assets/fonts/roboto/bold-latin-ext.woff2) format("woff2");
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF,
U+2C60-2C7F, U+A720-A7FF;
unicode-range:
U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
@@ -233,8 +235,9 @@
local("Roboto Bold"),
local("Roboto-Bold"),
url(../assets/fonts/roboto/bold-latin.woff2) format("woff2");
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC,
U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
unicode-range:
U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F,
U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
}
.material-icons {
@@ -0,0 +1,4 @@
{
"status": "failed",
"failedTests": []
}
@@ -1,489 +0,0 @@
import { test, expect, type Page } from "@playwright/test";
test.beforeEach(async ({ page }) => {
await page.goto("https://demo.playwright.dev/todomvc");
});
const TODO_ITEMS = [
"buy some cheese",
"feed the cat",
"book a doctors appointment",
];
test.describe("New Todo", () => {
test("should allow me to add todo items", async ({ page }) => {
// create a new todo locator
const newTodo = page.getByPlaceholder("What needs to be done?");
// Create 1st todo.
await newTodo.fill(TODO_ITEMS[0]);
await newTodo.press("Enter");
// Make sure the list only has one todo item.
await expect(page.getByTestId("todo-title")).toHaveText([TODO_ITEMS[0]]);
// Create 2nd todo.
await newTodo.fill(TODO_ITEMS[1]);
await newTodo.press("Enter");
// Make sure the list now has two todo items.
await expect(page.getByTestId("todo-title")).toHaveText([
TODO_ITEMS[0],
TODO_ITEMS[1],
]);
await checkNumberOfTodosInLocalStorage(page, 2);
});
test("should clear text input field when an item is added", async ({
page,
}) => {
// create a new todo locator
const newTodo = page.getByPlaceholder("What needs to be done?");
// Create one todo item.
await newTodo.fill(TODO_ITEMS[0]);
await newTodo.press("Enter");
// Check that input is empty.
await expect(newTodo).toBeEmpty();
await checkNumberOfTodosInLocalStorage(page, 1);
});
test("should append new items to the bottom of the list", async ({
page,
}) => {
// Create 3 items.
await createDefaultTodos(page);
// create a todo count locator
const todoCount = page.getByTestId("todo-count");
// Check test using different methods.
await expect(page.getByText("3 items left")).toBeVisible();
await expect(todoCount).toHaveText("3 items left");
await expect(todoCount).toContainText("3");
await expect(todoCount).toHaveText(/3/);
// Check all items in one call.
await expect(page.getByTestId("todo-title")).toHaveText(TODO_ITEMS);
await checkNumberOfTodosInLocalStorage(page, 3);
});
});
test.describe("Mark all as completed", () => {
test.beforeEach(async ({ page }) => {
await createDefaultTodos(page);
await checkNumberOfTodosInLocalStorage(page, 3);
});
test.afterEach(async ({ page }) => {
await checkNumberOfTodosInLocalStorage(page, 3);
});
test("should allow me to mark all items as completed", async ({ page }) => {
// Complete all todos.
await page.getByLabel("Mark all as complete").check();
// Ensure all todos have 'completed' class.
await expect(page.getByTestId("todo-item")).toHaveClass([
"completed",
"completed",
"completed",
]);
await checkNumberOfCompletedTodosInLocalStorage(page, 3);
});
test("should allow me to clear the complete state of all items", async ({
page,
}) => {
const toggleAll = page.getByLabel("Mark all as complete");
// Check and then immediately uncheck.
await toggleAll.check();
await toggleAll.uncheck();
// Should be no completed classes.
await expect(page.getByTestId("todo-item")).toHaveClass(["", "", ""]);
});
test("complete all checkbox should update state when items are completed / cleared", async ({
page,
}) => {
const toggleAll = page.getByLabel("Mark all as complete");
await toggleAll.check();
await expect(toggleAll).toBeChecked();
await checkNumberOfCompletedTodosInLocalStorage(page, 3);
// Uncheck first todo.
const firstTodo = page.getByTestId("todo-item").nth(0);
await firstTodo.getByRole("checkbox").uncheck();
// Reuse toggleAll locator and make sure its not checked.
await expect(toggleAll).not.toBeChecked();
await firstTodo.getByRole("checkbox").check();
await checkNumberOfCompletedTodosInLocalStorage(page, 3);
// Assert the toggle all is checked again.
await expect(toggleAll).toBeChecked();
});
});
test.describe("Item", () => {
test("should allow me to mark items as complete", async ({ page }) => {
// create a new todo locator
const newTodo = page.getByPlaceholder("What needs to be done?");
// Create two items.
for (const item of TODO_ITEMS.slice(0, 2)) {
await newTodo.fill(item);
await newTodo.press("Enter");
}
// Check first item.
const firstTodo = page.getByTestId("todo-item").nth(0);
await firstTodo.getByRole("checkbox").check();
await expect(firstTodo).toHaveClass("completed");
// Check second item.
const secondTodo = page.getByTestId("todo-item").nth(1);
await expect(secondTodo).not.toHaveClass("completed");
await secondTodo.getByRole("checkbox").check();
// Assert completed class.
await expect(firstTodo).toHaveClass("completed");
await expect(secondTodo).toHaveClass("completed");
});
test("should allow me to un-mark items as complete", async ({ page }) => {
// create a new todo locator
const newTodo = page.getByPlaceholder("What needs to be done?");
// Create two items.
for (const item of TODO_ITEMS.slice(0, 2)) {
await newTodo.fill(item);
await newTodo.press("Enter");
}
const firstTodo = page.getByTestId("todo-item").nth(0);
const secondTodo = page.getByTestId("todo-item").nth(1);
const firstTodoCheckbox = firstTodo.getByRole("checkbox");
await firstTodoCheckbox.check();
await expect(firstTodo).toHaveClass("completed");
await expect(secondTodo).not.toHaveClass("completed");
await checkNumberOfCompletedTodosInLocalStorage(page, 1);
await firstTodoCheckbox.uncheck();
await expect(firstTodo).not.toHaveClass("completed");
await expect(secondTodo).not.toHaveClass("completed");
await checkNumberOfCompletedTodosInLocalStorage(page, 0);
});
test("should allow me to edit an item", async ({ page }) => {
await createDefaultTodos(page);
const todoItems = page.getByTestId("todo-item");
const secondTodo = todoItems.nth(1);
await secondTodo.dblclick();
await expect(secondTodo.getByRole("textbox", { name: "Edit" })).toHaveValue(
TODO_ITEMS[1]
);
await secondTodo
.getByRole("textbox", { name: "Edit" })
.fill("buy some sausages");
await secondTodo.getByRole("textbox", { name: "Edit" }).press("Enter");
// Explicitly assert the new text value.
await expect(todoItems).toHaveText([
TODO_ITEMS[0],
"buy some sausages",
TODO_ITEMS[2],
]);
await checkTodosInLocalStorage(page, "buy some sausages");
});
});
test.describe("Editing", () => {
test.beforeEach(async ({ page }) => {
await createDefaultTodos(page);
await checkNumberOfTodosInLocalStorage(page, 3);
});
test("should hide other controls when editing", async ({ page }) => {
const todoItem = page.getByTestId("todo-item").nth(1);
await todoItem.dblclick();
await expect(todoItem.getByRole("checkbox")).not.toBeVisible();
await expect(
todoItem.locator("label", {
hasText: TODO_ITEMS[1],
})
).not.toBeVisible();
await checkNumberOfTodosInLocalStorage(page, 3);
});
test("should save edits on blur", async ({ page }) => {
const todoItems = page.getByTestId("todo-item");
await todoItems.nth(1).dblclick();
await todoItems
.nth(1)
.getByRole("textbox", { name: "Edit" })
.fill("buy some sausages");
await todoItems
.nth(1)
.getByRole("textbox", { name: "Edit" })
.dispatchEvent("blur");
await expect(todoItems).toHaveText([
TODO_ITEMS[0],
"buy some sausages",
TODO_ITEMS[2],
]);
await checkTodosInLocalStorage(page, "buy some sausages");
});
test("should trim entered text", async ({ page }) => {
const todoItems = page.getByTestId("todo-item");
await todoItems.nth(1).dblclick();
await todoItems
.nth(1)
.getByRole("textbox", { name: "Edit" })
.fill(" buy some sausages ");
await todoItems
.nth(1)
.getByRole("textbox", { name: "Edit" })
.press("Enter");
await expect(todoItems).toHaveText([
TODO_ITEMS[0],
"buy some sausages",
TODO_ITEMS[2],
]);
await checkTodosInLocalStorage(page, "buy some sausages");
});
test("should remove the item if an empty text string was entered", async ({
page,
}) => {
const todoItems = page.getByTestId("todo-item");
await todoItems.nth(1).dblclick();
await todoItems.nth(1).getByRole("textbox", { name: "Edit" }).fill("");
await todoItems
.nth(1)
.getByRole("textbox", { name: "Edit" })
.press("Enter");
await expect(todoItems).toHaveText([TODO_ITEMS[0], TODO_ITEMS[2]]);
});
test("should cancel edits on escape", async ({ page }) => {
const todoItems = page.getByTestId("todo-item");
await todoItems.nth(1).dblclick();
await todoItems
.nth(1)
.getByRole("textbox", { name: "Edit" })
.fill("buy some sausages");
await todoItems
.nth(1)
.getByRole("textbox", { name: "Edit" })
.press("Escape");
await expect(todoItems).toHaveText(TODO_ITEMS);
});
});
test.describe("Counter", () => {
test("should display the current number of todo items", async ({ page }) => {
// create a new todo locator
const newTodo = page.getByPlaceholder("What needs to be done?");
// create a todo count locator
const todoCount = page.getByTestId("todo-count");
await newTodo.fill(TODO_ITEMS[0]);
await newTodo.press("Enter");
await expect(todoCount).toContainText("1");
await newTodo.fill(TODO_ITEMS[1]);
await newTodo.press("Enter");
await expect(todoCount).toContainText("2");
await checkNumberOfTodosInLocalStorage(page, 2);
});
});
test.describe("Clear completed button", () => {
test.beforeEach(async ({ page }) => {
await createDefaultTodos(page);
});
test("should display the correct text", async ({ page }) => {
await page.locator(".todo-list li .toggle").first().check();
await expect(
page.getByRole("button", { name: "Clear completed" })
).toBeVisible();
});
test("should remove completed items when clicked", async ({ page }) => {
const todoItems = page.getByTestId("todo-item");
await todoItems.nth(1).getByRole("checkbox").check();
await page.getByRole("button", { name: "Clear completed" }).click();
await expect(todoItems).toHaveCount(2);
await expect(todoItems).toHaveText([TODO_ITEMS[0], TODO_ITEMS[2]]);
});
test("should be hidden when there are no items that are completed", async ({
page,
}) => {
await page.locator(".todo-list li .toggle").first().check();
await page.getByRole("button", { name: "Clear completed" }).click();
await expect(
page.getByRole("button", { name: "Clear completed" })
).toBeHidden();
});
});
test.describe("Persistence", () => {
test("should persist its data", async ({ page }) => {
// create a new todo locator
const newTodo = page.getByPlaceholder("What needs to be done?");
for (const item of TODO_ITEMS.slice(0, 2)) {
await newTodo.fill(item);
await newTodo.press("Enter");
}
const todoItems = page.getByTestId("todo-item");
const firstTodoCheck = todoItems.nth(0).getByRole("checkbox");
await firstTodoCheck.check();
await expect(todoItems).toHaveText([TODO_ITEMS[0], TODO_ITEMS[1]]);
await expect(firstTodoCheck).toBeChecked();
await expect(todoItems).toHaveClass(["completed", ""]);
// Ensure there is 1 completed item.
await checkNumberOfCompletedTodosInLocalStorage(page, 1);
// Now reload.
await page.reload();
await expect(todoItems).toHaveText([TODO_ITEMS[0], TODO_ITEMS[1]]);
await expect(firstTodoCheck).toBeChecked();
await expect(todoItems).toHaveClass(["completed", ""]);
});
});
test.describe("Routing", () => {
test.beforeEach(async ({ page }) => {
await createDefaultTodos(page);
// make sure the app had a chance to save updated todos in storage
// before navigating to a new view, otherwise the items can get lost :(
// in some frameworks like Durandal
await checkTodosInLocalStorage(page, TODO_ITEMS[0]);
});
test("should allow me to display active items", async ({ page }) => {
const todoItem = page.getByTestId("todo-item");
await page.getByTestId("todo-item").nth(1).getByRole("checkbox").check();
await checkNumberOfCompletedTodosInLocalStorage(page, 1);
await page.getByRole("link", { name: "Active" }).click();
await expect(todoItem).toHaveCount(2);
await expect(todoItem).toHaveText([TODO_ITEMS[0], TODO_ITEMS[2]]);
});
test("should respect the back button", async ({ page }) => {
const todoItem = page.getByTestId("todo-item");
await page.getByTestId("todo-item").nth(1).getByRole("checkbox").check();
await checkNumberOfCompletedTodosInLocalStorage(page, 1);
await test.step("Showing all items", async () => {
await page.getByRole("link", { name: "All" }).click();
await expect(todoItem).toHaveCount(3);
});
await test.step("Showing active items", async () => {
await page.getByRole("link", { name: "Active" }).click();
});
await test.step("Showing completed items", async () => {
await page.getByRole("link", { name: "Completed" }).click();
});
await expect(todoItem).toHaveCount(1);
await page.goBack();
await expect(todoItem).toHaveCount(2);
await page.goBack();
await expect(todoItem).toHaveCount(3);
});
test("should allow me to display completed items", async ({ page }) => {
await page.getByTestId("todo-item").nth(1).getByRole("checkbox").check();
await checkNumberOfCompletedTodosInLocalStorage(page, 1);
await page.getByRole("link", { name: "Completed" }).click();
await expect(page.getByTestId("todo-item")).toHaveCount(1);
});
test("should allow me to display all items", async ({ page }) => {
await page.getByTestId("todo-item").nth(1).getByRole("checkbox").check();
await checkNumberOfCompletedTodosInLocalStorage(page, 1);
await page.getByRole("link", { name: "Active" }).click();
await page.getByRole("link", { name: "Completed" }).click();
await page.getByRole("link", { name: "All" }).click();
await expect(page.getByTestId("todo-item")).toHaveCount(3);
});
test("should highlight the currently applied filter", async ({ page }) => {
await expect(page.getByRole("link", { name: "All" })).toHaveClass(
"selected"
);
//create locators for active and completed links
const activeLink = page.getByRole("link", { name: "Active" });
const completedLink = page.getByRole("link", { name: "Completed" });
await activeLink.click();
// Page change - active items.
await expect(activeLink).toHaveClass("selected");
await completedLink.click();
// Page change - completed items.
await expect(completedLink).toHaveClass("selected");
});
});
async function createDefaultTodos(page: Page) {
// create a new todo locator
const newTodo = page.getByPlaceholder("What needs to be done?");
for (const item of TODO_ITEMS) {
await newTodo.fill(item);
await newTodo.press("Enter");
}
}
async function checkNumberOfTodosInLocalStorage(page: Page, expected: number) {
return await page.waitForFunction((e) => {
return JSON.parse(localStorage["react-todos"]).length === e;
}, expected);
}
async function checkNumberOfCompletedTodosInLocalStorage(
page: Page,
expected: number
) {
return await page.waitForFunction((e) => {
return (
JSON.parse(localStorage["react-todos"]).filter(
(todo: any) => todo.completed
).length === e
);
}, expected);
}
async function checkTodosInLocalStorage(page: Page, title: string) {
return await page.waitForFunction((t) => {
return JSON.parse(localStorage["react-todos"])
.map((todo: any) => todo.title)
.includes(t);
}, title);
}
-32
View File
@@ -1,32 +0,0 @@
import { test, expect } from "./fixtures/auth";
test("redirect to login", async ({ page }) => {
await page.goto("/");
await expect(page).toHaveURL(/\/login/);
await page.goto("/files/");
await expect(page).toHaveURL(/\/login\?redirect=\/files\//);
});
test("login and logout", async ({ authPage, page, context }) => {
await authPage.goto();
await expect(page).toHaveTitle(/Login - File Browser$/);
await authPage.loginAs("fake", "fake");
await expect(authPage.wrongCredentials).toBeVisible();
await authPage.loginAs();
await expect(authPage.wrongCredentials).toBeHidden();
// await page.waitForURL("**/files/", { timeout: 5000 });
await expect(page).toHaveTitle(/.*Files - File Browser$/);
let cookies = await context.cookies();
expect(cookies.find((c) => c.name == "auth")?.value).toBeDefined();
await authPage.logout();
// await page.waitForURL("**/login", { timeout: 5000 });
await expect(page).toHaveTitle(/Login - File Browser$/);
cookies = await context.cookies();
expect(cookies.find((c) => c.name == "auth")?.value).toBeUndefined();
});
-40
View File
@@ -1,40 +0,0 @@
import {
type Page,
type Locator,
test as base,
expect,
} from "@playwright/test";
export class AuthPage {
public readonly wrongCredentials: Locator;
constructor(public readonly page: Page) {
this.wrongCredentials = this.page.locator("div.wrong");
}
async goto() {
await this.page.goto("/login");
}
async loginAs(username = "admin", password = "admin") {
await this.page.getByPlaceholder("Username").fill(username);
await this.page.getByPlaceholder("Password").fill(password);
await this.page.getByRole("button", { name: "Login" }).click();
}
async logout() {
await this.page.getByRole("button", { name: "Logout" }).click();
}
}
const test = base.extend<{ authPage: AuthPage }>({
authPage: async ({ page }, use) => {
const authPage = new AuthPage(page);
await authPage.goto();
await authPage.loginAs();
await use(authPage);
// await authPage.logout();
},
});
export { test, expect };
-61
View File
@@ -1,61 +0,0 @@
import {
type Locator,
type Page,
test as base,
expect,
} from "@playwright/test";
import { AuthPage } from "./auth";
type SettingsType = "profile" | "shares" | "global" | "users";
export class SettingsPage {
public readonly hideDotfiles: Locator; // checkbox
public readonly singleClick: Locator; // checkbox
public readonly dateFormat: Locator; // checkbox
private readonly languages: Locator; // selection
private readonly submitProfile: Locator; // submit
private readonly submitPassword: Locator; // submit
constructor(public readonly page: Page) {
this.hideDotfiles = this.page.locator('input[name="hideDotfiles"]');
this.singleClick = this.page.locator('input[name="singleClick"]');
this.dateFormat = this.page.locator('input[name="dateFormat"]');
this.languages = this.page.locator('select[name="selectLanguage"]');
this.submitProfile = this.page.locator('input[name="submitProfile"]');
this.submitPassword = this.page.locator('input[name="submitPassword"]');
}
async goto(type: SettingsType = "profile") {
await this.page.goto(`/settings/${type}`);
}
async setLanguage(locale: string = "en") {
await this.languages.selectOption(locale);
}
async saveProfile() {
await this.submitProfile.click();
}
async savePassword() {
await this.submitPassword.click();
}
}
const test = base.extend<{ settingsPage: SettingsPage }>({
page: async ({ page }, use) => {
// Sign in with our account.
const authPage = new AuthPage(page);
await authPage.goto();
await authPage.loginAs();
await expect(page).toHaveTitle(/.*Files - File Browser$/);
// Use signed-in page in the test.
await use(page);
},
settingsPage: async ({ page }, use) => {
const settingsPage = new SettingsPage(page);
await use(settingsPage);
},
});
export { test, expect };
-20
View File
@@ -1,20 +0,0 @@
//classes: Vue-Toastification__toast Vue-Toastification__toast--success bottom-center
import { type Page, type Locator, expect } from "@playwright/test";
export class Toast {
private readonly success: Locator;
private readonly error: Locator;
constructor(public readonly page: Page) {
this.success = this.page.locator("div.Vue-Toastification__toast--success");
this.error = this.page.locator("div.Vue-Toastification__toast--error");
}
async isSuccess() {
await expect(this.success).toBeVisible();
}
async isError() {
await expect(this.error).toBeVisible();
}
}
@@ -1,46 +0,0 @@
import { test, expect } from "./fixtures/settings";
import { Toast } from "./fixtures/toast";
// test.describe("profile settings", () => {
test("settings button", async ({ page }) => {
const button = page.getByLabel("Settings", { exact: true });
await expect(button).toBeVisible();
await button.click();
await expect(page).toHaveTitle(/^Profile Settings/);
await expect(
page.getByRole("heading", { name: "Profile Settings" })
).toBeVisible();
});
test("set locale", async ({ settingsPage, page }) => {
const toast = new Toast(page);
await settingsPage.goto("profile");
await expect(page).toHaveTitle(/^Profile Settings/);
// await settingsPage.saveProfile();
// await toast.isSuccess();
// await expect(
// page.getByText("Settings updated!", { exact: true })
// ).toBeVisible();
await settingsPage.setLanguage("hu");
await settingsPage.saveProfile();
await toast.isSuccess();
await expect(
page.getByText("Beállítások frissítve!", { exact: true })
).toBeVisible();
await expect(
page.getByRole("heading", { name: "Profilbeállítások" })
).toBeVisible();
await settingsPage.setLanguage("en");
await settingsPage.saveProfile();
await toast.isSuccess();
await expect(
page.getByText("Settings updated!", { exact: true })
).toBeVisible();
await expect(
page.getByRole("heading", { name: "Profile Settings" })
).toBeVisible();
});
// });
+18 -2
View File
@@ -1,13 +1,29 @@
{
"extends": "@vue/tsconfig/tsconfig.dom.json",
"include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
"exclude": ["src/**/__tests__/*"],
"exclude": [
"src/**/__tests__/*",
// Excluding non-TS Vue files which use the old Options API.
// This can be removed once those files are properly migrated to
// the new Composition API with TS support.
"src/components/Shell.vue",
"src/components/prompts/Copy.vue",
"src/components/prompts/Move.vue",
"src/components/prompts/Delete.vue",
"src/components/prompts/FileList.vue",
"src/components/prompts/Rename.vue",
"src/components/prompts/Share.vue"
],
"compilerOptions": {
"composite": true,
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
"types": ["vite/client", "@intlify/unplugin-vue-i18n/messages"],
"paths": {
"@/*": ["./src/*"]
}
},
// Version 0.8.0 of @vue/tsconfig enabled this automatically.
// Disabling for now since it's causing quite a lot of errors.
// Should be revisited.
"noUncheckedIndexedAccess": false
}
}
+2 -3
View File
@@ -1,11 +1,10 @@
{
"extends": "@tsconfig/node22/tsconfig.json",
"extends": "@tsconfig/node24/tsconfig.json",
"include": [
"vite.config.*",
"vitest.config.*",
"cypress.config.*",
"nightwatch.conf.*",
"playwright.config.*"
"nightwatch.conf.*"
],
"compilerOptions": {
"composite": true,
-14
View File
@@ -1,14 +0,0 @@
{
"extends": "./tsconfig.app.json",
// vue-tsc wont shut up about error TS9005
// in non-TS vue files so exclude them
"exclude": [
"src/components/Shell.vue",
"src/components/prompts/Copy.vue",
"src/components/prompts/Move.vue",
"src/components/prompts/Delete.vue",
"src/components/prompts/FileList.vue",
"src/components/prompts/Rename.vue",
"src/components/prompts/Share.vue"
]
}
+5 -4
View File
@@ -8,7 +8,7 @@ require (
github.com/disintegration/imaging v1.6.2
github.com/dsoprea/go-exif/v3 v3.0.1
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568
github.com/golang-jwt/jwt/v4 v4.5.2
github.com/golang-jwt/jwt/v5 v5.3.0
github.com/gorilla/mux v1.8.1
github.com/gorilla/websocket v1.5.3
github.com/jellydator/ttlcache/v3 v3.4.0
@@ -17,7 +17,7 @@ require (
github.com/mholt/archives v0.1.5
github.com/mitchellh/go-homedir v1.1.0
github.com/pelletier/go-toml/v2 v2.2.4
github.com/shirou/gopsutil/v3 v3.24.5
github.com/shirou/gopsutil/v4 v4.25.10
github.com/spf13/afero v1.15.0
github.com/spf13/cobra v1.10.1
github.com/spf13/pflag v1.0.10
@@ -29,7 +29,7 @@ require (
golang.org/x/image v0.33.0
golang.org/x/text v0.31.0
gopkg.in/natefinch/lumberjack.v2 v2.2.1
gopkg.in/yaml.v2 v2.4.0
gopkg.in/yaml.v3 v3.0.1
)
require (
@@ -44,6 +44,7 @@ require (
github.com/dsnet/compress v0.0.2-0.20230904184137-39efe44ab707 // indirect
github.com/dsoprea/go-logging v0.0.0-20200710184922-b02d349568dd // indirect
github.com/dsoprea/go-utility/v2 v2.0.0-20221003172846-a3e1774ef349 // indirect
github.com/ebitengine/purego v0.9.0 // indirect
github.com/fsnotify/fsnotify v1.9.0 // indirect
github.com/go-errors/errors v1.5.1 // indirect
github.com/go-ole/go-ole v1.3.0 // indirect
@@ -73,5 +74,5 @@ require (
golang.org/x/sync v0.18.0 // indirect
golang.org/x/sys v0.38.0 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
)
+6 -4
View File
@@ -74,6 +74,8 @@ github.com/dsoprea/go-utility/v2 v2.0.0-20221003142440-7a1927d49d9d/go.mod h1:LV
github.com/dsoprea/go-utility/v2 v2.0.0-20221003160719-7bc88537c05e/go.mod h1:VZ7cB0pTjm1ADBWhJUOHESu4ZYy9JN+ZPqjfiW09EPU=
github.com/dsoprea/go-utility/v2 v2.0.0-20221003172846-a3e1774ef349 h1:DilThiXje0z+3UQ5YjYiSRRzVdtamFpvBQXKwMglWqw=
github.com/dsoprea/go-utility/v2 v2.0.0-20221003172846-a3e1774ef349/go.mod h1:4GC5sXji84i/p+irqghpPFZBF8tRN/Q7+700G0/DLe8=
github.com/ebitengine/purego v0.9.0 h1:mh0zpKBIXDceC63hpvPuGLiJ8ZAa3DfrFTudmfi8A4k=
github.com/ebitengine/purego v0.9.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ=
@@ -95,8 +97,8 @@ github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs=
github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI=
github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo=
github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
github.com/golang/geo v0.0.0-20190916061304-5b978397cfec/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI=
github.com/golang/geo v0.0.0-20200319012246-673a6f80352d/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI=
github.com/golang/geo v0.0.0-20210211234256-740aa86cb551/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI=
@@ -198,8 +200,8 @@ github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD
github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk=
github.com/sagikazarmark/locafero v0.11.0 h1:1iurJgmM9G3PA/I+wWYIOw/5SyBtxapeHDcg+AAIFXc=
github.com/sagikazarmark/locafero v0.11.0/go.mod h1:nVIGvgyzw595SUSUE6tvCp3YYTeHs15MvlmU87WwIik=
github.com/shirou/gopsutil/v3 v3.24.5 h1:i0t8kL+kQTvpAYToeuiVk3TgDeKOFioZO3Ztz/iZ9pI=
github.com/shirou/gopsutil/v3 v3.24.5/go.mod h1:bsoOS1aStSs9ErQ1WWfxllSeS1K5D+U30r2NfcubMVk=
github.com/shirou/gopsutil/v4 v4.25.10 h1:at8lk/5T1OgtuCp+AwrDofFRjnvosn0nkN2OLQ6g8tA=
github.com/shirou/gopsutil/v4 v4.25.10/go.mod h1:+kSwyC8DRUD9XXEHCAFjK+0nuArFJM0lva+StQAcskM=
github.com/sorairolake/lzip-go v0.3.8 h1:j5Q2313INdTA80ureWYRhX+1K78mUXfMoPZCw/ivWik=
github.com/sorairolake/lzip-go v0.3.8/go.mod h1:JcBqGMV0frlxwrsE9sMWXDjqn3EeVf0/54YPsw66qkU=
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 h1:+jumHNA0Wrelhe64i8F6HNlS8pkoyMv5sreGx2Ry5Rw=
+9 -5
View File
@@ -9,8 +9,8 @@ import (
"strings"
"time"
"github.com/golang-jwt/jwt/v4"
"github.com/golang-jwt/jwt/v4/request"
"github.com/golang-jwt/jwt/v5"
"github.com/golang-jwt/jwt/v5/request"
fbErrors "github.com/filebrowser/filebrowser/v2/errors"
"github.com/filebrowser/filebrowser/v2/users"
@@ -69,15 +69,19 @@ func withUser(fn handleFunc) handleFunc {
var tk authToken
token, err := request.ParseFromRequest(r, &extractor{}, keyFunc, request.WithClaims(&tk))
if err != nil || !token.Valid {
return http.StatusUnauthorized, nil
}
expired := !tk.VerifyExpiresAt(time.Now().Add(time.Hour), true)
err = jwt.NewValidator(jwt.WithExpirationRequired()).Validate(tk)
if err != nil {
return http.StatusUnauthorized, nil
}
expiresSoon := tk.ExpiresAt != nil && time.Until(tk.ExpiresAt.Time) < time.Hour
updated := tk.IssuedAt != nil && tk.IssuedAt.Unix() < d.store.Users.LastUpdate(tk.User.ID)
if expired || updated {
if expiresSoon || updated {
w.Header().Add("X-Renew-Token", "true")
}
-14
View File
@@ -1,14 +0,0 @@
//go:build dev
package http
// global headers to append to every response
// cross-origin headers are necessary to be able to
// access them from a different URL during development
var globalHeaders = map[string]string{
"Cache-Control": "no-cache, no-store, must-revalidate",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Headers": "*",
"Access-Control-Allow-Methods": "*",
"Access-Control-Allow-Credentials": "true",
}
+1 -1
View File
@@ -14,7 +14,7 @@ import (
"path/filepath"
"strings"
"github.com/shirou/gopsutil/v3/disk"
"github.com/shirou/gopsutil/v4/disk"
"github.com/spf13/afero"
fbErrors "github.com/filebrowser/filebrowser/v2/errors"
+2 -1
View File
@@ -4,7 +4,8 @@
"config:recommended",
"group:allNonMajor",
"group:allDigest",
":disableDependencyDashboard"
":disableDependencyDashboard",
":semanticCommitTypeAll(chore)"
],
"postUpdateOptions": [
"gomodUpdateImportPaths",
-14
View File
@@ -1,14 +0,0 @@
#!/usr/bin/env bash
set -e
if ! [ -x "$(command -v standard-version)" ]; then
echo "standard-version is not installed. please run 'npm i -g standard-version'"
exit 1
fi
standard-version --dry-run --skip
read -p "Continue (y/n)? " -n 1 -r
echo ;
if [[ $REPLY =~ ^[Yy]$ ]]; then
standard-version -s ;
fi
-11
View File
@@ -1,11 +0,0 @@
#!/usr/bin/env bash
set -e
if ! [ -x "$(command -v commitlint)" ]; then
echo "commitlint is not installed. please run 'npm i -g commitlint'"
exit 1
fi
for commit_hash in $(git log --pretty=format:%H origin/master..HEAD); do
commitlint -f ${commit_hash}~1 -t ${commit_hash}
done
-8
View File
@@ -1,8 +0,0 @@
{
"port": 80,
"baseURL": "",
"address": "",
"log": "stdout",
"database": "/database/filebrowser.db",
"root": "/srv"
}
+1 -1
View File
@@ -9,7 +9,7 @@ import (
"github.com/asdine/storm/v3"
"github.com/pelletier/go-toml/v2"
"gopkg.in/yaml.v2"
"gopkg.in/yaml.v3"
"github.com/filebrowser/filebrowser/v2/auth"
"github.com/filebrowser/filebrowser/v2/settings"
-37
View File
@@ -1,37 +0,0 @@
include common.mk
# tools
TOOLS_DIR := $(BASE_PATH)/tools
TOOLS_GO_DEPS := $(TOOLS_DIR)/go.mod $(TOOLS_DIR)/go.sum
TOOLS_BIN := $(TOOLS_DIR)/bin
$(eval $(shell mkdir -p $(TOOLS_BIN)))
PATH := $(TOOLS_BIN):$(PATH)
export PATH
.PHONY: clean-tools
clean-tools:
$Q rm -rf $(TOOLS_BIN)
goimports=$(TOOLS_BIN)/goimports
$(goimports): $(TOOLS_GO_DEPS)
$Q cd $(TOOLS_DIR) && $(go) build -o $@ golang.org/x/tools/cmd/goimports
golangci-lint=$(TOOLS_BIN)/golangci-lint
$(golangci-lint): $(TOOLS_GO_DEPS)
$Q cd $(TOOLS_DIR) && $(go) build -o $@ github.com/golangci/golangci-lint/v2/cmd/golangci-lint
# js tools
TOOLS_JS_DEPS=$(TOOLS_DIR)/node_modules/.modified
$(TOOLS_JS_DEPS): $(TOOLS_DIR)/package.json $(TOOLS_DIR)/yarn.lock
$Q cd ${TOOLS_DIR} && yarn install
$Q touch -am $@
standard-version=$(TOOLS_BIN)/standard-version
$(standard-version): $(TOOLS_JS_DEPS)
$Q ln -sf $(TOOLS_DIR)/node_modules/.bin/standard-version $@
$Q touch -am $@
commitlint=$(TOOLS_BIN)/commitlint
$(commitlint): $(TOOLS_JS_DEPS)
$Q ln -sf $(TOOLS_DIR)/node_modules/.bin/commitlint $@
$Q touch -am $@
-216
View File
@@ -1,216 +0,0 @@
module github.com/filebrowser/filebrowser/v2/tools
go 1.25
require (
github.com/golangci/golangci-lint/v2 v2.6.1
golang.org/x/tools v0.38.0
)
require (
4d63.com/gocheckcompilerdirectives v1.3.0 // indirect
4d63.com/gochecknoglobals v0.2.2 // indirect
codeberg.org/chavacava/garif v0.2.0 // indirect
dev.gaijin.team/go/exhaustruct/v4 v4.0.0 // indirect
dev.gaijin.team/go/golib v0.6.0 // indirect
github.com/4meepo/tagalign v1.4.3 // indirect
github.com/Abirdcfly/dupword v0.1.7 // indirect
github.com/AdminBenni/iota-mixing v1.0.0 // indirect
github.com/AlwxSin/noinlineerr v1.0.5 // indirect
github.com/Antonboom/errname v1.1.1 // indirect
github.com/Antonboom/nilnil v1.1.1 // indirect
github.com/Antonboom/testifylint v1.6.4 // indirect
github.com/BurntSushi/toml v1.5.0 // indirect
github.com/Djarvur/go-err113 v0.1.1 // indirect
github.com/Masterminds/semver/v3 v3.4.0 // indirect
github.com/MirrexOne/unqueryvet v1.2.1 // indirect
github.com/OpenPeeDeeP/depguard/v2 v2.2.1 // indirect
github.com/alecthomas/chroma/v2 v2.20.0 // indirect
github.com/alecthomas/go-check-sumtype v0.3.1 // indirect
github.com/alexkohler/nakedret/v2 v2.0.6 // indirect
github.com/alexkohler/prealloc v1.0.0 // indirect
github.com/alfatraining/structtag v1.0.0 // indirect
github.com/alingse/asasalint v0.0.11 // indirect
github.com/alingse/nilnesserr v0.2.0 // indirect
github.com/ashanbrown/forbidigo/v2 v2.3.0 // indirect
github.com/ashanbrown/makezero/v2 v2.1.0 // indirect
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/bkielbasa/cyclop v1.2.3 // indirect
github.com/blizzy78/varnamelen v0.8.0 // indirect
github.com/bombsimon/wsl/v4 v4.7.0 // indirect
github.com/bombsimon/wsl/v5 v5.3.0 // indirect
github.com/breml/bidichk v0.3.3 // indirect
github.com/breml/errchkjson v0.4.1 // indirect
github.com/butuzov/ireturn v0.4.0 // indirect
github.com/butuzov/mirror v1.3.0 // indirect
github.com/catenacyber/perfsprint v0.10.0 // indirect
github.com/ccojocar/zxcvbn-go v1.0.4 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/charithe/durationcheck v0.0.11 // indirect
github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc // indirect
github.com/charmbracelet/lipgloss v1.1.0 // indirect
github.com/charmbracelet/x/ansi v0.8.0 // indirect
github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd // indirect
github.com/charmbracelet/x/term v0.2.1 // indirect
github.com/ckaznocha/intrange v0.3.1 // indirect
github.com/curioswitch/go-reassign v0.3.0 // indirect
github.com/daixiang0/gci v0.13.7 // indirect
github.com/dave/dst v0.27.3 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/denis-tingaikin/go-header v0.5.0 // indirect
github.com/dlclark/regexp2 v1.11.5 // indirect
github.com/ettle/strcase v0.2.0 // indirect
github.com/fatih/color v1.18.0 // indirect
github.com/fatih/structtag v1.2.0 // indirect
github.com/firefart/nonamedreturns v1.0.6 // indirect
github.com/fsnotify/fsnotify v1.5.4 // indirect
github.com/fzipp/gocyclo v0.6.0 // indirect
github.com/ghostiam/protogetter v0.3.17 // indirect
github.com/go-critic/go-critic v0.14.2 // indirect
github.com/go-toolsmith/astcast v1.1.0 // indirect
github.com/go-toolsmith/astcopy v1.1.0 // indirect
github.com/go-toolsmith/astequal v1.2.0 // indirect
github.com/go-toolsmith/astfmt v1.1.0 // indirect
github.com/go-toolsmith/astp v1.1.0 // indirect
github.com/go-toolsmith/strparse v1.1.0 // indirect
github.com/go-toolsmith/typep v1.1.0 // indirect
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
github.com/go-xmlfmt/xmlfmt v1.1.3 // indirect
github.com/gobwas/glob v0.2.3 // indirect
github.com/godoc-lint/godoc-lint v0.10.1 // indirect
github.com/gofrs/flock v0.13.0 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/golangci/asciicheck v0.5.0 // indirect
github.com/golangci/dupl v0.0.0-20250308024227-f665c8d69b32 // indirect
github.com/golangci/go-printf-func-name v0.1.1 // indirect
github.com/golangci/gofmt v0.0.0-20250106114630-d62b90e6713d // indirect
github.com/golangci/golines v0.0.0-20250217134842-442fd0091d95 // indirect
github.com/golangci/misspell v0.7.0 // indirect
github.com/golangci/plugin-module-register v0.1.2 // indirect
github.com/golangci/revgrep v0.8.0 // indirect
github.com/golangci/swaggoswag v0.0.0-20250504205917-77f2aca3143e // indirect
github.com/golangci/unconvert v0.0.0-20250410112200-a129a6e6413e // indirect
github.com/google/go-cmp v0.7.0 // indirect
github.com/gordonklaus/ineffassign v0.2.0 // indirect
github.com/gostaticanalysis/analysisutil v0.7.1 // indirect
github.com/gostaticanalysis/comment v1.5.0 // indirect
github.com/gostaticanalysis/forcetypeassert v0.2.0 // indirect
github.com/gostaticanalysis/nilerr v0.1.2 // indirect
github.com/hashicorp/go-immutable-radix/v2 v2.1.0 // indirect
github.com/hashicorp/go-version v1.7.0 // indirect
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/hexops/gotextdiff v1.0.3 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jgautheron/goconst v1.8.2 // indirect
github.com/jingyugao/rowserrcheck v1.1.1 // indirect
github.com/jjti/go-spancheck v0.6.5 // indirect
github.com/julz/importas v0.2.0 // indirect
github.com/karamaru-alpha/copyloopvar v1.2.2 // indirect
github.com/kisielk/errcheck v1.9.0 // indirect
github.com/kkHAIKE/contextcheck v1.1.6 // indirect
github.com/kulti/thelper v0.7.1 // indirect
github.com/kunwardeep/paralleltest v1.0.15 // indirect
github.com/lasiar/canonicalheader v1.1.2 // indirect
github.com/ldez/exptostd v0.4.5 // indirect
github.com/ldez/gomoddirectives v0.7.1 // indirect
github.com/ldez/grignotin v0.10.1 // indirect
github.com/ldez/tagliatelle v0.7.2 // indirect
github.com/ldez/usetesting v0.5.0 // indirect
github.com/leonklingele/grouper v1.1.2 // indirect
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
github.com/macabu/inamedparam v0.2.0 // indirect
github.com/magiconair/properties v1.8.6 // indirect
github.com/manuelarte/embeddedstructfieldcheck v0.4.0 // indirect
github.com/manuelarte/funcorder v0.5.0 // indirect
github.com/maratori/testableexamples v1.0.0 // indirect
github.com/maratori/testpackage v1.1.1 // indirect
github.com/matoous/godox v1.1.0 // indirect
github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-runewidth v0.0.16 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
github.com/mgechev/revive v1.12.0 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/moricho/tparallel v0.3.2 // indirect
github.com/muesli/termenv v0.16.0 // indirect
github.com/nakabonne/nestif v0.3.1 // indirect
github.com/nishanths/exhaustive v0.12.0 // indirect
github.com/nishanths/predeclared v0.2.2 // indirect
github.com/nunnatsa/ginkgolinter v0.21.2 // indirect
github.com/pelletier/go-toml v1.9.5 // indirect
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/polyfloyd/go-errorlint v1.8.0 // indirect
github.com/prometheus/client_golang v1.12.1 // indirect
github.com/prometheus/client_model v0.2.0 // indirect
github.com/prometheus/common v0.32.1 // indirect
github.com/prometheus/procfs v0.7.3 // indirect
github.com/quasilyte/go-ruleguard v0.4.5 // indirect
github.com/quasilyte/go-ruleguard/dsl v0.3.23 // indirect
github.com/quasilyte/gogrep v0.5.0 // indirect
github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727 // indirect
github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 // indirect
github.com/raeperd/recvcheck v0.2.0 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/rogpeppe/go-internal v1.14.1 // indirect
github.com/ryancurrah/gomodguard v1.4.1 // indirect
github.com/ryanrolds/sqlclosecheck v0.5.1 // indirect
github.com/sanposhiho/wastedassign/v2 v2.1.0 // indirect
github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 // indirect
github.com/sashamelentyev/interfacebloat v1.1.0 // indirect
github.com/sashamelentyev/usestdlibvars v1.29.0 // indirect
github.com/securego/gosec/v2 v2.22.10 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/sivchari/containedctx v1.0.3 // indirect
github.com/sonatard/noctx v0.4.0 // indirect
github.com/sourcegraph/go-diff v0.7.0 // indirect
github.com/spf13/afero v1.14.0 // indirect
github.com/spf13/cast v1.5.0 // indirect
github.com/spf13/cobra v1.10.1 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.10 // indirect
github.com/spf13/viper v1.12.0 // indirect
github.com/ssgreg/nlreturn/v2 v2.2.1 // indirect
github.com/stbenjam/no-sprintf-host-port v0.2.0 // indirect
github.com/stretchr/objx v0.5.2 // indirect
github.com/stretchr/testify v1.11.1 // indirect
github.com/subosito/gotenv v1.4.1 // indirect
github.com/tetafro/godot v1.5.4 // indirect
github.com/timakin/bodyclose v0.0.0-20241222091800-1db5c5ca4d67 // indirect
github.com/timonwong/loggercheck v0.11.0 // indirect
github.com/tomarrell/wrapcheck/v2 v2.11.0 // indirect
github.com/tommy-muehle/go-mnd/v2 v2.5.1 // indirect
github.com/ultraware/funlen v0.2.0 // indirect
github.com/ultraware/whitespace v0.2.0 // indirect
github.com/uudashr/gocognit v1.2.0 // indirect
github.com/uudashr/iface v1.4.1 // indirect
github.com/xen0n/gosmopolitan v1.3.0 // indirect
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
github.com/yagipy/maintidx v1.0.0 // indirect
github.com/yeya24/promlinter v0.3.0 // indirect
github.com/ykadowak/zerologlint v0.1.5 // indirect
gitlab.com/bosi/decorder v0.4.2 // indirect
go-simpler.org/musttag v0.14.0 // indirect
go-simpler.org/sloglint v0.11.1 // indirect
go.augendre.info/arangolint v0.3.1 // indirect
go.augendre.info/fatcontext v0.9.0 // indirect
go.uber.org/automaxprocs v1.6.0 // indirect
go.uber.org/multierr v1.10.0 // indirect
go.uber.org/zap v1.27.0 // indirect
golang.org/x/exp/typeparams v0.0.0-20251023183803-a4bb9ffd2546 // indirect
golang.org/x/mod v0.29.0 // indirect
golang.org/x/sync v0.17.0 // indirect
golang.org/x/sys v0.37.0 // indirect
golang.org/x/telemetry v0.0.0-20251008203120-078029d740a8 // indirect
golang.org/x/text v0.30.0 // indirect
google.golang.org/protobuf v1.36.8 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
honnef.co/go/tools v0.6.1 // indirect
mvdan.cc/gofumpt v0.9.2 // indirect
mvdan.cc/unparam v0.0.0-20251027182757-5beb8c8f8f15 // indirect
)
File diff suppressed because it is too large Load Diff
-8
View File
@@ -1,8 +0,0 @@
{
"dependencies": {
"@commitlint/cli": "^15.0.0",
"@commitlint/config-conventional": "^15.0.0",
"standard-version": "^9.3.2"
},
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
}
-15
View File
@@ -1,15 +0,0 @@
//go:build tools
// +build tools
package tools
// Manage tool dependencies via go.mod.
//
// https://github.com/golang/go/wiki/Modules#how-can-i-track-tool-dependencies-for-a-module
// https://github.com/golang/go/issues/25922
//
// nolint
import (
_ "github.com/golangci/golangci-lint/v2/cmd/golangci-lint"
_ "golang.org/x/tools/cmd/goimports"
)
File diff suppressed because it is too large Load Diff
+6
View File
@@ -2,6 +2,12 @@
Most of the configuration can be understood through the command line interface documentation. To access it, you need to install File Browser and run `filebrowser --help`. In this page, we cover some specific, more complex, topics.
## Flags as Environment Variables
In some situations, it is easier to use environment variables instead of flags. For example, if you're using our provided Docker image, it's easier for you to use environment variables to customize the settings instead of flags.
All flags should be available as environment variables prefixed with `FB_`. For example, the flag `--disable-thumbnails` is available as `FB_DISABLE_THUMBNAILS`.
## Custom Branding
You can customize File Browser to use your own branding. This includes the following:
+1 -1
View File
@@ -10,7 +10,7 @@
> [!WARNING]
>
> This project is currently on **maintenance-only** mode. For more information, read the information on [GitHub](https://github.com/filebrowser/filebrowser#project-status).
> This project is on **maintenance-only** mode. For more information, read the information on [GitHub](https://github.com/filebrowser/filebrowser#project-status).
![Preview](static/example.gif)
+2 -3
View File
@@ -3,11 +3,10 @@ include $(TOPDIR)/rules.mk
ARCH:=arm
BOARD:=airoha
BOARDNAME:=Airoha ARM
SUBTARGETS:=an7581 en7523
SUBTARGETS:=en7523 an7581
FEATURES:=dt squashfs nand ramdisk gpio
KERNEL_PATCHVER:=6.12
KERNEL_TESTING_PATCHVER:=6.6
KERNEL_PATCHVER:=6.6
include $(INCLUDE_DIR)/target.mk
@@ -1,28 +0,0 @@
#
# Copyright (c) 2015 The Linux Foundation. All rights reserved.
# Copyright (c) 2011-2015 OpenWrt.org
#
. /lib/functions/uci-defaults.sh
. /lib/functions/system.sh
an7581_setup_interfaces()
{
local board="$1"
case "$board" in
bell,xg-040g-md)
ucidef_set_interfaces_lan_wan "lan2 lan3 lan4" "eth1"
;;
*)
echo "Unsupported hardware. Network interfaces not initialized"
;;
esac
}
board_config_update
board=$(board_name)
an7581_setup_interfaces $board
board_config_flush
exit 0
@@ -1,15 +0,0 @@
REQUIRE_IMAGE_METADATA=1
platform_do_upgrade() {
local board=$(board_name)
case "$board" in
*)
nand_do_upgrade "$1"
;;
esac
}
platform_check_image() {
return 0
}
-413
View File
@@ -1,413 +0,0 @@
CONFIG_64BIT=y
CONFIG_AIROHA_CPU_PM_DOMAIN=y
CONFIG_AIROHA_SCU_SSR=y
CONFIG_AIROHA_THERMAL=y
CONFIG_AIROHA_WATCHDOG=y
CONFIG_AMPERE_ERRATUM_AC03_CPU_38=y
CONFIG_ARCH_AIROHA=y
CONFIG_ARCH_BINFMT_ELF_EXTRA_PHDRS=y
CONFIG_ARCH_CORRECT_STACKTRACE_ON_KRETPROBE=y
CONFIG_ARCH_DEFAULT_KEXEC_IMAGE_VERIFY_SIG=y
CONFIG_ARCH_DMA_ADDR_T_64BIT=y
CONFIG_ARCH_FORCE_MAX_ORDER=10
CONFIG_ARCH_KEEP_MEMBLOCK=y
CONFIG_ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE=y
CONFIG_ARCH_MMAP_RND_BITS=18
CONFIG_ARCH_MMAP_RND_BITS_MAX=24
CONFIG_ARCH_MMAP_RND_BITS_MIN=18
CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11
CONFIG_ARCH_PKEY_BITS=3
CONFIG_ARCH_PROC_KCORE_TEXT=y
CONFIG_ARCH_SPARSEMEM_ENABLE=y
CONFIG_ARCH_STACKWALK=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_ARCH_WANTS_EXECMEM_LATE=y
CONFIG_ARCH_WANTS_NO_INSTR=y
CONFIG_ARCH_WANTS_THP_SWAP=y
CONFIG_ARM64=y
CONFIG_ARM64_4K_PAGES=y
CONFIG_ARM64_ERRATUM_843419=y
CONFIG_ARM64_LD_HAS_FIX_ERRATUM_843419=y
CONFIG_ARM64_PA_BITS=48
CONFIG_ARM64_PA_BITS_48=y
CONFIG_ARM64_PLATFORM_DEVICES=y
CONFIG_ARM64_TAGGED_ADDR_ABI=y
CONFIG_ARM64_VA_BITS=39
CONFIG_ARM64_VA_BITS_39=y
CONFIG_ARM_AIROHA_SOC_CPUFREQ=y
CONFIG_ARM_AMBA=y
CONFIG_ARM_ARCH_TIMER=y
CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y
CONFIG_ARM_GIC=y
CONFIG_ARM_GIC_V2M=y
CONFIG_ARM_GIC_V3=y
CONFIG_ARM_GIC_V3_ITS=y
CONFIG_ARM_PMU=y
CONFIG_ARM_PMUV3=y
CONFIG_ARM_PSCI_FW=y
CONFIG_ARM_SMCCC_SOC_ID=y
CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y
CONFIG_BLK_MQ_PCI=y
CONFIG_BLK_PM=y
CONFIG_BLOCK_NOTIFIERS=y
CONFIG_BUFFER_HEAD=y
CONFIG_BUILTIN_RETURN_ADDRESS_STRIPS_PAC=y
CONFIG_CC_HAVE_SHADOW_CALL_STACK=y
CONFIG_CC_HAVE_STACKPROTECTOR_SYSREG=y
CONFIG_CLONE_BACKWARDS=y
CONFIG_COMMON_CLK=y
CONFIG_COMMON_CLK_EN7523=y
CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
# CONFIG_COMPAT_32BIT_TIME is not set
CONFIG_CONTEXT_TRACKING=y
CONFIG_CONTEXT_TRACKING_IDLE=y
CONFIG_CPUFREQ_DT=y
CONFIG_CPUFREQ_DT_PLATDEV=y
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
CONFIG_CPU_FREQ_GOV_ATTR_SET=y
CONFIG_CPU_FREQ_GOV_COMMON=y
CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
CONFIG_CPU_FREQ_GOV_ONDEMAND=y
CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=y
CONFIG_CPU_FREQ_GOV_USERSPACE=y
CONFIG_CPU_FREQ_STAT=y
CONFIG_CPU_LITTLE_ENDIAN=y
CONFIG_CPU_MITIGATIONS=y
CONFIG_CPU_RMAP=y
CONFIG_CRC16=y
CONFIG_CRC_CCITT=y
CONFIG_CRYPTO_AUTHENC=y
CONFIG_CRYPTO_CBC=y
CONFIG_CRYPTO_CRC32C=y
CONFIG_CRYPTO_DEFLATE=y
CONFIG_CRYPTO_DRBG=y
CONFIG_CRYPTO_DRBG_HMAC=y
CONFIG_CRYPTO_DRBG_MENU=y
CONFIG_CRYPTO_ECB=y
CONFIG_CRYPTO_ECHAINIV=y
CONFIG_CRYPTO_GENIV=y
CONFIG_CRYPTO_HASH_INFO=y
CONFIG_CRYPTO_HMAC=y
CONFIG_CRYPTO_JITTERENTROPY=y
CONFIG_CRYPTO_JITTERENTROPY_MEMORY_BLOCKS=64
CONFIG_CRYPTO_JITTERENTROPY_MEMORY_BLOCKSIZE=32
CONFIG_CRYPTO_JITTERENTROPY_OSR=1
CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
CONFIG_CRYPTO_LIB_GF128MUL=y
CONFIG_CRYPTO_LIB_SHA1=y
CONFIG_CRYPTO_LIB_SHA256=y
CONFIG_CRYPTO_LIB_UTILS=y
CONFIG_CRYPTO_LZO=y
CONFIG_CRYPTO_RNG=y
CONFIG_CRYPTO_RNG2=y
CONFIG_CRYPTO_RNG_DEFAULT=y
CONFIG_CRYPTO_SEQIV=y
CONFIG_CRYPTO_SHA256=y
CONFIG_CRYPTO_SHA3=y
CONFIG_CRYPTO_SHA512=y
CONFIG_CRYPTO_ZSTD=y
CONFIG_DCACHE_WORD_ACCESS=y
CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_MISC=y
CONFIG_DEV_COREDUMP=y
CONFIG_DMADEVICES=y
CONFIG_DMA_BOUNCE_UNALIGNED_KMALLOC=y
CONFIG_DMA_DIRECT_REMAP=y
CONFIG_DMA_ENGINE=y
CONFIG_DMA_NEED_SYNC=y
CONFIG_DMA_OF=y
CONFIG_DTC=y
CONFIG_EDAC_SUPPORT=y
CONFIG_EXCLUSIVE_SYSTEM_RAM=y
CONFIG_EXT4_FS=y
CONFIG_FIXED_PHY=y
CONFIG_FIX_EARLYCON_MEM=y
CONFIG_FRAME_POINTER=y
CONFIG_FS_IOMAP=y
CONFIG_FS_MBCACHE=y
CONFIG_FUNCTION_ALIGNMENT=4
CONFIG_FUNCTION_ALIGNMENT_4B=y
CONFIG_FWNODE_MDIO=y
# CONFIG_FW_LOADER_USER_HELPER is not set
CONFIG_GCC_SUPPORTS_DYNAMIC_FTRACE_WITH_ARGS=y
CONFIG_GENERIC_ALLOCATOR=y
CONFIG_GENERIC_ARCH_TOPOLOGY=y
CONFIG_GENERIC_BUG=y
CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
CONFIG_GENERIC_CPU_AUTOPROBE=y
CONFIG_GENERIC_CPU_DEVICES=y
CONFIG_GENERIC_CPU_VULNERABILITIES=y
CONFIG_GENERIC_CSUM=y
CONFIG_GENERIC_EARLY_IOREMAP=y
CONFIG_GENERIC_GETTIMEOFDAY=y
CONFIG_GENERIC_IDLE_POLL_SETUP=y
CONFIG_GENERIC_IOREMAP=y
CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
CONFIG_GENERIC_IRQ_MIGRATION=y
CONFIG_GENERIC_IRQ_SHOW=y
CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y
CONFIG_GENERIC_MSI_IRQ=y
CONFIG_GENERIC_PCI_IOMAP=y
CONFIG_GENERIC_PHY=y
CONFIG_GENERIC_PINCONF=y
CONFIG_GENERIC_PINCTRL_GROUPS=y
CONFIG_GENERIC_PINMUX_FUNCTIONS=y
CONFIG_GENERIC_SCHED_CLOCK=y
CONFIG_GENERIC_SMP_IDLE_THREAD=y
CONFIG_GENERIC_STRNCPY_FROM_USER=y
CONFIG_GENERIC_STRNLEN_USER=y
CONFIG_GENERIC_TIME_VSYSCALL=y
CONFIG_GLOB=y
CONFIG_GPIOLIB_IRQCHIP=y
CONFIG_GPIO_CDEV=y
CONFIG_GPIO_EN7523=y
CONFIG_GPIO_GENERIC=y
CONFIG_GRO_CELLS=y
CONFIG_HARDIRQS_SW_RESEND=y
CONFIG_HAS_DMA=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_IOPORT_MAP=y
CONFIG_HOTPLUG_CORE_SYNC=y
CONFIG_HOTPLUG_CORE_SYNC_DEAD=y
CONFIG_HOTPLUG_CPU=y
CONFIG_HW_RANDOM=y
CONFIG_HW_RANDOM_AIROHA=y
CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000
CONFIG_INET_AH=y
CONFIG_INET_ESP=y
# CONFIG_INET_ESP_OFFLOAD is not set
CONFIG_INET_IPCOMP=y
CONFIG_INET_TUNNEL=y
CONFIG_INET_XFRM_TUNNEL=y
CONFIG_INITRAMFS_SOURCE=""
CONFIG_IO_URING=y
CONFIG_IPV6=y
CONFIG_IPV6_MULTIPLE_TABLES=y
# CONFIG_IPV6_SUBTREES is not set
CONFIG_IP_MROUTE=y
CONFIG_IP_MROUTE_COMMON=y
# CONFIG_IP_MROUTE_MULTIPLE_TABLES is not set
CONFIG_IP_PNP=y
# CONFIG_IP_PNP_BOOTP is not set
# CONFIG_IP_PNP_DHCP is not set
# CONFIG_IP_PNP_RARP is not set
# CONFIG_IP_ROUTE_MULTIPATH is not set
# CONFIG_IP_ROUTE_VERBOSE is not set
CONFIG_IRQCHIP=y
CONFIG_IRQ_DOMAIN=y
CONFIG_IRQ_DOMAIN_HIERARCHY=y
CONFIG_IRQ_FORCED_THREADING=y
CONFIG_IRQ_MSI_LIB=y
CONFIG_IRQ_WORK=y
CONFIG_JBD2=y
CONFIG_LIBFDT=y
CONFIG_LOCK_DEBUGGING_SUPPORT=y
CONFIG_LOCK_SPIN_ON_OWNER=y
CONFIG_LRU_GEN_WALKS_MMU=y
CONFIG_LZO_COMPRESS=y
CONFIG_LZO_DECOMPRESS=y
# CONFIG_MDIO_AIROHA is not set
CONFIG_MDIO_BUS=y
CONFIG_MDIO_DEVICE=y
CONFIG_MDIO_DEVRES=y
CONFIG_MEDIATEK_GE_SOC_PHY=y
CONFIG_MFD_SYSCON=y
CONFIG_MIGRATION=y
CONFIG_MMC=y
CONFIG_MMC_BLOCK=y
CONFIG_MMC_CQHCI=y
CONFIG_MMC_MTK=y
CONFIG_MMU_LAZY_TLB_REFCOUNT=y
CONFIG_MODULES_TREE_LOOKUP=y
CONFIG_MODULES_USE_ELF_RELA=y
CONFIG_MTD_NAND_CORE=y
CONFIG_MTD_NAND_ECC=y
CONFIG_MTD_NAND_MTK_BMT=y
CONFIG_MTD_RAW_NAND=y
CONFIG_MTD_SPI_NAND=y
CONFIG_MTD_SPLIT_FIRMWARE=y
CONFIG_MTD_SPLIT_FIT_FW=y
CONFIG_MTD_UBI=y
CONFIG_MTD_UBI_BEB_LIMIT=20
CONFIG_MTD_UBI_BLOCK=y
CONFIG_MTD_UBI_WL_THRESHOLD=4096
CONFIG_MTK_NET_PHYLIB=y
CONFIG_MUTEX_SPIN_ON_OWNER=y
CONFIG_NEED_DMA_MAP_STATE=y
CONFIG_NEED_SG_DMA_LENGTH=y
CONFIG_NET_AIROHA=y
CONFIG_NET_AIROHA_FLOW_STATS=y
CONFIG_NET_AIROHA_NPU=y
CONFIG_NET_DEVLINK=y
CONFIG_NET_DSA=y
CONFIG_NET_DSA_MT7530=y
# CONFIG_NET_DSA_MT7530_MDIO is not set
CONFIG_NET_DSA_MT7530_MMIO=y
CONFIG_NET_DSA_TAG_MTK=y
CONFIG_NET_EGRESS=y
CONFIG_NET_FLOW_LIMIT=y
CONFIG_NET_INGRESS=y
CONFIG_NET_SELFTESTS=y
# CONFIG_NET_VENDOR_3COM is not set
CONFIG_NET_VENDOR_AIROHA=y
# CONFIG_NET_VENDOR_MEDIATEK is not set
CONFIG_NET_XGRESS=y
CONFIG_NLS=y
CONFIG_NO_HZ_COMMON=y
CONFIG_NO_HZ_IDLE=y
CONFIG_NR_CPUS=4
CONFIG_NVMEM=y
CONFIG_NVMEM_BLOCK=y
CONFIG_NVMEM_LAYOUTS=y
CONFIG_NVMEM_LAYOUT_ASCII_ENV=y
CONFIG_NVMEM_SYSFS=y
CONFIG_OF=y
CONFIG_OF_ADDRESS=y
CONFIG_OF_EARLY_FLATTREE=y
CONFIG_OF_FLATTREE=y
CONFIG_OF_GPIO=y
CONFIG_OF_IRQ=y
CONFIG_OF_KOBJ=y
CONFIG_OF_MDIO=y
CONFIG_PADATA=y
CONFIG_PAGE_POOL=y
CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
CONFIG_PARTITION_PERCPU=y
CONFIG_PCI=y
CONFIG_PCIEAER=y
CONFIG_PCIEASPM=y
# CONFIG_PCIEASPM_DEFAULT is not set
CONFIG_PCIEASPM_PERFORMANCE=y
# CONFIG_PCIEASPM_POWERSAVE is not set
# CONFIG_PCIEASPM_POWER_SUPERSAVE is not set
CONFIG_PCIEPORTBUS=y
CONFIG_PCIE_MEDIATEK=y
CONFIG_PCIE_MEDIATEK_GEN3=y
CONFIG_PCIE_PME=y
CONFIG_PCI_DOMAINS=y
CONFIG_PCI_DOMAINS_GENERIC=y
CONFIG_PCI_MSI=y
CONFIG_PCS_AIROHA=y
CONFIG_PCS_AIROHA_AN7581=y
# CONFIG_PCS_AIROHA_AN7583 is not set
CONFIG_PERF_EVENTS=y
CONFIG_PER_VMA_LOCK=y
CONFIG_PGTABLE_LEVELS=3
CONFIG_PHYLIB=y
CONFIG_PHYLIB_LEDS=y
CONFIG_PHYLINK=y
CONFIG_PHYS_ADDR_T_64BIT=y
CONFIG_PHY_AIROHA_PCIE=y
CONFIG_PHY_AIROHA_USB=y
CONFIG_PINCTRL=y
CONFIG_PINCTRL_AIROHA=y
# CONFIG_PINCTRL_MT2712 is not set
# CONFIG_PINCTRL_MT6765 is not set
# CONFIG_PINCTRL_MT6795 is not set
# CONFIG_PINCTRL_MT6797 is not set
# CONFIG_PINCTRL_MT7622 is not set
# CONFIG_PINCTRL_MT7981 is not set
# CONFIG_PINCTRL_MT7986 is not set
# CONFIG_PINCTRL_MT8173 is not set
# CONFIG_PINCTRL_MT8183 is not set
# CONFIG_PINCTRL_MT8186 is not set
# CONFIG_PINCTRL_MT8188 is not set
# CONFIG_PINCTRL_MT8516 is not set
CONFIG_PM=y
CONFIG_PM_CLK=y
CONFIG_PM_GENERIC_DOMAINS=y
CONFIG_PM_GENERIC_DOMAINS_OF=y
CONFIG_PM_OPP=y
CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y
CONFIG_POWER_RESET=y
CONFIG_POWER_RESET_SYSCON=y
CONFIG_POWER_SUPPLY=y
CONFIG_PTP_1588_CLOCK_OPTIONAL=y
CONFIG_QUEUED_RWLOCKS=y
CONFIG_QUEUED_SPINLOCKS=y
CONFIG_RANDSTRUCT_NONE=y
CONFIG_RAS=y
CONFIG_RATIONAL=y
CONFIG_REGMAP=y
CONFIG_REGMAP_MMIO=y
CONFIG_REGULATOR=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_RELOCATABLE=y
CONFIG_RESET_CONTROLLER=y
CONFIG_RFS_ACCEL=y
CONFIG_RODATA_FULL_DEFAULT_ENABLED=y
CONFIG_RPS=y
CONFIG_RWSEM_SPIN_ON_OWNER=y
CONFIG_SERIAL_8250_AIROHA=y
CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_FSL=y
CONFIG_SERIAL_8250_NR_UARTS=5
CONFIG_SERIAL_8250_RUNTIME_UARTS=5
CONFIG_SERIAL_8250_SHARE_IRQ=y
CONFIG_SERIAL_MCTRL_GPIO=y
CONFIG_SERIAL_OF_PLATFORM=y
CONFIG_SGL_ALLOC=y
CONFIG_SKB_EXTENSIONS=y
CONFIG_SMP=y
CONFIG_SOCK_RX_QUEUE_MAPPING=y
CONFIG_SOC_BUS=y
CONFIG_SOFTIRQ_ON_OWN_STACK=y
CONFIG_SPARSEMEM=y
CONFIG_SPARSEMEM_EXTREME=y
CONFIG_SPARSEMEM_VMEMMAP=y
CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
CONFIG_SPARSE_IRQ=y
CONFIG_SPI=y
# CONFIG_SPI_AIROHA_EN7523 is not set
CONFIG_SPI_AIROHA_SNFI=y
CONFIG_SPI_MASTER=y
CONFIG_SPI_MEM=y
CONFIG_SPLIT_PMD_PTLOCKS=y
CONFIG_SPLIT_PTE_PTLOCKS=y
CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y
CONFIG_SWIOTLB=y
CONFIG_SWPHY=y
CONFIG_SYSCTL_EXCEPTION_TRACE=y
CONFIG_THERMAL=y
CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0
CONFIG_THERMAL_GOV_STEP_WISE=y
CONFIG_THERMAL_OF=y
CONFIG_THREAD_INFO_IN_TASK=y
CONFIG_TICK_CPU_ACCOUNTING=y
CONFIG_TIMER_OF=y
CONFIG_TIMER_PROBE=y
CONFIG_TOOLS_SUPPORT_RELR=y
CONFIG_TRACE_IRQFLAGS_NMI_SUPPORT=y
CONFIG_TREE_RCU=y
CONFIG_TREE_SRCU=y
CONFIG_UBIFS_FS=y
# CONFIG_UNMAP_KERNEL_AT_EL0 is not set
CONFIG_USER_STACKTRACE_SUPPORT=y
CONFIG_VDSO_GETRANDOM=y
CONFIG_VMAP_STACK=y
CONFIG_WANT_DEV_COREDUMP=y
CONFIG_WATCHDOG_CORE=y
# CONFIG_WLAN is not set
# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set
CONFIG_XFRM_AH=y
CONFIG_XFRM_ALGO=y
CONFIG_XFRM_ESP=y
CONFIG_XFRM_IPCOMP=y
CONFIG_XFRM_MIGRATE=y
CONFIG_XPS=y
CONFIG_XXHASH=y
CONFIG_ZLIB_DEFLATE=y
CONFIG_ZLIB_INFLATE=y
CONFIG_ZONE_DMA32=y
CONFIG_ZSTD_COMMON=y
CONFIG_ZSTD_COMPRESS=y
CONFIG_ZSTD_DECOMPRESS=y
@@ -1,28 +0,0 @@
#
# Copyright (c) 2015 The Linux Foundation. All rights reserved.
# Copyright (c) 2011-2015 OpenWrt.org
#
. /lib/functions/uci-defaults.sh
. /lib/functions/system.sh
an7583_setup_interfaces()
{
local board="$1"
case "$board" in
airoha,an7583-evb)
ucidef_set_interface_lan "lan1 lan2 lan3 lan4 eth1"
;;
*)
echo "Unsupported hardware. Network interfaces not initialized"
;;
esac
}
board_config_update
board=$(board_name)
an7583_setup_interfaces $board
board_config_flush
exit 0
-402
View File
@@ -1,402 +0,0 @@
CONFIG_64BIT=y
CONFIG_AIROHA_CPU_PM_DOMAIN=y
CONFIG_AIROHA_SCU_SSR=y
CONFIG_AIROHA_THERMAL=y
CONFIG_AIROHA_WATCHDOG=y
CONFIG_AMPERE_ERRATUM_AC03_CPU_38=y
CONFIG_ARCH_AIROHA=y
CONFIG_ARCH_BINFMT_ELF_EXTRA_PHDRS=y
CONFIG_ARCH_CORRECT_STACKTRACE_ON_KRETPROBE=y
CONFIG_ARCH_DEFAULT_KEXEC_IMAGE_VERIFY_SIG=y
CONFIG_ARCH_DMA_ADDR_T_64BIT=y
CONFIG_ARCH_FORCE_MAX_ORDER=10
CONFIG_ARCH_KEEP_MEMBLOCK=y
CONFIG_ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE=y
CONFIG_ARCH_MMAP_RND_BITS=18
CONFIG_ARCH_MMAP_RND_BITS_MAX=24
CONFIG_ARCH_MMAP_RND_BITS_MIN=18
CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11
CONFIG_ARCH_PROC_KCORE_TEXT=y
CONFIG_ARCH_SPARSEMEM_ENABLE=y
CONFIG_ARCH_STACKWALK=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_ARCH_WANTS_NO_INSTR=y
CONFIG_ARCH_WANTS_THP_SWAP=y
CONFIG_ARM64=y
CONFIG_ARM64_4K_PAGES=y
CONFIG_ARM64_ERRATUM_843419=y
CONFIG_ARM64_LD_HAS_FIX_ERRATUM_843419=y
CONFIG_ARM64_PA_BITS=48
CONFIG_ARM64_PA_BITS_48=y
CONFIG_ARM64_PLATFORM_DEVICES=y
CONFIG_ARM64_TAGGED_ADDR_ABI=y
CONFIG_ARM64_VA_BITS=39
CONFIG_ARM64_VA_BITS_39=y
# CONFIG_ARM64_VA_BITS_48 is not set
# CONFIG_ARM64_VA_BITS_52 is not set
CONFIG_ARM_AIROHA_SOC_CPUFREQ=y
CONFIG_ARM_AMBA=y
CONFIG_ARM_ARCH_TIMER=y
CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y
# CONFIG_ARM_DEBUG_WX is not set
CONFIG_ARM_GIC=y
CONFIG_ARM_GIC_V2M=y
CONFIG_ARM_GIC_V3=y
CONFIG_ARM_GIC_V3_ITS=y
CONFIG_ARM_PMU=y
CONFIG_ARM_PMUV3=y
CONFIG_ARM_PSCI_FW=y
CONFIG_ARM_SMCCC_SOC_ID=y
# CONFIG_ARM_SMMU is not set
# CONFIG_ARM_SMMU_V3 is not set
CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y
CONFIG_BLK_MQ_PCI=y
CONFIG_BLK_PM=y
CONFIG_BUFFER_HEAD=y
CONFIG_BUILTIN_RETURN_ADDRESS_STRIPS_PAC=y
CONFIG_CC_HAVE_SHADOW_CALL_STACK=y
CONFIG_CC_HAVE_STACKPROTECTOR_SYSREG=y
CONFIG_CLONE_BACKWARDS=y
CONFIG_COMMON_CLK=y
CONFIG_COMMON_CLK_EN7523=y
CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
# CONFIG_COMPAT_32BIT_TIME is not set
# CONFIG_COMPRESSED_INSTALL is not set
CONFIG_CONTEXT_TRACKING=y
CONFIG_CONTEXT_TRACKING_IDLE=y
CONFIG_CPUFREQ_DT=y
CONFIG_CPUFREQ_DT_PLATDEV=y
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
CONFIG_CPU_FREQ_GOV_ATTR_SET=y
CONFIG_CPU_FREQ_GOV_COMMON=y
CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
CONFIG_CPU_FREQ_GOV_ONDEMAND=y
CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=y
CONFIG_CPU_FREQ_GOV_USERSPACE=y
CONFIG_CPU_FREQ_STAT=y
CONFIG_CPU_LITTLE_ENDIAN=y
CONFIG_CPU_RMAP=y
CONFIG_CRC16=y
CONFIG_CRC_CCITT=y
CONFIG_CRYPTO_CRC32C=y
CONFIG_CRYPTO_DEFLATE=y
CONFIG_CRYPTO_DEV_EIP93=y
CONFIG_CRYPTO_DRBG=y
CONFIG_CRYPTO_DRBG_HMAC=y
CONFIG_CRYPTO_DRBG_MENU=y
CONFIG_CRYPTO_ECB=y
CONFIG_CRYPTO_HASH_INFO=y
CONFIG_CRYPTO_HMAC=y
CONFIG_CRYPTO_JITTERENTROPY=y
CONFIG_CRYPTO_JITTERENTROPY_MEMORY_BLOCKS=64
CONFIG_CRYPTO_JITTERENTROPY_MEMORY_BLOCKSIZE=32
CONFIG_CRYPTO_JITTERENTROPY_OSR=1
CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
CONFIG_CRYPTO_LIB_GF128MUL=y
CONFIG_CRYPTO_LIB_SHA1=y
CONFIG_CRYPTO_LIB_SHA256=y
CONFIG_CRYPTO_LIB_UTILS=y
CONFIG_CRYPTO_LZO=y
CONFIG_CRYPTO_RNG=y
CONFIG_CRYPTO_RNG2=y
CONFIG_CRYPTO_RNG_DEFAULT=y
CONFIG_CRYPTO_SHA256=y
CONFIG_CRYPTO_SHA3=y
CONFIG_CRYPTO_SHA512=y
CONFIG_CRYPTO_ZSTD=y
CONFIG_DCACHE_WORD_ACCESS=y
CONFIG_DEBUG_MISC=y
CONFIG_DMADEVICES=y
CONFIG_DMA_BOUNCE_UNALIGNED_KMALLOC=y
CONFIG_DMA_DIRECT_REMAP=y
CONFIG_DMA_ENGINE=y
CONFIG_DMA_NEED_SYNC=y
CONFIG_DMA_OF=y
CONFIG_DMA_OPS_HELPERS=y
CONFIG_DTC=y
CONFIG_EDAC_SUPPORT=y
CONFIG_EXT4_FS=y
CONFIG_FIXED_PHY=y
CONFIG_FIX_EARLYCON_MEM=y
CONFIG_FRAME_POINTER=y
CONFIG_FS_IOMAP=y
CONFIG_FS_MBCACHE=y
CONFIG_FUNCTION_ALIGNMENT=4
CONFIG_FUNCTION_ALIGNMENT_4B=y
CONFIG_FWNODE_MDIO=y
CONFIG_FW_CACHE=y
# CONFIG_FW_LOADER_USER_HELPER is not set
CONFIG_GCC_SUPPORTS_DYNAMIC_FTRACE_WITH_ARGS=y
CONFIG_GENERIC_ALLOCATOR=y
CONFIG_GENERIC_ARCH_TOPOLOGY=y
CONFIG_GENERIC_BUG=y
CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
CONFIG_GENERIC_CPU_AUTOPROBE=y
CONFIG_GENERIC_CPU_DEVICES=y
CONFIG_GENERIC_CPU_VULNERABILITIES=y
CONFIG_GENERIC_CSUM=y
CONFIG_GENERIC_EARLY_IOREMAP=y
CONFIG_GENERIC_GETTIMEOFDAY=y
CONFIG_GENERIC_IDLE_POLL_SETUP=y
CONFIG_GENERIC_IOREMAP=y
CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
CONFIG_GENERIC_IRQ_SHOW=y
CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y
CONFIG_GENERIC_MSI_IRQ=y
CONFIG_GENERIC_PCI_IOMAP=y
CONFIG_GENERIC_PHY=y
CONFIG_GENERIC_PINCONF=y
CONFIG_GENERIC_PINCTRL_GROUPS=y
CONFIG_GENERIC_PINMUX_FUNCTIONS=y
CONFIG_GENERIC_SCHED_CLOCK=y
CONFIG_GENERIC_SMP_IDLE_THREAD=y
CONFIG_GENERIC_STRNCPY_FROM_USER=y
CONFIG_GENERIC_STRNLEN_USER=y
CONFIG_GENERIC_TIME_VSYSCALL=y
CONFIG_GLOB=y
CONFIG_GPIOLIB_IRQCHIP=y
CONFIG_GPIO_CDEV=y
CONFIG_GPIO_EN7523=y
CONFIG_GPIO_GENERIC=y
CONFIG_GRO_CELLS=y
CONFIG_HARDIRQS_SW_RESEND=y
CONFIG_HAS_DMA=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_IOPORT_MAP=y
CONFIG_HOTPLUG_CORE_SYNC=y
CONFIG_HOTPLUG_CORE_SYNC_DEAD=y
CONFIG_HOTPLUG_CPU=y
CONFIG_HW_RANDOM=y
CONFIG_HW_RANDOM_AIROHA=y
# CONFIG_HISILICON_ERRATUM_162100801 is not set
# CONFIG_IDPF is not set
CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000
CONFIG_INET_AH=y
CONFIG_INET_ESP=y
# CONFIG_INET_ESP_OFFLOAD is not set
CONFIG_INET_IPCOMP=y
CONFIG_INET_TUNNEL=y
CONFIG_INET_XFRM_TUNNEL=y
CONFIG_IO_URING=y
CONFIG_IPC_NS=y
CONFIG_IPV6=y
CONFIG_IPV6_MULTIPLE_TABLES=y
# CONFIG_IPV6_SUBTREES is not set
CONFIG_IP_MROUTE=y
CONFIG_IP_MROUTE_COMMON=y
# CONFIG_IP_MROUTE_MULTIPLE_TABLES is not set
CONFIG_IP_PNP=y
# CONFIG_IP_PNP_BOOTP is not set
# CONFIG_IP_PNP_DHCP is not set
# CONFIG_IP_PNP_RARP is not set
# CONFIG_IP_ROUTE_MULTIPATH is not set
# CONFIG_IP_ROUTE_VERBOSE is not set
CONFIG_IRQCHIP=y
CONFIG_IRQ_DOMAIN=y
CONFIG_IRQ_DOMAIN_HIERARCHY=y
CONFIG_IRQ_FORCED_THREADING=y
CONFIG_IRQ_MSI_LIB=y
CONFIG_IRQ_WORK=y
CONFIG_JBD2=y
CONFIG_LIBFDT=y
CONFIG_LOCK_DEBUGGING_SUPPORT=y
CONFIG_LOCK_SPIN_ON_OWNER=y
CONFIG_LRU_GEN_WALKS_MMU=y
CONFIG_LZO_COMPRESS=y
CONFIG_LZO_DECOMPRESS=y
CONFIG_MDIO_BUS=y
CONFIG_MDIO_DEVICE=y
CONFIG_MDIO_AIROHA=y
CONFIG_MDIO_DEVRES=y
# CONFIG_MEDIATEK_GE_SOC_PHY is not set
# CONFIG_MEMCG is not set
CONFIG_MFD_SYSCON=y
CONFIG_MIGRATION=y
CONFIG_MMC=y
CONFIG_MMC_BLOCK=y
CONFIG_MMC_CQHCI=y
CONFIG_MMC_MTK=y
CONFIG_MMU_LAZY_TLB_REFCOUNT=y
CONFIG_MODULES_TREE_LOOKUP=y
CONFIG_MODULES_USE_ELF_RELA=y
CONFIG_MTD_NAND_CORE=y
CONFIG_MTD_NAND_ECC=y
CONFIG_MTD_NAND_MTK_BMT=y
CONFIG_MTD_RAW_NAND=y
CONFIG_MTD_SPI_NAND=y
CONFIG_MTD_SPLIT_FIRMWARE=y
CONFIG_MTD_SPLIT_FIT_FW=y
CONFIG_MTD_UBI=y
CONFIG_MTD_UBI_BEB_LIMIT=20
CONFIG_MTD_UBI_BLOCK=y
CONFIG_MTD_UBI_WL_THRESHOLD=4096
CONFIG_MUTEX_SPIN_ON_OWNER=y
CONFIG_NEED_DMA_MAP_STATE=y
CONFIG_NEED_SG_DMA_LENGTH=y
CONFIG_NET_AIROHA=y
CONFIG_NET_AIROHA_FLOW_STATS=y
CONFIG_NET_AIROHA_NPU=y
CONFIG_NET_DEVLINK=y
CONFIG_NET_DSA=y
CONFIG_NET_DSA_MT7530=y
CONFIG_NET_DSA_MT7530_MDIO=y
CONFIG_NET_DSA_MT7530_MMIO=y
CONFIG_NET_DSA_TAG_MTK=y
CONFIG_NET_FLOW_LIMIT=y
# CONFIG_NET_MEDIATEK_SOC is not set
CONFIG_NET_SELFTESTS=y
# CONFIG_NET_VENDOR_3COM is not set
CONFIG_NET_VENDOR_AIROHA=y
# CONFIG_NET_VENDOR_MEDIATEK is not set
CONFIG_NLS=y
CONFIG_NO_HZ_COMMON=y
CONFIG_NO_HZ_IDLE=y
CONFIG_NR_CPUS=4
CONFIG_NVMEM=y
CONFIG_NVMEM_BLOCK=y
CONFIG_NVMEM_LAYOUTS=y
CONFIG_NVMEM_LAYOUT_ASCII_ENV=y
CONFIG_NVMEM_SYSFS=y
CONFIG_OF=y
CONFIG_OF_ADDRESS=y
CONFIG_OF_EARLY_FLATTREE=y
CONFIG_OF_FLATTREE=y
CONFIG_OF_GPIO=y
CONFIG_OF_IRQ=y
CONFIG_OF_KOBJ=y
CONFIG_OF_MDIO=y
CONFIG_PAGE_POOL=y
CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
CONFIG_PARTITION_PERCPU=y
CONFIG_PCI=y
CONFIG_PCIEAER=y
CONFIG_PCIEASPM=y
# CONFIG_PCIEASPM_DEFAULT is not set
CONFIG_PCIEASPM_PERFORMANCE=y
# CONFIG_PCIEASPM_POWERSAVE is not set
# CONFIG_PCIEASPM_POWER_SUPERSAVE is not set
CONFIG_PCIEPORTBUS=y
CONFIG_PCIE_MEDIATEK=y
CONFIG_PCIE_MEDIATEK_GEN3=y
CONFIG_PCIE_PME=y
CONFIG_PCI_DOMAINS=y
CONFIG_PCI_DOMAINS_GENERIC=y
CONFIG_PCI_MSI=y
# CONFIG_PCS_AIROHA_AN7581 is not set
CONFIG_PCS_AIROHA_AN7583=y
CONFIG_PERF_EVENTS=y
CONFIG_PER_VMA_LOCK=y
CONFIG_PGTABLE_LEVELS=3
CONFIG_PHYLIB=y
CONFIG_PHYLIB_LEDS=y
CONFIG_PHYLINK=y
CONFIG_PHYS_ADDR_T_64BIT=y
CONFIG_PHY_AIROHA_PCIE=y
# CONFIG_PHY_AIROHA_USB is not set
CONFIG_PINCTRL=y
CONFIG_PINCTRL_AIROHA=y
# CONFIG_PINCTRL_MT2712 is not set
# CONFIG_PINCTRL_MT6765 is not set
# CONFIG_PINCTRL_MT6795 is not set
# CONFIG_PINCTRL_MT6797 is not set
# CONFIG_PINCTRL_MT7622 is not set
# CONFIG_PINCTRL_MT7981 is not set
# CONFIG_PINCTRL_MT7986 is not set
# CONFIG_PINCTRL_MT8173 is not set
# CONFIG_PINCTRL_MT8183 is not set
# CONFIG_PINCTRL_MT8186 is not set
# CONFIG_PINCTRL_MT8188 is not set
# CONFIG_PINCTRL_MT8516 is not set
CONFIG_PM=y
CONFIG_PM_CLK=y
CONFIG_PM_OPP=y
CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y
CONFIG_POWER_RESET=y
CONFIG_POWER_RESET_SYSCON=y
CONFIG_POWER_SUPPLY=y
CONFIG_PTP_1588_CLOCK_OPTIONAL=y
CONFIG_QUEUED_RWLOCKS=y
CONFIG_QUEUED_SPINLOCKS=y
CONFIG_RANDSTRUCT_NONE=y
CONFIG_RAS=y
CONFIG_RATIONAL=y
CONFIG_REGMAP=y
CONFIG_REGMAP_MMIO=y
CONFIG_REGULATOR=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_RELOCATABLE=y
CONFIG_RESET_CONTROLLER=y
CONFIG_RFS_ACCEL=y
CONFIG_RODATA_FULL_DEFAULT_ENABLED=y
CONFIG_RPS=y
CONFIG_RWSEM_SPIN_ON_OWNER=y
CONFIG_SERIAL_8250_AIROHA=y
CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_FSL=y
CONFIG_SERIAL_8250_NR_UARTS=5
CONFIG_SERIAL_8250_RUNTIME_UARTS=5
CONFIG_SERIAL_8250_SHARE_IRQ=y
CONFIG_SERIAL_MCTRL_GPIO=y
CONFIG_SERIAL_OF_PLATFORM=y
CONFIG_SGL_ALLOC=y
CONFIG_SKB_EXTENSIONS=y
CONFIG_SMP=y
CONFIG_SOCK_RX_QUEUE_MAPPING=y
CONFIG_SOC_BUS=y
CONFIG_SOFTIRQ_ON_OWN_STACK=y
CONFIG_SPARSEMEM=y
CONFIG_SPARSEMEM_EXTREME=y
CONFIG_SPARSEMEM_VMEMMAP=y
CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
CONFIG_SPARSE_IRQ=y
CONFIG_SPI=y
# CONFIG_SPI_AIROHA_EN7523 is not set
CONFIG_SPI_AIROHA_SNFI=y
CONFIG_SPI_MASTER=y
CONFIG_SPI_MEM=y
CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y
CONFIG_SWIOTLB=y
CONFIG_SWPHY=y
CONFIG_SYSCTL_EXCEPTION_TRACE=y
# CONFIG_TEST_FPU is not set
CONFIG_THERMAL=y
CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0
CONFIG_THERMAL_GOV_STEP_WISE=y
CONFIG_THERMAL_OF=y
CONFIG_THREAD_INFO_IN_TASK=y
CONFIG_TICK_CPU_ACCOUNTING=y
CONFIG_TIMER_OF=y
CONFIG_TIMER_PROBE=y
CONFIG_TRACE_IRQFLAGS_NMI_SUPPORT=y
CONFIG_TREE_RCU=y
CONFIG_TREE_SRCU=y
CONFIG_UBIFS_FS=y
# CONFIG_UNMAP_KERNEL_AT_EL0 is not set
CONFIG_USER_STACKTRACE_SUPPORT=y
CONFIG_VDSO_GETRANDOM=y
CONFIG_VMAP_STACK=y
CONFIG_WATCHDOG_CORE=y
# CONFIG_WLAN is not set
# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set
CONFIG_XFRM_AH=y
CONFIG_XFRM_ALGO=y
CONFIG_XFRM_ESP=y
CONFIG_XFRM_IPCOMP=y
CONFIG_XFRM_MIGRATE=y
CONFIG_XPS=y
CONFIG_XXHASH=y
CONFIG_ZLIB_DEFLATE=y
CONFIG_ZLIB_INFLATE=y
CONFIG_ZONE_DMA32=y
CONFIG_ZSTD_COMMON=y
CONFIG_ZSTD_COMPRESS=y
CONFIG_ZSTD_DECOMPRESS=y
-402
View File
@@ -1,402 +0,0 @@
CONFIG_64BIT=y
CONFIG_AIROHA_CPU_PM_DOMAIN=y
CONFIG_AIROHA_SCU_SSR=y
CONFIG_AIROHA_THERMAL=y
CONFIG_AIROHA_WATCHDOG=y
CONFIG_AMPERE_ERRATUM_AC03_CPU_38=y
CONFIG_ARCH_AIROHA=y
CONFIG_ARCH_BINFMT_ELF_EXTRA_PHDRS=y
CONFIG_ARCH_CORRECT_STACKTRACE_ON_KRETPROBE=y
CONFIG_ARCH_DEFAULT_KEXEC_IMAGE_VERIFY_SIG=y
CONFIG_ARCH_DMA_ADDR_T_64BIT=y
CONFIG_ARCH_FORCE_MAX_ORDER=10
CONFIG_ARCH_KEEP_MEMBLOCK=y
CONFIG_ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE=y
CONFIG_ARCH_MMAP_RND_BITS=18
CONFIG_ARCH_MMAP_RND_BITS_MAX=24
CONFIG_ARCH_MMAP_RND_BITS_MIN=18
CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11
CONFIG_ARCH_PROC_KCORE_TEXT=y
CONFIG_ARCH_SPARSEMEM_ENABLE=y
CONFIG_ARCH_STACKWALK=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_ARCH_WANTS_NO_INSTR=y
CONFIG_ARCH_WANTS_THP_SWAP=y
CONFIG_ARM64=y
CONFIG_ARM64_4K_PAGES=y
CONFIG_ARM64_ERRATUM_843419=y
CONFIG_ARM64_LD_HAS_FIX_ERRATUM_843419=y
CONFIG_ARM64_PA_BITS=48
CONFIG_ARM64_PA_BITS_48=y
CONFIG_ARM64_PLATFORM_DEVICES=y
CONFIG_ARM64_TAGGED_ADDR_ABI=y
CONFIG_ARM64_VA_BITS=39
CONFIG_ARM64_VA_BITS_39=y
# CONFIG_ARM64_VA_BITS_48 is not set
# CONFIG_ARM64_VA_BITS_52 is not set
CONFIG_ARM_AIROHA_SOC_CPUFREQ=y
CONFIG_ARM_AMBA=y
CONFIG_ARM_ARCH_TIMER=y
CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y
# CONFIG_ARM_DEBUG_WX is not set
CONFIG_ARM_GIC=y
CONFIG_ARM_GIC_V2M=y
CONFIG_ARM_GIC_V3=y
CONFIG_ARM_GIC_V3_ITS=y
CONFIG_ARM_PMU=y
CONFIG_ARM_PMUV3=y
CONFIG_ARM_PSCI_FW=y
CONFIG_ARM_SMCCC_SOC_ID=y
# CONFIG_ARM_SMMU is not set
# CONFIG_ARM_SMMU_V3 is not set
CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y
CONFIG_BLK_MQ_PCI=y
CONFIG_BLK_PM=y
CONFIG_BUFFER_HEAD=y
CONFIG_BUILTIN_RETURN_ADDRESS_STRIPS_PAC=y
CONFIG_CC_HAVE_SHADOW_CALL_STACK=y
CONFIG_CC_HAVE_STACKPROTECTOR_SYSREG=y
CONFIG_CLONE_BACKWARDS=y
CONFIG_COMMON_CLK=y
CONFIG_COMMON_CLK_EN7523=y
CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
# CONFIG_COMPAT_32BIT_TIME is not set
# CONFIG_COMPRESSED_INSTALL is not set
CONFIG_CONTEXT_TRACKING=y
CONFIG_CONTEXT_TRACKING_IDLE=y
CONFIG_CPUFREQ_DT=y
CONFIG_CPUFREQ_DT_PLATDEV=y
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
CONFIG_CPU_FREQ_GOV_ATTR_SET=y
CONFIG_CPU_FREQ_GOV_COMMON=y
CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
CONFIG_CPU_FREQ_GOV_ONDEMAND=y
CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=y
CONFIG_CPU_FREQ_GOV_USERSPACE=y
CONFIG_CPU_FREQ_STAT=y
CONFIG_CPU_LITTLE_ENDIAN=y
CONFIG_CPU_RMAP=y
CONFIG_CRC16=y
CONFIG_CRC_CCITT=y
CONFIG_CRYPTO_CRC32C=y
CONFIG_CRYPTO_DEFLATE=y
CONFIG_CRYPTO_DEV_EIP93=y
CONFIG_CRYPTO_DRBG=y
CONFIG_CRYPTO_DRBG_HMAC=y
CONFIG_CRYPTO_DRBG_MENU=y
CONFIG_CRYPTO_ECB=y
CONFIG_CRYPTO_HASH_INFO=y
CONFIG_CRYPTO_HMAC=y
CONFIG_CRYPTO_JITTERENTROPY=y
CONFIG_CRYPTO_JITTERENTROPY_MEMORY_BLOCKS=64
CONFIG_CRYPTO_JITTERENTROPY_MEMORY_BLOCKSIZE=32
CONFIG_CRYPTO_JITTERENTROPY_OSR=1
CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
CONFIG_CRYPTO_LIB_GF128MUL=y
CONFIG_CRYPTO_LIB_SHA1=y
CONFIG_CRYPTO_LIB_SHA256=y
CONFIG_CRYPTO_LIB_UTILS=y
CONFIG_CRYPTO_LZO=y
CONFIG_CRYPTO_RNG=y
CONFIG_CRYPTO_RNG2=y
CONFIG_CRYPTO_RNG_DEFAULT=y
CONFIG_CRYPTO_SHA256=y
CONFIG_CRYPTO_SHA3=y
CONFIG_CRYPTO_SHA512=y
CONFIG_CRYPTO_ZSTD=y
CONFIG_DCACHE_WORD_ACCESS=y
CONFIG_DEBUG_MISC=y
CONFIG_DMADEVICES=y
CONFIG_DMA_BOUNCE_UNALIGNED_KMALLOC=y
CONFIG_DMA_DIRECT_REMAP=y
CONFIG_DMA_ENGINE=y
CONFIG_DMA_NEED_SYNC=y
CONFIG_DMA_OF=y
CONFIG_DMA_OPS_HELPERS=y
CONFIG_DTC=y
CONFIG_EDAC_SUPPORT=y
CONFIG_EXT4_FS=y
CONFIG_FIXED_PHY=y
CONFIG_FIX_EARLYCON_MEM=y
CONFIG_FRAME_POINTER=y
CONFIG_FS_IOMAP=y
CONFIG_FS_MBCACHE=y
CONFIG_FUNCTION_ALIGNMENT=4
CONFIG_FUNCTION_ALIGNMENT_4B=y
CONFIG_FWNODE_MDIO=y
CONFIG_FW_CACHE=y
# CONFIG_FW_LOADER_USER_HELPER is not set
CONFIG_GCC_SUPPORTS_DYNAMIC_FTRACE_WITH_ARGS=y
CONFIG_GENERIC_ALLOCATOR=y
CONFIG_GENERIC_ARCH_TOPOLOGY=y
CONFIG_GENERIC_BUG=y
CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
CONFIG_GENERIC_CPU_AUTOPROBE=y
CONFIG_GENERIC_CPU_DEVICES=y
CONFIG_GENERIC_CPU_VULNERABILITIES=y
CONFIG_GENERIC_CSUM=y
CONFIG_GENERIC_EARLY_IOREMAP=y
CONFIG_GENERIC_GETTIMEOFDAY=y
CONFIG_GENERIC_IDLE_POLL_SETUP=y
CONFIG_GENERIC_IOREMAP=y
CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
CONFIG_GENERIC_IRQ_SHOW=y
CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y
CONFIG_GENERIC_MSI_IRQ=y
CONFIG_GENERIC_PCI_IOMAP=y
CONFIG_GENERIC_PHY=y
CONFIG_GENERIC_PINCONF=y
CONFIG_GENERIC_PINCTRL_GROUPS=y
CONFIG_GENERIC_PINMUX_FUNCTIONS=y
CONFIG_GENERIC_SCHED_CLOCK=y
CONFIG_GENERIC_SMP_IDLE_THREAD=y
CONFIG_GENERIC_STRNCPY_FROM_USER=y
CONFIG_GENERIC_STRNLEN_USER=y
CONFIG_GENERIC_TIME_VSYSCALL=y
CONFIG_GLOB=y
CONFIG_GPIOLIB_IRQCHIP=y
CONFIG_GPIO_CDEV=y
CONFIG_GPIO_EN7523=y
CONFIG_GPIO_GENERIC=y
CONFIG_GRO_CELLS=y
CONFIG_HARDIRQS_SW_RESEND=y
CONFIG_HAS_DMA=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_IOPORT_MAP=y
CONFIG_HOTPLUG_CORE_SYNC=y
CONFIG_HOTPLUG_CORE_SYNC_DEAD=y
CONFIG_HOTPLUG_CPU=y
CONFIG_HW_RANDOM=y
CONFIG_HW_RANDOM_AIROHA=y
# CONFIG_HISILICON_ERRATUM_162100801 is not set
# CONFIG_IDPF is not set
CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000
CONFIG_INET_AH=y
CONFIG_INET_ESP=y
# CONFIG_INET_ESP_OFFLOAD is not set
CONFIG_INET_IPCOMP=y
CONFIG_INET_TUNNEL=y
CONFIG_INET_XFRM_TUNNEL=y
CONFIG_IO_URING=y
CONFIG_IPC_NS=y
CONFIG_IPV6=y
CONFIG_IPV6_MULTIPLE_TABLES=y
# CONFIG_IPV6_SUBTREES is not set
CONFIG_IP_MROUTE=y
CONFIG_IP_MROUTE_COMMON=y
# CONFIG_IP_MROUTE_MULTIPLE_TABLES is not set
CONFIG_IP_PNP=y
# CONFIG_IP_PNP_BOOTP is not set
# CONFIG_IP_PNP_DHCP is not set
# CONFIG_IP_PNP_RARP is not set
# CONFIG_IP_ROUTE_MULTIPATH is not set
# CONFIG_IP_ROUTE_VERBOSE is not set
CONFIG_IRQCHIP=y
CONFIG_IRQ_DOMAIN=y
CONFIG_IRQ_DOMAIN_HIERARCHY=y
CONFIG_IRQ_FORCED_THREADING=y
CONFIG_IRQ_MSI_LIB=y
CONFIG_IRQ_WORK=y
CONFIG_JBD2=y
CONFIG_LIBFDT=y
CONFIG_LOCK_DEBUGGING_SUPPORT=y
CONFIG_LOCK_SPIN_ON_OWNER=y
CONFIG_LRU_GEN_WALKS_MMU=y
CONFIG_LZO_COMPRESS=y
CONFIG_LZO_DECOMPRESS=y
CONFIG_MDIO_BUS=y
CONFIG_MDIO_DEVICE=y
CONFIG_MDIO_AIROHA=y
CONFIG_MDIO_DEVRES=y
# CONFIG_MEDIATEK_GE_SOC_PHY is not set
# CONFIG_MEMCG is not set
CONFIG_MFD_SYSCON=y
CONFIG_MIGRATION=y
CONFIG_MMC=y
CONFIG_MMC_BLOCK=y
CONFIG_MMC_CQHCI=y
CONFIG_MMC_MTK=y
CONFIG_MMU_LAZY_TLB_REFCOUNT=y
CONFIG_MODULES_TREE_LOOKUP=y
CONFIG_MODULES_USE_ELF_RELA=y
CONFIG_MTD_NAND_CORE=y
CONFIG_MTD_NAND_ECC=y
CONFIG_MTD_NAND_MTK_BMT=y
CONFIG_MTD_RAW_NAND=y
CONFIG_MTD_SPI_NAND=y
CONFIG_MTD_SPLIT_FIRMWARE=y
CONFIG_MTD_SPLIT_FIT_FW=y
CONFIG_MTD_UBI=y
CONFIG_MTD_UBI_BEB_LIMIT=20
CONFIG_MTD_UBI_BLOCK=y
CONFIG_MTD_UBI_WL_THRESHOLD=4096
CONFIG_MUTEX_SPIN_ON_OWNER=y
CONFIG_NEED_DMA_MAP_STATE=y
CONFIG_NEED_SG_DMA_LENGTH=y
CONFIG_NET_AIROHA=y
CONFIG_NET_AIROHA_FLOW_STATS=y
CONFIG_NET_AIROHA_NPU=y
CONFIG_NET_DEVLINK=y
CONFIG_NET_DSA=y
CONFIG_NET_DSA_MT7530=y
CONFIG_NET_DSA_MT7530_MDIO=y
CONFIG_NET_DSA_MT7530_MMIO=y
CONFIG_NET_DSA_TAG_MTK=y
CONFIG_NET_FLOW_LIMIT=y
# CONFIG_NET_MEDIATEK_SOC is not set
CONFIG_NET_SELFTESTS=y
# CONFIG_NET_VENDOR_3COM is not set
CONFIG_NET_VENDOR_AIROHA=y
# CONFIG_NET_VENDOR_MEDIATEK is not set
CONFIG_NLS=y
CONFIG_NO_HZ_COMMON=y
CONFIG_NO_HZ_IDLE=y
CONFIG_NR_CPUS=4
CONFIG_NVMEM=y
CONFIG_NVMEM_BLOCK=y
CONFIG_NVMEM_LAYOUTS=y
CONFIG_NVMEM_LAYOUT_ASCII_ENV=y
CONFIG_NVMEM_SYSFS=y
CONFIG_OF=y
CONFIG_OF_ADDRESS=y
CONFIG_OF_EARLY_FLATTREE=y
CONFIG_OF_FLATTREE=y
CONFIG_OF_GPIO=y
CONFIG_OF_IRQ=y
CONFIG_OF_KOBJ=y
CONFIG_OF_MDIO=y
CONFIG_PAGE_POOL=y
CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
CONFIG_PARTITION_PERCPU=y
CONFIG_PCI=y
CONFIG_PCIEAER=y
CONFIG_PCIEASPM=y
# CONFIG_PCIEASPM_DEFAULT is not set
CONFIG_PCIEASPM_PERFORMANCE=y
# CONFIG_PCIEASPM_POWERSAVE is not set
# CONFIG_PCIEASPM_POWER_SUPERSAVE is not set
CONFIG_PCIEPORTBUS=y
CONFIG_PCIE_MEDIATEK=y
CONFIG_PCIE_MEDIATEK_GEN3=y
CONFIG_PCIE_PME=y
CONFIG_PCI_DOMAINS=y
CONFIG_PCI_DOMAINS_GENERIC=y
CONFIG_PCI_MSI=y
# CONFIG_PCS_AIROHA_AN7581 is not set
CONFIG_PCS_AIROHA_AN7583=y
CONFIG_PERF_EVENTS=y
CONFIG_PER_VMA_LOCK=y
CONFIG_PGTABLE_LEVELS=3
CONFIG_PHYLIB=y
CONFIG_PHYLIB_LEDS=y
CONFIG_PHYLINK=y
CONFIG_PHYS_ADDR_T_64BIT=y
CONFIG_PHY_AIROHA_PCIE=y
# CONFIG_PHY_AIROHA_USB is not set
CONFIG_PINCTRL=y
CONFIG_PINCTRL_AIROHA=y
# CONFIG_PINCTRL_MT2712 is not set
# CONFIG_PINCTRL_MT6765 is not set
# CONFIG_PINCTRL_MT6795 is not set
# CONFIG_PINCTRL_MT6797 is not set
# CONFIG_PINCTRL_MT7622 is not set
# CONFIG_PINCTRL_MT7981 is not set
# CONFIG_PINCTRL_MT7986 is not set
# CONFIG_PINCTRL_MT8173 is not set
# CONFIG_PINCTRL_MT8183 is not set
# CONFIG_PINCTRL_MT8186 is not set
# CONFIG_PINCTRL_MT8188 is not set
# CONFIG_PINCTRL_MT8516 is not set
CONFIG_PM=y
CONFIG_PM_CLK=y
CONFIG_PM_OPP=y
CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y
CONFIG_POWER_RESET=y
CONFIG_POWER_RESET_SYSCON=y
CONFIG_POWER_SUPPLY=y
CONFIG_PTP_1588_CLOCK_OPTIONAL=y
CONFIG_QUEUED_RWLOCKS=y
CONFIG_QUEUED_SPINLOCKS=y
CONFIG_RANDSTRUCT_NONE=y
CONFIG_RAS=y
CONFIG_RATIONAL=y
CONFIG_REGMAP=y
CONFIG_REGMAP_MMIO=y
CONFIG_REGULATOR=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_RELOCATABLE=y
CONFIG_RESET_CONTROLLER=y
CONFIG_RFS_ACCEL=y
CONFIG_RODATA_FULL_DEFAULT_ENABLED=y
CONFIG_RPS=y
CONFIG_RWSEM_SPIN_ON_OWNER=y
CONFIG_SERIAL_8250_AIROHA=y
CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_FSL=y
CONFIG_SERIAL_8250_NR_UARTS=5
CONFIG_SERIAL_8250_RUNTIME_UARTS=5
CONFIG_SERIAL_8250_SHARE_IRQ=y
CONFIG_SERIAL_MCTRL_GPIO=y
CONFIG_SERIAL_OF_PLATFORM=y
CONFIG_SGL_ALLOC=y
CONFIG_SKB_EXTENSIONS=y
CONFIG_SMP=y
CONFIG_SOCK_RX_QUEUE_MAPPING=y
CONFIG_SOC_BUS=y
CONFIG_SOFTIRQ_ON_OWN_STACK=y
CONFIG_SPARSEMEM=y
CONFIG_SPARSEMEM_EXTREME=y
CONFIG_SPARSEMEM_VMEMMAP=y
CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
CONFIG_SPARSE_IRQ=y
CONFIG_SPI=y
# CONFIG_SPI_AIROHA_EN7523 is not set
CONFIG_SPI_AIROHA_SNFI=y
CONFIG_SPI_MASTER=y
CONFIG_SPI_MEM=y
CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y
CONFIG_SWIOTLB=y
CONFIG_SWPHY=y
CONFIG_SYSCTL_EXCEPTION_TRACE=y
# CONFIG_TEST_FPU is not set
CONFIG_THERMAL=y
CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0
CONFIG_THERMAL_GOV_STEP_WISE=y
CONFIG_THERMAL_OF=y
CONFIG_THREAD_INFO_IN_TASK=y
CONFIG_TICK_CPU_ACCOUNTING=y
CONFIG_TIMER_OF=y
CONFIG_TIMER_PROBE=y
CONFIG_TRACE_IRQFLAGS_NMI_SUPPORT=y
CONFIG_TREE_RCU=y
CONFIG_TREE_SRCU=y
CONFIG_UBIFS_FS=y
# CONFIG_UNMAP_KERNEL_AT_EL0 is not set
CONFIG_USER_STACKTRACE_SUPPORT=y
CONFIG_VDSO_GETRANDOM=y
CONFIG_VMAP_STACK=y
CONFIG_WATCHDOG_CORE=y
# CONFIG_WLAN is not set
# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set
CONFIG_XFRM_AH=y
CONFIG_XFRM_ALGO=y
CONFIG_XFRM_ESP=y
CONFIG_XFRM_IPCOMP=y
CONFIG_XFRM_MIGRATE=y
CONFIG_XPS=y
CONFIG_XXHASH=y
CONFIG_ZLIB_DEFLATE=y
CONFIG_ZLIB_INFLATE=y
CONFIG_ZONE_DMA32=y
CONFIG_ZSTD_COMMON=y
CONFIG_ZSTD_COMPRESS=y
CONFIG_ZSTD_DECOMPRESS=y
-11
View File
@@ -1,11 +0,0 @@
ARCH:=aarch64
SUBTARGET:=an7583
BOARDNAME:=AN7583
CPU_TYPE:=cortex-a53
KERNELNAME:=Image dtbs
FEATURES+=pwm source-only
define Target/Description
Build firmware images for Airoha an7583 ARM based boards.
endef
@@ -57,13 +57,6 @@
};
};
pcie2_rst_pins: pcie2-rst-pins {
conf {
pins = "pcie_reset2";
drive-open-drain = <1>;
};
};
gswp1_led0_pins: gswp1-led0-pins {
mux {
function = "phy1_led0";
@@ -106,17 +99,6 @@
};
};
&usb0 {
status = "okay";
};
&usb1 {
status = "okay";
mediatek,u3p-dis-msk = <0x1>;
phys = <&usb1_phy PHY_TYPE_USB2>;
};
&mmc0 {
pinctrl-names = "default", "state_uhs";
pinctrl-0 = <&mmc_pins>;
@@ -174,46 +156,6 @@
status = "okay";
};
&pcie2 {
pinctrl-names = "default";
pinctrl-0 = <&pcie2_rst_pins>;
status = "okay";
};
&mdio {
as21xx_1: ethernet-phy@1d {
compatible = "ethernet-phy-ieee802.3-c45";
reg = <0x1d>;
firmware-name = "as21x1x_fw.bin";
reset-deassert-us = <1000000>;
reset-assert-us = <1000000>;
reset-gpios = <&en7581_pinctrl 31 GPIO_ACTIVE_LOW>;
leds {
#address-cells = <1>;
#size-cells = <0>;
led@0 {
reg = <0>;
color = <LED_COLOR_ID_GREEN>;
function = LED_FUNCTION_LAN;
function-enumerator = <0>;
default-state = "keep";
};
led@1 {
reg = <1>;
color = <LED_COLOR_ID_GREEN>;
function = LED_FUNCTION_LAN;
function-enumerator = <1>;
default-state = "keep";
};
};
};
};
&eth {
status = "okay";
};
@@ -222,13 +164,6 @@
status = "okay";
};
&gdm4 {
status = "okay";
phy-handle = <&as21xx_1>;
phy-mode = "usxgmii";
};
&switch {
pinctrl-names = "default";
pinctrl-0 = <&mdio_pins>;
@@ -1,265 +0,0 @@
// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
/dts-v1/;
#include <dt-bindings/leds/common.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include "an7581.dtsi"
/ {
model = "Nokia Bell XG-040G-MD";
compatible = "bell,xg-040g-md", "airoha,an7581";
efuse-banks {
compatible = "airoha,an7581-efuses";
#address-cells = <0x01>;
#size-cells = <0x00>;
bank@0 {
reg = <0x00>;
};
bank@1 {
reg = <0x01>;
};
};
aliases {
serial0 = &uart1;
};
chosen {
bootargs = "console=ttyS0,115200n8 loglevel=7 earlycon";
stdout-path = "serial0:115200n8";
bootargs-append = " ubi.mtd=rootfs,2048 rootfstype=squashfs loglevel=8 ubi.block=0,rootfs ro init=/etc/preinit";
};
memory@80000000 {
device_type = "memory";
reg = <0x0 0x80000000 0x2 0x00000000>;
};
leds {
compatible = "gpio-leds";
led-0 {
label = "pwr";
color = <0x01>;
function = "power";
gpios = <0x24 0x11 0x01>;
default-state = "on";
};
led-2 {
label = "pon";
color = <0x02>;
function = "status";
gpios = <0x24 0x13 0x01>;
default-state = "off";
};
led-3 {
label = "internet";
color = <0x02>;
function = "status";
gpios = <0x24 0x14 0x01>;
default-state = "on";
};
};
};
&en7581_pinctrl {
gpio-ranges = <&en7581_pinctrl 0 13 47>;
mdio_pins: mdio-pins {
mux {
function = "mdio";
groups = "mdio";
};
conf {
pins = "gpio2";
output-high;
};
};
pcie0_rst_pins: pcie0-rst-pins {
conf {
pins = "pcie_reset0";
drive-open-drain = <1>;
};
};
pcie1_rst_pins: pcie1-rst-pins {
conf {
pins = "pcie_reset1";
drive-open-drain = <1>;
};
};
gswp1_led0_pins: gswp1-led0-pins {
mux {
function = "phy1_led0";
pins = "gpio33";
};
};
gswp2_led0_pins: gswp2-led0-pins {
mux {
function = "phy2_led0";
pins = "gpio34";
};
};
gswp3_led0_pins: gswp3-led0-pins {
mux {
function = "phy3_led0";
pins = "gpio35";
};
};
gswp4_led0_pins: gswp4-led0-pins {
mux {
function = "phy4_led0";
pins = "gpio42";
};
};
pwm_gpio18_idx10_pins: pwm-gpio18-idx10-pins {
function = "pwm";
pins = "gpio18";
output-enable;
};
};
&snfi {
status = "okay";
};
&spi_nand {
#address-cells = <1>;
#size-cells = <1>;
partitions {
compatible = "fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;
partition@0 {
label = "bootloader";
reg = <0x0 0x00080000>;
read-only;
};
partition@80000 {
label = "env";
reg = <0x00080000 0x00080000>;
};
partition@100000 {
label = "ubi";
reg = <0x00100000 0x00>;
};
};
};
&i2c0 {
status = "okay";
};
&npu {
status = "okay";
};
&eth {
status = "okay";
};
&gdm1 {
status = "okay";
};
&gdm4 {
status = "okay";
phy-handle = <&phy15>;
phy-mode = "2500base-x";
label = "lan1";
};
&switch {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&mdio_pins>;
ports {
port@2 {
status = "okay";
label = "lan2";
};
port@3 {
status = "okay";
label = "lan3";
};
port@4 {
status = "okay";
label = "lan4";
};
};
mdio {
ethernet-phy@1 {
status = "okay";
pinctrl-names = "gbe-led";
pinctrl-0 = <&gswp2_led0_pins>;
leds {
gsw-phy1-led0@0 {
reg = <0x00>;
function = LED_FUNCTION_LAN;
status = "okay";
active-low;
};
};
};
ethernet-phy@2 {
status = "okay";
pinctrl-names = "gbe-led";
pinctrl-0 = <&gswp3_led0_pins>;
leds {
gsw-phy2-led0@0 {
reg = <0x00>;
function = LED_FUNCTION_LAN;
status = "okay";
active-low;
};
};
};
ethernet-phy@3 {
status = "okay";
pinctrl-names = "gbe-led";
pinctrl-0 = <&gswp4_led0_pins>;
leds {
gsw-phy3-led0@0 {
reg = <0x00>;
function = LED_FUNCTION_LAN;
status = "okay";
active-low;
};
};
};
phy15: ethernet-phy@f {
/* Airoha EN8811H */
compatible = "ethernet-phy-id03a2.a411", "ethernet-phy-ieee802.3-c45";
reg = <15>;
phy-mode = "2500base-x";
phandle = <0x38>;
};
};
};
+3 -153
View File
@@ -3,9 +3,6 @@
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/clock/en7523-clk.h>
#include <dt-bindings/phy/phy.h>
#include <dt-bindings/phy/airoha,an7581-usb-phy.h>
#include <dt-bindings/soc/airoha,scu-ssr.h>
#include <dt-bindings/reset/airoha,en7581-reset.h>
#include <dt-bindings/leds/common.h>
#include <dt-bindings/thermal/thermal.h>
@@ -441,48 +438,6 @@
status = "disabled";
};
pon_pcs: pcs@1fa08000 {
compatible = "airoha,an7581-pcs-pon";
reg = <0x0 0x1fa08000 0x0 0x1000>,
<0x0 0x1fa80000 0x0 0x60>,
<0x0 0x1fa80a00 0x0 0x164>,
<0x0 0x1fa84000 0x0 0x450>,
<0x0 0x1fa85900 0x0 0x338>,
<0x0 0x1fa86000 0x0 0x300>,
<0x0 0x1fa8a000 0x0 0x1000>,
<0x0 0x1fa8b000 0x0 0x1000>;
reg-names = "xfi_mac", "hsgmii_an", "hsgmii_pcs",
"multi_sgmii", "usxgmii",
"hsgmii_rate_adp", "xfi_ana", "xfi_pma";
resets = <&scuclk EN7581_XPON_MAC_RST>,
<&scuclk EN7581_XPON_PHY_RST>;
reset-names = "mac", "phy";
airoha,scu = <&scuclk>;
};
eth_pcs: pcs@1fa09000 {
compatible = "airoha,an7581-pcs-eth";
reg = <0x0 0x1fa09000 0x0 0x1000>,
<0x0 0x1fa70000 0x0 0x60>,
<0x0 0x1fa70a00 0x0 0x164>,
<0x0 0x1fa74000 0x0 0x450>,
<0x0 0x1fa75900 0x0 0x338>,
<0x0 0x1fa76000 0x0 0x300>,
<0x0 0x1fa7a000 0x0 0x1000>,
<0x0 0x1fa7b000 0x0 0x1000>;
reg-names = "xfi_mac", "hsgmii_an", "hsgmii_pcs",
"multi_sgmii", "usxgmii",
"hsgmii_rate_adp", "xfi_ana", "xfi_pma";
resets = <&scuclk EN7581_XSI_MAC_RST>,
<&scuclk EN7581_XSI_PHY_RST>;
reset-names = "mac", "phy";
airoha,scu = <&scuclk>;
};
chip_scu: syscon@1fa20000 {
compatible = "airoha,en7581-chip-scu", "syscon";
reg = <0x0 0x1fa20000 0x0 0x388>;
@@ -493,8 +448,8 @@
reg = <0x0 0x1fbe3400 0x0 0xff>;
};
scuclk: clock-controller@1fb00000 {
compatible = "airoha,en7581-scu", "syscon";
scuclk: clock-controller@1fa20000 {
compatible = "airoha,en7581-scu";
reg = <0x0 0x1fb00000 0x0 0x970>;
#clock-cells = <1>;
#reset-cells = <1>;
@@ -506,52 +461,6 @@
interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
};
usb0: usb@1fab0000 {
compatible = "mediatek,mtk-xhci";
reg = <0x0 0x1fab0000 0x0 0x3e00>,
<0x0 0x1fab3e00 0x0 0x100>;
reg-names = "mac", "ippc";
interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
phys = <&usb0_phy PHY_TYPE_USB2>, <&usb0_phy PHY_TYPE_USB3>;
status = "disabled";
};
usb0_phy: phy@1fac0000 {
compatible = "airoha,an7581-usb-phy";
reg = <0x0 0x1fac0000 0x0 0x10000>;
airoha,scu = <&scuclk>;
airoha,usb2-monitor-clk-sel = <AIROHA_USB2_MONCLK_SEL1>;
airoha,serdes-port = <AIROHA_SCU_SERDES_USB1>;
#phy-cells = <1>;
};
usb1: usb@1fad0000 {
compatible = "mediatek,mtk-xhci";
reg = <0x0 0x1fad0000 0x0 0x3e00>,
<0x0 0x1fad3e00 0x0 0x100>;
reg-names = "mac", "ippc";
interrupts = <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>;
phys = <&usb1_phy PHY_TYPE_USB2>, <&usb1_phy PHY_TYPE_USB3>;
status = "disabled";
};
usb1_phy: phy@1fae0000 {
compatible = "airoha,an7581-usb-phy";
reg = <0x0 0x1fae0000 0x0 0x10000>;
airoha,scu = <&scuclk>;
airoha,usb2-monitor-clk-sel = <AIROHA_USB2_MONCLK_SEL2>;
airoha,serdes-port = <AIROHA_SCU_SERDES_USB2>;
#phy-cells = <1>;
};
crypto@1e004000 {
compatible = "inside-secure,safexcel-eip93ies";
reg = <0x0 0x1fb70000 0x0 0x1000>;
@@ -767,49 +676,6 @@
};
};
pcie2: pcie@1fc40000 {
compatible = "airoha,en7581-pcie";
device_type = "pci";
linux,pci-domain = <2>;
#address-cells = <3>;
#size-cells = <2>;
reg = <0x0 0x1fc40000 0x0 0x1670>;
reg-names = "pcie-mac";
clocks = <&scuclk EN7523_CLK_PCIE>;
clock-names = "sys-ck";
phys = <&usb1_phy PHY_TYPE_USB3>;
phy-names = "pcie-phy";
ranges = <0x02000000 0 0x28000000 0x0 0x28000000 0 0x4000000>;
resets = <&scuclk EN7581_PCIE0_RST>,
<&scuclk EN7581_PCIE1_RST>,
<&scuclk EN7581_PCIE2_RST>;
reset-names = "phy-lane0", "phy-lane1", "phy-lane2";
mediatek,pbus-csr = <&pbus_csr 0x10 0x14>;
interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
bus-range = <0x00 0xff>;
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 7>;
interrupt-map = <0 0 0 1 &pcie_intc2 0>,
<0 0 0 2 &pcie_intc2 1>,
<0 0 0 3 &pcie_intc2 2>,
<0 0 0 4 &pcie_intc2 3>;
status = "disabled";
pcie_intc2: interrupt-controller {
interrupt-controller;
#address-cells = <0>;
#interrupt-cells = <1>;
};
};
npu: npu@1e900000 {
compatible = "airoha,en7581-npu";
reg = <0x0 0x1e900000 0x0 0x313000>;
@@ -887,22 +753,6 @@
pause;
};
};
gdm2: ethernet@2 {
compatible = "airoha,eth-mac";
reg = <2>;
pcs = <&pon_pcs>;
status = "disabled";
};
gdm4: ethernet@4 {
compatible = "airoha,eth-mac";
reg = <4>;
pcs = <&eth_pcs>;
status = "disabled";
};
};
switch: switch@1fb58000 {
@@ -966,7 +816,7 @@
};
};
mdio: mdio {
mdio {
#address-cells = <1>;
#size-cells = <0>;
@@ -1,297 +0,0 @@
// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
/dts-v1/;
#include <dt-bindings/leds/common.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include "an7583.dtsi"
/ {
model = "Airoha AN7583 Evaluation Board";
compatible = "airoha,an7583-evb", "airoha,an7583", "airoha,en7583";
aliases {
serial0 = &uart1;
};
chosen {
bootargs = "console=ttyS0,115200 earlycon";
stdout-path = "serial0:115200n8";
};
memory@80000000 {
device_type = "memory";
reg = <0x0 0x80000000 0x2 0x00000000>;
};
gpio-keys-polled {
compatible = "gpio-keys-polled";
poll-interval = <100>;
btn-reset {
label = "reset";
linux,code = <BTN_0>;
gpios = <&an7583_pinctrl 0 GPIO_ACTIVE_LOW>;
};
};
leds {
compatible = "gpio-leds";
led-1 {
label = "pon";
color = <LED_COLOR_ID_GREEN>;
function = LED_FUNCTION_STATUS;
gpios = <&an7583_pinctrl 12 GPIO_ACTIVE_LOW>;
};
led-2 {
label = "internet";
color = <LED_COLOR_ID_GREEN>;
function = LED_FUNCTION_STATUS;
gpios = <&an7583_pinctrl 26 GPIO_ACTIVE_LOW>;
};
led-3 {
label = "wps";
color = <LED_COLOR_ID_GREEN>;
function = LED_FUNCTION_STATUS;
gpios = <&an7583_pinctrl 31 GPIO_ACTIVE_LOW>;
};
led-4 {
label = "los";
color = <LED_COLOR_ID_RED>;
function = LED_FUNCTION_STATUS;
gpios = <&an7583_pinctrl 27 GPIO_ACTIVE_LOW>;
};
led-5 {
label = "voip_hook";
color = <LED_COLOR_ID_GREEN>;
function = LED_FUNCTION_STATUS;
gpios = <&an7583_pinctrl 29 GPIO_ACTIVE_LOW>;
};
};
};
&an7583_pinctrl {
gpio-ranges = <&an7583_pinctrl 0 2 53>;
mdio0_pins: mdio0-pins {
conf {
pins = "mdio_0";
output-high;
};
};
pcie0_rst_pins: pcie0-rst-pins {
conf {
pins = "pcie_reset0";
drive-open-drain = <1>;
};
};
pcie1_rst_pins: pcie1-rst-pins {
conf {
pins = "pcie_reset1";
drive-open-drain = <1>;
};
};
gswp1_led0_pins: gswp1-led0-pins {
mux {
function = "phy1_led0";
pins = "gpio1";
};
};
gswp2_led0_pins: gswp2-led0-pins {
mux {
function = "phy2_led0";
pins = "gpio2";
};
};
gswp3_led0_pins: gswp3-led0-pins {
mux {
function = "phy3_led0";
pins = "gpio3";
};
};
gswp4_led0_pins: gswp4-led0-pins {
mux {
function = "phy4_led0";
pins = "gpio4";
};
};
mmc_pins: mmc-pins {
mux {
function = "emmc";
groups = "emmc";
};
};
};
&mmc0 {
pinctrl-names = "default", "state_uhs";
pinctrl-0 = <&mmc_pins>;
pinctrl-1 = <&mmc_pins>;
status = "okay";
#address-cells = <1>;
#size-cells = <0>;
card@0 {
compatible = "mmc-card";
reg = <0>;
block {
compatible = "block-device";
partitions {
block-partition-factory {
partname = "art";
nvmem-layout {
compatible = "fixed-layout";
#address-cells = <1>;
#size-cells = <1>;
eeprom_factory_0: eeprom@0 {
reg = <0x40000 0x1e00>;
};
mac_factory_2c0000: mac@2c0000 {
reg = <0x2c0000 0x6>;
};
pon_mac_factory_2c0006: pon_mac@2c0006 {
reg = <0x2c0006 0x6>;
};
onu_type_factory_2e0000: onu_type@2e0000 {
reg = <0x2e0000 0x10>;
};
board_config_factory_2e0010: board_config@2e0010 {
reg = <0x2e0010 0x8>;
};
};
};
};
};
};
};
&i2c0 {
status = "okay";
};
&i2c1 {
status = "okay";
};
&mdio_0 {
pinctrl-names = "default";
pinctrl-0 = <&mdio0_pins>;
en8811: ethernet-phy@f {
reg = <0xf>;
reset-gpios = <&an7583_pinctrl 28 GPIO_ACTIVE_LOW>;
reset-assert-us = <10000>;
reset-deassert-us = <20000>;
leds {
#address-cells = <1>;
#size-cells = <0>;
led@0 {
reg = <0>;
function = LED_FUNCTION_LAN;
color = <LED_COLOR_ID_GREEN>;
function-enumerator = <0>;
default-state = "keep";
};
led@1 {
reg = <1>;
function = LED_FUNCTION_LAN;
color = <LED_COLOR_ID_GREEN>;
function-enumerator = <1>;
default-state = "keep";
};
};
};
};
&npu {
status = "okay";
};
&eth {
status = "okay";
nvmem-cells = <&mac_factory_2c0000>;
nvmem-cell-names = "mac";
};
&gdm1 {
status = "okay";
};
&gdm3 {
status = "okay";
phy-handle = <&en8811>;
phy-mode = "2500base-x";
};
&switch {
status = "okay";
};
&gsw_phy1 {
pinctrl-names = "gbe-led";
pinctrl-0 = <&gswp1_led0_pins>;
status = "okay";
};
&gsw_phy1_led0 {
status = "okay";
active-low;
};
&gsw_phy2 {
pinctrl-names = "gbe-led";
pinctrl-0 = <&gswp2_led0_pins>;
status = "okay";
};
&gsw_phy2_led0 {
status = "okay";
active-low;
};
&gsw_phy3 {
pinctrl-names = "gbe-led";
pinctrl-0 = <&gswp3_led0_pins>;
status = "okay";
};
&gsw_phy3_led0 {
status = "okay";
active-low;
};
&gsw_phy4 {
pinctrl-names = "gbe-led";
pinctrl-0 = <&gswp4_led0_pins>;
status = "okay";
};
&gsw_phy4_led0 {
status = "okay";
active-low;
};
-226
View File
@@ -1,226 +0,0 @@
// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
/dts-v1/;
#include <dt-bindings/leds/common.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include "an7583.dtsi"
/ {
model = "Airoha AN7583 Evaluation Board";
compatible = "airoha,an7583-evb", "airoha,an7583", "airoha,en7583";
aliases {
serial0 = &uart1;
};
chosen {
bootargs = "console=ttyS0,115200 earlycon";
stdout-path = "serial0:115200n8";
};
memory@80000000 {
device_type = "memory";
reg = <0x0 0x80000000 0x2 0x00000000>;
};
};
&an7583_pinctrl {
gpio-ranges = <&an7583_pinctrl 0 2 53>;
mdio0_pins: mdio0-pins {
conf {
pins = "mdio_0";
output-high;
};
};
pcie0_rst_pins: pcie0-rst-pins {
conf {
pins = "pcie_reset0";
drive-open-drain = <1>;
};
};
pcie1_rst_pins: pcie1-rst-pins {
conf {
pins = "pcie_reset1";
drive-open-drain = <1>;
};
};
gswp1_led0_pins: gswp1-led0-pins {
mux {
function = "phy1_led0";
pins = "gpio1";
};
};
};
&snfi {
status = "okay";
};
&spi_nand {
partitions {
compatible = "fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;
bl2@0 {
label = "bl2";
reg = <0x0 0x20000>;
};
ubi@20000 {
label = "ubi";
reg = <0x20000 0x0>;
};
};
};
&i2c0 {
status = "okay";
};
&npu {
status = "okay";
};
&eth {
status = "okay";
};
&gdm1 {
status = "okay";
};
&switch {
status = "okay";
};
&gsw_phy1 {
pinctrl-names = "gbe-led";
pinctrl-0 = <&gswp1_led0_pins>;
status = "okay";
};
&gsw_phy1_led0 {
status = "okay";
active-low;
};
&gsw_port2 {
status = "disabled";
};
&gsw_port3 {
status = "disabled";
};
&gsw_port4 {
status = "disabled";
};
&gsw_phy2 {
status = "disabled";
};
&gsw_phy3 {
status = "disabled";
};
&gsw_phy4 {
status = "disabled";
};
&mdio_0 {
pinctrl-names = "default";
pinctrl-0 = <&mdio0_pins>;
/* Present but not HW connected to GDM port */
/*
* as21xx_0: ethernet-phy@1d {
* reg = <0x1d>;
* compatible = "ethernet-phy-ieee802.3-c45";
* status = "disabled";
*
* firmware-name = "as21x1x_fw.bin";
*
* reset-deassert-us = <350000>;
* reset-assert-us = <200000>;
* reset-gpios = <&an7583_pinctrl 34 GPIO_ACTIVE_LOW>;
*
* leds {
* #address-cells = <1>;
* #size-cells = <0>;
*
* led@0 {
* reg = <0>;
* color = <LED_COLOR_ID_GREEN>;
* function = LED_FUNCTION_LAN;
* function-enumerator = <0>;
* default-state = "keep";
* };
*
* led@1 {
* reg = <1>;
* color = <LED_COLOR_ID_GREEN>;
* function = LED_FUNCTION_LAN;
* function-enumerator = <1>;
* default-state = "keep";
* };
* };
* };
*/
as21xx_1: ethernet-phy@1f {
reg = <0x1f>;
compatible = "ethernet-phy-ieee802.3-c45";
firmware-name = "as21x1x_fw.bin";
reset-deassert-us = <350000>;
reset-assert-us = <200000>;
reset-gpios = <&an7583_pinctrl 35 GPIO_ACTIVE_LOW>;
leds {
#address-cells = <1>;
#size-cells = <0>;
led@0 {
reg = <0>;
color = <LED_COLOR_ID_GREEN>;
function = LED_FUNCTION_LAN;
function-enumerator = <0>;
default-state = "keep";
};
led@1 {
reg = <1>;
color = <LED_COLOR_ID_GREEN>;
function = LED_FUNCTION_LAN;
function-enumerator = <1>;
default-state = "keep";
};
};
};
};
/* GDM2 seems to be connected to PON */
/*
*&gdm2 {
* status = "disabled";
*
* phy-handle = <&as21xx_0>;
* phy-mode = "usxgmii";
*};
*/
&gdm3 {
status = "okay";
phy-handle = <&as21xx_1>;
phy-mode = "usxgmii";
};
-844
View File
@@ -1,844 +0,0 @@
// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/clock/en7523-clk.h>
#include <dt-bindings/phy/phy.h>
#include <dt-bindings/reset/airoha,an7583-reset.h>
#include <dt-bindings/leds/common.h>
#include <dt-bindings/thermal/thermal.h>
/ {
interrupt-parent = <&gic>;
#address-cells = <2>;
#size-cells = <2>;
reserved-memory {
#address-cells = <2>;
#size-cells = <2>;
ranges;
atf@80000000 {
no-map;
reg = <0x0 0x80000000 0x0 0x200000>;
};
npu_binary: npu-binary@84000000 {
no-map;
reg = <0x0 0x84000000 0x0 0xa00000>;
};
qdma0_buf: qdma0-buf@87000000 {
no-map;
reg = <0x0 0x87000000 0x0 0x2000000>;
};
qdma1_buf: qdma1-buf@89000000 {
no-map;
reg = <0x0 0x89000000 0x0 0x1000000>;
};
};
psci {
compatible = "arm,psci-1.0";
method = "smc";
};
cpus {
#address-cells = <1>;
#size-cells = <0>;
cpu-map {
cluster0 {
core0 {
cpu = <&cpu0>;
};
core1 {
cpu = <&cpu1>;
};
};
};
cpu0: cpu@0 {
device_type = "cpu";
compatible = "arm,cortex-a53";
reg = <0x0>;
operating-points-v2 = <&cpu_opp_table>;
enable-method = "psci";
clocks = <&cpufreq>;
clock-names = "cpu";
power-domains = <&cpufreq>;
power-domain-names = "perf";
next-level-cache = <&l2>;
#cooling-cells = <2>;
};
cpu1: cpu@1 {
device_type = "cpu";
compatible = "arm,cortex-a53";
reg = <0x1>;
operating-points-v2 = <&cpu_opp_table>;
enable-method = "psci";
clocks = <&cpufreq>;
clock-names = "cpu";
power-domains = <&cpufreq>;
power-domain-names = "perf";
next-level-cache = <&l2>;
#cooling-cells = <2>;
};
l2: l2-cache {
compatible = "cache";
cache-size = <0x80000>;
cache-line-size = <64>;
cache-level = <2>;
cache-unified;
};
};
cpufreq: cpufreq {
compatible = "airoha,en7581-cpufreq";
operating-points-v2 = <&cpu_smcc_opp_table>;
#power-domain-cells = <0>;
#clock-cells = <0>;
};
cpu_opp_table: opp-table {
compatible = "operating-points-v2";
opp-shared;
opp-500000000 {
opp-hz = /bits/ 64 <500000000>;
required-opps = <&smcc_opp0>;
};
opp-550000000 {
opp-hz = /bits/ 64 <550000000>;
required-opps = <&smcc_opp1>;
};
opp-600000000 {
opp-hz = /bits/ 64 <600000000>;
required-opps = <&smcc_opp2>;
};
opp-650000000 {
opp-hz = /bits/ 64 <650000000>;
required-opps = <&smcc_opp3>;
};
opp-7000000000 {
opp-hz = /bits/ 64 <700000000>;
required-opps = <&smcc_opp4>;
};
opp-7500000000 {
opp-hz = /bits/ 64 <750000000>;
required-opps = <&smcc_opp5>;
};
opp-8000000000 {
opp-hz = /bits/ 64 <800000000>;
required-opps = <&smcc_opp6>;
};
opp-8500000000 {
opp-hz = /bits/ 64 <850000000>;
required-opps = <&smcc_opp7>;
};
opp-9000000000 {
opp-hz = /bits/ 64 <900000000>;
required-opps = <&smcc_opp8>;
};
opp-9500000000 {
opp-hz = /bits/ 64 <950000000>;
required-opps = <&smcc_opp9>;
};
opp-10000000000 {
opp-hz = /bits/ 64 <1000000000>;
required-opps = <&smcc_opp10>;
};
opp-10500000000 {
opp-hz = /bits/ 64 <1050000000>;
required-opps = <&smcc_opp11>;
};
opp-11000000000 {
opp-hz = /bits/ 64 <1100000000>;
required-opps = <&smcc_opp12>;
};
opp-11500000000 {
opp-hz = /bits/ 64 <1150000000>;
required-opps = <&smcc_opp13>;
};
opp-12000000000 {
opp-hz = /bits/ 64 <1200000000>;
required-opps = <&smcc_opp14>;
};
};
cpu_smcc_opp_table: opp-table-cpu-smcc {
compatible = "operating-points-v2";
smcc_opp0: opp0 {
opp-level = <0>;
};
smcc_opp1: opp1 {
opp-level = <1>;
};
smcc_opp2: opp2 {
opp-level = <2>;
};
smcc_opp3: opp3 {
opp-level = <3>;
};
smcc_opp4: opp4 {
opp-level = <4>;
};
smcc_opp5: opp5 {
opp-level = <5>;
};
smcc_opp6: opp6 {
opp-level = <6>;
};
smcc_opp7: opp7 {
opp-level = <7>;
};
smcc_opp8: opp8 {
opp-level = <8>;
};
smcc_opp9: opp9 {
opp-level = <9>;
};
smcc_opp10: opp10 {
opp-level = <10>;
};
smcc_opp11: opp11 {
opp-level = <11>;
};
smcc_opp12: opp12 {
opp-level = <12>;
};
smcc_opp13: opp13 {
opp-level = <13>;
};
smcc_opp14: opp14 {
opp-level = <14>;
};
};
timer {
compatible = "arm,armv8-timer";
interrupt-parent = <&gic>;
interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
<GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
<GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
<GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
};
thermal-zones {
cpu_thermal: cpu-thermal {
polling-delay-passive = <10000>;
polling-delay = <5000>;
thermal-sensors = <&thermal 0>;
trips {
cpu_hot: cpu-hot {
temperature = <95000>;
hysteresis = <1000>;
type = "hot";
};
cpu-critical {
temperature = <110000>;
hysteresis = <1000>;
type = "critical";
};
};
cooling-maps {
map0 {
trip = <&cpu_hot>;
cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
<&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
};
};
};
};
clk25m: oscillator {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <25000000>;
clock-output-names = "clkxtal";
};
sys_hclk: clk-oscillator-100mhz {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <100000000>;
clock-output-names = "sys_hclk";
};
vmmc_3v3: regulator-vmmc-3v3 {
compatible = "regulator-fixed";
regulator-name = "vmmc";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-always-on;
};
sfp1: sfp1 {
compatible = "sff,sfp";
};
sfp2: sfp2 {
compatible = "sff,sfp";
};
soc {
compatible = "simple-bus";
#address-cells = <2>;
#size-cells = <2>;
ranges;
gic: interrupt-controller@9000000 {
compatible = "arm,gic-v3";
interrupt-controller;
#interrupt-cells = <3>;
#address-cells = <1>;
#size-cells = <1>;
reg = <0x0 0x09000000 0x0 0x20000>,
<0x0 0x09080000 0x0 0x80000>,
<0x0 0x09400000 0x0 0x2000>,
<0x0 0x09500000 0x0 0x2000>,
<0x0 0x09600000 0x0 0x20000>;
interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_LOW>;
};
chip_scu: syscon@1fa20000 {
compatible = "airoha,en7581-chip-scu", "syscon", "simple-mfd";
reg = <0x0 0x1fa20000 0x0 0x388>;
thermal: thermal {
compatible = "airoha,an7583-thermal";
#thermal-sensor-cells = <0>;
};
};
pbus_csr: syscon@1fbe3400 {
compatible = "airoha,en7581-pbus-csr", "syscon";
reg = <0x0 0x1fbe3400 0x0 0xff>;
};
scuclk: system-controller@1fa20000 {
compatible = "airoha,an7583-scu", "syscon";
reg = <0x0 0x1fb00000 0x0 0x970>;
#address-cells = <1>;
#size-cells = <0>;
#clock-cells = <1>;
#reset-cells = <1>;
airoha,chip-scu = <&chip_scu>;
mdio_0: mdio-bus@c8 {
compatible = "airoha,an7583-mdio";
reg = <0xc8>;
clocks = <&scuclk AN7583_CLK_MDIO0>;
resets = <&scuclk AN7583_MDIO0>;
};
mdio_1: mdio-bus@cc {
compatible = "airoha,an7583-mdio";
reg = <0xcc>;
clocks = <&scuclk AN7583_CLK_MDIO1>;
resets = <&scuclk AN7583_MDIO1>;
};
};
system-controller@1fbf0200 {
compatible = "syscon", "simple-mfd";
reg = <0x0 0x1fbf0200 0x0 0xc0>;
an7583_pinctrl: pinctrl {
compatible = "airoha,an7583-pinctrl";
interrupt-parent = <&gic>;
interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
};
};
i2cclock: i2cclock@0 {
#clock-cells = <0>;
compatible = "fixed-clock";
/* 20 MHz */
clock-frequency = <20000000>;
};
i2c0: i2c0@1fbf8000 {
compatible = "airoha,an7581-i2c";
reg = <0x0 0x1fbf8000 0x0 0x100>;
clocks = <&i2cclock>;
/* 100 kHz */
clock-frequency = <100000>;
#address-cells = <1>;
#size-cells = <0>;
status = "disable"
};
i2c1: i2c1@1fbf8100 {
compatible = "airoha,an7581-i2c";
reg = <0x0 0x1fbf8100 0x0 0x100>;
clocks = <&i2cclock>;
/* 100 kHz */
clock-frequency = <100000>;
#address-cells = <1>;
#size-cells = <0>;
status = "disable"
};
mmc0: mmc@1fa0e000 {
compatible = "mediatek,mt7622-mmc";
reg = <0x0 0x1fa0e000 0x0 0x1000>,
<0x0 0x1fa0c000 0x0 0x60>;
interrupts = <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&scuclk EN7581_CLK_EMMC>, <&clk25m>;
clock-names = "source", "hclk";
bus-width = <4>;
max-frequency = <52000000>;
vmmc-supply = <&vmmc_3v3>;
disable-wp;
cap-mmc-highspeed;
non-removable;
status = "disabled";
};
snfi: spi@1fa10000 {
compatible = "airoha,en7581-snand";
reg = <0x0 0x1fa10000 0x0 0x140>,
<0x0 0x1fa11000 0x0 0x160>;
clocks = <&scuclk EN7523_CLK_SPI>;
clock-names = "spi";
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
spi_nand: nand@0 {
compatible = "spi-nand";
reg = <0>;
spi-max-frequency = <50000000>;
spi-tx-bus-width = <1>;
spi-rx-bus-width = <2>;
};
};
uart1: serial@1fbf0000 {
compatible = "ns16550";
reg = <0x0 0x1fbf0000 0x0 0x30>;
reg-io-width = <4>;
reg-shift = <2>;
interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
clock-frequency = <1843200>;
};
watchdog@1fbf0100 {
compatible = "airoha,en7581-wdt";
reg = <0x0 0x1fbf0100 0x0 0x38>;
clocks = <&sys_hclk>;
clock-names = "bus";
};
uart2: serial@1fbf0300 {
compatible = "airoha,en7523-uart";
reg = <0x0 0x1fbf0300 0x0 0x30>;
reg-io-width = <4>;
reg-shift = <2>;
interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
clock-frequency = <7372800>;
status = "disabled";
};
hsuart3: serial@1fbe1000 {
compatible = "airoha,en7523-uart";
reg = <0x0 0x1fbe1000 0x0 0x40>;
reg-io-width = <4>;
reg-shift = <2>;
interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
clock-frequency = <7372800>;
status = "disabled";
};
uart4: serial@1fbf0600 {
compatible = "airoha,en7523-uart";
reg = <0x0 0x1fbf0600 0x0 0x30>;
reg-io-width = <4>;
reg-shift = <2>;
interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
clock-frequency = <7372800>;
status = "disabled";
};
uart5: serial@1fbf0700 {
compatible = "airoha,en7523-uart";
reg = <0x0 0x1fbf0700 0x0 0x30>;
reg-io-width = <4>;
reg-shift = <2>;
interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
clock-frequency = <7372800>;
status = "disabled";
};
crypto@1e004000 {
compatible = "inside-secure,safexcel-eip93ies";
reg = <0x0 0x1fb70000 0x0 0x1000>;
interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
};
npu: npu@1e900000 {
compatible = "airoha,an7583-npu";
reg = <0x0 0x1e900000 0x0 0x313000>;
interrupts = <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
memory-region = <&npu_binary>;
memory-region-names = "binary";
status = "disabled";
};
pon_pcs: pcs@1fa08000 {
compatible = "airoha,an7583-pcs-pon";
reg = <0x0 0x1fa08000 0x0 0x1000>,
<0x0 0x1fa80000 0x0 0x60>,
<0x0 0x1fa80a00 0x0 0x164>,
<0x0 0x1fa84000 0x0 0x450>,
<0x0 0x1fa85900 0x0 0x338>,
<0x0 0x1fa86000 0x0 0x300>,
<0x0 0x1fa8f000 0x0 0x1000>,
<0x0 0x1fa8e000 0x0 0x1000>;
reg-names = "xfi_mac", "hsgmii_an", "hsgmii_pcs",
"multi_sgmii", "usxgmii",
"hsgmii_rate_adp", "xfi_ana", "xfi_pma";
resets = <&scuclk AN7583_XPON_MAC_RST>,
<&scuclk AN7583_XPON_PHY_RST>,
<&scuclk AN7583_XPON_XFI_RST>;
reset-names = "mac", "phy", "xfi";
airoha,scu = <&scuclk>;
};
eth_pcs: pcs@1fa09000 {
compatible = "airoha,an7583-pcs-eth";
reg = <0x0 0x1fa09000 0x0 0x1000>,
<0x0 0x1fa70000 0x0 0x60>,
<0x0 0x1fa70a00 0x0 0x164>,
<0x0 0x1fa74000 0x0 0x450>,
<0x0 0x1fa75900 0x0 0x338>,
<0x0 0x1fa76000 0x0 0x300>,
<0x0 0x1fa7f000 0x0 0x1000>,
<0x0 0x1fa7e000 0x0 0x1000>;
reg-names = "xfi_mac", "hsgmii_an", "hsgmii_pcs",
"multi_sgmii", "usxgmii",
"hsgmii_rate_adp", "xfi_ana", "xfi_pma";
resets = <&scuclk AN7583_XSI_MAC_RST>,
<&scuclk AN7583_XSI_PHY_RST>;
reset-names = "mac", "phy";
airoha,scu = <&scuclk>;
};
eth: ethernet@1fb50000 {
compatible = "airoha,an7583-eth";
reg = <0 0x1fb50000 0 0x2600>,
<0 0x1fb54000 0 0x2000>,
<0 0x1fb56000 0 0x2000>;
reg-names = "fe", "qdma0", "qdma1";
resets = <&scuclk AN7583_FE_RST>,
<&scuclk AN7583_FE_PDMA_RST>,
<&scuclk AN7583_FE_QDMA_RST>,
<&scuclk AN7583_DUAL_HSI0_MAC_RST>,
<&scuclk AN7583_DUAL_HSI1_MAC_RST>,
<&scuclk AN7583_XFP_MAC_RST>;
reset-names = "fe", "pdma", "qdma",
"hsi0-mac", "hsi1-mac",
"xfp-mac";
interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
memory-region = <&qdma0_buf>, <&qdma1_buf>;
memory-region-names = "qdma0-buf", "qdma1-buf";
airoha,npu = <&npu>;
status = "disabled";
#address-cells = <1>;
#size-cells = <0>;
gdm1: ethernet@1 {
compatible = "airoha,eth-mac";
reg = <1>;
phy-mode = "internal";
status = "disabled";
fixed-link {
speed = <10000>;
full-duplex;
pause;
};
};
gdm2: ethernet@2 {
compatible = "airoha,eth-mac";
reg = <2>;
pcs = <&pon_pcs>;
status = "disabled";
};
gdm3: ethernet@3 {
compatible = "airoha,eth-mac";
reg = <3>;
pcs = <&eth_pcs>;
airoha,gdm-srcport = <0x16>;
status = "disabled";
};
};
switch: switch@1fb58000 {
compatible = "airoha,an7583-switch";
reg = <0 0x1fb58000 0 0x8000>;
resets = <&scuclk AN7583_GSW_RST>;
interrupt-controller;
#interrupt-cells = <1>;
interrupt-parent = <&gic>;
interrupts = <GIC_SPI 209 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
#address-cells = <1>;
#size-cells = <1>;
ports {
#address-cells = <1>;
#size-cells = <0>;
gsw_port1: port@1 {
reg = <1>;
label = "lan1";
phy-mode = "internal";
phy-handle = <&gsw_phy1>;
};
gsw_port2: port@2 {
reg = <2>;
label = "lan2";
phy-mode = "internal";
phy-handle = <&gsw_phy2>;
};
gsw_port3: port@3 {
reg = <3>;
label = "lan3";
phy-mode = "internal";
phy-handle = <&gsw_phy3>;
};
gsw_port4: port@4 {
reg = <4>;
label = "lan4";
phy-mode = "internal";
phy-handle = <&gsw_phy4>;
};
port@6 {
reg = <6>;
label = "cpu";
ethernet = <&gdm1>;
phy-mode = "internal";
fixed-link {
speed = <10000>;
full-duplex;
pause;
};
};
};
mdio: mdio {
#address-cells = <1>;
#size-cells = <0>;
gsw_phy1: ethernet-phy@1 {
compatible = "ethernet-phy-ieee802.3-c22";
reg = <9>;
phy-mode = "internal";
leds {
#address-cells = <1>;
#size-cells = <0>;
gsw_phy1_led0: gsw-phy1-led0@0 {
reg = <0>;
function = "phy1_led0";
status = "disabled";
};
gsw_phy1_led1: gsw-phy1-led1@1 {
reg = <1>;
function = "phy1_led1";
status = "disabled";
};
};
};
gsw_phy2: ethernet-phy@2 {
compatible = "ethernet-phy-ieee802.3-c22";
reg = <10>;
phy-mode = "internal";
leds {
#address-cells = <1>;
#size-cells = <0>;
gsw_phy2_led0: gsw-phy2-led0@0 {
reg = <0>;
function = "phy2_led0";
status = "disabled";
};
gsw_phy2_led1: gsw-phy2-led1@1 {
reg = <1>;
function = "phy1_led1";
status = "disabled";
};
};
};
gsw_phy3: ethernet-phy@3 {
compatible = "ethernet-phy-ieee802.3-c22";
reg = <11>;
phy-mode = "internal";
leds {
#address-cells = <1>;
#size-cells = <0>;
gsw_phy3_led0: gsw-phy3-led0@0 {
reg = <0>;
function = LED_FUNCTION_LAN;
status = "disabled";
};
gsw_phy3_led1: gsw-phy3-led1@1 {
reg = <1>;
function = LED_FUNCTION_LAN;
status = "disabled";
};
};
};
gsw_phy4: ethernet-phy@4 {
compatible = "ethernet-phy-ieee802.3-c22";
reg = <12>;
phy-mode = "internal";
leds {
#address-cells = <1>;
#size-cells = <0>;
gsw_phy4_led0: gsw-phy4-led0@0 {
reg = <0>;
function = LED_FUNCTION_LAN;
status = "disabled";
};
gsw_phy4_led1: gsw-phy4-led1@1 {
reg = <1>;
function = LED_FUNCTION_LAN;
status = "disabled";
};
};
};
};
};
};
};
+5 -12
View File
@@ -4,7 +4,6 @@
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/clock/en7523-clk.h>
#include <dt-bindings/reset/airoha,en7523-reset.h>
/ {
interrupt-parent = <&gic>;
@@ -90,7 +89,6 @@
reg = <0x1fa20000 0x400>,
<0x1fb00000 0x1000>;
#clock-cells = <1>;
#reset-cells = <1>;
};
gic: interrupt-controller@9000000 {
@@ -205,22 +203,17 @@
};
spi_ctrl: spi_controller@1fa10000 {
compatible = "airoha,en7523-snand";
reg = <0x1fa10000 0x140>,
<0x1fa11000 0x160>;
clocks = <&scu EN7523_CLK_SPI>;
clock-names = "spi";
compatible = "airoha,en7523-spi";
reg = <0x1fa10000 0x140>;
#address-cells = <1>;
#size-cells = <0>;
spi-rx-bus-width = <2>;
spi-tx-bus-width = <2>;
nand: nand@0 {
compatible = "spi-nand";
reg = <0>;
spi-max-frequency = <50000000>;
spi-tx-bus-width = <1>;
spi-rx-bus-width = <2>;
nand-ecc-engine = <&nand>;
};
};
};
-402
View File
@@ -1,402 +0,0 @@
CONFIG_64BIT=y
CONFIG_AIROHA_CPU_PM_DOMAIN=y
CONFIG_AIROHA_SCU_SSR=y
CONFIG_AIROHA_THERMAL=y
CONFIG_AIROHA_WATCHDOG=y
CONFIG_AMPERE_ERRATUM_AC03_CPU_38=y
CONFIG_ARCH_AIROHA=y
CONFIG_ARCH_BINFMT_ELF_EXTRA_PHDRS=y
CONFIG_ARCH_CORRECT_STACKTRACE_ON_KRETPROBE=y
CONFIG_ARCH_DEFAULT_KEXEC_IMAGE_VERIFY_SIG=y
CONFIG_ARCH_DMA_ADDR_T_64BIT=y
CONFIG_ARCH_FORCE_MAX_ORDER=10
CONFIG_ARCH_KEEP_MEMBLOCK=y
CONFIG_ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE=y
CONFIG_ARCH_MMAP_RND_BITS=18
CONFIG_ARCH_MMAP_RND_BITS_MAX=24
CONFIG_ARCH_MMAP_RND_BITS_MIN=18
CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11
CONFIG_ARCH_PROC_KCORE_TEXT=y
CONFIG_ARCH_SPARSEMEM_ENABLE=y
CONFIG_ARCH_STACKWALK=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_ARCH_WANTS_NO_INSTR=y
CONFIG_ARCH_WANTS_THP_SWAP=y
CONFIG_ARM64=y
CONFIG_ARM64_4K_PAGES=y
CONFIG_ARM64_ERRATUM_843419=y
CONFIG_ARM64_LD_HAS_FIX_ERRATUM_843419=y
CONFIG_ARM64_PA_BITS=48
CONFIG_ARM64_PA_BITS_48=y
CONFIG_ARM64_PLATFORM_DEVICES=y
CONFIG_ARM64_TAGGED_ADDR_ABI=y
CONFIG_ARM64_VA_BITS=39
CONFIG_ARM64_VA_BITS_39=y
# CONFIG_ARM64_VA_BITS_48 is not set
# CONFIG_ARM64_VA_BITS_52 is not set
CONFIG_ARM_AIROHA_SOC_CPUFREQ=y
CONFIG_ARM_AMBA=y
CONFIG_ARM_ARCH_TIMER=y
CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y
# CONFIG_ARM_DEBUG_WX is not set
CONFIG_ARM_GIC=y
CONFIG_ARM_GIC_V2M=y
CONFIG_ARM_GIC_V3=y
CONFIG_ARM_GIC_V3_ITS=y
CONFIG_ARM_PMU=y
CONFIG_ARM_PMUV3=y
CONFIG_ARM_PSCI_FW=y
CONFIG_ARM_SMCCC_SOC_ID=y
# CONFIG_ARM_SMMU is not set
# CONFIG_ARM_SMMU_V3 is not set
CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y
CONFIG_BLK_MQ_PCI=y
CONFIG_BLK_PM=y
CONFIG_BUFFER_HEAD=y
CONFIG_BUILTIN_RETURN_ADDRESS_STRIPS_PAC=y
CONFIG_CC_HAVE_SHADOW_CALL_STACK=y
CONFIG_CC_HAVE_STACKPROTECTOR_SYSREG=y
CONFIG_CLONE_BACKWARDS=y
CONFIG_COMMON_CLK=y
CONFIG_COMMON_CLK_EN7523=y
CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
# CONFIG_COMPAT_32BIT_TIME is not set
# CONFIG_COMPRESSED_INSTALL is not set
CONFIG_CONTEXT_TRACKING=y
CONFIG_CONTEXT_TRACKING_IDLE=y
CONFIG_CPUFREQ_DT=y
CONFIG_CPUFREQ_DT_PLATDEV=y
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
CONFIG_CPU_FREQ_GOV_ATTR_SET=y
CONFIG_CPU_FREQ_GOV_COMMON=y
CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
CONFIG_CPU_FREQ_GOV_ONDEMAND=y
CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=y
CONFIG_CPU_FREQ_GOV_USERSPACE=y
CONFIG_CPU_FREQ_STAT=y
CONFIG_CPU_LITTLE_ENDIAN=y
CONFIG_CPU_RMAP=y
CONFIG_CRC16=y
CONFIG_CRC_CCITT=y
CONFIG_CRYPTO_CRC32C=y
CONFIG_CRYPTO_DEFLATE=y
CONFIG_CRYPTO_DEV_EIP93=y
CONFIG_CRYPTO_DRBG=y
CONFIG_CRYPTO_DRBG_HMAC=y
CONFIG_CRYPTO_DRBG_MENU=y
CONFIG_CRYPTO_ECB=y
CONFIG_CRYPTO_HASH_INFO=y
CONFIG_CRYPTO_HMAC=y
CONFIG_CRYPTO_JITTERENTROPY=y
CONFIG_CRYPTO_JITTERENTROPY_MEMORY_BLOCKS=64
CONFIG_CRYPTO_JITTERENTROPY_MEMORY_BLOCKSIZE=32
CONFIG_CRYPTO_JITTERENTROPY_OSR=1
CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
CONFIG_CRYPTO_LIB_GF128MUL=y
CONFIG_CRYPTO_LIB_SHA1=y
CONFIG_CRYPTO_LIB_SHA256=y
CONFIG_CRYPTO_LIB_UTILS=y
CONFIG_CRYPTO_LZO=y
CONFIG_CRYPTO_RNG=y
CONFIG_CRYPTO_RNG2=y
CONFIG_CRYPTO_RNG_DEFAULT=y
CONFIG_CRYPTO_SHA256=y
CONFIG_CRYPTO_SHA3=y
CONFIG_CRYPTO_SHA512=y
CONFIG_CRYPTO_ZSTD=y
CONFIG_DCACHE_WORD_ACCESS=y
CONFIG_DEBUG_MISC=y
CONFIG_DMADEVICES=y
CONFIG_DMA_BOUNCE_UNALIGNED_KMALLOC=y
CONFIG_DMA_DIRECT_REMAP=y
CONFIG_DMA_ENGINE=y
CONFIG_DMA_NEED_SYNC=y
CONFIG_DMA_OF=y
CONFIG_DMA_OPS_HELPERS=y
CONFIG_DTC=y
CONFIG_EDAC_SUPPORT=y
CONFIG_EXT4_FS=y
CONFIG_FIXED_PHY=y
CONFIG_FIX_EARLYCON_MEM=y
CONFIG_FRAME_POINTER=y
CONFIG_FS_IOMAP=y
CONFIG_FS_MBCACHE=y
CONFIG_FUNCTION_ALIGNMENT=4
CONFIG_FUNCTION_ALIGNMENT_4B=y
CONFIG_FWNODE_MDIO=y
CONFIG_FW_CACHE=y
# CONFIG_FW_LOADER_USER_HELPER is not set
CONFIG_GCC_SUPPORTS_DYNAMIC_FTRACE_WITH_ARGS=y
CONFIG_GENERIC_ALLOCATOR=y
CONFIG_GENERIC_ARCH_TOPOLOGY=y
CONFIG_GENERIC_BUG=y
CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
CONFIG_GENERIC_CPU_AUTOPROBE=y
CONFIG_GENERIC_CPU_DEVICES=y
CONFIG_GENERIC_CPU_VULNERABILITIES=y
CONFIG_GENERIC_CSUM=y
CONFIG_GENERIC_EARLY_IOREMAP=y
CONFIG_GENERIC_GETTIMEOFDAY=y
CONFIG_GENERIC_IDLE_POLL_SETUP=y
CONFIG_GENERIC_IOREMAP=y
CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
CONFIG_GENERIC_IRQ_SHOW=y
CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y
CONFIG_GENERIC_MSI_IRQ=y
CONFIG_GENERIC_PCI_IOMAP=y
CONFIG_GENERIC_PHY=y
CONFIG_GENERIC_PINCONF=y
CONFIG_GENERIC_PINCTRL_GROUPS=y
CONFIG_GENERIC_PINMUX_FUNCTIONS=y
CONFIG_GENERIC_SCHED_CLOCK=y
CONFIG_GENERIC_SMP_IDLE_THREAD=y
CONFIG_GENERIC_STRNCPY_FROM_USER=y
CONFIG_GENERIC_STRNLEN_USER=y
CONFIG_GENERIC_TIME_VSYSCALL=y
CONFIG_GLOB=y
CONFIG_GPIOLIB_IRQCHIP=y
CONFIG_GPIO_CDEV=y
CONFIG_GPIO_EN7523=y
CONFIG_GPIO_GENERIC=y
CONFIG_GRO_CELLS=y
CONFIG_HARDIRQS_SW_RESEND=y
CONFIG_HAS_DMA=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_IOPORT_MAP=y
CONFIG_HOTPLUG_CORE_SYNC=y
CONFIG_HOTPLUG_CORE_SYNC_DEAD=y
CONFIG_HOTPLUG_CPU=y
CONFIG_HW_RANDOM=y
CONFIG_HW_RANDOM_AIROHA=y
# CONFIG_HISILICON_ERRATUM_162100801 is not set
# CONFIG_IDPF is not set
CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000
CONFIG_INET_AH=y
CONFIG_INET_ESP=y
# CONFIG_INET_ESP_OFFLOAD is not set
CONFIG_INET_IPCOMP=y
CONFIG_INET_TUNNEL=y
CONFIG_INET_XFRM_TUNNEL=y
CONFIG_IO_URING=y
CONFIG_IPC_NS=y
CONFIG_IPV6=y
CONFIG_IPV6_MULTIPLE_TABLES=y
# CONFIG_IPV6_SUBTREES is not set
CONFIG_IP_MROUTE=y
CONFIG_IP_MROUTE_COMMON=y
# CONFIG_IP_MROUTE_MULTIPLE_TABLES is not set
CONFIG_IP_PNP=y
# CONFIG_IP_PNP_BOOTP is not set
# CONFIG_IP_PNP_DHCP is not set
# CONFIG_IP_PNP_RARP is not set
# CONFIG_IP_ROUTE_MULTIPATH is not set
# CONFIG_IP_ROUTE_VERBOSE is not set
CONFIG_IRQCHIP=y
CONFIG_IRQ_DOMAIN=y
CONFIG_IRQ_DOMAIN_HIERARCHY=y
CONFIG_IRQ_FORCED_THREADING=y
CONFIG_IRQ_MSI_LIB=y
CONFIG_IRQ_WORK=y
CONFIG_JBD2=y
CONFIG_LIBFDT=y
CONFIG_LOCK_DEBUGGING_SUPPORT=y
CONFIG_LOCK_SPIN_ON_OWNER=y
CONFIG_LRU_GEN_WALKS_MMU=y
CONFIG_LZO_COMPRESS=y
CONFIG_LZO_DECOMPRESS=y
CONFIG_MDIO_BUS=y
CONFIG_MDIO_DEVICE=y
CONFIG_MDIO_AIROHA=y
CONFIG_MDIO_DEVRES=y
# CONFIG_MEDIATEK_GE_SOC_PHY is not set
# CONFIG_MEMCG is not set
CONFIG_MFD_SYSCON=y
CONFIG_MIGRATION=y
CONFIG_MMC=y
CONFIG_MMC_BLOCK=y
CONFIG_MMC_CQHCI=y
CONFIG_MMC_MTK=y
CONFIG_MMU_LAZY_TLB_REFCOUNT=y
CONFIG_MODULES_TREE_LOOKUP=y
CONFIG_MODULES_USE_ELF_RELA=y
CONFIG_MTD_NAND_CORE=y
CONFIG_MTD_NAND_ECC=y
CONFIG_MTD_NAND_MTK_BMT=y
CONFIG_MTD_RAW_NAND=y
CONFIG_MTD_SPI_NAND=y
CONFIG_MTD_SPLIT_FIRMWARE=y
CONFIG_MTD_SPLIT_FIT_FW=y
CONFIG_MTD_UBI=y
CONFIG_MTD_UBI_BEB_LIMIT=20
CONFIG_MTD_UBI_BLOCK=y
CONFIG_MTD_UBI_WL_THRESHOLD=4096
CONFIG_MUTEX_SPIN_ON_OWNER=y
CONFIG_NEED_DMA_MAP_STATE=y
CONFIG_NEED_SG_DMA_LENGTH=y
CONFIG_NET_AIROHA=y
CONFIG_NET_AIROHA_FLOW_STATS=y
CONFIG_NET_AIROHA_NPU=y
CONFIG_NET_DEVLINK=y
CONFIG_NET_DSA=y
CONFIG_NET_DSA_MT7530=y
CONFIG_NET_DSA_MT7530_MDIO=y
CONFIG_NET_DSA_MT7530_MMIO=y
CONFIG_NET_DSA_TAG_MTK=y
CONFIG_NET_FLOW_LIMIT=y
# CONFIG_NET_MEDIATEK_SOC is not set
CONFIG_NET_SELFTESTS=y
# CONFIG_NET_VENDOR_3COM is not set
CONFIG_NET_VENDOR_AIROHA=y
# CONFIG_NET_VENDOR_MEDIATEK is not set
CONFIG_NLS=y
CONFIG_NO_HZ_COMMON=y
CONFIG_NO_HZ_IDLE=y
CONFIG_NR_CPUS=4
CONFIG_NVMEM=y
CONFIG_NVMEM_BLOCK=y
CONFIG_NVMEM_LAYOUTS=y
CONFIG_NVMEM_LAYOUT_ASCII_ENV=y
CONFIG_NVMEM_SYSFS=y
CONFIG_OF=y
CONFIG_OF_ADDRESS=y
CONFIG_OF_EARLY_FLATTREE=y
CONFIG_OF_FLATTREE=y
CONFIG_OF_GPIO=y
CONFIG_OF_IRQ=y
CONFIG_OF_KOBJ=y
CONFIG_OF_MDIO=y
CONFIG_PAGE_POOL=y
CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
CONFIG_PARTITION_PERCPU=y
CONFIG_PCI=y
CONFIG_PCIEAER=y
CONFIG_PCIEASPM=y
# CONFIG_PCIEASPM_DEFAULT is not set
CONFIG_PCIEASPM_PERFORMANCE=y
# CONFIG_PCIEASPM_POWERSAVE is not set
# CONFIG_PCIEASPM_POWER_SUPERSAVE is not set
CONFIG_PCIEPORTBUS=y
CONFIG_PCIE_MEDIATEK=y
CONFIG_PCIE_MEDIATEK_GEN3=y
CONFIG_PCIE_PME=y
CONFIG_PCI_DOMAINS=y
CONFIG_PCI_DOMAINS_GENERIC=y
CONFIG_PCI_MSI=y
# CONFIG_PCS_AIROHA_AN7581 is not set
CONFIG_PCS_AIROHA_AN7583=y
CONFIG_PERF_EVENTS=y
CONFIG_PER_VMA_LOCK=y
CONFIG_PGTABLE_LEVELS=3
CONFIG_PHYLIB=y
CONFIG_PHYLIB_LEDS=y
CONFIG_PHYLINK=y
CONFIG_PHYS_ADDR_T_64BIT=y
CONFIG_PHY_AIROHA_PCIE=y
# CONFIG_PHY_AIROHA_USB is not set
CONFIG_PINCTRL=y
CONFIG_PINCTRL_AIROHA=y
# CONFIG_PINCTRL_MT2712 is not set
# CONFIG_PINCTRL_MT6765 is not set
# CONFIG_PINCTRL_MT6795 is not set
# CONFIG_PINCTRL_MT6797 is not set
# CONFIG_PINCTRL_MT7622 is not set
# CONFIG_PINCTRL_MT7981 is not set
# CONFIG_PINCTRL_MT7986 is not set
# CONFIG_PINCTRL_MT8173 is not set
# CONFIG_PINCTRL_MT8183 is not set
# CONFIG_PINCTRL_MT8186 is not set
# CONFIG_PINCTRL_MT8188 is not set
# CONFIG_PINCTRL_MT8516 is not set
CONFIG_PM=y
CONFIG_PM_CLK=y
CONFIG_PM_OPP=y
CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y
CONFIG_POWER_RESET=y
CONFIG_POWER_RESET_SYSCON=y
CONFIG_POWER_SUPPLY=y
CONFIG_PTP_1588_CLOCK_OPTIONAL=y
CONFIG_QUEUED_RWLOCKS=y
CONFIG_QUEUED_SPINLOCKS=y
CONFIG_RANDSTRUCT_NONE=y
CONFIG_RAS=y
CONFIG_RATIONAL=y
CONFIG_REGMAP=y
CONFIG_REGMAP_MMIO=y
CONFIG_REGULATOR=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_RELOCATABLE=y
CONFIG_RESET_CONTROLLER=y
CONFIG_RFS_ACCEL=y
CONFIG_RODATA_FULL_DEFAULT_ENABLED=y
CONFIG_RPS=y
CONFIG_RWSEM_SPIN_ON_OWNER=y
CONFIG_SERIAL_8250_AIROHA=y
CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_FSL=y
CONFIG_SERIAL_8250_NR_UARTS=5
CONFIG_SERIAL_8250_RUNTIME_UARTS=5
CONFIG_SERIAL_8250_SHARE_IRQ=y
CONFIG_SERIAL_MCTRL_GPIO=y
CONFIG_SERIAL_OF_PLATFORM=y
CONFIG_SGL_ALLOC=y
CONFIG_SKB_EXTENSIONS=y
CONFIG_SMP=y
CONFIG_SOCK_RX_QUEUE_MAPPING=y
CONFIG_SOC_BUS=y
CONFIG_SOFTIRQ_ON_OWN_STACK=y
CONFIG_SPARSEMEM=y
CONFIG_SPARSEMEM_EXTREME=y
CONFIG_SPARSEMEM_VMEMMAP=y
CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
CONFIG_SPARSE_IRQ=y
CONFIG_SPI=y
# CONFIG_SPI_AIROHA_EN7523 is not set
CONFIG_SPI_AIROHA_SNFI=y
CONFIG_SPI_MASTER=y
CONFIG_SPI_MEM=y
CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y
CONFIG_SWIOTLB=y
CONFIG_SWPHY=y
CONFIG_SYSCTL_EXCEPTION_TRACE=y
# CONFIG_TEST_FPU is not set
CONFIG_THERMAL=y
CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0
CONFIG_THERMAL_GOV_STEP_WISE=y
CONFIG_THERMAL_OF=y
CONFIG_THREAD_INFO_IN_TASK=y
CONFIG_TICK_CPU_ACCOUNTING=y
CONFIG_TIMER_OF=y
CONFIG_TIMER_PROBE=y
CONFIG_TRACE_IRQFLAGS_NMI_SUPPORT=y
CONFIG_TREE_RCU=y
CONFIG_TREE_SRCU=y
CONFIG_UBIFS_FS=y
# CONFIG_UNMAP_KERNEL_AT_EL0 is not set
CONFIG_USER_STACKTRACE_SUPPORT=y
CONFIG_VDSO_GETRANDOM=y
CONFIG_VMAP_STACK=y
CONFIG_WATCHDOG_CORE=y
# CONFIG_WLAN is not set
# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set
CONFIG_XFRM_AH=y
CONFIG_XFRM_ALGO=y
CONFIG_XFRM_ESP=y
CONFIG_XFRM_IPCOMP=y
CONFIG_XFRM_MIGRATE=y
CONFIG_XPS=y
CONFIG_XXHASH=y
CONFIG_ZLIB_DEFLATE=y
CONFIG_ZLIB_INFLATE=y
CONFIG_ZONE_DMA32=y
CONFIG_ZSTD_COMMON=y
CONFIG_ZSTD_COMPRESS=y
CONFIG_ZSTD_DECOMPRESS=y
+2 -8
View File
@@ -1,10 +1,6 @@
include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/image.mk
loadaddr-$(CONFIG_TARGET_airoha_an7581) := 0x80200000
loadaddr-$(CONFIG_TARGET_airoha_an7583) := 0x80200000
loadaddr-$(CONFIG_TARGET_airoha_en7523) := 0x80200000
# default all platform image(fit) build
define Device/Default
PROFILES = Default $$(DEVICE_NAME)
@@ -12,11 +8,9 @@ define Device/Default
KERNEL = kernel-bin | lzma | \
fit lzma $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb
KERNEL_INITRAMFS = kernel-bin | lzma | \
fit lzma $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb
KERNEL_LOADADDR = $(loadaddr-y)
fit lzma $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb with-initrd
FILESYSTEMS := squashfs
DEVICE_DTS = $$(SOC)-$(lastword $(subst _, ,$(1)))
DEVICE_DTS_DIR := ../dts
DEVICE_DTS_DIR := $(DTS_DIR)
IMAGES := sysupgrade.bin
IMAGE/sysupgrade.bin := append-kernel | pad-to 128k | append-rootfs | \
pad-rootfs | append-metadata
+3 -42
View File
@@ -1,17 +1,3 @@
define Build/an7581-emmc-bl2-bl31-uboot
head -c $$((0x800)) /dev/zero > $@
cat $(STAGING_DIR_IMAGE)/an7581_$1-bl2.fip >> $@
dd if=$(STAGING_DIR_IMAGE)/an7581_$1-bl31-u-boot.fip of=$@ bs=1 seek=$$((0x20000)) conv=notrunc
endef
define Build/an7581-preloader
cat $(STAGING_DIR_IMAGE)/an7581_$1-bl2.fip >> $@
endef
define Build/an7581-bl31-uboot
cat $(STAGING_DIR_IMAGE)/an7581_$1-bl31-u-boot.fip >> $@
endef
define Device/FitImageLzma
KERNEL_SUFFIX := -uImage.itb
KERNEL = kernel-bin | lzma | fit lzma $$(KDIR)/image-$$(DEVICE_DTS).dtb
@@ -24,11 +10,10 @@ define Device/airoha_an7581-evb
DEVICE_MODEL := AN7581 Evaluation Board (SNAND)
DEVICE_PACKAGES := kmod-leds-pwm kmod-i2c-an7581 kmod-pwm-airoha kmod-input-gpio-keys-polled
DEVICE_DTS := an7581-evb
DEVICE_DTS_DIR := ../dts
DEVICE_DTS_CONFIG := config@1
KERNEL_LOADADDR := 0x80088000
IMAGE/sysupgrade.bin := append-kernel | pad-to 128k | append-rootfs | pad-rootfs | append-metadata
ARTIFACT/preloader.bin := an7581-preloader rfb
ARTIFACT/bl31-uboot.fip := an7581-bl31-uboot rfb
ARTIFACTS := preloader.bin bl31-uboot.fip
endef
TARGET_DEVICES += airoha_an7581-evb
@@ -36,31 +21,7 @@ define Device/airoha_an7581-evb-emmc
DEVICE_VENDOR := Airoha
DEVICE_MODEL := AN7581 Evaluation Board (EMMC)
DEVICE_DTS := an7581-evb-emmc
DEVICE_DTS_DIR := ../dts
DEVICE_PACKAGES := kmod-i2c-an7581
ARTIFACT/preloader.bin := an7581-preloader rfb
ARTIFACT/bl31-uboot.fip := an7581-bl31-uboot rfb
ARTIFACTS := preloader.bin bl31-uboot.fip
endef
TARGET_DEVICES += airoha_an7581-evb-emmc
define Device/bell_xg-040g-md
$(call Device/FitImageLzma)
DEVICE_VENDOR := Nokia Bell
DEVICE_MODEL := Nokia Bell XG-040G-MD
DEVICE_DTS_CONFIG := config@1
KERNEL_LOADADDR := 0x80088000
UBINIZE_OPTS := -E 5
BLOCKSIZE := 128k
PAGESIZE := 2048
KERNEL_SIZE := 10240k
IMAGE_SIZE := 261120k
KERNEL_IN_UBI := 1
UBINIZE_OPTS := -m 2048 -p 128KiB -s 2048
DEVICE_PACKAGES := airoha-en7581-npu-firmware kmod-phy-airoha-en8811h kmod-i2c-an7581 kmod-input-gpio-keys-polled
IMAGES += factory.bin sysupgrade.bin
IMAGE/factory.bin := append-kernel | pad-to $$$$(KERNEL_SIZE) | append-ubi
IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata
SOC := an7581
endef
TARGET_DEVICES += bell_xg-040g-md
-25
View File
@@ -1,25 +0,0 @@
define Device/FitImageLzma
KERNEL_SUFFIX := -uImage.itb
KERNEL = kernel-bin | lzma | fit lzma $$(KDIR)/image-$$(DEVICE_DTS).dtb
KERNEL_NAME := Image
endef
define Device/airoha_an7583-evb
$(call Device/FitImageLzma)
DEVICE_VENDOR := Airoha
DEVICE_MODEL := AN7583 Evaluation Board (SNAND)
DEVICE_PACKAGES := kmod-phy-aeonsemi-as21xxx kmod-leds-pwm kmod-pwm-airoha kmod-input-gpio-keys-polled
DEVICE_DTS := an7583-evb
DEVICE_DTS_CONFIG := config@1
KERNEL_LOADADDR := 0x80088000
IMAGE/sysupgrade.bin := append-kernel | pad-to 128k | append-rootfs | pad-rootfs | append-metadata
endef
TARGET_DEVICES += airoha_an7583-evb
define Device/airoha_an7583-evb-emmc
DEVICE_VENDOR := Airoha
DEVICE_MODEL := AN7583 Evaluation Board (EMMC)
DEVICE_DTS := an7583-evb-emmc
DEVICE_PACKAGES := kmod-phy-airoha-en8811h kmod-i2c-an7581
endef
TARGET_DEVICES += airoha_an7583-evb-emmc
+4 -1
View File
@@ -1,3 +1,5 @@
KERNEL_LOADADDR := 0x80208000
define Target/Description
Build firmware images for Airoha EN7523 ARM based boards.
endef
@@ -6,5 +8,6 @@ define Device/airoha_en7523-evb
DEVICE_VENDOR := Airoha
DEVICE_MODEL := EN7523 Evaluation Board
DEVICE_DTS := en7523-evb
DEVICE_DTS_DIR := ../dts
endef
TARGET_DEVICES += airoha_en7523-evb
TARGET_DEVICES += airoha_en7523-evb
@@ -1,40 +0,0 @@
From 8e38e08f2c560328a873c35aff1a0dbea6a7d084 Mon Sep 17 00:00:00 2001
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Tue, 1 Oct 2024 12:10:25 +0200
Subject: [PATCH 2/2] net: airoha: fix PSE memory configuration in
airoha_fe_pse_ports_init()
Align PSE memory configuration to vendor SDK. In particular, increase
initial value of PSE reserved memory in airoha_fe_pse_ports_init()
routine by the value used for the second Packet Processor Engine (PPE2)
and do not overwrite the default value.
Introduced by commit 23020f049327 ("net: airoha: Introduce ethernet support
for EN7581 SoC")
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20241001-airoha-eth-pse-fix-v2-2-9a56cdffd074@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/ethernet/mediatek/airoha_eth.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
--- a/drivers/net/ethernet/mediatek/airoha_eth.c
+++ b/drivers/net/ethernet/mediatek/airoha_eth.c
@@ -1166,11 +1166,13 @@ static void airoha_fe_pse_ports_init(str
[FE_PSE_PORT_GDM4] = 2,
[FE_PSE_PORT_CDM5] = 2,
};
+ u32 all_rsv;
int q;
+ all_rsv = airoha_fe_get_pse_all_rsv(eth);
/* hw misses PPE2 oq rsv */
- airoha_fe_set(eth, REG_FE_PSE_BUF_SET,
- PSE_RSV_PAGES * pse_port_num_queues[FE_PSE_PORT_PPE2]);
+ all_rsv += PSE_RSV_PAGES * pse_port_num_queues[FE_PSE_PORT_PPE2];
+ airoha_fe_set(eth, REG_FE_PSE_BUF_SET, all_rsv);
/* CMD1 */
for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_CDM1]; q++)
@@ -1,52 +0,0 @@
From 1f3e7ff4f296af1f4350f457d5bd82bc825e645a Mon Sep 17 00:00:00 2001
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Tue, 1 Oct 2024 12:10:24 +0200
Subject: [PATCH 1/2] net: airoha: read default PSE reserved pages value before
updating
Store the default value for the number of PSE reserved pages in orig_val
at the beginning of airoha_fe_set_pse_oq_rsv routine, before updating it
with airoha_fe_set_pse_queue_rsv_pages().
Introduce airoha_fe_get_pse_all_rsv utility routine.
Introduced by commit 23020f049327 ("net: airoha: Introduce ethernet support
for EN7581 SoC")
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20241001-airoha-eth-pse-fix-v2-1-9a56cdffd074@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/ethernet/mediatek/airoha_eth.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
--- a/drivers/net/ethernet/mediatek/airoha_eth.c
+++ b/drivers/net/ethernet/mediatek/airoha_eth.c
@@ -1116,17 +1116,23 @@ static void airoha_fe_set_pse_queue_rsv_
PSE_CFG_WR_EN_MASK | PSE_CFG_OQRSV_SEL_MASK);
}
+static u32 airoha_fe_get_pse_all_rsv(struct airoha_eth *eth)
+{
+ u32 val = airoha_fe_rr(eth, REG_FE_PSE_BUF_SET);
+
+ return FIELD_GET(PSE_ALLRSV_MASK, val);
+}
+
static int airoha_fe_set_pse_oq_rsv(struct airoha_eth *eth,
u32 port, u32 queue, u32 val)
{
- u32 orig_val, tmp, all_rsv, fq_limit;
+ u32 orig_val = airoha_fe_get_pse_queue_rsv_pages(eth, port, queue);
+ u32 tmp, all_rsv, fq_limit;
airoha_fe_set_pse_queue_rsv_pages(eth, port, queue, val);
/* modify all rsv */
- orig_val = airoha_fe_get_pse_queue_rsv_pages(eth, port, queue);
- tmp = airoha_fe_rr(eth, REG_FE_PSE_BUF_SET);
- all_rsv = FIELD_GET(PSE_ALLRSV_MASK, tmp);
+ all_rsv = airoha_fe_get_pse_all_rsv(eth);
all_rsv += (val - orig_val);
airoha_fe_rmw(eth, REG_FE_PSE_BUF_SET, PSE_ALLRSV_MASK,
FIELD_PREP(PSE_ALLRSV_MASK, all_rsv));
@@ -1,33 +0,0 @@
From 2518b119639162251b6cc7195aec394930c1d867 Mon Sep 17 00:00:00 2001
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Wed, 9 Oct 2024 00:21:47 +0200
Subject: [PATCH] net: airoha: Fix EGRESS_RATE_METER_EN_MASK definition
Fix typo in EGRESS_RATE_METER_EN_MASK mask definition. This bus in not
introducing any user visible problem since, even if we are setting
EGRESS_RATE_METER_EN_MASK bit in REG_EGRESS_RATE_METER_CFG register,
egress QoS metering is not supported yet since we are missing some other
hw configurations (e.g token bucket rate, token bucket size).
Introduced by commit 23020f049327 ("net: airoha: Introduce ethernet support
for EN7581 SoC")
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20241009-airoha-fixes-v2-1-18af63ec19bf@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/ethernet/mediatek/airoha_eth.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/net/ethernet/mediatek/airoha_eth.c
+++ b/drivers/net/ethernet/mediatek/airoha_eth.c
@@ -554,7 +554,7 @@
#define FWD_DSCP_LOW_THR_MASK GENMASK(17, 0)
#define REG_EGRESS_RATE_METER_CFG 0x100c
-#define EGRESS_RATE_METER_EN_MASK BIT(29)
+#define EGRESS_RATE_METER_EN_MASK BIT(31)
#define EGRESS_RATE_METER_EQ_RATE_EN_MASK BIT(17)
#define EGRESS_RATE_METER_WINDOW_SZ_MASK GENMASK(16, 12)
#define EGRESS_RATE_METER_TIMESLICE_MASK GENMASK(10, 0)
@@ -1,42 +0,0 @@
From 1d304174106c93ce05f6088813ad7203b3eb381a Mon Sep 17 00:00:00 2001
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Sat, 12 Oct 2024 11:01:11 +0200
Subject: [PATCH] net: airoha: Implement BQL support
Introduce BQL support in the airoha_eth driver reporting to the kernel
info about tx hw DMA queues in order to avoid bufferbloat and keep the
latency small.
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Link: https://patch.msgid.link/20241012-en7581-bql-v2-1-4deb4efdb60b@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/ethernet/mediatek/airoha_eth.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
--- a/drivers/net/ethernet/mediatek/airoha_eth.c
+++ b/drivers/net/ethernet/mediatek/airoha_eth.c
@@ -1709,9 +1709,11 @@ static int airoha_qdma_tx_napi_poll(stru
WRITE_ONCE(desc->msg1, 0);
if (skb) {
+ u16 queue = skb_get_queue_mapping(skb);
struct netdev_queue *txq;
- txq = netdev_get_tx_queue(skb->dev, qid);
+ txq = netdev_get_tx_queue(skb->dev, queue);
+ netdev_tx_completed_queue(txq, 1, skb->len);
if (netif_tx_queue_stopped(txq) &&
q->ndesc - q->queued >= q->free_thr)
netif_tx_wake_queue(txq);
@@ -2499,7 +2501,9 @@ static netdev_tx_t airoha_dev_xmit(struc
q->queued += i;
skb_tx_timestamp(skb);
- if (!netdev_xmit_more())
+ netdev_tx_sent_queue(txq, skb->len);
+
+ if (netif_xmit_stopped(txq) || !netdev_xmit_more())
airoha_qdma_rmw(qdma, REG_TX_CPU_IDX(qid),
TX_RING_CPU_IDX_MASK,
FIELD_PREP(TX_RING_CPU_IDX_MASK, q->head));
@@ -1,31 +0,0 @@
From 4658f57ba7f60c3bd8e14c1ca7acf2090aee8436 Mon Sep 17 00:00:00 2001
From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
Date: Tue, 12 Aug 2025 06:21:35 +0300
Subject: [PATCH v6 02/13] spi: airoha: remove unnecessary restriction length
The "length < 160" restriction is not needed because airoha_snand_write_data()
and airoha_snand_read_data() will properly handle data transfers above
SPI_MAX_TRANSFER_SIZE.
Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
drivers/spi/spi-airoha-snfi.c | 7 -------
1 file changed, 7 deletions(-)
--- a/drivers/spi/spi-airoha-snfi.c
+++ b/drivers/spi/spi-airoha-snfi.c
@@ -619,13 +619,6 @@ static int airoha_snand_adjust_op_size(s
if (op->data.nbytes > max_len)
op->data.nbytes = max_len;
- } else {
- max_len = 1 + op->addr.nbytes + op->dummy.nbytes;
- if (max_len >= 160)
- return -EOPNOTSUPP;
-
- if (op->data.nbytes > 160 - max_len)
- op->data.nbytes = 160 - max_len;
}
return 0;
@@ -1,29 +0,0 @@
From fb41a3e3bc357592b28a8abb504df99dad642588 Mon Sep 17 00:00:00 2001
From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
Date: Mon, 11 Aug 2025 13:09:51 +0300
Subject: [PATCH v6 04/13] spi: airoha: remove unnecessary switch to non-dma
mode
The code switches to dma at the start of dirmap operation and returns
to non-dma at the end of dirmap operation, so an additional switch to
non-dma at the start of dirmap write is not required.
Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
drivers/spi/spi-airoha-snfi.c | 3 ---
1 file changed, 3 deletions(-)
--- a/drivers/spi/spi-airoha-snfi.c
+++ b/drivers/spi/spi-airoha-snfi.c
@@ -815,9 +815,6 @@ static ssize_t airoha_snand_dirmap_write
int err;
as_ctrl = spi_controller_get_devdata(spi->controller);
- err = airoha_snand_set_mode(as_ctrl, SPI_MODE_MANUAL);
- if (err < 0)
- return err;
memcpy(txrx_buf + offs, buf, len);
dma_addr = dma_map_single(as_ctrl->dev, txrx_buf, SPI_NAND_CACHE_SIZE,
@@ -1,135 +0,0 @@
From 995b1a65206ee28d5403db0518cb230f2ce429ef Mon Sep 17 00:00:00 2001
From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
Date: Mon, 11 Aug 2025 19:57:43 +0300
Subject: [PATCH v6 07/13] spi: airoha: unify dirmap read/write code
Makes dirmap writing looks similar to dirmap reading. Just a minor
refactoring, no behavior change is expected.
Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
---
drivers/spi/spi-airoha-snfi.c | 50 ++++++++++++++++++++++-------------
1 file changed, 32 insertions(+), 18 deletions(-)
--- a/drivers/spi/spi-airoha-snfi.c
+++ b/drivers/spi/spi-airoha-snfi.c
@@ -672,6 +672,8 @@ static ssize_t airoha_snand_dirmap_read(
u32 val, rd_mode;
int err;
+ as_ctrl = spi_controller_get_devdata(spi->controller);
+
switch (op->cmd.opcode) {
case SPI_NAND_OP_READ_FROM_CACHE_DUAL:
rd_mode = 1;
@@ -684,7 +686,6 @@ static ssize_t airoha_snand_dirmap_read(
break;
}
- as_ctrl = spi_controller_get_devdata(spi->controller);
err = airoha_snand_set_mode(as_ctrl, SPI_MODE_DMA);
if (err < 0)
return err;
@@ -748,7 +749,7 @@ static ssize_t airoha_snand_dirmap_read(
if (err)
goto error_dma_unmap;
- /* trigger dma start read */
+ /* trigger dma reading */
err = regmap_clear_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CON,
SPI_NFI_RD_TRIG);
if (err)
@@ -806,37 +807,47 @@ error_dma_mode_off:
static ssize_t airoha_snand_dirmap_write(struct spi_mem_dirmap_desc *desc,
u64 offs, size_t len, const void *buf)
{
- struct spi_mem_op *op = &desc->info.op_tmpl;
struct spi_device *spi = desc->mem->spi;
u8 *txrx_buf = spi_get_ctldata(spi);
struct airoha_snand_ctrl *as_ctrl;
dma_addr_t dma_addr;
- u32 wr_mode, val;
+ u32 wr_mode, val, opcode;
int err;
as_ctrl = spi_controller_get_devdata(spi->controller);
+ opcode = desc->info.op_tmpl.cmd.opcode;
+ switch (opcode) {
+ case SPI_NAND_OP_PROGRAM_LOAD_SINGLE:
+ case SPI_NAND_OP_PROGRAM_LOAD_RAMDOM_SINGLE:
+ wr_mode = 0;
+ break;
+ case SPI_NAND_OP_PROGRAM_LOAD_QUAD:
+ case SPI_NAND_OP_PROGRAM_LOAD_RAMDON_QUAD:
+ wr_mode = 2;
+ break;
+ default:
+ /* unknown opcode */
+ return -EOPNOTSUPP;
+ }
+
memcpy(txrx_buf + offs, buf, len);
- dma_addr = dma_map_single(as_ctrl->dev, txrx_buf, SPI_NAND_CACHE_SIZE,
- DMA_TO_DEVICE);
- err = dma_mapping_error(as_ctrl->dev, dma_addr);
- if (err)
- return err;
err = airoha_snand_set_mode(as_ctrl, SPI_MODE_DMA);
if (err < 0)
- goto error_dma_unmap;
+ return err;
err = airoha_snand_nfi_config(as_ctrl);
if (err)
- goto error_dma_unmap;
+ goto error_dma_mode_off;
- if (op->cmd.opcode == SPI_NAND_OP_PROGRAM_LOAD_QUAD ||
- op->cmd.opcode == SPI_NAND_OP_PROGRAM_LOAD_RAMDON_QUAD)
- wr_mode = BIT(1);
- else
- wr_mode = 0;
+ dma_addr = dma_map_single(as_ctrl->dev, txrx_buf, SPI_NAND_CACHE_SIZE,
+ DMA_TO_DEVICE);
+ err = dma_mapping_error(as_ctrl->dev, dma_addr);
+ if (err)
+ goto error_dma_mode_off;
+ /* set dma addr */
err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_STRADDR,
dma_addr);
if (err)
@@ -850,12 +861,13 @@ static ssize_t airoha_snand_dirmap_write
if (err)
goto error_dma_unmap;
+ /* set write command */
err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_PG_CTL1,
- FIELD_PREP(SPI_NFI_PG_LOAD_CMD,
- op->cmd.opcode));
+ FIELD_PREP(SPI_NFI_PG_LOAD_CMD, opcode));
if (err)
goto error_dma_unmap;
+ /* set write mode */
err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_SNF_MISC_CTL,
FIELD_PREP(SPI_NFI_DATA_READ_WR_MODE, wr_mode));
if (err)
@@ -887,6 +899,7 @@ static ssize_t airoha_snand_dirmap_write
if (err)
goto error_dma_unmap;
+ /* trigger dma writing */
err = regmap_clear_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CON,
SPI_NFI_WR_TRIG);
if (err)
@@ -931,6 +944,7 @@ static ssize_t airoha_snand_dirmap_write
error_dma_unmap:
dma_unmap_single(as_ctrl->dev, dma_addr, SPI_NAND_CACHE_SIZE,
DMA_TO_DEVICE);
+error_dma_mode_off:
airoha_snand_set_mode(as_ctrl, SPI_MODE_MANUAL);
return err;
}
@@ -1,92 +0,0 @@
From baaba9b8d3d907575323cbb7fabeae23db2a542b Mon Sep 17 00:00:00 2001
From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
Date: Mon, 11 Aug 2025 20:52:34 +0300
Subject: [PATCH v6 08/13] spi: airoha: support of dualio/quadio flash reading
commands
Airoha snfi spi controller supports acceleration of DUAL/QUAD
operations, but does not supports DUAL_IO/QUAD_IO operations.
Luckily DUAL/QUAD operations do the same as DUAL_IO/QUAD_IO ones,
so we can issue corresponding DUAL/QUAD operation instead of
DUAL_IO/QUAD_IO one.
Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
drivers/spi/spi-airoha-snfi.c | 28 ++++++++++++++++++++++------
1 file changed, 22 insertions(+), 6 deletions(-)
--- a/drivers/spi/spi-airoha-snfi.c
+++ b/drivers/spi/spi-airoha-snfi.c
@@ -147,6 +147,8 @@
#define SPI_NFI_CUS_SEC_SIZE_EN BIT(16)
#define REG_SPI_NFI_RD_CTL2 0x0510
+#define SPI_NFI_DATA_READ_CMD GENMASK(7, 0)
+
#define REG_SPI_NFI_RD_CTL3 0x0514
#define REG_SPI_NFI_PG_CTL1 0x0524
@@ -179,7 +181,9 @@
#define SPI_NAND_OP_READ_FROM_CACHE_SINGLE 0x03
#define SPI_NAND_OP_READ_FROM_CACHE_SINGLE_FAST 0x0b
#define SPI_NAND_OP_READ_FROM_CACHE_DUAL 0x3b
+#define SPI_NAND_OP_READ_FROM_CACHE_DUALIO 0xbb
#define SPI_NAND_OP_READ_FROM_CACHE_QUAD 0x6b
+#define SPI_NAND_OP_READ_FROM_CACHE_QUADIO 0xeb
#define SPI_NAND_OP_WRITE_ENABLE 0x06
#define SPI_NAND_OP_WRITE_DISABLE 0x04
#define SPI_NAND_OP_PROGRAM_LOAD_SINGLE 0x02
@@ -664,26 +668,38 @@ static int airoha_snand_dirmap_create(st
static ssize_t airoha_snand_dirmap_read(struct spi_mem_dirmap_desc *desc,
u64 offs, size_t len, void *buf)
{
- struct spi_mem_op *op = &desc->info.op_tmpl;
struct spi_device *spi = desc->mem->spi;
struct airoha_snand_ctrl *as_ctrl;
u8 *txrx_buf = spi_get_ctldata(spi);
dma_addr_t dma_addr;
- u32 val, rd_mode;
+ u32 val, rd_mode, opcode;
int err;
as_ctrl = spi_controller_get_devdata(spi->controller);
- switch (op->cmd.opcode) {
+ /*
+ * DUALIO and QUADIO opcodes are not supported by the spi controller,
+ * replace them with supported opcodes.
+ */
+ opcode = desc->info.op_tmpl.cmd.opcode;
+ switch (opcode) {
+ case SPI_NAND_OP_READ_FROM_CACHE_SINGLE:
+ case SPI_NAND_OP_READ_FROM_CACHE_SINGLE_FAST:
+ rd_mode = 0;
+ break;
case SPI_NAND_OP_READ_FROM_CACHE_DUAL:
+ case SPI_NAND_OP_READ_FROM_CACHE_DUALIO:
+ opcode = SPI_NAND_OP_READ_FROM_CACHE_DUAL;
rd_mode = 1;
break;
case SPI_NAND_OP_READ_FROM_CACHE_QUAD:
+ case SPI_NAND_OP_READ_FROM_CACHE_QUADIO:
+ opcode = SPI_NAND_OP_READ_FROM_CACHE_QUAD;
rd_mode = 2;
break;
default:
- rd_mode = 0;
- break;
+ /* unknown opcode */
+ return -EOPNOTSUPP;
}
err = airoha_snand_set_mode(as_ctrl, SPI_MODE_DMA);
@@ -717,7 +733,7 @@ static ssize_t airoha_snand_dirmap_read(
/* set read command */
err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_RD_CTL2,
- op->cmd.opcode);
+ FIELD_PREP(SPI_NFI_DATA_READ_CMD, opcode));
if (err)
goto error_dma_unmap;
@@ -1,29 +0,0 @@
From 6ca9cd453cb5d8a6411791295771b4dbd1c623de Mon Sep 17 00:00:00 2001
From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
Date: Mon, 11 Aug 2025 21:18:04 +0300
Subject: [PATCH v6 09/13] spi: airoha: buffer must be 0xff-ed before writing
During writing, the entire flash page (including OOB) will be updated
with the values from the temporary buffer, so we need to fill the
untouched areas of the buffer with 0xff value to prevent accidental
data overwriting.
Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
---
drivers/spi/spi-airoha-snfi.c | 4 ++++
1 file changed, 4 insertions(+)
--- a/drivers/spi/spi-airoha-snfi.c
+++ b/drivers/spi/spi-airoha-snfi.c
@@ -847,7 +847,11 @@ static ssize_t airoha_snand_dirmap_write
return -EOPNOTSUPP;
}
+ if (offs > 0)
+ memset(txrx_buf, 0xff, offs);
memcpy(txrx_buf + offs, buf, len);
+ if (bytes > offs + len)
+ memset(txrx_buf + offs + len, 0xff, bytes - offs - len);
err = airoha_snand_set_mode(as_ctrl, SPI_MODE_DMA);
if (err < 0)
@@ -1,62 +0,0 @@
From 4abbbc74306598159fe1dc545f929ae594bf4dd1 Mon Sep 17 00:00:00 2001
From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
Date: Thu, 14 Aug 2025 18:00:32 +0300
Subject: [PATCH v6 10/13] spi: airoha: avoid setting of page/oob sizes in
REG_SPI_NFI_PAGEFMT
spi-airoha-snfi uses custom sector size in REG_SPI_NFI_SECCUS_SIZE
register, so setting of page/oob sizes in REG_SPI_NFI_PAGEFMT is not
required.
Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
---
drivers/spi/spi-airoha-snfi.c | 38 -----------------------------------
1 file changed, 38 deletions(-)
--- a/drivers/spi/spi-airoha-snfi.c
+++ b/drivers/spi/spi-airoha-snfi.c
@@ -518,44 +518,6 @@ static int airoha_snand_nfi_config(struc
if (err)
return err;
- /* page format */
- switch (as_ctrl->nfi_cfg.spare_size) {
- case 26:
- val = FIELD_PREP(SPI_NFI_SPARE_SIZE, 0x1);
- break;
- case 27:
- val = FIELD_PREP(SPI_NFI_SPARE_SIZE, 0x2);
- break;
- case 28:
- val = FIELD_PREP(SPI_NFI_SPARE_SIZE, 0x3);
- break;
- default:
- val = FIELD_PREP(SPI_NFI_SPARE_SIZE, 0x0);
- break;
- }
-
- err = regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_PAGEFMT,
- SPI_NFI_SPARE_SIZE, val);
- if (err)
- return err;
-
- switch (as_ctrl->nfi_cfg.page_size) {
- case 2048:
- val = FIELD_PREP(SPI_NFI_PAGE_SIZE, 0x1);
- break;
- case 4096:
- val = FIELD_PREP(SPI_NFI_PAGE_SIZE, 0x2);
- break;
- default:
- val = FIELD_PREP(SPI_NFI_PAGE_SIZE, 0x0);
- break;
- }
-
- err = regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_PAGEFMT,
- SPI_NFI_PAGE_SIZE, val);
- if (err)
- return err;
-
/* sec num */
val = FIELD_PREP(SPI_NFI_SEC_NUM, as_ctrl->nfi_cfg.sec_num);
err = regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CON,
@@ -1,197 +0,0 @@
From 0d8f58869192df0acdba286d233b57a4feeaf94b Mon Sep 17 00:00:00 2001
From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
Date: Thu, 14 Aug 2025 18:49:34 +0300
Subject: [PATCH v6 11/13] spi: airoha: reduce the number of modification of
REG_SPI_NFI_CNFG and REG_SPI_NFI_SECCUS_SIZE registers
This just reduce the number of modification of REG_SPI_NFI_CNFG and
REG_SPI_NFI_SECCUS_SIZE registers during dirmap operation.
This patch is a necessary step to avoid reading flash page settings
from SNFI registers during driver startup.
Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
drivers/spi/spi-airoha-snfi.c | 135 +++++++++++++++++++++++++---------
1 file changed, 102 insertions(+), 33 deletions(-)
--- a/drivers/spi/spi-airoha-snfi.c
+++ b/drivers/spi/spi-airoha-snfi.c
@@ -668,7 +668,48 @@ static ssize_t airoha_snand_dirmap_read(
if (err < 0)
return err;
- err = airoha_snand_nfi_config(as_ctrl);
+ /* NFI reset */
+ err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_CON,
+ SPI_NFI_FIFO_FLUSH | SPI_NFI_RST);
+ if (err)
+ goto error_dma_mode_off;
+
+ /* NFI configure:
+ * - No AutoFDM (custom sector size (SECCUS) register will be used)
+ * - No SoC's hardware ECC (flash internal ECC will be used)
+ * - Use burst mode (faster, but requires 16 byte alignment for addresses)
+ * - Setup for reading (SPI_NFI_READ_MODE)
+ * - Setup reading command: FIELD_PREP(SPI_NFI_OPMODE, 6)
+ * - Use DMA instead of PIO for data reading
+ */
+ err = regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG,
+ SPI_NFI_DMA_MODE |
+ SPI_NFI_READ_MODE |
+ SPI_NFI_DMA_BURST_EN |
+ SPI_NFI_HW_ECC_EN |
+ SPI_NFI_AUTO_FDM_EN |
+ SPI_NFI_OPMODE,
+ SPI_NFI_DMA_MODE |
+ SPI_NFI_READ_MODE |
+ SPI_NFI_DMA_BURST_EN |
+ FIELD_PREP(SPI_NFI_OPMODE, 6));
+ if (err)
+ goto error_dma_mode_off;
+
+ /* Set number of sector will be read */
+ val = FIELD_PREP(SPI_NFI_SEC_NUM, as_ctrl->nfi_cfg.sec_num);
+ err = regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CON,
+ SPI_NFI_SEC_NUM, val);
+ if (err)
+ goto error_dma_mode_off;
+
+ /* Set custom sector size */
+ val = as_ctrl->nfi_cfg.sec_size;
+ err = regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_SECCUS_SIZE,
+ SPI_NFI_CUS_SEC_SIZE |
+ SPI_NFI_CUS_SEC_SIZE_EN,
+ FIELD_PREP(SPI_NFI_CUS_SEC_SIZE, val) |
+ SPI_NFI_CUS_SEC_SIZE_EN);
if (err)
goto error_dma_mode_off;
@@ -684,7 +725,14 @@ static ssize_t airoha_snand_dirmap_read(
if (err)
goto error_dma_unmap;
- /* set cust sec size */
+ /*
+ * Setup transfer length
+ * ---------------------
+ * The following rule MUST be met:
+ * transfer_length =
+ * = NFI_SNF_MISC_CTL2.read_data_byte_number =
+ * = NFI_CON.sector_number * NFI_SECCUS.custom_sector_size
+ */
val = as_ctrl->nfi_cfg.sec_size * as_ctrl->nfi_cfg.sec_num;
val = FIELD_PREP(SPI_NFI_READ_DATA_BYTE_NUM, val);
err = regmap_update_bits(as_ctrl->regmap_nfi,
@@ -711,18 +759,6 @@ static ssize_t airoha_snand_dirmap_read(
if (err)
goto error_dma_unmap;
- /* set nfi read */
- err = regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG,
- SPI_NFI_OPMODE,
- FIELD_PREP(SPI_NFI_OPMODE, 6));
- if (err)
- goto error_dma_unmap;
-
- err = regmap_set_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG,
- SPI_NFI_READ_MODE | SPI_NFI_DMA_MODE);
- if (err)
- goto error_dma_unmap;
-
err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_CMD, 0x0);
if (err)
goto error_dma_unmap;
@@ -819,7 +855,48 @@ static ssize_t airoha_snand_dirmap_write
if (err < 0)
return err;
- err = airoha_snand_nfi_config(as_ctrl);
+ /* NFI reset */
+ err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_CON,
+ SPI_NFI_FIFO_FLUSH | SPI_NFI_RST);
+ if (err)
+ goto error_dma_mode_off;
+
+ /*
+ * NFI configure:
+ * - No AutoFDM (custom sector size (SECCUS) register will be used)
+ * - No SoC's hardware ECC (flash internal ECC will be used)
+ * - Use burst mode (faster, but requires 16 byte alignment for addresses)
+ * - Setup for writing (SPI_NFI_READ_MODE bit is cleared)
+ * - Setup writing command: FIELD_PREP(SPI_NFI_OPMODE, 3)
+ * - Use DMA instead of PIO for data writing
+ */
+ err = regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG,
+ SPI_NFI_DMA_MODE |
+ SPI_NFI_READ_MODE |
+ SPI_NFI_DMA_BURST_EN |
+ SPI_NFI_HW_ECC_EN |
+ SPI_NFI_AUTO_FDM_EN |
+ SPI_NFI_OPMODE,
+ SPI_NFI_DMA_MODE |
+ SPI_NFI_DMA_BURST_EN |
+ FIELD_PREP(SPI_NFI_OPMODE, 3));
+ if (err)
+ goto error_dma_mode_off;
+
+ /* Set number of sector will be written */
+ val = FIELD_PREP(SPI_NFI_SEC_NUM, as_ctrl->nfi_cfg.sec_num);
+ err = regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CON,
+ SPI_NFI_SEC_NUM, val);
+ if (err)
+ goto error_dma_mode_off;
+
+ /* Set custom sector size */
+ val = as_ctrl->nfi_cfg.sec_size;
+ err = regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_SECCUS_SIZE,
+ SPI_NFI_CUS_SEC_SIZE |
+ SPI_NFI_CUS_SEC_SIZE_EN,
+ FIELD_PREP(SPI_NFI_CUS_SEC_SIZE, val) |
+ SPI_NFI_CUS_SEC_SIZE_EN);
if (err)
goto error_dma_mode_off;
@@ -835,8 +912,16 @@ static ssize_t airoha_snand_dirmap_write
if (err)
goto error_dma_unmap;
- val = FIELD_PREP(SPI_NFI_PROG_LOAD_BYTE_NUM,
- as_ctrl->nfi_cfg.sec_size * as_ctrl->nfi_cfg.sec_num);
+ /*
+ * Setup transfer length
+ * ---------------------
+ * The following rule MUST be met:
+ * transfer_length =
+ * = NFI_SNF_MISC_CTL2.write_data_byte_number =
+ * = NFI_CON.sector_number * NFI_SECCUS.custom_sector_size
+ */
+ val = as_ctrl->nfi_cfg.sec_size * as_ctrl->nfi_cfg.sec_num;
+ val = FIELD_PREP(SPI_NFI_PROG_LOAD_BYTE_NUM, val);
err = regmap_update_bits(as_ctrl->regmap_nfi,
REG_SPI_NFI_SNF_MISC_CTL2,
SPI_NFI_PROG_LOAD_BYTE_NUM, val);
@@ -861,22 +946,6 @@ static ssize_t airoha_snand_dirmap_write
if (err)
goto error_dma_unmap;
- err = regmap_clear_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG,
- SPI_NFI_READ_MODE);
- if (err)
- goto error_dma_unmap;
-
- err = regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG,
- SPI_NFI_OPMODE,
- FIELD_PREP(SPI_NFI_OPMODE, 3));
- if (err)
- goto error_dma_unmap;
-
- err = regmap_set_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG,
- SPI_NFI_DMA_MODE);
- if (err)
- goto error_dma_unmap;
-
err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_CMD, 0x80);
if (err)
goto error_dma_unmap;
@@ -1,140 +0,0 @@
From 893ee23d650ca9ee36541b9a5ae0bc18be01a11f Mon Sep 17 00:00:00 2001
From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
Date: Thu, 14 Aug 2025 22:47:17 +0300
Subject: [PATCH v6 12/13] spi: airoha: set custom sector size equal to flash
page size
Set custom sector size equal to flash page size including oob. Thus we
will always read a single sector. The maximum custom sector size is
8187, so all possible flash sector sizes are supported.
This patch is a necessary step to avoid reading flash page settings
from SNFI registers during driver startup.
Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
drivers/spi/spi-airoha-snfi.c | 35 +++++++++++++++++++----------------
1 file changed, 19 insertions(+), 16 deletions(-)
--- a/drivers/spi/spi-airoha-snfi.c
+++ b/drivers/spi/spi-airoha-snfi.c
@@ -519,7 +519,7 @@ static int airoha_snand_nfi_config(struc
return err;
/* sec num */
- val = FIELD_PREP(SPI_NFI_SEC_NUM, as_ctrl->nfi_cfg.sec_num);
+ val = FIELD_PREP(SPI_NFI_SEC_NUM, 1);
err = regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CON,
SPI_NFI_SEC_NUM, val);
if (err)
@@ -532,7 +532,8 @@ static int airoha_snand_nfi_config(struc
return err;
/* set cust sec size */
- val = FIELD_PREP(SPI_NFI_CUS_SEC_SIZE, as_ctrl->nfi_cfg.sec_size);
+ val = FIELD_PREP(SPI_NFI_CUS_SEC_SIZE,
+ as_ctrl->nfi_cfg.sec_size * as_ctrl->nfi_cfg.sec_num);
return regmap_update_bits(as_ctrl->regmap_nfi,
REG_SPI_NFI_SECCUS_SIZE,
SPI_NFI_CUS_SEC_SIZE, val);
@@ -635,10 +636,13 @@ static ssize_t airoha_snand_dirmap_read(
u8 *txrx_buf = spi_get_ctldata(spi);
dma_addr_t dma_addr;
u32 val, rd_mode, opcode;
+ size_t bytes;
int err;
as_ctrl = spi_controller_get_devdata(spi->controller);
+ bytes = as_ctrl->nfi_cfg.sec_num * as_ctrl->nfi_cfg.sec_size;
+
/*
* DUALIO and QUADIO opcodes are not supported by the spi controller,
* replace them with supported opcodes.
@@ -697,18 +701,17 @@ static ssize_t airoha_snand_dirmap_read(
goto error_dma_mode_off;
/* Set number of sector will be read */
- val = FIELD_PREP(SPI_NFI_SEC_NUM, as_ctrl->nfi_cfg.sec_num);
err = regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CON,
- SPI_NFI_SEC_NUM, val);
+ SPI_NFI_SEC_NUM,
+ FIELD_PREP(SPI_NFI_SEC_NUM, 1));
if (err)
goto error_dma_mode_off;
/* Set custom sector size */
- val = as_ctrl->nfi_cfg.sec_size;
err = regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_SECCUS_SIZE,
SPI_NFI_CUS_SEC_SIZE |
SPI_NFI_CUS_SEC_SIZE_EN,
- FIELD_PREP(SPI_NFI_CUS_SEC_SIZE, val) |
+ FIELD_PREP(SPI_NFI_CUS_SEC_SIZE, bytes) |
SPI_NFI_CUS_SEC_SIZE_EN);
if (err)
goto error_dma_mode_off;
@@ -733,11 +736,10 @@ static ssize_t airoha_snand_dirmap_read(
* = NFI_SNF_MISC_CTL2.read_data_byte_number =
* = NFI_CON.sector_number * NFI_SECCUS.custom_sector_size
*/
- val = as_ctrl->nfi_cfg.sec_size * as_ctrl->nfi_cfg.sec_num;
- val = FIELD_PREP(SPI_NFI_READ_DATA_BYTE_NUM, val);
err = regmap_update_bits(as_ctrl->regmap_nfi,
REG_SPI_NFI_SNF_MISC_CTL2,
- SPI_NFI_READ_DATA_BYTE_NUM, val);
+ SPI_NFI_READ_DATA_BYTE_NUM,
+ FIELD_PREP(SPI_NFI_READ_DATA_BYTE_NUM, bytes));
if (err)
goto error_dma_unmap;
@@ -826,10 +828,13 @@ static ssize_t airoha_snand_dirmap_write
struct airoha_snand_ctrl *as_ctrl;
dma_addr_t dma_addr;
u32 wr_mode, val, opcode;
+ size_t bytes;
int err;
as_ctrl = spi_controller_get_devdata(spi->controller);
+ bytes = as_ctrl->nfi_cfg.sec_num * as_ctrl->nfi_cfg.sec_size;
+
opcode = desc->info.op_tmpl.cmd.opcode;
switch (opcode) {
case SPI_NAND_OP_PROGRAM_LOAD_SINGLE:
@@ -884,18 +889,17 @@ static ssize_t airoha_snand_dirmap_write
goto error_dma_mode_off;
/* Set number of sector will be written */
- val = FIELD_PREP(SPI_NFI_SEC_NUM, as_ctrl->nfi_cfg.sec_num);
err = regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CON,
- SPI_NFI_SEC_NUM, val);
+ SPI_NFI_SEC_NUM,
+ FIELD_PREP(SPI_NFI_SEC_NUM, 1));
if (err)
goto error_dma_mode_off;
/* Set custom sector size */
- val = as_ctrl->nfi_cfg.sec_size;
err = regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_SECCUS_SIZE,
SPI_NFI_CUS_SEC_SIZE |
SPI_NFI_CUS_SEC_SIZE_EN,
- FIELD_PREP(SPI_NFI_CUS_SEC_SIZE, val) |
+ FIELD_PREP(SPI_NFI_CUS_SEC_SIZE, bytes) |
SPI_NFI_CUS_SEC_SIZE_EN);
if (err)
goto error_dma_mode_off;
@@ -920,11 +924,10 @@ static ssize_t airoha_snand_dirmap_write
* = NFI_SNF_MISC_CTL2.write_data_byte_number =
* = NFI_CON.sector_number * NFI_SECCUS.custom_sector_size
*/
- val = as_ctrl->nfi_cfg.sec_size * as_ctrl->nfi_cfg.sec_num;
- val = FIELD_PREP(SPI_NFI_PROG_LOAD_BYTE_NUM, val);
err = regmap_update_bits(as_ctrl->regmap_nfi,
REG_SPI_NFI_SNF_MISC_CTL2,
- SPI_NFI_PROG_LOAD_BYTE_NUM, val);
+ SPI_NFI_PROG_LOAD_BYTE_NUM,
+ FIELD_PREP(SPI_NFI_PROG_LOAD_BYTE_NUM, bytes));
if (err)
goto error_dma_unmap;
@@ -1,204 +0,0 @@
From 64a4d6e84145227211485067022cd4e5cf052e04 Mon Sep 17 00:00:00 2001
From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
Date: Thu, 14 Aug 2025 23:56:24 +0300
Subject: [PATCH v6 13/13] spi: airoha: avoid reading flash page settings from
SNFI registers during driver startup
The spinand driver do 3 type of dirmap requests:
* read/write whole flash page without oob
(offs = 0, len = page_size)
* read/write whole flash page including oob
(offs = 0, len = page_size + oob_size)
* read/write oob area only
(offs = page_size, len = oob_size)
The trick is:
* read/write a single "sector"
* set a custom sector size equal to offs + len. It's a bit safer to
rounded up "sector size" value 64.
* set the transfer length equal to custom sector size
And it works!
Thus we can remove a dirty hack that reads flash page settings from
SNFI registers during driver startup. Also airoha_snand_adjust_op_size()
function becomes unnecessary.
Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
---
drivers/spi/spi-airoha-snfi.c | 115 ++--------------------------------
1 file changed, 5 insertions(+), 110 deletions(-)
--- a/drivers/spi/spi-airoha-snfi.c
+++ b/drivers/spi/spi-airoha-snfi.c
@@ -223,13 +223,6 @@ struct airoha_snand_ctrl {
struct regmap *regmap_ctrl;
struct regmap *regmap_nfi;
struct clk *spi_clk;
-
- struct {
- size_t page_size;
- size_t sec_size;
- u8 sec_num;
- u8 spare_size;
- } nfi_cfg;
};
static int airoha_snand_set_fifo_op(struct airoha_snand_ctrl *as_ctrl,
@@ -490,55 +483,6 @@ static int airoha_snand_nfi_init(struct
SPI_NFI_ALL_IRQ_EN, SPI_NFI_AHB_DONE_EN);
}
-static int airoha_snand_nfi_config(struct airoha_snand_ctrl *as_ctrl)
-{
- int err;
- u32 val;
-
- err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_CON,
- SPI_NFI_FIFO_FLUSH | SPI_NFI_RST);
- if (err)
- return err;
-
- /* auto FDM */
- err = regmap_clear_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG,
- SPI_NFI_AUTO_FDM_EN);
- if (err)
- return err;
-
- /* HW ECC */
- err = regmap_clear_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG,
- SPI_NFI_HW_ECC_EN);
- if (err)
- return err;
-
- /* DMA Burst */
- err = regmap_set_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG,
- SPI_NFI_DMA_BURST_EN);
- if (err)
- return err;
-
- /* sec num */
- val = FIELD_PREP(SPI_NFI_SEC_NUM, 1);
- err = regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CON,
- SPI_NFI_SEC_NUM, val);
- if (err)
- return err;
-
- /* enable cust sec size */
- err = regmap_set_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_SECCUS_SIZE,
- SPI_NFI_CUS_SEC_SIZE_EN);
- if (err)
- return err;
-
- /* set cust sec size */
- val = FIELD_PREP(SPI_NFI_CUS_SEC_SIZE,
- as_ctrl->nfi_cfg.sec_size * as_ctrl->nfi_cfg.sec_num);
- return regmap_update_bits(as_ctrl->regmap_nfi,
- REG_SPI_NFI_SECCUS_SIZE,
- SPI_NFI_CUS_SEC_SIZE, val);
-}
-
static bool airoha_snand_is_page_ops(const struct spi_mem_op *op)
{
if (op->addr.nbytes != 2)
@@ -571,26 +515,6 @@ static bool airoha_snand_is_page_ops(con
}
}
-static int airoha_snand_adjust_op_size(struct spi_mem *mem,
- struct spi_mem_op *op)
-{
- size_t max_len;
-
- if (airoha_snand_is_page_ops(op)) {
- struct airoha_snand_ctrl *as_ctrl;
-
- as_ctrl = spi_controller_get_devdata(mem->spi->controller);
- max_len = as_ctrl->nfi_cfg.sec_size;
- max_len += as_ctrl->nfi_cfg.spare_size;
- max_len *= as_ctrl->nfi_cfg.sec_num;
-
- if (op->data.nbytes > max_len)
- op->data.nbytes = max_len;
- }
-
- return 0;
-}
-
static bool airoha_snand_supports_op(struct spi_mem *mem,
const struct spi_mem_op *op)
{
@@ -641,7 +565,8 @@ static ssize_t airoha_snand_dirmap_read(
as_ctrl = spi_controller_get_devdata(spi->controller);
- bytes = as_ctrl->nfi_cfg.sec_num * as_ctrl->nfi_cfg.sec_size;
+ /* minimum oob size is 64 */
+ bytes = round_up(offs + len, 64);
/*
* DUALIO and QUADIO opcodes are not supported by the spi controller,
@@ -833,7 +758,8 @@ static ssize_t airoha_snand_dirmap_write
as_ctrl = spi_controller_get_devdata(spi->controller);
- bytes = as_ctrl->nfi_cfg.sec_num * as_ctrl->nfi_cfg.sec_size;
+ /* minimum oob size is 64 */
+ bytes = round_up(offs + len, 64);
opcode = desc->info.op_tmpl.cmd.opcode;
switch (opcode) {
@@ -1080,7 +1006,6 @@ static int airoha_snand_exec_op(struct s
}
static const struct spi_controller_mem_ops airoha_snand_mem_ops = {
- .adjust_op_size = airoha_snand_adjust_op_size,
.supports_op = airoha_snand_supports_op,
.exec_op = airoha_snand_exec_op,
.dirmap_create = airoha_snand_dirmap_create,
@@ -1105,36 +1030,6 @@ static int airoha_snand_setup(struct spi
return 0;
}
-static int airoha_snand_nfi_setup(struct airoha_snand_ctrl *as_ctrl)
-{
- u32 val, sec_size, sec_num;
- int err;
-
- err = regmap_read(as_ctrl->regmap_nfi, REG_SPI_NFI_CON, &val);
- if (err)
- return err;
-
- sec_num = FIELD_GET(SPI_NFI_SEC_NUM, val);
-
- err = regmap_read(as_ctrl->regmap_nfi, REG_SPI_NFI_SECCUS_SIZE, &val);
- if (err)
- return err;
-
- sec_size = FIELD_GET(SPI_NFI_CUS_SEC_SIZE, val);
-
- /* init default value */
- as_ctrl->nfi_cfg.sec_size = sec_size;
- as_ctrl->nfi_cfg.sec_num = sec_num;
- as_ctrl->nfi_cfg.page_size = round_down(sec_size * sec_num, 1024);
- as_ctrl->nfi_cfg.spare_size = 16;
-
- err = airoha_snand_nfi_init(as_ctrl);
- if (err)
- return err;
-
- return airoha_snand_nfi_config(as_ctrl);
-}
-
static const struct regmap_config spi_ctrl_regmap_config = {
.name = "ctrl",
.reg_bits = 32,
@@ -1208,7 +1103,7 @@ static int airoha_snand_probe(struct pla
ctrl->setup = airoha_snand_setup;
device_set_node(&ctrl->dev, dev_fwnode(dev));
- err = airoha_snand_nfi_setup(as_ctrl);
+ err = airoha_snand_nfi_init(as_ctrl);
if (err)
return err;
@@ -1,27 +0,0 @@
From 12664d09a94bd0f50f31a3811447f70275ea9bb8 Mon Sep 17 00:00:00 2001
From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
Date: Thu, 9 Oct 2025 19:49:18 +0300
Subject: [PATCH 1/2] spi: airoha-snfi: make compatible with EN7523 SoC
The driver is fully compatible with EN7523 based SoCs, so add
corresponding compatible string.
This driver is better than en7523-spi because it supports DMA.
Measurements shows that DMA based flash reading is 4 times faster
than non-dma one.
Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
---
drivers/spi/spi-airoha-snfi.c | 1 +
1 file changed, 1 insertion(+)
--- a/drivers/spi/spi-airoha-snfi.c
+++ b/drivers/spi/spi-airoha-snfi.c
@@ -1047,6 +1047,7 @@ static const struct regmap_config spi_nf
};
static const struct of_device_id airoha_snand_ids[] = {
+ { .compatible = "airoha,en7523-snand" },
{ .compatible = "airoha,en7581-snand" },
{ /* sentinel */ }
};
@@ -1,97 +0,0 @@
From 0299de52cbb2274345e12518298a8014adb56411 Mon Sep 17 00:00:00 2001
From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
Date: Thu, 9 Oct 2025 19:33:23 +0300
Subject: [PATCH 2/2] spi: airoha-snfi: en7523: workaround flash damaging if
UART_TXD was short to GND
We found that some serial console may pull TX line to GROUND during board
boot time. Airoha uses TX line as one of it's BOOT pins. This will lead
to booting in RESERVED boot mode.
It was found that some flashes operates incorrectly in RESERVED mode.
Micron and Skyhigh flashes are definitely affected by the issue,
Winbond flashes are NOT affected.
Details:
--------
DMA reading of odd pages on affected flashes operates incorrectly. Page
reading offset (start of the page) on hardware level is replaced by 0x10.
Thus results in incorrect data reading. Usage of UBI make things even
worse. Any attempt to access UBI leads to ubi damaging. As result OS loading
becomes impossible.
Non-DMA reading is OK.
This patch detects booting in reserved mode, turn off DMA and print big
fat warning.
Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
---
drivers/spi/spi-airoha-snfi.c | 38 ++++++++++++++++++++++++++++++++---
1 file changed, 35 insertions(+), 3 deletions(-)
--- a/drivers/spi/spi-airoha-snfi.c
+++ b/drivers/spi/spi-airoha-snfi.c
@@ -1013,6 +1013,11 @@ static const struct spi_controller_mem_o
.dirmap_write = airoha_snand_dirmap_write,
};
+static const struct spi_controller_mem_ops airoha_snand_nodma_mem_ops = {
+ .supports_op = airoha_snand_supports_op,
+ .exec_op = airoha_snand_exec_op,
+};
+
static int airoha_snand_setup(struct spi_device *spi)
{
struct airoha_snand_ctrl *as_ctrl;
@@ -1059,7 +1064,10 @@ static int airoha_snand_probe(struct pla
struct device *dev = &pdev->dev;
struct spi_controller *ctrl;
void __iomem *base;
- int err;
+ int err, dma_enabled;
+#if defined(CONFIG_ARM)
+ u32 sfc_strap;
+#endif
ctrl = devm_spi_alloc_host(dev, sizeof(*as_ctrl));
if (!ctrl)
@@ -1093,12 +1101,36 @@ static int airoha_snand_probe(struct pla
return dev_err_probe(dev, PTR_ERR(as_ctrl->spi_clk),
"unable to get spi clk\n");
- err = dma_set_mask(as_ctrl->dev, DMA_BIT_MASK(32));
+ dma_enabled = 1;
+#if defined(CONFIG_ARM)
+ err = regmap_read(as_ctrl->regmap_ctrl,
+ REG_SPI_CTRL_SFC_STRAP, &sfc_strap);
if (err)
return err;
+ if (!(sfc_strap & 0x04)) {
+ dma_enabled = 0;
+ printk(KERN_WARNING "\n"
+ "=== WARNING ======================================================\n"
+ "Detected booting in RESERVED mode (UART_TXD was short to GND).\n"
+ "This mode is known for incorrect DMA reading of some flashes.\n"
+ "Usage of DMA for flash operations will be disabled to prevent data\n"
+ "damage. Unplug your serial console and power cycle the board\n"
+ "to boot with full performance.\n"
+ "==================================================================\n\n");
+ }
+#endif
+
+ if (dma_enabled) {
+ err = dma_set_mask(as_ctrl->dev, DMA_BIT_MASK(32));
+ if (err)
+ return err;
+ }
+
ctrl->num_chipselect = 2;
- ctrl->mem_ops = &airoha_snand_mem_ops;
+ ctrl->mem_ops = dma_enabled ?
+ &airoha_snand_mem_ops :
+ &airoha_snand_nodma_mem_ops;
ctrl->bits_per_word_mask = SPI_BPW_MASK(8);
ctrl->mode_bits = SPI_RX_DUAL;
ctrl->setup = airoha_snand_setup;
@@ -1,306 +0,0 @@
From 5c5db81bff81a0fcd9ad998543d4241cbfe4742f Mon Sep 17 00:00:00 2001
From: Christian Marangi <ansuelsmth@gmail.com>
Date: Thu, 17 Oct 2024 14:44:38 +0200
Subject: [PATCH 2/2] hwrng: airoha - add support for Airoha EN7581 TRNG
Add support for Airoha TRNG. The Airoha SoC provide a True RNG module
that can output 4 bytes of raw data at times.
The module makes use of various noise source to provide True Random
Number Generation.
On probe the module is reset to operate Health Test and verify correct
execution of it.
The module can also provide DRBG function but the execution mode is
mutually exclusive, running as TRNG doesn't permit to also run it as
DRBG.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Reviewed-by: Martin Kaiser <martin@kaiser.cx>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
---
drivers/char/hw_random/Kconfig | 13 ++
drivers/char/hw_random/Makefile | 1 +
drivers/char/hw_random/airoha-trng.c | 243 +++++++++++++++++++++++++++
3 files changed, 257 insertions(+)
create mode 100644 drivers/char/hw_random/airoha-trng.c
--- a/drivers/char/hw_random/Kconfig
+++ b/drivers/char/hw_random/Kconfig
@@ -62,6 +62,19 @@ config HW_RANDOM_AMD
If unsure, say Y.
+config HW_RANDOM_AIROHA
+ tristate "Airoha True HW Random Number Generator support"
+ depends on ARCH_AIROHA || COMPILE_TEST
+ default HW_RANDOM
+ help
+ This driver provides kernel-side support for the True Random Number
+ Generator hardware found on Airoha SoC.
+
+ To compile this driver as a module, choose M here: the
+ module will be called airoha-rng.
+
+ If unsure, say Y.
+
config HW_RANDOM_ATMEL
tristate "Atmel Random Number Generator support"
depends on (ARCH_AT91 || COMPILE_TEST)
--- a/drivers/char/hw_random/Makefile
+++ b/drivers/char/hw_random/Makefile
@@ -8,6 +8,7 @@ rng-core-y := core.o
obj-$(CONFIG_HW_RANDOM_TIMERIOMEM) += timeriomem-rng.o
obj-$(CONFIG_HW_RANDOM_INTEL) += intel-rng.o
obj-$(CONFIG_HW_RANDOM_AMD) += amd-rng.o
+obj-$(CONFIG_HW_RANDOM_AIROHA) += airoha-trng.o
obj-$(CONFIG_HW_RANDOM_ATMEL) += atmel-rng.o
obj-$(CONFIG_HW_RANDOM_BA431) += ba431-rng.o
obj-$(CONFIG_HW_RANDOM_GEODE) += geode-rng.o
--- /dev/null
+++ b/drivers/char/hw_random/airoha-trng.c
@@ -0,0 +1,243 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (C) 2024 Christian Marangi */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/bitfield.h>
+#include <linux/delay.h>
+#include <linux/hw_random.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/platform_device.h>
+
+#define TRNG_IP_RDY 0x800
+#define CNT_TRANS GENMASK(15, 8)
+#define SAMPLE_RDY BIT(0)
+#define TRNG_NS_SEK_AND_DAT_EN 0x804
+#define RNG_EN BIT(31) /* referenced as ring_en */
+#define RAW_DATA_EN BIT(16)
+#define TRNG_HEALTH_TEST_SW_RST 0x808
+#define SW_RST BIT(0) /* Active High */
+#define TRNG_INTR_EN 0x818
+#define INTR_MASK BIT(16)
+#define CONTINUOUS_HEALTH_INITR_EN BIT(2)
+#define SW_STARTUP_INITR_EN BIT(1)
+#define RST_STARTUP_INITR_EN BIT(0)
+/* Notice that Health Test are done only out of Reset and with RNG_EN */
+#define TRNG_HEALTH_TEST_STATUS 0x824
+#define CONTINUOUS_HEALTH_AP_TEST_FAIL BIT(23)
+#define CONTINUOUS_HEALTH_RC_TEST_FAIL BIT(22)
+#define SW_STARTUP_TEST_DONE BIT(21)
+#define SW_STARTUP_AP_TEST_FAIL BIT(20)
+#define SW_STARTUP_RC_TEST_FAIL BIT(19)
+#define RST_STARTUP_TEST_DONE BIT(18)
+#define RST_STARTUP_AP_TEST_FAIL BIT(17)
+#define RST_STARTUP_RC_TEST_FAIL BIT(16)
+#define RAW_DATA_VALID BIT(7)
+
+#define TRNG_RAW_DATA_OUT 0x828
+
+#define TRNG_CNT_TRANS_VALID 0x80
+#define BUSY_LOOP_SLEEP 10
+#define BUSY_LOOP_TIMEOUT (BUSY_LOOP_SLEEP * 10000)
+
+struct airoha_trng {
+ void __iomem *base;
+ struct hwrng rng;
+ struct device *dev;
+
+ struct completion rng_op_done;
+};
+
+static int airoha_trng_irq_mask(struct airoha_trng *trng)
+{
+ u32 val;
+
+ val = readl(trng->base + TRNG_INTR_EN);
+ val |= INTR_MASK;
+ writel(val, trng->base + TRNG_INTR_EN);
+
+ return 0;
+}
+
+static int airoha_trng_irq_unmask(struct airoha_trng *trng)
+{
+ u32 val;
+
+ val = readl(trng->base + TRNG_INTR_EN);
+ val &= ~INTR_MASK;
+ writel(val, trng->base + TRNG_INTR_EN);
+
+ return 0;
+}
+
+static int airoha_trng_init(struct hwrng *rng)
+{
+ struct airoha_trng *trng = container_of(rng, struct airoha_trng, rng);
+ int ret;
+ u32 val;
+
+ val = readl(trng->base + TRNG_NS_SEK_AND_DAT_EN);
+ val |= RNG_EN;
+ writel(val, trng->base + TRNG_NS_SEK_AND_DAT_EN);
+
+ /* Set out of SW Reset */
+ airoha_trng_irq_unmask(trng);
+ writel(0, trng->base + TRNG_HEALTH_TEST_SW_RST);
+
+ ret = wait_for_completion_timeout(&trng->rng_op_done, BUSY_LOOP_TIMEOUT);
+ if (ret <= 0) {
+ dev_err(trng->dev, "Timeout waiting for Health Check\n");
+ airoha_trng_irq_mask(trng);
+ return -ENODEV;
+ }
+
+ /* Check if Health Test Failed */
+ val = readl(trng->base + TRNG_HEALTH_TEST_STATUS);
+ if (val & (RST_STARTUP_AP_TEST_FAIL | RST_STARTUP_RC_TEST_FAIL)) {
+ dev_err(trng->dev, "Health Check fail: %s test fail\n",
+ val & RST_STARTUP_AP_TEST_FAIL ? "AP" : "RC");
+ return -ENODEV;
+ }
+
+ /* Check if IP is ready */
+ ret = readl_poll_timeout(trng->base + TRNG_IP_RDY, val,
+ val & SAMPLE_RDY, 10, 1000);
+ if (ret < 0) {
+ dev_err(trng->dev, "Timeout waiting for IP ready");
+ return -ENODEV;
+ }
+
+ /* CNT_TRANS must be 0x80 for IP to be considered ready */
+ ret = readl_poll_timeout(trng->base + TRNG_IP_RDY, val,
+ FIELD_GET(CNT_TRANS, val) == TRNG_CNT_TRANS_VALID,
+ 10, 1000);
+ if (ret < 0) {
+ dev_err(trng->dev, "Timeout waiting for IP ready");
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+static void airoha_trng_cleanup(struct hwrng *rng)
+{
+ struct airoha_trng *trng = container_of(rng, struct airoha_trng, rng);
+ u32 val;
+
+ val = readl(trng->base + TRNG_NS_SEK_AND_DAT_EN);
+ val &= ~RNG_EN;
+ writel(val, trng->base + TRNG_NS_SEK_AND_DAT_EN);
+
+ /* Put it in SW Reset */
+ writel(SW_RST, trng->base + TRNG_HEALTH_TEST_SW_RST);
+}
+
+static int airoha_trng_read(struct hwrng *rng, void *buf, size_t max, bool wait)
+{
+ struct airoha_trng *trng = container_of(rng, struct airoha_trng, rng);
+ u32 *data = buf;
+ u32 status;
+ int ret;
+
+ ret = readl_poll_timeout(trng->base + TRNG_HEALTH_TEST_STATUS, status,
+ status & RAW_DATA_VALID, 10, 1000);
+ if (ret < 0) {
+ dev_err(trng->dev, "Timeout waiting for TRNG RAW Data valid\n");
+ return ret;
+ }
+
+ *data = readl(trng->base + TRNG_RAW_DATA_OUT);
+
+ return 4;
+}
+
+static irqreturn_t airoha_trng_irq(int irq, void *priv)
+{
+ struct airoha_trng *trng = (struct airoha_trng *)priv;
+
+ airoha_trng_irq_mask(trng);
+ /* Just complete the task, we will read the value later */
+ complete(&trng->rng_op_done);
+
+ return IRQ_HANDLED;
+}
+
+static int airoha_trng_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct airoha_trng *trng;
+ int irq, ret;
+ u32 val;
+
+ trng = devm_kzalloc(dev, sizeof(*trng), GFP_KERNEL);
+ if (!trng)
+ return -ENOMEM;
+
+ trng->base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(trng->base))
+ return PTR_ERR(trng->base);
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0)
+ return irq;
+
+ airoha_trng_irq_mask(trng);
+ ret = devm_request_irq(&pdev->dev, irq, airoha_trng_irq, 0,
+ pdev->name, (void *)trng);
+ if (ret) {
+ dev_err(dev, "Can't get interrupt working.\n");
+ return ret;
+ }
+
+ init_completion(&trng->rng_op_done);
+
+ /* Enable interrupt for SW reset Health Check */
+ val = readl(trng->base + TRNG_INTR_EN);
+ val |= RST_STARTUP_INITR_EN;
+ writel(val, trng->base + TRNG_INTR_EN);
+
+ /* Set output to raw data */
+ val = readl(trng->base + TRNG_NS_SEK_AND_DAT_EN);
+ val |= RAW_DATA_EN;
+ writel(val, trng->base + TRNG_NS_SEK_AND_DAT_EN);
+
+ /* Put it in SW Reset */
+ writel(SW_RST, trng->base + TRNG_HEALTH_TEST_SW_RST);
+
+ trng->dev = dev;
+ trng->rng.name = pdev->name;
+ trng->rng.init = airoha_trng_init;
+ trng->rng.cleanup = airoha_trng_cleanup;
+ trng->rng.read = airoha_trng_read;
+
+ ret = devm_hwrng_register(dev, &trng->rng);
+ if (ret) {
+ dev_err(dev, "failed to register rng device: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static const struct of_device_id airoha_trng_of_match[] = {
+ { .compatible = "airoha,en7581-trng", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, airoha_trng_of_match);
+
+static struct platform_driver airoha_trng_driver = {
+ .driver = {
+ .name = "airoha-trng",
+ .of_match_table = airoha_trng_of_match,
+ },
+ .probe = airoha_trng_probe,
+};
+
+module_platform_driver(airoha_trng_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Christian Marangi <ansuelsmth@gmail.com>");
+MODULE_DESCRIPTION("Airoha True Random Number Generator driver");
@@ -1,92 +0,0 @@
From 3affa310de523d63e52ea8e2efb3c476df29e414 Mon Sep 17 00:00:00 2001
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Tue, 29 Oct 2024 13:17:09 +0100
Subject: [PATCH 1/2] net: airoha: Read completion queue data in
airoha_qdma_tx_napi_poll()
In order to avoid any possible race, read completion queue head and
pending entry in airoha_qdma_tx_napi_poll routine instead of doing it in
airoha_irq_handler. Remove unused airoha_tx_irq_queue unused fields.
This is a preliminary patch to add Qdisc offload for airoha_eth driver.
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Link: https://patch.msgid.link/20241029-airoha-en7581-tx-napi-work-v1-1-96ad1686b946@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/ethernet/mediatek/airoha_eth.c | 31 +++++++++-------------
1 file changed, 13 insertions(+), 18 deletions(-)
--- a/drivers/net/ethernet/mediatek/airoha_eth.c
+++ b/drivers/net/ethernet/mediatek/airoha_eth.c
@@ -752,11 +752,9 @@ struct airoha_tx_irq_queue {
struct airoha_qdma *qdma;
struct napi_struct napi;
- u32 *q;
int size;
- int queued;
- u16 head;
+ u32 *q;
};
struct airoha_hw_stats {
@@ -1655,25 +1653,31 @@ static int airoha_qdma_init_rx(struct ai
static int airoha_qdma_tx_napi_poll(struct napi_struct *napi, int budget)
{
struct airoha_tx_irq_queue *irq_q;
+ int id, done = 0, irq_queued;
struct airoha_qdma *qdma;
struct airoha_eth *eth;
- int id, done = 0;
+ u32 status, head;
irq_q = container_of(napi, struct airoha_tx_irq_queue, napi);
qdma = irq_q->qdma;
id = irq_q - &qdma->q_tx_irq[0];
eth = qdma->eth;
- while (irq_q->queued > 0 && done < budget) {
- u32 qid, last, val = irq_q->q[irq_q->head];
+ status = airoha_qdma_rr(qdma, REG_IRQ_STATUS(id));
+ head = FIELD_GET(IRQ_HEAD_IDX_MASK, status);
+ head = head % irq_q->size;
+ irq_queued = FIELD_GET(IRQ_ENTRY_LEN_MASK, status);
+
+ while (irq_queued > 0 && done < budget) {
+ u32 qid, last, val = irq_q->q[head];
struct airoha_queue *q;
if (val == 0xff)
break;
- irq_q->q[irq_q->head] = 0xff; /* mark as done */
- irq_q->head = (irq_q->head + 1) % irq_q->size;
- irq_q->queued--;
+ irq_q->q[head] = 0xff; /* mark as done */
+ head = (head + 1) % irq_q->size;
+ irq_queued--;
done++;
last = FIELD_GET(IRQ_DESC_IDX_MASK, val);
@@ -2025,20 +2029,11 @@ static irqreturn_t airoha_irq_handler(in
if (intr[0] & INT_TX_MASK) {
for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++) {
- struct airoha_tx_irq_queue *irq_q = &qdma->q_tx_irq[i];
- u32 status, head;
-
if (!(intr[0] & TX_DONE_INT_MASK(i)))
continue;
airoha_qdma_irq_disable(qdma, QDMA_INT_REG_IDX0,
TX_DONE_INT_MASK(i));
-
- status = airoha_qdma_rr(qdma, REG_IRQ_STATUS(i));
- head = FIELD_GET(IRQ_HEAD_IDX_MASK, status);
- irq_q->head = head % irq_q->size;
- irq_q->queued = FIELD_GET(IRQ_ENTRY_LEN_MASK, status);
-
napi_schedule(&qdma->q_tx_irq[i].napi);
}
}
@@ -1,130 +0,0 @@
From 0c729f53b8c33b9e5eadc2d5e673759e3510501e Mon Sep 17 00:00:00 2001
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Tue, 29 Oct 2024 13:17:10 +0100
Subject: [PATCH 2/2] net: airoha: Simplify Tx napi logic
Simplify Tx napi logic relying just on the packet index provided by
completion queue indicating the completed packet that can be removed
from the Tx DMA ring.
This is a preliminary patch to add Qdisc offload for airoha_eth driver.
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Link: https://patch.msgid.link/20241029-airoha-en7581-tx-napi-work-v1-2-96ad1686b946@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/ethernet/mediatek/airoha_eth.c | 73 ++++++++++++----------
1 file changed, 41 insertions(+), 32 deletions(-)
--- a/drivers/net/ethernet/mediatek/airoha_eth.c
+++ b/drivers/net/ethernet/mediatek/airoha_eth.c
@@ -1669,8 +1669,12 @@ static int airoha_qdma_tx_napi_poll(stru
irq_queued = FIELD_GET(IRQ_ENTRY_LEN_MASK, status);
while (irq_queued > 0 && done < budget) {
- u32 qid, last, val = irq_q->q[head];
+ u32 qid, val = irq_q->q[head];
+ struct airoha_qdma_desc *desc;
+ struct airoha_queue_entry *e;
struct airoha_queue *q;
+ u32 index, desc_ctrl;
+ struct sk_buff *skb;
if (val == 0xff)
break;
@@ -1680,9 +1684,7 @@ static int airoha_qdma_tx_napi_poll(stru
irq_queued--;
done++;
- last = FIELD_GET(IRQ_DESC_IDX_MASK, val);
qid = FIELD_GET(IRQ_RING_IDX_MASK, val);
-
if (qid >= ARRAY_SIZE(qdma->q_tx))
continue;
@@ -1690,46 +1692,53 @@ static int airoha_qdma_tx_napi_poll(stru
if (!q->ndesc)
continue;
+ index = FIELD_GET(IRQ_DESC_IDX_MASK, val);
+ if (index >= q->ndesc)
+ continue;
+
spin_lock_bh(&q->lock);
- while (q->queued > 0) {
- struct airoha_qdma_desc *desc = &q->desc[q->tail];
- struct airoha_queue_entry *e = &q->entry[q->tail];
- u32 desc_ctrl = le32_to_cpu(desc->ctrl);
- struct sk_buff *skb = e->skb;
- u16 index = q->tail;
-
- if (!(desc_ctrl & QDMA_DESC_DONE_MASK) &&
- !(desc_ctrl & QDMA_DESC_DROP_MASK))
- break;
+ if (!q->queued)
+ goto unlock;
- q->tail = (q->tail + 1) % q->ndesc;
- q->queued--;
+ desc = &q->desc[index];
+ desc_ctrl = le32_to_cpu(desc->ctrl);
- dma_unmap_single(eth->dev, e->dma_addr, e->dma_len,
- DMA_TO_DEVICE);
-
- WRITE_ONCE(desc->msg0, 0);
- WRITE_ONCE(desc->msg1, 0);
+ if (!(desc_ctrl & QDMA_DESC_DONE_MASK) &&
+ !(desc_ctrl & QDMA_DESC_DROP_MASK))
+ goto unlock;
+
+ e = &q->entry[index];
+ skb = e->skb;
+
+ dma_unmap_single(eth->dev, e->dma_addr, e->dma_len,
+ DMA_TO_DEVICE);
+ memset(e, 0, sizeof(*e));
+ WRITE_ONCE(desc->msg0, 0);
+ WRITE_ONCE(desc->msg1, 0);
+ q->queued--;
+
+ /* completion ring can report out-of-order indexes if hw QoS
+ * is enabled and packets with different priority are queued
+ * to same DMA ring. Take into account possible out-of-order
+ * reports incrementing DMA ring tail pointer
+ */
+ while (q->tail != q->head && !q->entry[q->tail].dma_addr)
+ q->tail = (q->tail + 1) % q->ndesc;
- if (skb) {
- u16 queue = skb_get_queue_mapping(skb);
- struct netdev_queue *txq;
-
- txq = netdev_get_tx_queue(skb->dev, queue);
- netdev_tx_completed_queue(txq, 1, skb->len);
- if (netif_tx_queue_stopped(txq) &&
- q->ndesc - q->queued >= q->free_thr)
- netif_tx_wake_queue(txq);
-
- dev_kfree_skb_any(skb);
- e->skb = NULL;
- }
+ if (skb) {
+ u16 queue = skb_get_queue_mapping(skb);
+ struct netdev_queue *txq;
+
+ txq = netdev_get_tx_queue(skb->dev, queue);
+ netdev_tx_completed_queue(txq, 1, skb->len);
+ if (netif_tx_queue_stopped(txq) &&
+ q->ndesc - q->queued >= q->free_thr)
+ netif_tx_wake_queue(txq);
- if (index == last)
- break;
+ dev_kfree_skb_any(skb);
}
-
+unlock:
spin_unlock_bh(&q->lock);
}
@@ -1,267 +0,0 @@
From 3cf67f3769b8227ca75ca7102180a2e270ee01aa Mon Sep 17 00:00:00 2001
From: Christian Marangi <ansuelsmth@gmail.com>
Date: Fri, 11 Oct 2024 12:43:53 +0200
Subject: [PATCH] watchdog: Add support for Airoha EN7851 watchdog
Add support for Airoha EN7851 watchdog. This is a very basic watchdog
with no pretimeout support, max timeout is 28 seconds and it ticks based
on half the SoC BUS clock.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Reviewed-by: Guenter Roeck <linux@roeck-us.net>
Link: https://lore.kernel.org/r/20241011104411.28659-2-ansuelsmth@gmail.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Wim Van Sebroeck <wim@linux-watchdog.org>
---
drivers/watchdog/Kconfig | 8 ++
drivers/watchdog/Makefile | 1 +
drivers/watchdog/airoha_wdt.c | 216 ++++++++++++++++++++++++++++++++++
3 files changed, 225 insertions(+)
create mode 100644 drivers/watchdog/airoha_wdt.c
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -408,6 +408,14 @@ config SL28CPLD_WATCHDOG
# ARM Architecture
+config AIROHA_WATCHDOG
+ tristate "Airoha EN7581 Watchdog"
+ depends on ARCH_AIROHA || COMPILE_TEST
+ select WATCHDOG_CORE
+ help
+ Watchdog timer embedded into Airoha SoC. This will reboot your
+ system when the timeout is reached.
+
config ARM_SP805_WATCHDOG
tristate "ARM SP805 Watchdog"
depends on (ARM || ARM64 || COMPILE_TEST) && ARM_AMBA
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -40,6 +40,7 @@ obj-$(CONFIG_USBPCWATCHDOG) += pcwd_usb.
obj-$(CONFIG_ARM_SP805_WATCHDOG) += sp805_wdt.o
obj-$(CONFIG_ARM_SBSA_WATCHDOG) += sbsa_gwdt.o
obj-$(CONFIG_ARMADA_37XX_WATCHDOG) += armada_37xx_wdt.o
+obj-$(CONFIG_AIROHA_WATCHDOG) += airoha_wdt.o
obj-$(CONFIG_ASM9260_WATCHDOG) += asm9260_wdt.o
obj-$(CONFIG_AT91RM9200_WATCHDOG) += at91rm9200_wdt.o
obj-$(CONFIG_AT91SAM9X_WATCHDOG) += at91sam9_wdt.o
--- /dev/null
+++ b/drivers/watchdog/airoha_wdt.c
@@ -0,0 +1,216 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Airoha Watchdog Driver
+ *
+ * Copyright (c) 2024, AIROHA All rights reserved.
+ *
+ * Mayur Kumar <mayur.kumar@airoha.com>
+ * Christian Marangi <ansuelsmth@gmail.com>
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/types.h>
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/math.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/watchdog.h>
+
+/* Base address of timer and watchdog registers */
+#define TIMER_CTRL 0x0
+#define WDT_ENABLE BIT(25)
+#define WDT_TIMER_INTERRUPT BIT(21)
+/* Timer3 is used as Watchdog Timer */
+#define WDT_TIMER_ENABLE BIT(5)
+#define WDT_TIMER_LOAD_VALUE 0x2c
+#define WDT_TIMER_CUR_VALUE 0x30
+#define WDT_TIMER_VAL GENMASK(31, 0)
+#define WDT_RELOAD 0x38
+#define WDT_RLD BIT(0)
+
+/* Airoha watchdog structure description */
+struct airoha_wdt_desc {
+ struct watchdog_device wdog_dev;
+ unsigned int wdt_freq;
+ void __iomem *base;
+};
+
+#define WDT_HEARTBEAT 24
+static int heartbeat = WDT_HEARTBEAT;
+module_param(heartbeat, int, 0);
+MODULE_PARM_DESC(heartbeat, "Watchdog heartbeats in seconds. (default="
+ __MODULE_STRING(WDT_HEARTBEAT) ")");
+
+static bool nowayout = WATCHDOG_NOWAYOUT;
+module_param(nowayout, bool, 0);
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
+ __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
+
+static int airoha_wdt_start(struct watchdog_device *wdog_dev)
+{
+ struct airoha_wdt_desc *airoha_wdt = watchdog_get_drvdata(wdog_dev);
+ u32 val;
+
+ val = readl(airoha_wdt->base + TIMER_CTRL);
+ val |= (WDT_TIMER_ENABLE | WDT_ENABLE | WDT_TIMER_INTERRUPT);
+ writel(val, airoha_wdt->base + TIMER_CTRL);
+ val = wdog_dev->timeout * airoha_wdt->wdt_freq;
+ writel(val, airoha_wdt->base + WDT_TIMER_LOAD_VALUE);
+
+ return 0;
+}
+
+static int airoha_wdt_stop(struct watchdog_device *wdog_dev)
+{
+ struct airoha_wdt_desc *airoha_wdt = watchdog_get_drvdata(wdog_dev);
+ u32 val;
+
+ val = readl(airoha_wdt->base + TIMER_CTRL);
+ val &= (~WDT_ENABLE & ~WDT_TIMER_ENABLE);
+ writel(val, airoha_wdt->base + TIMER_CTRL);
+
+ return 0;
+}
+
+static int airoha_wdt_ping(struct watchdog_device *wdog_dev)
+{
+ struct airoha_wdt_desc *airoha_wdt = watchdog_get_drvdata(wdog_dev);
+ u32 val;
+
+ val = readl(airoha_wdt->base + WDT_RELOAD);
+ val |= WDT_RLD;
+ writel(val, airoha_wdt->base + WDT_RELOAD);
+
+ return 0;
+}
+
+static int airoha_wdt_set_timeout(struct watchdog_device *wdog_dev, unsigned int timeout)
+{
+ wdog_dev->timeout = timeout;
+
+ if (watchdog_active(wdog_dev)) {
+ airoha_wdt_stop(wdog_dev);
+ return airoha_wdt_start(wdog_dev);
+ }
+
+ return 0;
+}
+
+static unsigned int airoha_wdt_get_timeleft(struct watchdog_device *wdog_dev)
+{
+ struct airoha_wdt_desc *airoha_wdt = watchdog_get_drvdata(wdog_dev);
+ u32 val;
+
+ val = readl(airoha_wdt->base + WDT_TIMER_CUR_VALUE);
+ return DIV_ROUND_UP(val, airoha_wdt->wdt_freq);
+}
+
+static const struct watchdog_info airoha_wdt_info = {
+ .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING,
+ .identity = "Airoha Watchdog",
+};
+
+static const struct watchdog_ops airoha_wdt_ops = {
+ .owner = THIS_MODULE,
+ .start = airoha_wdt_start,
+ .stop = airoha_wdt_stop,
+ .ping = airoha_wdt_ping,
+ .set_timeout = airoha_wdt_set_timeout,
+ .get_timeleft = airoha_wdt_get_timeleft,
+};
+
+static int airoha_wdt_probe(struct platform_device *pdev)
+{
+ struct airoha_wdt_desc *airoha_wdt;
+ struct watchdog_device *wdog_dev;
+ struct device *dev = &pdev->dev;
+ struct clk *bus_clk;
+ int ret;
+
+ airoha_wdt = devm_kzalloc(dev, sizeof(*airoha_wdt), GFP_KERNEL);
+ if (!airoha_wdt)
+ return -ENOMEM;
+
+ airoha_wdt->base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(airoha_wdt->base))
+ return PTR_ERR(airoha_wdt->base);
+
+ bus_clk = devm_clk_get_enabled(dev, "bus");
+ if (IS_ERR(bus_clk))
+ return dev_err_probe(dev, PTR_ERR(bus_clk),
+ "failed to enable bus clock\n");
+
+ /* Watchdog ticks at half the bus rate */
+ airoha_wdt->wdt_freq = clk_get_rate(bus_clk) / 2;
+
+ /* Initialize struct watchdog device */
+ wdog_dev = &airoha_wdt->wdog_dev;
+ wdog_dev->timeout = heartbeat;
+ wdog_dev->info = &airoha_wdt_info;
+ wdog_dev->ops = &airoha_wdt_ops;
+ /* Bus 300MHz, watchdog 150MHz, 28 seconds */
+ wdog_dev->max_timeout = FIELD_MAX(WDT_TIMER_VAL) / airoha_wdt->wdt_freq;
+ wdog_dev->parent = dev;
+
+ watchdog_set_drvdata(wdog_dev, airoha_wdt);
+ watchdog_set_nowayout(wdog_dev, nowayout);
+ watchdog_stop_on_unregister(wdog_dev);
+
+ ret = devm_watchdog_register_device(dev, wdog_dev);
+ if (ret)
+ return ret;
+
+ platform_set_drvdata(pdev, airoha_wdt);
+ return 0;
+}
+
+static int airoha_wdt_suspend(struct device *dev)
+{
+ struct airoha_wdt_desc *airoha_wdt = dev_get_drvdata(dev);
+
+ if (watchdog_active(&airoha_wdt->wdog_dev))
+ airoha_wdt_stop(&airoha_wdt->wdog_dev);
+
+ return 0;
+}
+
+static int airoha_wdt_resume(struct device *dev)
+{
+ struct airoha_wdt_desc *airoha_wdt = dev_get_drvdata(dev);
+
+ if (watchdog_active(&airoha_wdt->wdog_dev)) {
+ airoha_wdt_start(&airoha_wdt->wdog_dev);
+ airoha_wdt_ping(&airoha_wdt->wdog_dev);
+ }
+ return 0;
+}
+
+static const struct of_device_id airoha_wdt_of_match[] = {
+ { .compatible = "airoha,en7581-wdt", },
+ { },
+};
+
+MODULE_DEVICE_TABLE(of, airoha_wdt_of_match);
+
+static DEFINE_SIMPLE_DEV_PM_OPS(airoha_wdt_pm_ops, airoha_wdt_suspend, airoha_wdt_resume);
+
+static struct platform_driver airoha_wdt_driver = {
+ .probe = airoha_wdt_probe,
+ .driver = {
+ .name = "airoha-wdt",
+ .pm = pm_sleep_ptr(&airoha_wdt_pm_ops),
+ .of_match_table = airoha_wdt_of_match,
+ },
+};
+
+module_platform_driver(airoha_wdt_driver);
+
+MODULE_AUTHOR("Mayur Kumar <mayur.kumar@airoha.com>");
+MODULE_AUTHOR("Christian Marangi <ansuelsmth@gmail.com>");
+MODULE_DESCRIPTION("Airoha EN7581 Watchdog Driver");
+MODULE_LICENSE("GPL");
@@ -1,174 +0,0 @@
From 82e6bf912d5846646892becea659b39d178d79e3 Mon Sep 17 00:00:00 2001
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Tue, 12 Nov 2024 01:08:53 +0100
Subject: [PATCH 5/6] clk: en7523: move en7581_reset_register() in
en7581_clk_hw_init()
Move en7581_reset_register routine in en7581_clk_hw_init() since reset
feature is supported just by EN7581 SoC.
Get rid of reset struct in en_clk_soc_data data struct.
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Link: https://lore.kernel.org/r/20241112-clk-en7581-syscon-v2-6-8ada5e394ae4@kernel.org
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
---
drivers/clk/clk-en7523.c | 93 ++++++++++++++--------------------------
1 file changed, 33 insertions(+), 60 deletions(-)
--- a/drivers/clk/clk-en7523.c
+++ b/drivers/clk/clk-en7523.c
@@ -76,11 +76,6 @@ struct en_rst_data {
struct en_clk_soc_data {
const struct clk_ops pcie_ops;
- struct {
- const u16 *bank_ofs;
- const u16 *idx_map;
- u16 idx_map_nr;
- } reset;
int (*hw_init)(struct platform_device *pdev,
struct clk_hw_onecell_data *clk_data);
};
@@ -596,32 +591,6 @@ static void en7581_register_clocks(struc
clk_data->num = EN7523_NUM_CLOCKS;
}
-static int en7581_clk_hw_init(struct platform_device *pdev,
- struct clk_hw_onecell_data *clk_data)
-{
- void __iomem *np_base;
- struct regmap *map;
- u32 val;
-
- map = syscon_regmap_lookup_by_compatible("airoha,en7581-chip-scu");
- if (IS_ERR(map))
- return PTR_ERR(map);
-
- np_base = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(np_base))
- return PTR_ERR(np_base);
-
- en7581_register_clocks(&pdev->dev, clk_data, map, np_base);
-
- val = readl(np_base + REG_NP_SCU_SSTR);
- val &= ~(REG_PCIE_XSI0_SEL_MASK | REG_PCIE_XSI1_SEL_MASK);
- writel(val, np_base + REG_NP_SCU_SSTR);
- val = readl(np_base + REG_NP_SCU_PCIC);
- writel(val | 3, np_base + REG_NP_SCU_PCIC);
-
- return 0;
-}
-
static int en7523_reset_update(struct reset_controller_dev *rcdev,
unsigned long id, bool assert)
{
@@ -671,23 +640,18 @@ static int en7523_reset_xlate(struct res
return rst_data->idx_map[reset_spec->args[0]];
}
-static const struct reset_control_ops en7523_reset_ops = {
+static const struct reset_control_ops en7581_reset_ops = {
.assert = en7523_reset_assert,
.deassert = en7523_reset_deassert,
.status = en7523_reset_status,
};
-static int en7523_reset_register(struct platform_device *pdev,
- const struct en_clk_soc_data *soc_data)
+static int en7581_reset_register(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct en_rst_data *rst_data;
void __iomem *base;
- /* no reset lines available */
- if (!soc_data->reset.idx_map_nr)
- return 0;
-
base = devm_platform_ioremap_resource(pdev, 1);
if (IS_ERR(base))
return PTR_ERR(base);
@@ -696,13 +660,13 @@ static int en7523_reset_register(struct
if (!rst_data)
return -ENOMEM;
- rst_data->bank_ofs = soc_data->reset.bank_ofs;
- rst_data->idx_map = soc_data->reset.idx_map;
+ rst_data->bank_ofs = en7581_rst_ofs;
+ rst_data->idx_map = en7581_rst_map;
rst_data->base = base;
- rst_data->rcdev.nr_resets = soc_data->reset.idx_map_nr;
+ rst_data->rcdev.nr_resets = ARRAY_SIZE(en7581_rst_map);
rst_data->rcdev.of_xlate = en7523_reset_xlate;
- rst_data->rcdev.ops = &en7523_reset_ops;
+ rst_data->rcdev.ops = &en7581_reset_ops;
rst_data->rcdev.of_node = dev->of_node;
rst_data->rcdev.of_reset_n_cells = 1;
rst_data->rcdev.owner = THIS_MODULE;
@@ -711,6 +675,32 @@ static int en7523_reset_register(struct
return devm_reset_controller_register(dev, &rst_data->rcdev);
}
+static int en7581_clk_hw_init(struct platform_device *pdev,
+ struct clk_hw_onecell_data *clk_data)
+{
+ void __iomem *np_base;
+ struct regmap *map;
+ u32 val;
+
+ map = syscon_regmap_lookup_by_compatible("airoha,en7581-chip-scu");
+ if (IS_ERR(map))
+ return PTR_ERR(map);
+
+ np_base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(np_base))
+ return PTR_ERR(np_base);
+
+ en7581_register_clocks(&pdev->dev, clk_data, map, np_base);
+
+ val = readl(np_base + REG_NP_SCU_SSTR);
+ val &= ~(REG_PCIE_XSI0_SEL_MASK | REG_PCIE_XSI1_SEL_MASK);
+ writel(val, np_base + REG_NP_SCU_SSTR);
+ val = readl(np_base + REG_NP_SCU_PCIC);
+ writel(val | 3, np_base + REG_NP_SCU_PCIC);
+
+ return en7581_reset_register(pdev);
+}
+
static int en7523_clk_probe(struct platform_device *pdev)
{
struct device_node *node = pdev->dev.of_node;
@@ -729,19 +719,7 @@ static int en7523_clk_probe(struct platf
if (r)
return r;
- r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
- if (r)
- return dev_err_probe(&pdev->dev, r, "Could not register clock provider: %s\n",
- pdev->name);
-
- r = en7523_reset_register(pdev, soc_data);
- if (r) {
- of_clk_del_provider(node);
- return dev_err_probe(&pdev->dev, r, "Could not register reset controller: %s\n",
- pdev->name);
- }
-
- return 0;
+ return of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
}
static const struct en_clk_soc_data en7523_data = {
@@ -759,11 +737,6 @@ static const struct en_clk_soc_data en75
.enable = en7581_pci_enable,
.disable = en7581_pci_disable,
},
- .reset = {
- .bank_ofs = en7581_rst_ofs,
- .idx_map = en7581_rst_map,
- .idx_map_nr = ARRAY_SIZE(en7581_rst_map),
- },
.hw_init = en7581_clk_hw_init,
};
@@ -1,84 +0,0 @@
From a9eaf305017a5ebe73ab34e85bd5414055a88f29 Mon Sep 17 00:00:00 2001
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Tue, 12 Nov 2024 01:08:54 +0100
Subject: [PATCH 6/6] clk: en7523: map io region in a single block
Map all clock-controller memory region in a single block.
This patch does not introduce any backward incompatibility since the dts
for EN7581 SoC is not upstream yet.
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Link: https://lore.kernel.org/r/20241112-clk-en7581-syscon-v2-7-8ada5e394ae4@kernel.org
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
---
drivers/clk/clk-en7523.c | 32 +++++++++++++-------------------
1 file changed, 13 insertions(+), 19 deletions(-)
--- a/drivers/clk/clk-en7523.c
+++ b/drivers/clk/clk-en7523.c
@@ -39,8 +39,8 @@
#define REG_PCIE_XSI1_SEL_MASK GENMASK(12, 11)
#define REG_CRYPTO_CLKSRC2 0x20c
-#define REG_RST_CTRL2 0x00
-#define REG_RST_CTRL1 0x04
+#define REG_RST_CTRL2 0x830
+#define REG_RST_CTRL1 0x834
struct en_clk_desc {
int id;
@@ -646,15 +646,9 @@ static const struct reset_control_ops en
.status = en7523_reset_status,
};
-static int en7581_reset_register(struct platform_device *pdev)
+static int en7581_reset_register(struct device *dev, void __iomem *base)
{
- struct device *dev = &pdev->dev;
struct en_rst_data *rst_data;
- void __iomem *base;
-
- base = devm_platform_ioremap_resource(pdev, 1);
- if (IS_ERR(base))
- return PTR_ERR(base);
rst_data = devm_kzalloc(dev, sizeof(*rst_data), GFP_KERNEL);
if (!rst_data)
@@ -678,27 +672,27 @@ static int en7581_reset_register(struct
static int en7581_clk_hw_init(struct platform_device *pdev,
struct clk_hw_onecell_data *clk_data)
{
- void __iomem *np_base;
struct regmap *map;
+ void __iomem *base;
u32 val;
map = syscon_regmap_lookup_by_compatible("airoha,en7581-chip-scu");
if (IS_ERR(map))
return PTR_ERR(map);
- np_base = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(np_base))
- return PTR_ERR(np_base);
+ base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(base))
+ return PTR_ERR(base);
- en7581_register_clocks(&pdev->dev, clk_data, map, np_base);
+ en7581_register_clocks(&pdev->dev, clk_data, map, base);
- val = readl(np_base + REG_NP_SCU_SSTR);
+ val = readl(base + REG_NP_SCU_SSTR);
val &= ~(REG_PCIE_XSI0_SEL_MASK | REG_PCIE_XSI1_SEL_MASK);
- writel(val, np_base + REG_NP_SCU_SSTR);
- val = readl(np_base + REG_NP_SCU_PCIC);
- writel(val | 3, np_base + REG_NP_SCU_PCIC);
+ writel(val, base + REG_NP_SCU_SSTR);
+ val = readl(base + REG_NP_SCU_PCIC);
+ writel(val | 3, base + REG_NP_SCU_PCIC);
- return en7581_reset_register(pdev);
+ return en7581_reset_register(&pdev->dev, base);
}
static int en7523_clk_probe(struct platform_device *pdev)
@@ -1,61 +0,0 @@
From ac6f0825e582f2216a582c9edf0cee7bfe347ba6 Mon Sep 17 00:00:00 2001
From: Kees Cook <kees@kernel.org>
Date: Sun, 17 Nov 2024 03:45:38 -0800
Subject: [PATCH] pinctrl: airoha: Use unsigned long for bit search
Instead of risking alignment problems and causing (false positive) array
bound warnings when casting a u32 to (64-bit) unsigned long, just use a
native unsigned long for doing bit searches. Avoids warning with GCC 15's
-Warray-bounds -fdiagnostics-details:
In file included from ../include/linux/bitmap.h:11,
from ../include/linux/cpumask.h:12,
from ../arch/x86/include/asm/paravirt.h:21,
from ../arch/x86/include/asm/irqflags.h:80,
from ../include/linux/irqflags.h:18,
from ../include/linux/spinlock.h:59,
from ../include/linux/irq.h:14,
from ../include/linux/irqchip/chained_irq.h:10,
from ../include/linux/gpio/driver.h:8,
from ../drivers/pinctrl/mediatek/pinctrl-airoha.c:11:
In function 'find_next_bit',
inlined from 'airoha_irq_handler' at ../drivers/pinctrl/mediatek/pinctrl-airoha.c:2394:3:
../include/linux/find.h:65:23: error: array subscript 'long unsigned int[0]' is partly outside array bounds of 'u32[1]' {aka 'unsigned int[1]'} [-Werror=array-bounds=]
65 | val = *addr & GENMASK(size - 1, offset);
| ^~~~~
../drivers/pinctrl/mediatek/pinctrl-airoha.c: In function 'airoha_irq_handler':
../drivers/pinctrl/mediatek/pinctrl-airoha.c:2387:21: note: object 'status' of size 4
2387 | u32 status;
| ^~~~~~
Signed-off-by: Kees Cook <kees@kernel.org>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Link: https://lore.kernel.org/20241117114534.work.292-kees@kernel.org
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
drivers/pinctrl/mediatek/pinctrl-airoha.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
--- a/drivers/pinctrl/mediatek/pinctrl-airoha.c
+++ b/drivers/pinctrl/mediatek/pinctrl-airoha.c
@@ -2384,15 +2384,16 @@ static irqreturn_t airoha_irq_handler(in
for (i = 0; i < ARRAY_SIZE(irq_status_regs); i++) {
struct gpio_irq_chip *girq = &pinctrl->gpiochip.chip.irq;
- u32 status;
+ u32 regmap;
+ unsigned long status;
int irq;
if (regmap_read(pinctrl->regmap, pinctrl->gpiochip.status[i],
- &status))
+ &regmap))
continue;
- for_each_set_bit(irq, (unsigned long *)&status,
- AIROHA_PIN_BANK_SIZE) {
+ status = regmap;
+ for_each_set_bit(irq, &status, AIROHA_PIN_BANK_SIZE) {
u32 offset = irq + i * AIROHA_PIN_BANK_SIZE;
generic_handle_irq(irq_find_mapping(girq->domain,
@@ -1,35 +0,0 @@
From 30d9d8f6a2d7e44a9f91737dd409dbc87ac6f6b7 Mon Sep 17 00:00:00 2001
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Tue, 15 Oct 2024 09:58:09 +0200
Subject: [PATCH] net: airoha: Fix typo in REG_CDM2_FWD_CFG configuration
Fix typo in airoha_fe_init routine configuring CDM2_OAM_QSEL_MASK field
of REG_CDM2_FWD_CFG register.
This bug is not introducing any user visible problem since Frame Engine
CDM2 port is used just by the second QDMA block and we currently enable
just QDMA1 block connected to the MT7530 dsa switch via CDM1 port.
Introduced by commit 23020f049327 ("net: airoha: Introduce ethernet
support for EN7581 SoC")
Reported-by: ChihWei Cheng <chihwei.cheng@airoha.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Reviewed-by: Simon Horman <horms@kernel.org>
Message-ID: <20241015-airoha-eth-cdm2-fixes-v1-1-9dc6993286c3@kernel.org>
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
drivers/net/ethernet/mediatek/airoha_eth.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/net/ethernet/mediatek/airoha_eth.c
+++ b/drivers/net/ethernet/mediatek/airoha_eth.c
@@ -1369,7 +1369,8 @@ static int airoha_fe_init(struct airoha_
airoha_fe_set(eth, REG_GDM_MISC_CFG,
GDM2_RDM_ACK_WAIT_PREF_MASK |
GDM2_CHN_VLD_MODE_MASK);
- airoha_fe_rmw(eth, REG_CDM2_FWD_CFG, CDM2_OAM_QSEL_MASK, 15);
+ airoha_fe_rmw(eth, REG_CDM2_FWD_CFG, CDM2_OAM_QSEL_MASK,
+ FIELD_PREP(CDM2_OAM_QSEL_MASK, 15));
/* init fragment and assemble Force Port */
/* NPU Core-3, NPU Bridge Channel-3 */
@@ -1,27 +0,0 @@
From 5f795590380476f1c9b7ed0ac945c9b0269dc23a Mon Sep 17 00:00:00 2001
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Fri, 3 Jan 2025 13:17:02 +0100
Subject: [PATCH 1/4] net: airoha: Enable Tx drop capability for each Tx DMA
ring
This is a preliminary patch in order to enable hw Qdisc offloading.
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
drivers/net/ethernet/mediatek/airoha_eth.c | 4 ++++
1 file changed, 4 insertions(+)
--- a/drivers/net/ethernet/mediatek/airoha_eth.c
+++ b/drivers/net/ethernet/mediatek/airoha_eth.c
@@ -1789,6 +1789,10 @@ static int airoha_qdma_init_tx_queue(str
WRITE_ONCE(q->desc[i].ctrl, cpu_to_le32(val));
}
+ /* xmit ring drop default setting */
+ airoha_qdma_set(qdma, REG_TX_RING_BLOCKING(qid),
+ TX_RING_IRQ_BLOCKING_TX_DROP_EN_MASK);
+
airoha_qdma_wr(qdma, REG_TX_RING_BASE(qid), dma_addr);
airoha_qdma_rmw(qdma, REG_TX_CPU_IDX(qid), TX_RING_CPU_IDX_MASK,
FIELD_PREP(TX_RING_CPU_IDX_MASK, q->head));
@@ -1,86 +0,0 @@
From 2b288b81560b94958cd68bbe54673e55a1730c95 Mon Sep 17 00:00:00 2001
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Fri, 3 Jan 2025 13:17:03 +0100
Subject: [PATCH 2/4] net: airoha: Introduce ndo_select_queue callback
Airoha EN7581 SoC supports 32 Tx DMA rings used to feed packets to QoS
channels. Each channels supports 8 QoS queues where the user can apply
QoS scheduling policies. In a similar way, the user can configure hw
rate shaping for each QoS channel.
Introduce ndo_select_queue callback in order to select the tx queue
based on QoS channel and QoS queue. In particular, for dsa device select
QoS channel according to the dsa user port index, rely on port id
otherwise. Select QoS queue based on the skb priority.
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
drivers/net/ethernet/mediatek/airoha_eth.c | 30 ++++++++++++++++++++--
1 file changed, 28 insertions(+), 2 deletions(-)
--- a/drivers/net/ethernet/mediatek/airoha_eth.c
+++ b/drivers/net/ethernet/mediatek/airoha_eth.c
@@ -23,6 +23,8 @@
#define AIROHA_MAX_NUM_XSI_RSTS 5
#define AIROHA_MAX_MTU 2000
#define AIROHA_MAX_PACKET_SIZE 2048
+#define AIROHA_NUM_QOS_CHANNELS 4
+#define AIROHA_NUM_QOS_QUEUES 8
#define AIROHA_NUM_TX_RING 32
#define AIROHA_NUM_RX_RING 32
#define AIROHA_FE_MC_MAX_VLAN_TABLE 64
@@ -2421,21 +2423,44 @@ static void airoha_dev_get_stats64(struc
} while (u64_stats_fetch_retry(&port->stats.syncp, start));
}
+static u16 airoha_dev_select_queue(struct net_device *dev, struct sk_buff *skb,
+ struct net_device *sb_dev)
+{
+ struct airoha_gdm_port *port = netdev_priv(dev);
+ int queue, channel;
+
+ /* For dsa device select QoS channel according to the dsa user port
+ * index, rely on port id otherwise. Select QoS queue based on the
+ * skb priority.
+ */
+ channel = netdev_uses_dsa(dev) ? skb_get_queue_mapping(skb) : port->id;
+ channel = channel % AIROHA_NUM_QOS_CHANNELS;
+ queue = (skb->priority - 1) % AIROHA_NUM_QOS_QUEUES; /* QoS queue */
+ queue = channel * AIROHA_NUM_QOS_QUEUES + queue;
+
+ return queue < dev->num_tx_queues ? queue : 0;
+}
+
static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
struct net_device *dev)
{
struct skb_shared_info *sinfo = skb_shinfo(skb);
struct airoha_gdm_port *port = netdev_priv(dev);
- u32 msg0 = 0, msg1, len = skb_headlen(skb);
- int i, qid = skb_get_queue_mapping(skb);
+ u32 msg0, msg1, len = skb_headlen(skb);
struct airoha_qdma *qdma = port->qdma;
u32 nr_frags = 1 + sinfo->nr_frags;
struct netdev_queue *txq;
struct airoha_queue *q;
void *data = skb->data;
+ int i, qid;
u16 index;
u8 fport;
+ qid = skb_get_queue_mapping(skb) % ARRAY_SIZE(qdma->q_tx);
+ msg0 = FIELD_PREP(QDMA_ETH_TXMSG_CHAN_MASK,
+ qid / AIROHA_NUM_QOS_QUEUES) |
+ FIELD_PREP(QDMA_ETH_TXMSG_QUEUE_MASK,
+ qid % AIROHA_NUM_QOS_QUEUES);
if (skb->ip_summed == CHECKSUM_PARTIAL)
msg0 |= FIELD_PREP(QDMA_ETH_TXMSG_TCO_MASK, 1) |
FIELD_PREP(QDMA_ETH_TXMSG_UCO_MASK, 1) |
@@ -2609,6 +2634,7 @@ static const struct net_device_ops airoh
.ndo_init = airoha_dev_init,
.ndo_open = airoha_dev_open,
.ndo_stop = airoha_dev_stop,
+ .ndo_select_queue = airoha_dev_select_queue,
.ndo_start_xmit = airoha_dev_xmit,
.ndo_get_stats64 = airoha_dev_get_stats64,
.ndo_set_mac_address = airoha_dev_set_macaddr,
@@ -1,292 +0,0 @@
From 20bf7d07c956e5c7a22d3076c599cbb7a6054917 Mon Sep 17 00:00:00 2001
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Fri, 3 Jan 2025 13:17:04 +0100
Subject: [PATCH 3/4] net: airoha: Add sched ETS offload support
Introduce support for ETS Qdisc offload available on the Airoha EN7581
ethernet controller. In order to be effective, ETS Qdisc must configured
as leaf of a HTB Qdisc (HTB Qdisc offload will be added in the following
patch). ETS Qdisc available on EN7581 ethernet controller supports at
most 8 concurrent bands (QoS queues). We can enable an ETS Qdisc for
each available QoS channel.
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
drivers/net/ethernet/mediatek/airoha_eth.c | 196 ++++++++++++++++++++-
1 file changed, 195 insertions(+), 1 deletion(-)
--- a/drivers/net/ethernet/mediatek/airoha_eth.c
+++ b/drivers/net/ethernet/mediatek/airoha_eth.c
@@ -15,6 +15,7 @@
#include <linux/u64_stats_sync.h>
#include <net/dsa.h>
#include <net/page_pool/helpers.h>
+#include <net/pkt_cls.h>
#include <uapi/linux/ppp_defs.h>
#define AIROHA_MAX_NUM_GDM_PORTS 1
@@ -543,9 +544,24 @@
#define INGRESS_SLOW_TICK_RATIO_MASK GENMASK(29, 16)
#define INGRESS_FAST_TICK_MASK GENMASK(15, 0)
+#define REG_QUEUE_CLOSE_CFG(_n) (0x00a0 + ((_n) & 0xfc))
+#define TXQ_DISABLE_CHAN_QUEUE_MASK(_n, _m) BIT((_m) + (((_n) & 0x3) << 3))
+
#define REG_TXQ_DIS_CFG_BASE(_n) ((_n) ? 0x20a0 : 0x00a0)
#define REG_TXQ_DIS_CFG(_n, _m) (REG_TXQ_DIS_CFG_BASE((_n)) + (_m) << 2)
+#define REG_CNTR_CFG(_n) (0x0400 + ((_n) << 3))
+#define CNTR_EN_MASK BIT(31)
+#define CNTR_ALL_CHAN_EN_MASK BIT(30)
+#define CNTR_ALL_QUEUE_EN_MASK BIT(29)
+#define CNTR_ALL_DSCP_RING_EN_MASK BIT(28)
+#define CNTR_SRC_MASK GENMASK(27, 24)
+#define CNTR_DSCP_RING_MASK GENMASK(20, 16)
+#define CNTR_CHAN_MASK GENMASK(7, 3)
+#define CNTR_QUEUE_MASK GENMASK(2, 0)
+
+#define REG_CNTR_VAL(_n) (0x0404 + ((_n) << 3))
+
#define REG_LMGR_INIT_CFG 0x1000
#define LMGR_INIT_START BIT(31)
#define LMGR_SRAM_MODE_MASK BIT(30)
@@ -571,9 +587,19 @@
#define TWRR_WEIGHT_SCALE_MASK BIT(31)
#define TWRR_WEIGHT_BASE_MASK BIT(3)
+#define REG_TXWRR_WEIGHT_CFG 0x1024
+#define TWRR_RW_CMD_MASK BIT(31)
+#define TWRR_RW_CMD_DONE BIT(30)
+#define TWRR_CHAN_IDX_MASK GENMASK(23, 19)
+#define TWRR_QUEUE_IDX_MASK GENMASK(18, 16)
+#define TWRR_VALUE_MASK GENMASK(15, 0)
+
#define REG_PSE_BUF_USAGE_CFG 0x1028
#define PSE_BUF_ESTIMATE_EN_MASK BIT(29)
+#define REG_CHAN_QOS_MODE(_n) (0x1040 + ((_n) << 2))
+#define CHAN_QOS_MODE_MASK(_n) GENMASK(2 + ((_n) << 2), (_n) << 2)
+
#define REG_GLB_TRTCM_CFG 0x1080
#define GLB_TRTCM_EN_MASK BIT(31)
#define GLB_TRTCM_MODE_MASK BIT(30)
@@ -722,6 +748,17 @@ enum {
FE_PSE_PORT_DROP = 0xf,
};
+enum tx_sched_mode {
+ TC_SCH_WRR8,
+ TC_SCH_SP,
+ TC_SCH_WRR7,
+ TC_SCH_WRR6,
+ TC_SCH_WRR5,
+ TC_SCH_WRR4,
+ TC_SCH_WRR3,
+ TC_SCH_WRR2,
+};
+
struct airoha_queue_entry {
union {
void *buf;
@@ -812,6 +849,10 @@ struct airoha_gdm_port {
int id;
struct airoha_hw_stats stats;
+
+ /* qos stats counters */
+ u64 cpu_tx_packets;
+ u64 fwd_tx_packets;
};
struct airoha_eth {
@@ -1961,6 +2002,27 @@ static void airoha_qdma_init_qos(struct
FIELD_PREP(SLA_SLOW_TICK_RATIO_MASK, 40));
}
+static void airoha_qdma_init_qos_stats(struct airoha_qdma *qdma)
+{
+ int i;
+
+ for (i = 0; i < AIROHA_NUM_QOS_CHANNELS; i++) {
+ /* Tx-cpu transferred count */
+ airoha_qdma_wr(qdma, REG_CNTR_VAL(i << 1), 0);
+ airoha_qdma_wr(qdma, REG_CNTR_CFG(i << 1),
+ CNTR_EN_MASK | CNTR_ALL_QUEUE_EN_MASK |
+ CNTR_ALL_DSCP_RING_EN_MASK |
+ FIELD_PREP(CNTR_CHAN_MASK, i));
+ /* Tx-fwd transferred count */
+ airoha_qdma_wr(qdma, REG_CNTR_VAL((i << 1) + 1), 0);
+ airoha_qdma_wr(qdma, REG_CNTR_CFG(i << 1),
+ CNTR_EN_MASK | CNTR_ALL_QUEUE_EN_MASK |
+ CNTR_ALL_DSCP_RING_EN_MASK |
+ FIELD_PREP(CNTR_SRC_MASK, 1) |
+ FIELD_PREP(CNTR_CHAN_MASK, i));
+ }
+}
+
static int airoha_qdma_hw_init(struct airoha_qdma *qdma)
{
int i;
@@ -2011,6 +2073,7 @@ static int airoha_qdma_hw_init(struct ai
airoha_qdma_set(qdma, REG_TXQ_CNGST_CFG,
TXQ_CNGST_DROP_EN | TXQ_CNGST_DEI_DROP_EN);
+ airoha_qdma_init_qos_stats(qdma);
return 0;
}
@@ -2630,6 +2693,135 @@ airoha_ethtool_get_rmon_stats(struct net
} while (u64_stats_fetch_retry(&port->stats.syncp, start));
}
+static int airoha_qdma_set_chan_tx_sched(struct airoha_gdm_port *port,
+ int channel, enum tx_sched_mode mode,
+ const u16 *weights, u8 n_weights)
+{
+ int i;
+
+ for (i = 0; i < AIROHA_NUM_TX_RING; i++)
+ airoha_qdma_clear(port->qdma, REG_QUEUE_CLOSE_CFG(channel),
+ TXQ_DISABLE_CHAN_QUEUE_MASK(channel, i));
+
+ for (i = 0; i < n_weights; i++) {
+ u32 status;
+ int err;
+
+ airoha_qdma_wr(port->qdma, REG_TXWRR_WEIGHT_CFG,
+ TWRR_RW_CMD_MASK |
+ FIELD_PREP(TWRR_CHAN_IDX_MASK, channel) |
+ FIELD_PREP(TWRR_QUEUE_IDX_MASK, i) |
+ FIELD_PREP(TWRR_VALUE_MASK, weights[i]));
+ err = read_poll_timeout(airoha_qdma_rr, status,
+ status & TWRR_RW_CMD_DONE,
+ USEC_PER_MSEC, 10 * USEC_PER_MSEC,
+ true, port->qdma,
+ REG_TXWRR_WEIGHT_CFG);
+ if (err)
+ return err;
+ }
+
+ airoha_qdma_rmw(port->qdma, REG_CHAN_QOS_MODE(channel >> 3),
+ CHAN_QOS_MODE_MASK(channel),
+ mode << __ffs(CHAN_QOS_MODE_MASK(channel)));
+
+ return 0;
+}
+
+static int airoha_qdma_set_tx_prio_sched(struct airoha_gdm_port *port,
+ int channel)
+{
+ static const u16 w[AIROHA_NUM_QOS_QUEUES] = {};
+
+ return airoha_qdma_set_chan_tx_sched(port, channel, TC_SCH_SP, w,
+ ARRAY_SIZE(w));
+}
+
+static int airoha_qdma_set_tx_ets_sched(struct airoha_gdm_port *port,
+ int channel,
+ struct tc_ets_qopt_offload *opt)
+{
+ struct tc_ets_qopt_offload_replace_params *p = &opt->replace_params;
+ enum tx_sched_mode mode = TC_SCH_SP;
+ u16 w[AIROHA_NUM_QOS_QUEUES] = {};
+ int i, nstrict = 0;
+
+ if (p->bands > AIROHA_NUM_QOS_QUEUES)
+ return -EINVAL;
+
+ for (i = 0; i < p->bands; i++) {
+ if (!p->quanta[i])
+ nstrict++;
+ }
+
+ /* this configuration is not supported by the hw */
+ if (nstrict == AIROHA_NUM_QOS_QUEUES - 1)
+ return -EINVAL;
+
+ for (i = 0; i < p->bands - nstrict; i++)
+ w[i] = p->weights[nstrict + i];
+
+ if (!nstrict)
+ mode = TC_SCH_WRR8;
+ else if (nstrict < AIROHA_NUM_QOS_QUEUES - 1)
+ mode = nstrict + 1;
+
+ return airoha_qdma_set_chan_tx_sched(port, channel, mode, w,
+ ARRAY_SIZE(w));
+}
+
+static int airoha_qdma_get_tx_ets_stats(struct airoha_gdm_port *port,
+ int channel,
+ struct tc_ets_qopt_offload *opt)
+{
+ u64 cpu_tx_packets = airoha_qdma_rr(port->qdma,
+ REG_CNTR_VAL(channel << 1));
+ u64 fwd_tx_packets = airoha_qdma_rr(port->qdma,
+ REG_CNTR_VAL((channel << 1) + 1));
+ u64 tx_packets = (cpu_tx_packets - port->cpu_tx_packets) +
+ (fwd_tx_packets - port->fwd_tx_packets);
+ _bstats_update(opt->stats.bstats, 0, tx_packets);
+
+ port->cpu_tx_packets = cpu_tx_packets;
+ port->fwd_tx_packets = fwd_tx_packets;
+
+ return 0;
+}
+
+static int airoha_tc_setup_qdisc_ets(struct airoha_gdm_port *port,
+ struct tc_ets_qopt_offload *opt)
+{
+ int channel = TC_H_MAJ(opt->handle) >> 16;
+
+ if (opt->parent == TC_H_ROOT)
+ return -EINVAL;
+
+ switch (opt->command) {
+ case TC_ETS_REPLACE:
+ return airoha_qdma_set_tx_ets_sched(port, channel, opt);
+ case TC_ETS_DESTROY:
+ /* PRIO is default qdisc scheduler */
+ return airoha_qdma_set_tx_prio_sched(port, channel);
+ case TC_ETS_STATS:
+ return airoha_qdma_get_tx_ets_stats(port, channel, opt);
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+static int airoha_dev_tc_setup(struct net_device *dev, enum tc_setup_type type,
+ void *type_data)
+{
+ struct airoha_gdm_port *port = netdev_priv(dev);
+
+ switch (type) {
+ case TC_SETUP_QDISC_ETS:
+ return airoha_tc_setup_qdisc_ets(port, type_data);
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
static const struct net_device_ops airoha_netdev_ops = {
.ndo_init = airoha_dev_init,
.ndo_open = airoha_dev_open,
@@ -2638,6 +2830,7 @@ static const struct net_device_ops airoh
.ndo_start_xmit = airoha_dev_xmit,
.ndo_get_stats64 = airoha_dev_get_stats64,
.ndo_set_mac_address = airoha_dev_set_macaddr,
+ .ndo_setup_tc = airoha_dev_tc_setup,
};
static const struct ethtool_ops airoha_ethtool_ops = {
@@ -2687,7 +2880,8 @@ static int airoha_alloc_gdm_port(struct
dev->watchdog_timeo = 5 * HZ;
dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_RXCSUM |
NETIF_F_TSO6 | NETIF_F_IPV6_CSUM |
- NETIF_F_SG | NETIF_F_TSO;
+ NETIF_F_SG | NETIF_F_TSO |
+ NETIF_F_HW_TC;
dev->features |= dev->hw_features;
dev->dev.of_node = np;
dev->irq = qdma->irq;
@@ -1,371 +0,0 @@
From ef1ca9271313b4ea7b03de69576aacef1e78f381 Mon Sep 17 00:00:00 2001
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Fri, 3 Jan 2025 13:17:05 +0100
Subject: [PATCH 4/4] net: airoha: Add sched HTB offload support
Introduce support for HTB Qdisc offload available in the Airoha EN7581
ethernet controller. EN7581 can offload only one level of HTB leafs.
Each HTB leaf represents a QoS channel supported by EN7581 SoC.
The typical use-case is creating a HTB leaf for QoS channel to rate
limit the egress traffic and attach an ETS Qdisc to each HTB leaf in
order to enforce traffic prioritization.
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
drivers/net/ethernet/mediatek/airoha_eth.c | 288 ++++++++++++++++++++-
1 file changed, 287 insertions(+), 1 deletion(-)
--- a/drivers/net/ethernet/mediatek/airoha_eth.c
+++ b/drivers/net/ethernet/mediatek/airoha_eth.c
@@ -28,6 +28,8 @@
#define AIROHA_NUM_QOS_QUEUES 8
#define AIROHA_NUM_TX_RING 32
#define AIROHA_NUM_RX_RING 32
+#define AIROHA_NUM_NETDEV_TX_RINGS (AIROHA_NUM_TX_RING + \
+ AIROHA_NUM_QOS_CHANNELS)
#define AIROHA_FE_MC_MAX_VLAN_TABLE 64
#define AIROHA_FE_MC_MAX_VLAN_PORT 16
#define AIROHA_NUM_TX_IRQ 2
@@ -43,6 +45,9 @@
#define PSE_RSV_PAGES 128
#define PSE_QUEUE_RSV_PAGES 64
+#define QDMA_METER_IDX(_n) ((_n) & 0xff)
+#define QDMA_METER_GROUP(_n) (((_n) >> 8) & 0x3)
+
/* FE */
#define PSE_BASE 0x0100
#define CSR_IFC_BASE 0x0200
@@ -583,6 +588,17 @@
#define EGRESS_SLOW_TICK_RATIO_MASK GENMASK(29, 16)
#define EGRESS_FAST_TICK_MASK GENMASK(15, 0)
+#define TRTCM_PARAM_RW_MASK BIT(31)
+#define TRTCM_PARAM_RW_DONE_MASK BIT(30)
+#define TRTCM_PARAM_TYPE_MASK GENMASK(29, 28)
+#define TRTCM_METER_GROUP_MASK GENMASK(27, 26)
+#define TRTCM_PARAM_INDEX_MASK GENMASK(23, 17)
+#define TRTCM_PARAM_RATE_TYPE_MASK BIT(16)
+
+#define REG_TRTCM_CFG_PARAM(_n) ((_n) + 0x4)
+#define REG_TRTCM_DATA_LOW(_n) ((_n) + 0x8)
+#define REG_TRTCM_DATA_HIGH(_n) ((_n) + 0xc)
+
#define REG_TXWRR_MODE_CFG 0x1020
#define TWRR_WEIGHT_SCALE_MASK BIT(31)
#define TWRR_WEIGHT_BASE_MASK BIT(3)
@@ -759,6 +775,29 @@ enum tx_sched_mode {
TC_SCH_WRR2,
};
+enum trtcm_param_type {
+ TRTCM_MISC_MODE, /* meter_en, pps_mode, tick_sel */
+ TRTCM_TOKEN_RATE_MODE,
+ TRTCM_BUCKETSIZE_SHIFT_MODE,
+ TRTCM_BUCKET_COUNTER_MODE,
+};
+
+enum trtcm_mode_type {
+ TRTCM_COMMIT_MODE,
+ TRTCM_PEAK_MODE,
+};
+
+enum trtcm_param {
+ TRTCM_TICK_SEL = BIT(0),
+ TRTCM_PKT_MODE = BIT(1),
+ TRTCM_METER_MODE = BIT(2),
+};
+
+#define MIN_TOKEN_SIZE 4096
+#define MAX_TOKEN_SIZE_OFFSET 17
+#define TRTCM_TOKEN_RATE_MASK GENMASK(23, 6)
+#define TRTCM_TOKEN_RATE_FRACTION_MASK GENMASK(5, 0)
+
struct airoha_queue_entry {
union {
void *buf;
@@ -850,6 +889,8 @@ struct airoha_gdm_port {
struct airoha_hw_stats stats;
+ DECLARE_BITMAP(qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS);
+
/* qos stats counters */
u64 cpu_tx_packets;
u64 fwd_tx_packets;
@@ -2809,6 +2850,243 @@ static int airoha_tc_setup_qdisc_ets(str
}
}
+static int airoha_qdma_get_trtcm_param(struct airoha_qdma *qdma, int channel,
+ u32 addr, enum trtcm_param_type param,
+ enum trtcm_mode_type mode,
+ u32 *val_low, u32 *val_high)
+{
+ u32 idx = QDMA_METER_IDX(channel), group = QDMA_METER_GROUP(channel);
+ u32 val, config = FIELD_PREP(TRTCM_PARAM_TYPE_MASK, param) |
+ FIELD_PREP(TRTCM_METER_GROUP_MASK, group) |
+ FIELD_PREP(TRTCM_PARAM_INDEX_MASK, idx) |
+ FIELD_PREP(TRTCM_PARAM_RATE_TYPE_MASK, mode);
+
+ airoha_qdma_wr(qdma, REG_TRTCM_CFG_PARAM(addr), config);
+ if (read_poll_timeout(airoha_qdma_rr, val,
+ val & TRTCM_PARAM_RW_DONE_MASK,
+ USEC_PER_MSEC, 10 * USEC_PER_MSEC, true,
+ qdma, REG_TRTCM_CFG_PARAM(addr)))
+ return -ETIMEDOUT;
+
+ *val_low = airoha_qdma_rr(qdma, REG_TRTCM_DATA_LOW(addr));
+ if (val_high)
+ *val_high = airoha_qdma_rr(qdma, REG_TRTCM_DATA_HIGH(addr));
+
+ return 0;
+}
+
+static int airoha_qdma_set_trtcm_param(struct airoha_qdma *qdma, int channel,
+ u32 addr, enum trtcm_param_type param,
+ enum trtcm_mode_type mode, u32 val)
+{
+ u32 idx = QDMA_METER_IDX(channel), group = QDMA_METER_GROUP(channel);
+ u32 config = TRTCM_PARAM_RW_MASK |
+ FIELD_PREP(TRTCM_PARAM_TYPE_MASK, param) |
+ FIELD_PREP(TRTCM_METER_GROUP_MASK, group) |
+ FIELD_PREP(TRTCM_PARAM_INDEX_MASK, idx) |
+ FIELD_PREP(TRTCM_PARAM_RATE_TYPE_MASK, mode);
+
+ airoha_qdma_wr(qdma, REG_TRTCM_DATA_LOW(addr), val);
+ airoha_qdma_wr(qdma, REG_TRTCM_CFG_PARAM(addr), config);
+
+ return read_poll_timeout(airoha_qdma_rr, val,
+ val & TRTCM_PARAM_RW_DONE_MASK,
+ USEC_PER_MSEC, 10 * USEC_PER_MSEC, true,
+ qdma, REG_TRTCM_CFG_PARAM(addr));
+}
+
+static int airoha_qdma_set_trtcm_config(struct airoha_qdma *qdma, int channel,
+ u32 addr, enum trtcm_mode_type mode,
+ bool enable, u32 enable_mask)
+{
+ u32 val;
+
+ if (airoha_qdma_get_trtcm_param(qdma, channel, addr, TRTCM_MISC_MODE,
+ mode, &val, NULL))
+ return -EINVAL;
+
+ val = enable ? val | enable_mask : val & ~enable_mask;
+
+ return airoha_qdma_set_trtcm_param(qdma, channel, addr, TRTCM_MISC_MODE,
+ mode, val);
+}
+
+static int airoha_qdma_set_trtcm_token_bucket(struct airoha_qdma *qdma,
+ int channel, u32 addr,
+ enum trtcm_mode_type mode,
+ u32 rate_val, u32 bucket_size)
+{
+ u32 val, config, tick, unit, rate, rate_frac;
+ int err;
+
+ if (airoha_qdma_get_trtcm_param(qdma, channel, addr, TRTCM_MISC_MODE,
+ mode, &config, NULL))
+ return -EINVAL;
+
+ val = airoha_qdma_rr(qdma, addr);
+ tick = FIELD_GET(INGRESS_FAST_TICK_MASK, val);
+ if (config & TRTCM_TICK_SEL)
+ tick *= FIELD_GET(INGRESS_SLOW_TICK_RATIO_MASK, val);
+ if (!tick)
+ return -EINVAL;
+
+ unit = (config & TRTCM_PKT_MODE) ? 1000000 / tick : 8000 / tick;
+ if (!unit)
+ return -EINVAL;
+
+ rate = rate_val / unit;
+ rate_frac = rate_val % unit;
+ rate_frac = FIELD_PREP(TRTCM_TOKEN_RATE_MASK, rate_frac) / unit;
+ rate = FIELD_PREP(TRTCM_TOKEN_RATE_MASK, rate) |
+ FIELD_PREP(TRTCM_TOKEN_RATE_FRACTION_MASK, rate_frac);
+
+ err = airoha_qdma_set_trtcm_param(qdma, channel, addr,
+ TRTCM_TOKEN_RATE_MODE, mode, rate);
+ if (err)
+ return err;
+
+ val = max_t(u32, bucket_size, MIN_TOKEN_SIZE);
+ val = min_t(u32, __fls(val), MAX_TOKEN_SIZE_OFFSET);
+
+ return airoha_qdma_set_trtcm_param(qdma, channel, addr,
+ TRTCM_BUCKETSIZE_SHIFT_MODE,
+ mode, val);
+}
+
+static int airoha_qdma_set_tx_rate_limit(struct airoha_gdm_port *port,
+ int channel, u32 rate,
+ u32 bucket_size)
+{
+ int i, err;
+
+ for (i = 0; i <= TRTCM_PEAK_MODE; i++) {
+ err = airoha_qdma_set_trtcm_config(port->qdma, channel,
+ REG_EGRESS_TRTCM_CFG, i,
+ !!rate, TRTCM_METER_MODE);
+ if (err)
+ return err;
+
+ err = airoha_qdma_set_trtcm_token_bucket(port->qdma, channel,
+ REG_EGRESS_TRTCM_CFG,
+ i, rate, bucket_size);
+ if (err)
+ return err;
+ }
+
+ return 0;
+}
+
+static int airoha_tc_htb_alloc_leaf_queue(struct airoha_gdm_port *port,
+ struct tc_htb_qopt_offload *opt)
+{
+ u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS;
+ u32 rate = div_u64(opt->rate, 1000) << 3; /* kbps */
+ struct net_device *dev = port->dev;
+ int num_tx_queues = dev->real_num_tx_queues;
+ int err;
+
+ if (opt->parent_classid != TC_HTB_CLASSID_ROOT) {
+ NL_SET_ERR_MSG_MOD(opt->extack, "invalid parent classid");
+ return -EINVAL;
+ }
+
+ err = airoha_qdma_set_tx_rate_limit(port, channel, rate, opt->quantum);
+ if (err) {
+ NL_SET_ERR_MSG_MOD(opt->extack,
+ "failed configuring htb offload");
+ return err;
+ }
+
+ if (opt->command == TC_HTB_NODE_MODIFY)
+ return 0;
+
+ err = netif_set_real_num_tx_queues(dev, num_tx_queues + 1);
+ if (err) {
+ airoha_qdma_set_tx_rate_limit(port, channel, 0, opt->quantum);
+ NL_SET_ERR_MSG_MOD(opt->extack,
+ "failed setting real_num_tx_queues");
+ return err;
+ }
+
+ set_bit(channel, port->qos_sq_bmap);
+ opt->qid = AIROHA_NUM_TX_RING + channel;
+
+ return 0;
+}
+
+static void airoha_tc_remove_htb_queue(struct airoha_gdm_port *port, int queue)
+{
+ struct net_device *dev = port->dev;
+
+ netif_set_real_num_tx_queues(dev, dev->real_num_tx_queues - 1);
+ airoha_qdma_set_tx_rate_limit(port, queue + 1, 0, 0);
+ clear_bit(queue, port->qos_sq_bmap);
+}
+
+static int airoha_tc_htb_delete_leaf_queue(struct airoha_gdm_port *port,
+ struct tc_htb_qopt_offload *opt)
+{
+ u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS;
+
+ if (!test_bit(channel, port->qos_sq_bmap)) {
+ NL_SET_ERR_MSG_MOD(opt->extack, "invalid queue id");
+ return -EINVAL;
+ }
+
+ airoha_tc_remove_htb_queue(port, channel);
+
+ return 0;
+}
+
+static int airoha_tc_htb_destroy(struct airoha_gdm_port *port)
+{
+ int q;
+
+ for_each_set_bit(q, port->qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS)
+ airoha_tc_remove_htb_queue(port, q);
+
+ return 0;
+}
+
+static int airoha_tc_get_htb_get_leaf_queue(struct airoha_gdm_port *port,
+ struct tc_htb_qopt_offload *opt)
+{
+ u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS;
+
+ if (!test_bit(channel, port->qos_sq_bmap)) {
+ NL_SET_ERR_MSG_MOD(opt->extack, "invalid queue id");
+ return -EINVAL;
+ }
+
+ opt->qid = channel;
+
+ return 0;
+}
+
+static int airoha_tc_setup_qdisc_htb(struct airoha_gdm_port *port,
+ struct tc_htb_qopt_offload *opt)
+{
+ switch (opt->command) {
+ case TC_HTB_CREATE:
+ break;
+ case TC_HTB_DESTROY:
+ return airoha_tc_htb_destroy(port);
+ case TC_HTB_NODE_MODIFY:
+ case TC_HTB_LEAF_ALLOC_QUEUE:
+ return airoha_tc_htb_alloc_leaf_queue(port, opt);
+ case TC_HTB_LEAF_DEL:
+ case TC_HTB_LEAF_DEL_LAST:
+ case TC_HTB_LEAF_DEL_LAST_FORCE:
+ return airoha_tc_htb_delete_leaf_queue(port, opt);
+ case TC_HTB_LEAF_QUERY_QUEUE:
+ return airoha_tc_get_htb_get_leaf_queue(port, opt);
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ return 0;
+}
+
static int airoha_dev_tc_setup(struct net_device *dev, enum tc_setup_type type,
void *type_data)
{
@@ -2817,6 +3095,8 @@ static int airoha_dev_tc_setup(struct ne
switch (type) {
case TC_SETUP_QDISC_ETS:
return airoha_tc_setup_qdisc_ets(port, type_data);
+ case TC_SETUP_QDISC_HTB:
+ return airoha_tc_setup_qdisc_htb(port, type_data);
default:
return -EOPNOTSUPP;
}
@@ -2867,7 +3147,8 @@ static int airoha_alloc_gdm_port(struct
}
dev = devm_alloc_etherdev_mqs(eth->dev, sizeof(*port),
- AIROHA_NUM_TX_RING, AIROHA_NUM_RX_RING);
+ AIROHA_NUM_NETDEV_TX_RINGS,
+ AIROHA_NUM_RX_RING);
if (!dev) {
dev_err(eth->dev, "alloc_etherdev failed\n");
return -ENOMEM;
@@ -2887,6 +3168,11 @@ static int airoha_alloc_gdm_port(struct
dev->irq = qdma->irq;
SET_NETDEV_DEV(dev, eth->dev);
+ /* reserve hw queues for HTB offloading */
+ err = netif_set_real_num_tx_queues(dev, AIROHA_NUM_TX_RING);
+ if (err)
+ return err;
+
err = of_get_ethdev_address(np, dev);
if (err) {
if (err == -EPROBE_DEFER)

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