Merge branch 'master'

This commit is contained in:
VIKING 2025-11-12 20:13:18 +08:00
commit 75fa41f09c
35 changed files with 518 additions and 280 deletions

View File

@ -78,7 +78,7 @@ _ignore = $(foreach p,$(IGNORE_PACKAGES),--ignore $(p))
prepare-tmpinfo: FORCE
@+$(MAKE) -r -s $(STAGING_DIR_HOST)/.prereq-build $(PREP_MK)
mkdir -p tmp/info feeds
[ -e $(TOPDIR)/feeds/base ] || ln -sf $(TOPDIR)/package $(TOPDIR)/feeds/base
[ -e $(TOPDIR)/feeds/base ] || ln -sf ../package $(TOPDIR)/feeds/base
$(_SINGLE)$(NO_TRACE_MAKE) -j1 -r -s -f include/scan.mk SCAN_TARGET="packageinfo" SCAN_DIR="package" SCAN_NAME="package" SCAN_DEPTH=5 SCAN_EXTRA=""
$(_SINGLE)$(NO_TRACE_MAKE) -j1 -r -s -f include/scan.mk SCAN_TARGET="targetinfo" SCAN_DIR="target/linux" SCAN_NAME="target" SCAN_DEPTH=3 SCAN_EXTRA="" SCAN_MAKEOPTS="TARGET_BUILD=1"
for type in package target; do \

View File

@ -13,7 +13,6 @@ include $(INCLUDE_DIR)/host-build.mk
define U-Boot/Default
BUILD_TARGET:=airoha
HIDDEN:=1
FIP_COMPRESS:=1
endef

View File

@ -604,3 +604,55 @@ define KernelPackage/sound-hda-intel/description
endef
$(eval $(call KernelPackage,sound-hda-intel))
define KernelPackage/sound-midi2
TITLE:=MIDI 2.0 and UMP Support
KCONFIG:= \
CONFIG_SND_UMP=y \
CONFIG_SND_UMP_LEGACY_RAWMIDI=y
FILES:=$(LINUX_DIR)/sound/core/snd-ump.ko
AUTOLOAD:=$(call AutoProbe,snd-ump)
$(call AddDepends/sound)
endef
define KernelPackage/sound-midi2/description
Kernel module for MIDI 2.0: sequencer, rawmidi, and USB-MIDI 2.0 support.
endef
$(eval $(call KernelPackage,sound-midi2))
define KernelPackage/sound-midi2-seq
TITLE:=MIDI 2.0 and UMP Support for Sequencer
KCONFIG:= \
CONFIG_SND_SEQ_UMP=y \
CONFIG_SND_SEQ_UMP_CLIENT=y
DEPENDS:=+kmod-sound-midi2 +kmod-sound-seq
$(call AddDepends/sound)
endef
$(eval $(call KernelPackage,sound-midi2-seq))
define KernelPackage/sound-midi2-usb
TITLE:=MIDI 2.0 and UMP Support for USB-MIDI
KCONFIG:=CONFIG_SND_USB_AUDIO_MIDI_V2=y
DEPENDS:=+kmod-sound-midi2 +kmod-usb-audio
$(call AddDepends/sound)
endef
$(eval $(call KernelPackage,sound-midi2-usb))
define KernelPackage/sound-dynamic-minors
TITLE:=Support more than 8 audio and MIDI devices
KCONFIG:=CONFIG_SND_DYNAMIC_MINORS=y
$(call AddDepends/sound)
endef
define KernelPackage/sound-dynamic-minors/description
Kernel module for dynamic minor device support.
Required for using more than 8 audio and MIDI devices.
endef
$(eval $(call KernelPackage,sound-dynamic-minors))

View File

@ -616,7 +616,7 @@ define KernelPackage/usb-audio
CONFIG_SND_USB_AUDIO
$(call AddDepends/usb)
$(call AddDepends/sound)
DEPENDS+=+kmod-media-controller
DEPENDS+=+kmod-media-controller +PACKAGE_kmod-sound-midi2-usb:kmod-sound-midi2
FILES:= \
$(LINUX_DIR)/sound/usb/snd-usbmidi-lib.ko \
$(LINUX_DIR)/sound/usb/snd-usb-audio.ko

View File

@ -12,9 +12,9 @@ PKG_RELEASE:=1
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL=$(PROJECT_GIT)/project/libnl-tiny.git
PKG_SOURCE_DATE:=2025-10-03
PKG_SOURCE_VERSION:=feca1d341d4baa9579ec62762672aa0f20edf564
PKG_MIRROR_HASH:=270788e1e7d2939aba2f9277101eebdfafabe5030317fa87936340061c374dfe
PKG_SOURCE_DATE:=2025-11-03
PKG_SOURCE_VERSION:=532ac744dedcf83c06e2f4a8320fcc8089f23b72
PKG_MIRROR_HASH:=f6f6432b0aa859ffe3012f5b57590823cb4540d97fd6a13ccd8d8f5572a0ca3f
CMAKE_INSTALL:=1
PKG_LICENSE:=LGPL-2.1

View File

@ -5,9 +5,9 @@ PKG_RELEASE=1
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL=$(PROJECT_GIT)/project/libubox.git
PKG_MIRROR_HASH:=1bd10702d3291b6bd78dffefae94d84b01ae5da9f3e2149f8e611e7535fb55bb
PKG_SOURCE_DATE:=2025-10-04
PKG_SOURCE_VERSION:=c163d7ab8cdc248a4f82efe339ba29fd8001b5e7
PKG_MIRROR_HASH:=09eea2e6f46cc3d481f952e2555b50bc4bb0fadc63cf75e32a8613fcbba1d8c8
PKG_SOURCE_DATE:=2025-11-03
PKG_SOURCE_VERSION:=e357be611cd9deb280c61bbdf331f5a85e75a485
PKG_ABI_VERSION:=$(call abi_version_str,$(PKG_SOURCE_DATE))
CMAKE_INSTALL:=1

View File

@ -11,9 +11,9 @@ PKG_NAME:=udebug
CMAKE_INSTALL:=1
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL=$(PROJECT_GIT)/project/udebug.git
PKG_MIRROR_HASH:=d198d95f83f0d2c17ea30039db85a4bd50360886b0963e227d2d879406b79c27
PKG_SOURCE_DATE:=2025-09-28
PKG_SOURCE_VERSION:=5327524e715332daaebf6b04c155d2880d230979
PKG_MIRROR_HASH:=eb40871f2259e17b6e3ee2c01930a6faffb5e0a7db7589827a9e1efda267726f
PKG_SOURCE_DATE:=2025-10-21
PKG_SOURCE_VERSION:=75f39cd4a8067a6f0503c2f1c83c6b1af733a6f2
PKG_ABI_VERSION:=$(call abi_version_str,$(PKG_SOURCE_DATE))
PKG_LICENSE:=GPL-2.0
@ -73,7 +73,7 @@ endef
define Package/udebug-cli/install
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/udebug-cli $(1)/usr/sbin/udebug
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/udebug $(1)/usr/sbin/udebug
endef
$(eval $(call BuildPackage,libudebug))

View File

@ -9,7 +9,7 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=firewall
PKG_RELEASE:=1
PKG_RELEASE:=2
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL=$(PROJECT_GIT)/project/firewall3.git

View File

@ -61,6 +61,7 @@ config rule
option name Allow-DHCPv6
option src wan
option proto udp
option dest_ip fe80::/10
option dest_port 546
option family ipv6
option target ACCEPT

View File

@ -6,6 +6,13 @@ import { find_phy } from 'wifi.utils';
import * as uci from 'uci';
import * as iwinfo from 'iwinfo';
function normalize_ssid(ssid) {
if (!ssid)
return 'unknown';
return '"' + replace(ssid, /[[:cntrl:]]/g,
function(c) { return '\\x' + hexenc(c); }) + '"'
}
function print_assoclist(stations) {
for (let mac, station in stations) {
printf(`${station.mac} ${station.signal} dBm / ${station.noise} dBm (SNR ${station.snr}) ${station.inactive_time} ms ago\n`);
@ -44,7 +51,7 @@ function print_info(list) {
let padding = ' ';
for (let bss in list) {
printf(`${bss.iface} ESSID: ${bss.ssid === null ? 'unknown' : '"' + bss.ssid + '"'}\n`);
printf(`${bss.iface} ESSID: ${normalize_ssid(bss.ssid)}\n`);
printf(`${padding}Access Point: ${bss.mac}\n`);
printf(`${padding}Mode: ${bss.mode} Channel: ${bss.channel} (${bss.freq} GHz) HT Mode: ${bss.htmode}\n`);
printf(`${padding}Center Channel 1: ${bss.center_freq1} 2: ${bss.center_freq2}\n`);
@ -69,6 +76,7 @@ function print_scan(cells) {
for (let cell in cells) {
printf('Cell %02d - Address: %s\n', idx++, cell.bssid);
printf('\t ESSID: %s\n', normalize_ssid(cell.ssid));
printf('\t Mode: %s Frequency: %s GHz Band: %s GHz Channel: %d\n', cell.mode, cell.frequency, cell.band, cell.channel);
printf('\t Signal: %d dBm Quality: %2d/70\n', cell.dbm, cell.quality);

View File

@ -172,29 +172,59 @@ function format_rate(rate) {
function format_mgmt_key(key) {
switch(+key) {
case 1:
case 11:
case 12:
case 13:
case 14:
case 15:
case 16:
case 17:
return '802.1x';
case 2:
return 'WPA PSK';
case 3:
return 'FT 802.1x';
case 4:
return 'FT PSK';
case 6:
return 'WPA PSK2';
case 5:
case 11: // deprecated 802.1x-suiteB-SHA256
return '802.1x-SHA256';
case 8:
case 6:
return 'WPA PSK-SHA256';
case 8: // SAE with SHA256
case 24: // SAE using group-dependent hash
return 'SAE';
case 9: // FT SAE with SHA256
case 25: // FT SAE using group-dependent hash
return 'FT SAE';
case 12:
return '802.1x-192bit';
case 13:
return 'FT 802.1x-SHA384';
case 14:
return 'FILS-SHA256';
case 15:
return 'FILS-SHA384';
case 16:
return 'FT FILS-SHA256';
case 17:
return 'FT FILS-SHA384';
case 18:
return 'OWE';
case 19:
return 'FT PSK-SHA384';
case 20:
return 'WPA PSK-SHA384';
}
return null;

View File

@ -324,7 +324,7 @@ hostapd_common_add_bss_config() {
config_add_string 'key1:wepkey' 'key2:wepkey' 'key3:wepkey' 'key4:wepkey' 'password:wpakey'
config_add_string wpa_psk_file
config_add_string wpa_psk_file sae_password_file
config_add_int multi_ap

View File

@ -12,9 +12,9 @@ PKG_RELEASE:=1
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL=$(PROJECT_GIT)/project/odhcp6c.git
PKG_SOURCE_DATE:=2025-11-04
PKG_SOURCE_VERSION:=b3e1db42b4dbb5f99705e4d1057ca49b44f4f5ee
PKG_MIRROR_HASH:=37ddaf182eba190efc091d7b9c963e84dfe0537ce498ad4be1c268bea134782e
PKG_SOURCE_DATE:=2025-11-09
PKG_SOURCE_VERSION:=e5690c1f13ed3605ece68d870abb3c4a2f09d571
PKG_MIRROR_HASH:=4dbf3980f8ac72f92f68c5dbac7179c28aab0e012a53162e0defbbf5959a9389
PKG_MAINTAINER:=Hans Dedecker <dedeckeh@gmail.com>
PKG_LICENSE:=GPL-2.0

View File

@ -1,5 +1,5 @@
#
# Copyright (C) 2013-2015 OpenWrt.org
# Copyright (C) 2013-2025 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
@ -8,7 +8,7 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=odhcpd
PKG_RELEASE:=1
PKG_RELEASE:=5
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL=$(PROJECT_GIT)/project/odhcpd.git
@ -19,7 +19,6 @@ PKG_SOURCE_VERSION:=d44af6dd8f4e1dd0d858ae19419057ab4f319310
PKG_MAINTAINER:=Hans Dedecker <dedeckeh@gmail.com>
PKG_LICENSE:=GPL-2.0
PKG_CONFIG_DEPENDS:=CONFIG_PACKAGE_odhcpd_$(BUILD_VARIANT)_ext_cer_id
PKG_ASLR_PIE_REGULAR:=1
include $(INCLUDE_DIR)/package.mk
@ -28,7 +27,6 @@ include $(INCLUDE_DIR)/cmake.mk
define Package/odhcpd/default
SECTION:=net
CATEGORY:=Network
TITLE:=OpenWrt DHCPv6(-PD)/RA Server & Relay
DEPENDS:=+libjson-c +libubox +libuci +libubus +libnl-tiny
endef
@ -38,48 +36,33 @@ define Package/odhcpd/default/description
requirements for IPv6 home routers.
endef
define Package/odhcpd/default/config
menu "Configuration"
depends on PACKAGE_$(1)
config PACKAGE_odhcpd_$(2)_ext_cer_id
int
default 0
prompt "CER-ID Extension ID (0 = disabled)"
endmenu
endef
define Package/odhcpd
$(call Package/odhcpd/default)
TITLE += and DHCPv4 server
$(Package/odhcpd/default)
TITLE:=OpenWrt DHCPv4/DHCPv6/NDP/RA server
VARIANT:=full
endef
Package/odhcpd/config=$(call Package/odhcpd/default/config,odhcpd,full)
define Package/odhcpd/description
$(call Package/odhcpd/default/description)
$(Package/odhcpd/default/description)
This is a variant providing server services for DHCPv4, RA, stateless and
stateful DHCPv6, prefix delegation and can be used to relay RA, DHCPv6 and
NDP between routed (non-bridged) interfaces in case no delegated prefixes
are available.
This is a variant with support for RA, DHCPv4 and DHCPv6. It can also be used
to relay RA, DHCPv6 and NDP messages between routed (non-bridged) interfaces
in case no delegated prefixes are available.
endef
define Package/odhcpd-ipv6only
$(call Package/odhcpd/default)
$(Package/odhcpd/default)
TITLE:=OpenWrt DHCPv6/NDP/RA server (without DHCPv4)
VARIANT:=ipv6only
DEPENDS+= @IPV6
DEPENDS+=@IPV6
endef
Package/odhcpd-ipv6only/config=$(call Package/odhcpd/default/config,odhcpd-ipv6only,ipv6only)
define Package/odhcpd-ipv6only/description
$(call Package/odhcpd/default/description)
$(Package/odhcpd/default/description)
This is a variant providing server services for RA, stateless and stateful
DHCPv6, prefix delegation and can be used to relay RA, DHCPv6 and NDP between
routed (non-bridged) interfaces in case no delegated prefixes are available.
This is a variant with support for RA and DHCPv6. It can also be used to
relay RA, DHCPv6 and NDP messages between routed (non-bridged) interfaces
in case no delegated prefixes are available.
endef
CMAKE_OPTIONS += -DUBUS=1
@ -88,10 +71,6 @@ ifeq ($(BUILD_VARIANT),full)
CMAKE_OPTIONS += -DDHCPV4_SUPPORT=1
endif
ifneq ($(CONFIG_PACKAGE_odhcpd_$(BUILD_VARIANT)_ext_cer_id),0)
CMAKE_OPTIONS += -DEXT_CER_ID=$(CONFIG_PACKAGE_odhcpd_$(BUILD_VARIANT)_ext_cer_id)
endif
define Package/odhcpd/install
$(INSTALL_DIR) $(1)/usr/sbin/
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/odhcpd $(1)/usr/sbin/

View File

@ -1,11 +1,20 @@
#!/bin/sh
if [ -n "$(uci -q get dhcp.odhcpd)" ]; then
local commit
commit=0
if [ -z "$(uci -q get dhcp.odhcpd.piofolder)" ]; then
uci set dhcp.odhcpd.piofolder=/tmp/odhcpd-piofolder
uci commit dhcp
commit=1
fi
if [ -n "$(uci -q get dhcp.odhcpd.legacy)" ]; then
uci delete dhcp.odhcpd.legacy
commit=1
fi
[ "$commit" -eq 1 ] && uci commit dhcp
exit 0
fi
@ -34,7 +43,7 @@ case "$protocol" in
;;
esac
uci get dhcp.lan 1>/dev/null 2>/dev/null || {
uci -q get dhcp.lan || {
uci batch <<EOF
set dhcp.lan=dhcp
set dhcp.lan.interface='lan'

View File

@ -17,6 +17,5 @@ reload_service() {
service_triggers()
{
procd_add_reload_trigger "dhcp"
procd_add_reload_trigger "dhcp" "network" "system"
}

View File

@ -5,9 +5,9 @@ PKG_RELEASE:=1
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL=$(PROJECT_GIT)/project/ubox.git
PKG_SOURCE_DATE:=2025-10-03
PKG_SOURCE_VERSION:=c75525a58a7ea1363f96bac9f9b4104971c1eb03
PKG_MIRROR_HASH:=8992d2629c6b391fe2eff6bbe0343140a67e9f7ae1f5bda1e52dafed993352f2
PKG_SOURCE_DATE:=2025-10-30
PKG_SOURCE_VERSION:=6f78fa496bf36c55864a41e353df7d13f04b1077
PKG_MIRROR_HASH:=41c28d9152cdf2998a4d867827655548f823de9de522a113a45ed1efef97d3ae
CMAKE_INSTALL:=1
PKG_LICENSE:=GPL-2.0

View File

@ -5,9 +5,9 @@ PKG_RELEASE:=1
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL=$(PROJECT_GIT)/project/ubus.git
PKG_SOURCE_DATE:=2025-10-17
PKG_SOURCE_VERSION:=60e04048a0e2f3e33651c19e62861b41be4c290f
PKG_MIRROR_HASH:=2db028305ae58afe184bb01e51d3635898d84ffcd04308a73ce143c05fc7b2db
PKG_SOURCE_DATE:=2025-11-03
PKG_SOURCE_VERSION:=0d4bcb56f5e1386e7dc99f1ec9f3b6c9211c8ab6
PKG_MIRROR_HASH:=c3f8519fbe1fa3795925e327eeaf292f0325c9ebb696ff2ea73877e9d0186075
PKG_ABI_VERSION:=$(call abi_version_str,$(PKG_SOURCE_DATE))
CMAKE_INSTALL:=1

View File

@ -13,9 +13,9 @@ PKG_RELEASE:=1
PKG_SOURCE_URL=$(PROJECT_GIT)/project/uci.git
PKG_SOURCE_PROTO:=git
PKG_SOURCE_DATE:=2025-10-05
PKG_SOURCE_VERSION:=5e69edac2ec4d23a443de11d6f3f11912d8b2d89
PKG_MIRROR_HASH:=7a9c61049635bbba61f6d05bb93f0e72806c8e253fabd75946c87e823c26bcfd
PKG_SOURCE_DATE:=2025-11-03
PKG_SOURCE_VERSION:=c1e2eee6c5e35438daf13fa72b04778ff07a00c7
PKG_MIRROR_HASH:=cad94326f6d0bae44ad59d6dc371c78cbb1ed5f74f85d79167cba0f1f8d01eee
PKG_ABI_VERSION:=20250120
PKG_LICENSE:=LGPL-2.1

View File

@ -300,7 +300,7 @@ 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_PHY_AIROHA_USB is not set
CONFIG_PINCTRL=y
CONFIG_PINCTRL_AIROHA=y
# CONFIG_PINCTRL_MT2712 is not set

View File

@ -0,0 +1,245 @@
From 3f47e67dff1f7266e112c50313d63824f6f17102 Mon Sep 17 00:00:00 2001
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Thu, 6 Nov 2025 13:53:23 +0100
Subject: [PATCH] net: airoha: Add the capability to consume out-of-order DMA
tx descriptors
EN7581 and AN7583 SoCs are capable of DMA mapping non-linear tx skbs on
non-consecutive DMA descriptors. This feature is useful when multiple
flows are queued on the same hw tx queue since it allows to fully utilize
the available tx DMA descriptors and to avoid the starvation of
high-priority flow we have in the current codebase due to head-of-line
blocking introduced by low-priority flows.
Tested-by: Xuegang Lu <xuegang.lu@airoha.com>
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Link: https://patch.msgid.link/20251106-airoha-tx-linked-list-v2-1-0706d4a322bd@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/ethernet/airoha/airoha_eth.c | 85 +++++++++++-------------
drivers/net/ethernet/airoha/airoha_eth.h | 7 +-
2 files changed, 45 insertions(+), 47 deletions(-)
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -892,19 +892,13 @@ static int airoha_qdma_tx_napi_poll(stru
dma_unmap_single(eth->dev, e->dma_addr, e->dma_len,
DMA_TO_DEVICE);
- memset(e, 0, sizeof(*e));
+ e->dma_addr = 0;
+ list_add_tail(&e->list, &q->tx_list);
+
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;
@@ -949,6 +943,7 @@ static int airoha_qdma_init_tx_queue(str
q->ndesc = size;
q->qdma = qdma;
q->free_thr = 1 + MAX_SKB_FRAGS;
+ INIT_LIST_HEAD(&q->tx_list);
q->entry = devm_kzalloc(eth->dev, q->ndesc * sizeof(*q->entry),
GFP_KERNEL);
@@ -961,9 +956,9 @@ static int airoha_qdma_init_tx_queue(str
return -ENOMEM;
for (i = 0; i < q->ndesc; i++) {
- u32 val;
+ u32 val = FIELD_PREP(QDMA_DESC_DONE_MASK, 1);
- val = FIELD_PREP(QDMA_DESC_DONE_MASK, 1);
+ list_add_tail(&q->entry[i].list, &q->tx_list);
WRITE_ONCE(q->desc[i].ctrl, cpu_to_le32(val));
}
@@ -973,9 +968,9 @@ static int airoha_qdma_init_tx_queue(str
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));
+ FIELD_PREP(TX_RING_CPU_IDX_MASK, 0));
airoha_qdma_rmw(qdma, REG_TX_DMA_IDX(qid), TX_RING_DMA_IDX_MASK,
- FIELD_PREP(TX_RING_DMA_IDX_MASK, q->head));
+ FIELD_PREP(TX_RING_DMA_IDX_MASK, 0));
return 0;
}
@@ -1031,17 +1026,21 @@ static int airoha_qdma_init_tx(struct ai
static void airoha_qdma_cleanup_tx_queue(struct airoha_queue *q)
{
struct airoha_eth *eth = q->qdma->eth;
+ int i;
spin_lock_bh(&q->lock);
- while (q->queued) {
- struct airoha_queue_entry *e = &q->entry[q->tail];
+ for (i = 0; i < q->ndesc; i++) {
+ struct airoha_queue_entry *e = &q->entry[i];
+
+ if (!e->dma_addr)
+ continue;
dma_unmap_single(eth->dev, e->dma_addr, e->dma_len,
DMA_TO_DEVICE);
dev_kfree_skb_any(e->skb);
+ e->dma_addr = 0;
e->skb = NULL;
-
- q->tail = (q->tail + 1) % q->ndesc;
+ list_add_tail(&e->list, &q->tx_list);
q->queued--;
}
spin_unlock_bh(&q->lock);
@@ -1883,20 +1882,6 @@ static u32 airoha_get_dsa_tag(struct sk_
#endif
}
-static bool airoha_dev_tx_queue_busy(struct airoha_queue *q, u32 nr_frags)
-{
- u32 tail = q->tail <= q->head ? q->tail + q->ndesc : q->tail;
- u32 index = q->head + nr_frags;
-
- /* completion napi can free out-of-order tx descriptors if hw QoS is
- * enabled and packets with different priorities are queued to the same
- * DMA ring. Take into account possible out-of-order reports checking
- * if the tx queue is full using circular buffer head/tail pointers
- * instead of the number of queued packets.
- */
- return index >= tail;
-}
-
static int airoha_get_fe_port(struct airoha_gdm_port *port)
{
struct airoha_qdma *qdma = port->qdma;
@@ -1919,8 +1904,10 @@ static netdev_tx_t airoha_dev_xmit(struc
struct airoha_gdm_port *port = netdev_priv(dev);
struct airoha_qdma *qdma = port->qdma;
u32 nr_frags, tag, msg0, msg1, len;
+ struct airoha_queue_entry *e;
struct netdev_queue *txq;
struct airoha_queue *q;
+ LIST_HEAD(tx_list);
void *data;
int i, qid;
u16 index;
@@ -1966,7 +1953,7 @@ static netdev_tx_t airoha_dev_xmit(struc
txq = netdev_get_tx_queue(dev, qid);
nr_frags = 1 + skb_shinfo(skb)->nr_frags;
- if (airoha_dev_tx_queue_busy(q, nr_frags)) {
+ if (q->queued + nr_frags >= q->ndesc) {
/* not enough space in the queue */
netif_tx_stop_queue(txq);
spin_unlock_bh(&q->lock);
@@ -1975,11 +1962,13 @@ static netdev_tx_t airoha_dev_xmit(struc
len = skb_headlen(skb);
data = skb->data;
- index = q->head;
+
+ e = list_first_entry(&q->tx_list, struct airoha_queue_entry,
+ list);
+ index = e - q->entry;
for (i = 0; i < nr_frags; i++) {
struct airoha_qdma_desc *desc = &q->desc[index];
- struct airoha_queue_entry *e = &q->entry[index];
skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
dma_addr_t addr;
u32 val;
@@ -1989,7 +1978,14 @@ static netdev_tx_t airoha_dev_xmit(struc
if (unlikely(dma_mapping_error(dev->dev.parent, addr)))
goto error_unmap;
- index = (index + 1) % q->ndesc;
+ list_move_tail(&e->list, &tx_list);
+ e->skb = i ? NULL : skb;
+ e->dma_addr = addr;
+ e->dma_len = len;
+
+ e = list_first_entry(&q->tx_list, struct airoha_queue_entry,
+ list);
+ index = e - q->entry;
val = FIELD_PREP(QDMA_DESC_LEN_MASK, len);
if (i < nr_frags - 1)
@@ -2002,15 +1998,9 @@ static netdev_tx_t airoha_dev_xmit(struc
WRITE_ONCE(desc->msg1, cpu_to_le32(msg1));
WRITE_ONCE(desc->msg2, cpu_to_le32(0xffff));
- e->skb = i ? NULL : skb;
- e->dma_addr = addr;
- e->dma_len = len;
-
data = skb_frag_address(frag);
len = skb_frag_size(frag);
}
-
- q->head = index;
q->queued += i;
skb_tx_timestamp(skb);
@@ -2019,7 +2009,7 @@ static netdev_tx_t airoha_dev_xmit(struc
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));
+ FIELD_PREP(TX_RING_CPU_IDX_MASK, index));
if (q->ndesc - q->queued < q->free_thr)
netif_tx_stop_queue(txq);
@@ -2029,10 +2019,13 @@ static netdev_tx_t airoha_dev_xmit(struc
return NETDEV_TX_OK;
error_unmap:
- for (i--; i >= 0; i--) {
- index = (q->head + i) % q->ndesc;
- dma_unmap_single(dev->dev.parent, q->entry[index].dma_addr,
- q->entry[index].dma_len, DMA_TO_DEVICE);
+ while (!list_empty(&tx_list)) {
+ e = list_first_entry(&tx_list, struct airoha_queue_entry,
+ list);
+ dma_unmap_single(dev->dev.parent, e->dma_addr, e->dma_len,
+ DMA_TO_DEVICE);
+ e->dma_addr = 0;
+ list_move_tail(&e->list, &q->tx_list);
}
spin_unlock_bh(&q->lock);
--- a/drivers/net/ethernet/airoha/airoha_eth.h
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
@@ -169,7 +169,10 @@ enum trtcm_param {
struct airoha_queue_entry {
union {
void *buf;
- struct sk_buff *skb;
+ struct {
+ struct list_head list;
+ struct sk_buff *skb;
+ };
};
dma_addr_t dma_addr;
u16 dma_len;
@@ -193,6 +196,8 @@ struct airoha_queue {
struct napi_struct napi;
struct page_pool *page_pool;
struct sk_buff *skb;
+
+ struct list_head tx_list;
};
struct airoha_tx_irq_queue {

View File

@ -13,7 +13,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -1383,6 +1383,10 @@ static int airoha_hw_init(struct platfor
@@ -1382,6 +1382,10 @@ static int airoha_hw_init(struct platfor
if (err)
return err;

View File

@ -28,7 +28,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
airoha_fe_crsn_qsel_init(eth);
@@ -1625,7 +1627,8 @@ static int airoha_dev_open(struct net_de
@@ -1624,7 +1626,8 @@ static int airoha_dev_open(struct net_de
if (err)
return err;

View File

@ -15,7 +15,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -3095,7 +3095,6 @@ static void airoha_remove(struct platfor
@@ -3088,7 +3088,6 @@ static void airoha_remove(struct platfor
}
static const char * const en7581_xsi_rsts_names[] = {
@ -23,7 +23,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
"hsi0-mac",
"hsi1-mac",
"hsi-mac",
@@ -3127,7 +3126,6 @@ static int airoha_en7581_get_src_port_id
@@ -3120,7 +3119,6 @@ static int airoha_en7581_get_src_port_id
}
static const char * const an7583_xsi_rsts_names[] = {

View File

@ -35,7 +35,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
static void airoha_set_macaddr(struct airoha_gdm_port *port, const u8 *addr)
{
struct airoha_eth *eth = port->qdma->eth;
@@ -1622,6 +1628,17 @@ static int airoha_dev_open(struct net_de
@@ -1621,6 +1627,17 @@ static int airoha_dev_open(struct net_de
struct airoha_gdm_port *port = netdev_priv(dev);
struct airoha_qdma *qdma = port->qdma;
@ -53,7 +53,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
netif_tx_start_all_queues(dev);
err = airoha_set_vip_for_gdm_port(port, true);
if (err)
@@ -1675,6 +1692,11 @@ static int airoha_dev_stop(struct net_de
@@ -1674,6 +1691,11 @@ static int airoha_dev_stop(struct net_de
}
}
@ -65,7 +65,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
return 0;
}
@@ -2823,6 +2845,20 @@ static const struct ethtool_ops airoha_e
@@ -2816,6 +2838,20 @@ static const struct ethtool_ops airoha_e
.get_link = ethtool_op_get_link,
};
@ -86,7 +86,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
static int airoha_metadata_dst_alloc(struct airoha_gdm_port *port)
{
int i;
@@ -2867,6 +2903,99 @@ bool airoha_is_valid_gdm_port(struct air
@@ -2860,6 +2896,99 @@ bool airoha_is_valid_gdm_port(struct air
return false;
}
@ -186,7 +186,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
static int airoha_alloc_gdm_port(struct airoha_eth *eth,
struct device_node *np, int index)
{
@@ -2945,6 +3074,12 @@ static int airoha_alloc_gdm_port(struct
@@ -2938,6 +3067,12 @@ static int airoha_alloc_gdm_port(struct
if (err)
return err;
@ -199,7 +199,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
err = register_netdev(dev);
if (err)
goto free_metadata_dst;
@@ -3060,6 +3195,10 @@ error_hw_cleanup:
@@ -3053,6 +3188,10 @@ error_hw_cleanup:
if (port && port->dev->reg_state == NETREG_REGISTERED) {
unregister_netdev(port->dev);
airoha_metadata_dst_free(port);
@ -210,7 +210,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
}
}
free_netdev(eth->napi_dev);
@@ -3087,6 +3226,10 @@ static void airoha_remove(struct platfor
@@ -3080,6 +3219,10 @@ static void airoha_remove(struct platfor
airoha_dev_stop(port->dev);
unregister_netdev(port->dev);
airoha_metadata_dst_free(port);
@ -223,7 +223,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
--- a/drivers/net/ethernet/airoha/airoha_eth.h
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
@@ -531,6 +531,10 @@ struct airoha_gdm_port {
@@ -536,6 +536,10 @@ struct airoha_gdm_port {
struct net_device *dev;
int id;

View File

@ -28,7 +28,7 @@ Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
static void airoha_set_macaddr(struct airoha_gdm_port *port, const u8 *addr)
{
@@ -1631,6 +1633,7 @@ static int airoha_dev_open(struct net_de
@@ -1630,6 +1632,7 @@ static int airoha_dev_open(struct net_de
struct airoha_gdm_port *port = netdev_priv(dev);
struct airoha_qdma *qdma = port->qdma;
@ -36,7 +36,7 @@ Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
if (airhoa_is_phy_external(port)) {
err = phylink_of_phy_connect(port->phylink, dev->dev.of_node, 0);
if (err) {
@@ -1641,6 +1644,7 @@ static int airoha_dev_open(struct net_de
@@ -1640,6 +1643,7 @@ static int airoha_dev_open(struct net_de
phylink_start(port->phylink);
}
@ -44,7 +44,7 @@ Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
netif_tx_start_all_queues(dev);
err = airoha_set_vip_for_gdm_port(port, true);
@@ -1695,10 +1699,12 @@ static int airoha_dev_stop(struct net_de
@@ -1694,10 +1698,12 @@ static int airoha_dev_stop(struct net_de
}
}
@ -57,7 +57,7 @@ Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
return 0;
}
@@ -2848,6 +2854,7 @@ static const struct ethtool_ops airoha_e
@@ -2841,6 +2847,7 @@ static const struct ethtool_ops airoha_e
.get_link = ethtool_op_get_link,
};
@ -65,7 +65,7 @@ Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
static struct phylink_pcs *airoha_phylink_mac_select_pcs(struct phylink_config *config,
phy_interface_t interface)
{
@@ -2861,6 +2868,7 @@ static void airoha_mac_config(struct phy
@@ -2854,6 +2861,7 @@ static void airoha_mac_config(struct phy
const struct phylink_link_state *state)
{
}
@ -73,7 +73,7 @@ Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
static int airoha_metadata_dst_alloc(struct airoha_gdm_port *port)
{
@@ -2906,6 +2914,7 @@ bool airoha_is_valid_gdm_port(struct air
@@ -2899,6 +2907,7 @@ bool airoha_is_valid_gdm_port(struct air
return false;
}
@ -81,7 +81,7 @@ Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
static void airoha_mac_link_up(struct phylink_config *config, struct phy_device *phy,
unsigned int mode, phy_interface_t interface,
int speed, int duplex, bool tx_pause, bool rx_pause)
@@ -2998,6 +3007,7 @@ static int airoha_setup_phylink(struct n
@@ -2991,6 +3000,7 @@ static int airoha_setup_phylink(struct n
return 0;
}
@ -89,7 +89,7 @@ Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
static int airoha_alloc_gdm_port(struct airoha_eth *eth,
struct device_node *np, int index)
@@ -3077,11 +3087,13 @@ static int airoha_alloc_gdm_port(struct
@@ -3070,11 +3080,13 @@ static int airoha_alloc_gdm_port(struct
if (err)
return err;
@ -103,7 +103,7 @@ Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
err = register_netdev(dev);
if (err)
@@ -3198,10 +3210,12 @@ error_hw_cleanup:
@@ -3191,10 +3203,12 @@ error_hw_cleanup:
if (port && port->dev->reg_state == NETREG_REGISTERED) {
unregister_netdev(port->dev);
airoha_metadata_dst_free(port);
@ -116,7 +116,7 @@ Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
}
}
free_netdev(eth->napi_dev);
@@ -3229,10 +3243,12 @@ static void airoha_remove(struct platfor
@@ -3222,10 +3236,12 @@ static void airoha_remove(struct platfor
airoha_dev_stop(port->dev);
unregister_netdev(port->dev);
airoha_metadata_dst_free(port);
@ -131,7 +131,7 @@ Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
--- a/drivers/net/ethernet/airoha/airoha_eth.h
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
@@ -531,9 +531,11 @@ struct airoha_gdm_port {
@@ -536,9 +536,11 @@ struct airoha_gdm_port {
struct net_device *dev;
int id;

View File

@ -394,7 +394,7 @@
reg = <0x0a600000 0x00700000>;
};
partition@a9c0000 {
partition@ad00000 {
label = "ubi";
reg = <0x0ad00000 0x05300000>;
};

View File

@ -452,26 +452,11 @@ int rtl83xx_lag_add(struct dsa_switch *ds, int group, int port, struct netdev_la
u32 algomsk = 0;
u32 algoidx = 0;
if (info->tx_type != NETDEV_LAG_TX_TYPE_HASH) {
pr_err("%s: Only mode LACP 802.3ad (4) allowed.\n", __func__);
return -EINVAL;
}
if (group >= priv->n_lags) {
pr_err("%s: LAG %d invalid.\n", __func__, group);
return -EINVAL;
}
if (port >= priv->cpu_port) {
pr_err("%s: Port %d invalid.\n", __func__, port);
return -EINVAL;
}
for (i = 0; i < priv->n_lags; i++) {
for (i = 0; i < priv->ds->num_lag_ids; i++) {
if (priv->lags_port_members[i] & BIT_ULL(port))
break;
}
if (i != priv->n_lags) {
if (i != priv->ds->num_lag_ids) {
pr_err("%s: Port %d already member of LAG %d.\n", __func__, port, i);
return -ENOSPC;
}
@ -513,16 +498,11 @@ int rtl83xx_lag_del(struct dsa_switch *ds, int group, int port)
{
struct rtl838x_switch_priv *priv = ds->priv;
if (group >= priv->n_lags) {
if (group >= priv->ds->num_lag_ids) {
pr_err("%s: LAG %d invalid.\n", __func__, group);
return -EINVAL;
}
if (port >= priv->cpu_port) {
pr_err("%s: Port %d invalid.\n", __func__, port);
return -EINVAL;
}
if (!(priv->lags_port_members[group] & BIT_ULL(port))) {
pr_err("%s: Port %d not member of LAG %d.\n", __func__, port, group);
return -ENOSPC;
@ -689,59 +669,6 @@ static int rtl83xx_l2_nexthop_rm(struct rtl838x_switch_priv *priv, struct rtl83x
return 0;
}
static int rtl83xx_handle_changeupper(struct rtl838x_switch_priv *priv,
struct net_device *ndev,
struct netdev_notifier_changeupper_info *info)
{
struct net_device *upper = info->upper_dev;
struct netdev_lag_upper_info *lag_upper_info = NULL;
int i, j, err;
if (!netif_is_lag_master(upper))
return 0;
mutex_lock(&priv->reg_mutex);
for (i = 0; i < priv->n_lags; i++) {
if ((!priv->lag_devs[i]) || (priv->lag_devs[i] == upper))
break;
}
for (j = 0; j < priv->cpu_port; j++) {
if (priv->ports[j].dp->user == ndev)
break;
}
if (j >= priv->cpu_port) {
err = -EINVAL;
goto out;
}
if (info->linking) {
lag_upper_info = info->upper_info;
if (!priv->lag_devs[i])
priv->lag_devs[i] = upper;
err = rtl83xx_lag_add(priv->ds, i, priv->ports[j].dp->index, lag_upper_info);
if (err) {
err = -EINVAL;
goto out;
}
} else {
if (!priv->lag_devs[i])
err = -EINVAL;
err = rtl83xx_lag_del(priv->ds, i, priv->ports[j].dp->index);
if (err) {
err = -EINVAL;
goto out;
}
if (!priv->lags_port_members[i])
priv->lag_devs[i] = NULL;
}
out:
mutex_unlock(&priv->reg_mutex);
return 0;
}
int rtl83xx_port_is_under(const struct net_device * dev, struct rtl838x_switch_priv *priv)
{
/* Is the lower network device a DSA user network device of our RTL930X-switch?
@ -764,31 +691,6 @@ int rtl83xx_port_is_under(const struct net_device * dev, struct rtl838x_switch_p
return -EINVAL;
}
static int rtl83xx_netdevice_event(struct notifier_block *this,
unsigned long event, void *ptr)
{
struct net_device *ndev = netdev_notifier_info_to_dev(ptr);
struct rtl838x_switch_priv *priv;
int err;
pr_debug("In: %s, event: %lu\n", __func__, event);
if ((event != NETDEV_CHANGEUPPER) && (event != NETDEV_CHANGELOWERSTATE))
return NOTIFY_DONE;
priv = container_of(this, struct rtl838x_switch_priv, nb);
switch (event) {
case NETDEV_CHANGEUPPER:
err = rtl83xx_handle_changeupper(priv, ndev, ptr);
break;
}
if (err)
return err;
return NOTIFY_DONE;
}
static const struct rhashtable_params route_ht_params = {
.key_len = sizeof(u32),
.key_offset = offsetof(struct rtl83xx_route, gw_ip),
@ -1563,7 +1465,7 @@ static int __init rtl83xx_sw_probe(struct platform_device *pdev)
priv->ds->num_ports = 29;
priv->fib_entries = 8192;
rtl8380_get_version(priv);
priv->n_lags = 8;
priv->ds->num_lag_ids = 8;
priv->l2_bucket_size = 4;
priv->n_pie_blocks = 12;
priv->port_ignore = 0x1f;
@ -1579,7 +1481,7 @@ static int __init rtl83xx_sw_probe(struct platform_device *pdev)
priv->ds->num_ports = 53;
priv->fib_entries = 16384;
rtl8390_get_version(priv);
priv->n_lags = 16;
priv->ds->num_lag_ids = 16;
priv->l2_bucket_size = 4;
priv->n_pie_blocks = 18;
priv->port_ignore = 0x3f;
@ -1598,7 +1500,7 @@ static int __init rtl83xx_sw_probe(struct platform_device *pdev)
* be constructed. For now, just set it to a static 'A'
*/
priv->version = RTL8390_VERSION_A;
priv->n_lags = 16;
priv->ds->num_lag_ids = 16;
sw_w32(1, RTL930X_ST_CTRL);
priv->l2_bucket_size = 8;
priv->n_pie_blocks = 16;
@ -1618,7 +1520,7 @@ static int __init rtl83xx_sw_probe(struct platform_device *pdev)
* be constructed. For now, just set it to a static 'A'
*/
priv->version = RTL8390_VERSION_A;
priv->n_lags = 16;
priv->ds->num_lag_ids = 16;
sw_w32(1, RTL931x_ST_CTRL);
priv->l2_bucket_size = 8;
priv->n_pie_blocks = 16;
@ -1701,14 +1603,6 @@ static int __init rtl83xx_sw_probe(struct platform_device *pdev)
for (int i = 0; i < 4; i++)
priv->mirror_group_ports[i] = -1;
/* Register netdevice event callback to catch changes in link aggregation groups */
priv->nb.notifier_call = rtl83xx_netdevice_event;
if (register_netdevice_notifier(&priv->nb)) {
priv->nb.notifier_call = NULL;
dev_err(dev, "Failed to register LAG netdev notifier\n");
goto err_register_nb;
}
/* Initialize hash table for L3 routing */
rhltable_init(&priv->routes, &route_ht_params);
@ -1756,8 +1650,6 @@ static int __init rtl83xx_sw_probe(struct platform_device *pdev)
err_register_fib_nb:
unregister_netevent_notifier(&priv->ne_nb);
err_register_ne_nb:
unregister_netdevice_notifier(&priv->nb);
err_register_nb:
dsa_switch_shutdown(priv->ds);
err_register_switch:
destroy_workqueue(priv->wq);

View File

@ -613,7 +613,7 @@ void rtl838x_dbgfs_init(struct rtl838x_switch_priv *priv)
debugfs_create_u8("id", 0444, port_dir, &priv->cpu_port);
/* Create entries for LAGs */
for (int i = 0; i < priv->n_lags; i++) {
for (int i = 0; i < priv->ds->num_lag_ids; i++) {
snprintf(lag_name, sizeof(lag_name), "lag.%02d", i);
if (priv->family_id == RTL8380_FAMILY_ID)
debugfs_create_x32(lag_name, 0644, rtl838x_dir,

View File

@ -1378,7 +1378,7 @@ static int rtldsa_port_enable(struct dsa_switch *ds, int port, struct phy_device
/* add port to switch mask of CPU_PORT */
priv->r->traffic_enable(priv->cpu_port, port);
if (priv->is_lagmember[port]) {
if (priv->lag_non_primary & BIT_ULL(port)) {
pr_debug("%s: %d is lag slave. ignore\n", __func__, port);
return 0;
}
@ -1479,7 +1479,7 @@ static void rtldsa_update_port_member(struct rtl838x_switch_priv *priv, int port
if (!dsa_port_offloads_bridge_dev(other_dp, bridge_dev))
continue;
if (join && priv->is_lagmember[other_port])
if (join && priv->lag_non_primary & BIT_ULL(other_port))
continue;
isolated = p->isolated && other_p->isolated;
@ -1508,7 +1508,7 @@ static int rtldsa_port_bridge_join(struct dsa_switch *ds, int port, struct dsa_b
pr_debug("%s %x: %d", __func__, (u32)priv, port);
if (priv->is_lagmember[port]) {
if (priv->lag_non_primary & BIT_ULL(port)) {
pr_debug("%s: %d is lag slave. ignore\n", __func__, port);
return 0;
}
@ -1940,7 +1940,7 @@ static int rtl83xx_port_fdb_add(struct dsa_switch *ds, int port,
int err = 0, idx;
u64 seed = priv->r->l2_hash_seed(mac, vid);
if (priv->is_lagmember[port]) {
if (priv->lag_non_primary & BIT_ULL(port)) {
pr_debug("%s: %d is lag slave. ignore\n", __func__, port);
return 0;
}
@ -2082,7 +2082,7 @@ static int rtl83xx_port_mdb_add(struct dsa_switch *ds, int port,
pr_debug("In %s port %d, mac %llx, vid: %d\n", __func__, port, mac, vid);
if (priv->is_lagmember[port]) {
if (priv->lag_non_primary & BIT_ULL(port)) {
pr_debug("%s: %d is lag slave. ignore\n", __func__, port);
return -EINVAL;
}
@ -2162,7 +2162,7 @@ static int rtl83xx_port_mdb_del(struct dsa_switch *ds, int port,
pr_debug("In %s, port %d, mac %llx, vid: %d\n", __func__, port, mac, vid);
if (priv->is_lagmember[port]) {
if (priv->lag_non_primary & BIT_ULL(port)) {
pr_info("%s: %d is lag slave. ignore\n", __func__, port);
return 0;
}
@ -2400,34 +2400,32 @@ static int rtl83xx_port_lag_join(struct dsa_switch *ds,
struct netlink_ext_ack *extack)
{
struct rtl838x_switch_priv *priv = ds->priv;
int i, err = 0;
int err = 0;
int group;
if (!rtl83xx_lag_can_offload(ds, lag.dev, info))
return -EOPNOTSUPP;
mutex_lock(&priv->reg_mutex);
for (i = 0; i < priv->n_lags; i++) {
if ((!priv->lag_devs[i]) || (priv->lag_devs[i] == lag.dev))
break;
}
if (port >= priv->cpu_port) {
err = -EINVAL;
goto out;
}
pr_info("port_lag_join: group %d, port %d\n",i, port);
if (!priv->lag_devs[i])
priv->lag_devs[i] = lag.dev;
if (priv->lag_primary[i] == -1) {
priv->lag_primary[i] = port;
} else
priv->is_lagmember[port] = 1;
group = dsa_lag_id(ds->dst, lag.dev);
priv->lagmembers |= (1ULL << port);
pr_info("port_lag_join: group %d, port %d\n", group, port);
if (priv->lag_primary[group] == -1)
priv->lag_primary[group] = port;
else
priv->lag_non_primary |= BIT_ULL(port);
priv->lagmembers |= BIT_ULL(port);
pr_debug("lag_members = %llX\n", priv->lagmembers);
err = rtl83xx_lag_add(priv->ds, i, port, info);
err = rtl83xx_lag_add(priv->ds, group, port, info);
if (err) {
err = -EINVAL;
goto out;
@ -2442,19 +2440,14 @@ out:
static int rtl83xx_port_lag_leave(struct dsa_switch *ds, int port,
struct dsa_lag lag)
{
int i, group = -1, err;
int group, err;
struct rtl838x_switch_priv *priv = ds->priv;
mutex_lock(&priv->reg_mutex);
for (i = 0; i < priv->n_lags; i++) {
if (priv->lags_port_members[i] & BIT_ULL(port)) {
group = i;
break;
}
}
group = dsa_lag_id(ds->dst, lag.dev);
if (group == -1) {
pr_info("port_lag_leave: port %d is not a member\n", port);
pr_info("port_lag_leave: group %d not set\n", port);
err = -EINVAL;
goto out;
}
@ -2464,17 +2457,15 @@ static int rtl83xx_port_lag_leave(struct dsa_switch *ds, int port,
goto out;
}
pr_info("port_lag_del: group %d, port %d\n",group, port);
priv->lagmembers &=~ (1ULL << port);
priv->lag_primary[i] = -1;
priv->is_lagmember[port] = 0;
priv->lagmembers &= ~BIT_ULL(port);
priv->lag_primary[group] = -1;
priv->lag_non_primary &= ~BIT_ULL(port);
pr_debug("lag_members = %llX\n", priv->lagmembers);
err = rtl83xx_lag_del(priv->ds, group, port);
if (err) {
err = -EINVAL;
goto out;
}
if (!priv->lags_port_members[i])
priv->lag_devs[i] = NULL;
out:
mutex_unlock(&priv->reg_mutex);

View File

@ -1164,14 +1164,24 @@ struct rtl838x_switch_priv {
u32 fib_entries;
int l2_bucket_size;
struct dentry *dbgfs_dir;
int n_lags;
/** @lags_port_members: Port (bit) is part of a specific LAG */
u64 lags_port_members[MAX_LAGS];
struct net_device *lag_devs[MAX_LAGS];
/** @lag_primary: port of a LAG is primary (repesenting) and is added to
* the port matrix
*/
u32 lag_primary[MAX_LAGS];
u32 is_lagmember[57];
/**
* @lag_non_primary: Port (bit) is part of any LAG but not the
* first/primary port which needs to be added in the port matrix
*/
u64 lag_non_primary;
/** @lagmembers: Port (bit) is part of any LAG */
u64 lagmembers;
struct workqueue_struct *wq;
struct notifier_block nb; /* TODO: change to different name */
struct notifier_block ne_nb;
struct notifier_block fib_nb;
bool eee_enabled;

View File

@ -205,7 +205,4 @@ void rtl930x_pie_rule_dump_raw(u32 r[]);
void rtl931x_print_matrix(void);
void rtldsa_930x_set_receive_management_action(int port, rma_ctrl_t type, action_type_t action);
void rtldsa_931x_set_receive_management_action(int port, rma_ctrl_t type, action_type_t action);
#endif /* _NET_DSA_RTL83XX_H */

View File

@ -738,8 +738,8 @@ static void rtl930x_write_mcast_pmask(int idx, u64 portmask)
rtl_table_release(q);
}
void rtldsa_930x_set_receive_management_action(int port, rma_ctrl_t type,
action_type_t action)
static void rtldsa_930x_set_receive_management_action(int port, rma_ctrl_t type,
action_type_t action)
{
u32 shift;
u32 value;

View File

@ -389,14 +389,24 @@ void rtl931x_print_matrix(void)
rtl_table_release(r);
}
void rtldsa_931x_set_receive_management_action(int port, rma_ctrl_t type, action_type_t action)
static void rtldsa_931x_set_receive_management_action(int port, rma_ctrl_t type,
action_type_t action)
{
u32 value = 0;
u32 shift;
u32 value;
u32 reg;
/* hack for value mapping */
if (type == GRATARP && action == COPY2CPU)
action = TRAP2MASTERCPU;
/* PTP doesn't allow to flood to all ports */
if (action == FLOODALL &&
(type == PTP || type == PTP_UDP || type == PTP_ETH2)) {
pr_warn("%s: Port flooding not supported for PTP\n", __func__);
return;
}
switch(action) {
case FORWARD:
value = 0;
@ -414,34 +424,47 @@ void rtldsa_931x_set_receive_management_action(int port, rma_ctrl_t type, action
value = 4;
break;
default:
break;
return;
}
switch(type) {
case BPDU:
sw_w32_mask(7 << ((port % 10) * 3), value << ((port % 10) * 3), RTL931X_RMA_BPDU_CTRL + ((port / 10) << 2));
break;
reg = RTL931X_RMA_BPDU_CTRL + (port / 10) * 4;
shift = (port % 10) * 3;
sw_w32_mask(GENMASK(shift + 2, shift), value << shift, reg);
break;
case PTP:
reg = RTL931X_RMA_PTP_CTRL + port * 4;
/* udp */
sw_w32_mask(3 << 2, value << 2, RTL931X_RMA_PTP_CTRL + (port << 2));
sw_w32_mask(GENMASK(3, 2), value << 2, reg);
/* eth2 */
sw_w32_mask(3, value, RTL931X_RMA_PTP_CTRL + (port << 2));
break;
sw_w32_mask(GENMASK(1, 0), value, reg);
break;
case PTP_UDP:
sw_w32_mask(3 << 2, value << 2, RTL931X_RMA_PTP_CTRL + (port << 2));
break;
reg = RTL931X_RMA_PTP_CTRL + port * 4;
sw_w32_mask(GENMASK(3, 2), value << 2, reg);
break;
case PTP_ETH2:
sw_w32_mask(3, value, RTL931X_RMA_PTP_CTRL + (port << 2));
break;
reg = RTL931X_RMA_PTP_CTRL + port * 4;
sw_w32_mask(GENMASK(1, 0), value, reg);
break;
case LLDP:
sw_w32_mask(7 << ((port % 10) * 3), value << ((port % 10) * 3), RTL931X_RMA_LLDP_CTRL + ((port / 10) << 2));
break;
reg = RTL931X_RMA_LLDP_CTRL + (port / 10) * 4;
shift = (port % 10) * 3;
sw_w32_mask(GENMASK(shift + 2, shift), value << shift, reg);
break;
case EAPOL:
sw_w32_mask(7 << ((port % 10) * 3), value << ((port % 10) * 3), RTL931X_RMA_EAPOL_CTRL + ((port / 10) << 2));
break;
reg = RTL931X_RMA_EAPOL_CTRL + (port / 10) * 4;
shift = (port % 10) * 3;
sw_w32_mask(GENMASK(shift + 2, shift), value << shift, reg);
break;
case GRATARP:
sw_w32_mask(3 << ((port & 0xf) << 1), value << ((port & 0xf) << 1), RTL931X_TRAP_ARP_GRAT_PORT_ACT + ((port >> 4) << 2));
break;
reg = RTL931X_TRAP_ARP_GRAT_PORT_ACT + (port / 16) * 4;
shift = (port % 16) * 2;
sw_w32_mask(GENMASK(shift + 1, shift), value << shift, reg);
break;
}
}

View File

@ -69,7 +69,6 @@ friendlyarm,nanopi-r4se|\
friendlyarm,nanopi-r4s-enterprise|\
friendlyarm,nanopi-r6c|\
friendlyarm,nanopi-r76s|\
radxa,e52c|\
radxa,rock-5-itx|\
radxa,rock-5t)
set_interface_core 10 "eth0"
@ -99,4 +98,8 @@ lyt,t68m)
set_interface_core 4 "lan3"
set_interface_core 8 "lan4"
;;
radxa,e52c)
set_interface_core 10 "lan"
set_interface_core 20 "wan"
;;
esac