Merge Official Source
Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
This commit is contained in:
commit
9439570689
@ -183,7 +183,7 @@ $(eval $(if $(NF_KMOD),$(call nf_add,IPT_NAT6,CONFIG_IP6_NF_NAT, $(P_V6)ip6table
|
|||||||
$(eval $(if $(NF_KMOD),$(call nf_add,IPT_NAT6,CONFIG_IP6_NF_TARGET_NPT, $(P_V6)ip6t_NPT),))
|
$(eval $(if $(NF_KMOD),$(call nf_add,IPT_NAT6,CONFIG_IP6_NF_TARGET_NPT, $(P_V6)ip6t_NPT),))
|
||||||
|
|
||||||
# userland only
|
# userland only
|
||||||
$(eval $(if $(NF_KMOD),,$(call nf_add,IPT_NAT,CONFIG_NF_NAT, ipt_SNAT ipt_DNAT)))
|
$(eval $(if $(NF_KMOD),,$(call nf_add,IPT_NAT,CONFIG_NF_NAT, ipt_NAT)))
|
||||||
$(eval $(if $(NF_KMOD),,$(call nf_add,IPT_NAT6,CONFIG_IP6_NF_TARGET_NPT, ip6t_DNPT ip6t_SNPT)))
|
$(eval $(if $(NF_KMOD),,$(call nf_add,IPT_NAT6,CONFIG_IP6_NF_TARGET_NPT, ip6t_DNPT ip6t_SNPT)))
|
||||||
|
|
||||||
$(eval $(call nf_add,IPT_NAT,CONFIG_NETFILTER_XT_TARGET_MASQUERADE, $(P_XT)xt_MASQUERADE))
|
$(eval $(call nf_add,IPT_NAT,CONFIG_NETFILTER_XT_TARGET_MASQUERADE, $(P_XT)xt_MASQUERADE))
|
||||||
|
|||||||
@ -104,5 +104,6 @@ VERSION_SED_SCRIPT:=$(SED) 's,%U,$(call sed_escape,$(VERSION_REPO)),g' \
|
|||||||
-e 's,%u,$(call sed_escape,$(VERSION_HOME_URL)),g' \
|
-e 's,%u,$(call sed_escape,$(VERSION_HOME_URL)),g' \
|
||||||
-e 's,%s,$(call sed_escape,$(VERSION_SUPPORT_URL)),g' \
|
-e 's,%s,$(call sed_escape,$(VERSION_SUPPORT_URL)),g' \
|
||||||
-e 's,%P,$(call sed_escape,$(VERSION_PRODUCT)),g' \
|
-e 's,%P,$(call sed_escape,$(VERSION_PRODUCT)),g' \
|
||||||
-e 's,%h,$(call sed_escape,$(VERSION_HWREV)),g'
|
-e 's,%h,$(call sed_escape,$(VERSION_HWREV)),g' \
|
||||||
|
-e 's,%B,$(call sed_escape,$(SOURCE_DATE_EPOCH)),g'
|
||||||
|
|
||||||
|
|||||||
@ -16,3 +16,4 @@ OPENWRT_DEVICE_MANUFACTURER_URL="%m"
|
|||||||
OPENWRT_DEVICE_PRODUCT="%P"
|
OPENWRT_DEVICE_PRODUCT="%P"
|
||||||
OPENWRT_DEVICE_REVISION="%h"
|
OPENWRT_DEVICE_REVISION="%h"
|
||||||
OPENWRT_RELEASE="%D %V %C"
|
OPENWRT_RELEASE="%D %V %C"
|
||||||
|
OPENWRT_BUILD_DATE="%B"
|
||||||
|
|||||||
@ -20,6 +20,7 @@ alfa-network,n5q|\
|
|||||||
alfa-network,pi-wifi4|\
|
alfa-network,pi-wifi4|\
|
||||||
alfa-network,r36a|\
|
alfa-network,r36a|\
|
||||||
alfa-network,tube-2hq|\
|
alfa-network,tube-2hq|\
|
||||||
|
alfa-network,wifi-camppro-nano-duo|\
|
||||||
araknis,an-300-ap-i-n|\
|
araknis,an-300-ap-i-n|\
|
||||||
arduino,yun|\
|
arduino,yun|\
|
||||||
asus,rt-ac59u|\
|
asus,rt-ac59u|\
|
||||||
|
|||||||
@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
|
|||||||
include $(INCLUDE_DIR)/kernel.mk
|
include $(INCLUDE_DIR)/kernel.mk
|
||||||
|
|
||||||
PKG_NAME:=gpio-nct5104d
|
PKG_NAME:=gpio-nct5104d
|
||||||
PKG_RELEASE:=1
|
PKG_RELEASE:=2
|
||||||
|
|
||||||
PKG_MAINTAINER:=Florian Eckert <Eckert.Florian@googlemail.com>
|
PKG_MAINTAINER:=Florian Eckert <Eckert.Florian@googlemail.com>
|
||||||
PKG_LICENSE:=GPL-2.0
|
PKG_LICENSE:=GPL-2.0
|
||||||
|
|||||||
@ -153,8 +153,7 @@ static struct nct5104d_gpio_bank nct5104d_gpio_bank[] = {
|
|||||||
static int nct5104d_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
|
static int nct5104d_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
struct nct5104d_gpio_bank *bank =
|
struct nct5104d_gpio_bank *bank = gpiochip_get_data(chip);
|
||||||
container_of(chip, struct nct5104d_gpio_bank, chip);
|
|
||||||
struct nct5104d_sio *sio = bank->data->sio;
|
struct nct5104d_sio *sio = bank->data->sio;
|
||||||
u8 dir;
|
u8 dir;
|
||||||
|
|
||||||
@ -175,8 +174,7 @@ static int nct5104d_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
|
|||||||
static int nct5104d_gpio_get(struct gpio_chip *chip, unsigned offset)
|
static int nct5104d_gpio_get(struct gpio_chip *chip, unsigned offset)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
struct nct5104d_gpio_bank *bank =
|
struct nct5104d_gpio_bank *bank = gpiochip_get_data(chip);
|
||||||
container_of(chip, struct nct5104d_gpio_bank, chip);
|
|
||||||
struct nct5104d_sio *sio = bank->data->sio;
|
struct nct5104d_sio *sio = bank->data->sio;
|
||||||
u8 data;
|
u8 data;
|
||||||
|
|
||||||
@ -196,8 +194,7 @@ static int nct5104d_gpio_direction_out(struct gpio_chip *chip,
|
|||||||
unsigned offset, int value)
|
unsigned offset, int value)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
struct nct5104d_gpio_bank *bank =
|
struct nct5104d_gpio_bank *bank = gpiochip_get_data(chip);
|
||||||
container_of(chip, struct nct5104d_gpio_bank, chip);
|
|
||||||
struct nct5104d_sio *sio = bank->data->sio;
|
struct nct5104d_sio *sio = bank->data->sio;
|
||||||
u8 dir, data_out;
|
u8 dir, data_out;
|
||||||
|
|
||||||
@ -225,8 +222,7 @@ static int nct5104d_gpio_direction_out(struct gpio_chip *chip,
|
|||||||
static void nct5104d_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
|
static void nct5104d_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
struct nct5104d_gpio_bank *bank =
|
struct nct5104d_gpio_bank *bank = gpiochip_get_data(chip);
|
||||||
container_of(chip, struct nct5104d_gpio_bank, chip);
|
|
||||||
struct nct5104d_sio *sio = bank->data->sio;
|
struct nct5104d_sio *sio = bank->data->sio;
|
||||||
u8 data_out;
|
u8 data_out;
|
||||||
|
|
||||||
@ -270,8 +266,6 @@ static int nct5104d_gpio_probe(struct platform_device *pdev)
|
|||||||
}
|
}
|
||||||
data->sio = sio;
|
data->sio = sio;
|
||||||
|
|
||||||
platform_set_drvdata(pdev, data);
|
|
||||||
|
|
||||||
/* For each GPIO bank, register a GPIO chip. */
|
/* For each GPIO bank, register a GPIO chip. */
|
||||||
for (i = 0; i < data->nr_bank; i++) {
|
for (i = 0; i < data->nr_bank; i++) {
|
||||||
struct nct5104d_gpio_bank *bank = &data->bank[i];
|
struct nct5104d_gpio_bank *bank = &data->bank[i];
|
||||||
@ -279,36 +273,10 @@ static int nct5104d_gpio_probe(struct platform_device *pdev)
|
|||||||
bank->chip.parent = &pdev->dev;
|
bank->chip.parent = &pdev->dev;
|
||||||
bank->data = data;
|
bank->data = data;
|
||||||
|
|
||||||
err = gpiochip_add(&bank->chip);
|
err = devm_gpiochip_add_data(&pdev->dev, &bank->chip, bank);
|
||||||
if (err) {
|
if (err)
|
||||||
dev_err(&pdev->dev,
|
return dev_err_probe(&pdev->dev, err,
|
||||||
"Failed to register gpiochip %d: %d\n",
|
"Failed to register gpiochip %d", err);
|
||||||
i, err);
|
|
||||||
goto err_gpiochip;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
err_gpiochip:
|
|
||||||
for (i = i - 1; i >= 0; i--) {
|
|
||||||
struct nct5104d_gpio_bank *bank = &data->bank[i];
|
|
||||||
|
|
||||||
gpiochip_remove (&bank->chip);
|
|
||||||
}
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int nct5104d_gpio_remove(struct platform_device *pdev)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
struct nct5104d_gpio_data *data = platform_get_drvdata(pdev);
|
|
||||||
|
|
||||||
for (i = 0; i < data->nr_bank; i++) {
|
|
||||||
struct nct5104d_gpio_bank *bank = &data->bank[i];
|
|
||||||
|
|
||||||
gpiochip_remove (&bank->chip);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -402,7 +370,6 @@ static struct platform_driver nct5104d_gpio_driver = {
|
|||||||
.name = DRVNAME,
|
.name = DRVNAME,
|
||||||
},
|
},
|
||||||
.probe = nct5104d_gpio_probe,
|
.probe = nct5104d_gpio_probe,
|
||||||
.remove = nct5104d_gpio_remove,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init nct5104d_gpio_init(void)
|
static int __init nct5104d_gpio_init(void)
|
||||||
|
|||||||
@ -10,7 +10,7 @@ include $(INCLUDE_DIR)/kernel.mk
|
|||||||
|
|
||||||
PKG_NAME:=ltq-adsl
|
PKG_NAME:=ltq-adsl
|
||||||
PKG_VERSION:=3.24.4.4
|
PKG_VERSION:=3.24.4.4
|
||||||
PKG_RELEASE:=4
|
PKG_RELEASE:=5
|
||||||
PKG_SOURCE:=drv_dsl_cpe_api_danube-$(PKG_VERSION).tar.gz
|
PKG_SOURCE:=drv_dsl_cpe_api_danube-$(PKG_VERSION).tar.gz
|
||||||
PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/ltq-dsl-$(BUILD_VARIANT)/drv_dsl_cpe_api-$(PKG_VERSION)
|
PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/ltq-dsl-$(BUILD_VARIANT)/drv_dsl_cpe_api-$(PKG_VERSION)
|
||||||
PKG_SOURCE_URL:=@OPENWRT
|
PKG_SOURCE_URL:=@OPENWRT
|
||||||
@ -53,20 +53,13 @@ CONFIGURE_ARGS += --enable-kernel-include="$(LINUX_DIR)/include" \
|
|||||||
--with-max-device="$(IFX_DSL_MAX_DEVICE)" \
|
--with-max-device="$(IFX_DSL_MAX_DEVICE)" \
|
||||||
--with-lines-per-device="$(IFX_DSL_LINES_PER_DEVICE)" \
|
--with-lines-per-device="$(IFX_DSL_LINES_PER_DEVICE)" \
|
||||||
--with-channels-per-line="$(IFX_DSL_CHANNELS_PER_LINE)" \
|
--with-channels-per-line="$(IFX_DSL_CHANNELS_PER_LINE)" \
|
||||||
|
--enable-model=full \
|
||||||
|
--disable-dsl-pm-retx-counters \
|
||||||
|
--disable-dsl-pm-retx-thresholds \
|
||||||
|
--disable-adsl-mib-support \
|
||||||
|
--disable-adsl-trace \
|
||||||
--disable-dsl-delt-static \
|
--disable-dsl-delt-static \
|
||||||
--disable-adsl-led \
|
--disable-adsl-led \
|
||||||
--enable-dsl-ceoc \
|
|
||||||
--enable-dsl-pm \
|
|
||||||
--enable-dsl-pm-total \
|
|
||||||
--enable-dsl-pm-history \
|
|
||||||
--enable-dsl-pm-showtime \
|
|
||||||
--enable-dsl-pm-channel-counters \
|
|
||||||
--enable-dsl-pm-datapath-counters \
|
|
||||||
--enable-dsl-pm-line-counters \
|
|
||||||
--enable-dsl-pm-channel-thresholds \
|
|
||||||
--enable-dsl-pm-datapath-thresholds \
|
|
||||||
--enable-dsl-pm-line-thresholds \
|
|
||||||
--enable-dsl-pm-optional-parameters \
|
|
||||||
--enable-linux-26 \
|
--enable-linux-26 \
|
||||||
--enable-kernelbuild="$(LINUX_DIR)" \
|
--enable-kernelbuild="$(LINUX_DIR)" \
|
||||||
ARCH=$(LINUX_KARCH)
|
ARCH=$(LINUX_KARCH)
|
||||||
|
|||||||
@ -171,7 +171,7 @@ endef
|
|||||||
define KernelPackage/mac80211-hwsim
|
define KernelPackage/mac80211-hwsim
|
||||||
$(call KernelPackage/mac80211/Default)
|
$(call KernelPackage/mac80211/Default)
|
||||||
TITLE:=mac80211 HW simulation device
|
TITLE:=mac80211 HW simulation device
|
||||||
DEPENDS+= +kmod-mac80211 +@DRIVER_11AX_SUPPORT +@DRIVER_11AC_SUPPORT
|
DEPENDS+= +kmod-mac80211 +@DRIVER_11BE_SUPPORT +@DRIVER_11AX_SUPPORT +@DRIVER_11AC_SUPPORT
|
||||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/virtual/mac80211_hwsim.ko
|
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/virtual/mac80211_hwsim.ko
|
||||||
AUTOLOAD:=$(call AutoProbe,mac80211_hwsim)
|
AUTOLOAD:=$(call AutoProbe,mac80211_hwsim)
|
||||||
endef
|
endef
|
||||||
|
|||||||
@ -0,0 +1,122 @@
|
|||||||
|
From: Karthikeyan Periyasamy <quic_periyasa@quicinc.com>
|
||||||
|
Date: Tue, 17 Sep 2024 19:32:39 +0530
|
||||||
|
Subject: [PATCH] wifi: cfg80211: check radio iface combination for multi radio
|
||||||
|
per wiphy
|
||||||
|
|
||||||
|
Currently, wiphy_verify_combinations() fails for the multi-radio per wiphy
|
||||||
|
due to the condition check on new global interface combination that DFS
|
||||||
|
only works on one channel. In a multi-radio scenario, new global interface
|
||||||
|
combination encompasses the capabilities of all radio combinations, so it
|
||||||
|
supports more than one channel with DFS. For multi-radio per wiphy,
|
||||||
|
interface combination verification needs to be performed for radio specific
|
||||||
|
interface combinations. This is necessary as the new global interface
|
||||||
|
combination combines the capabilities of all radio combinations.
|
||||||
|
|
||||||
|
Fixes: a01b1e9f9955 ("wifi: mac80211: add support for DFS with multiple radios")
|
||||||
|
Signed-off-by: Karthikeyan Periyasamy <quic_periyasa@quicinc.com>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/net/wireless/core.c
|
||||||
|
+++ b/net/wireless/core.c
|
||||||
|
@@ -599,16 +599,20 @@ use_default_name:
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(wiphy_new_nm);
|
||||||
|
|
||||||
|
-static int wiphy_verify_combinations(struct wiphy *wiphy)
|
||||||
|
+static
|
||||||
|
+int wiphy_verify_iface_combinations(struct wiphy *wiphy,
|
||||||
|
+ const struct ieee80211_iface_combination *iface_comb,
|
||||||
|
+ int n_iface_comb,
|
||||||
|
+ bool combined_radio)
|
||||||
|
{
|
||||||
|
const struct ieee80211_iface_combination *c;
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
- for (i = 0; i < wiphy->n_iface_combinations; i++) {
|
||||||
|
+ for (i = 0; i < n_iface_comb; i++) {
|
||||||
|
u32 cnt = 0;
|
||||||
|
u16 all_iftypes = 0;
|
||||||
|
|
||||||
|
- c = &wiphy->iface_combinations[i];
|
||||||
|
+ c = &iface_comb[i];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Combinations with just one interface aren't real,
|
||||||
|
@@ -621,9 +625,13 @@ static int wiphy_verify_combinations(str
|
||||||
|
if (WARN_ON(!c->num_different_channels))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
- /* DFS only works on one channel. */
|
||||||
|
- if (WARN_ON(c->radar_detect_widths &&
|
||||||
|
- (c->num_different_channels > 1)))
|
||||||
|
+ /* DFS only works on one channel. Avoid this check
|
||||||
|
+ * for multi-radio global combination, since it hold
|
||||||
|
+ * the capabilities of all radio combinations.
|
||||||
|
+ */
|
||||||
|
+ if (!combined_radio &&
|
||||||
|
+ WARN_ON(c->radar_detect_widths &&
|
||||||
|
+ c->num_different_channels > 1))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (WARN_ON(!c->n_limits))
|
||||||
|
@@ -644,13 +652,21 @@ static int wiphy_verify_combinations(str
|
||||||
|
if (WARN_ON(wiphy->software_iftypes & types))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
- /* Only a single P2P_DEVICE can be allowed */
|
||||||
|
- if (WARN_ON(types & BIT(NL80211_IFTYPE_P2P_DEVICE) &&
|
||||||
|
+ /* Only a single P2P_DEVICE can be allowed, avoid this
|
||||||
|
+ * check for multi-radio global combination, since it
|
||||||
|
+ * hold the capabilities of all radio combinations.
|
||||||
|
+ */
|
||||||
|
+ if (!combined_radio &&
|
||||||
|
+ WARN_ON(types & BIT(NL80211_IFTYPE_P2P_DEVICE) &&
|
||||||
|
c->limits[j].max > 1))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
- /* Only a single NAN can be allowed */
|
||||||
|
- if (WARN_ON(types & BIT(NL80211_IFTYPE_NAN) &&
|
||||||
|
+ /* Only a single NAN can be allowed, avoid this
|
||||||
|
+ * check for multi-radio global combination, since it
|
||||||
|
+ * hold the capabilities of all radio combinations.
|
||||||
|
+ */
|
||||||
|
+ if (!combined_radio &&
|
||||||
|
+ WARN_ON(types & BIT(NL80211_IFTYPE_NAN) &&
|
||||||
|
c->limits[j].max > 1))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
@@ -674,6 +690,34 @@ static int wiphy_verify_combinations(str
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int wiphy_verify_combinations(struct wiphy *wiphy)
|
||||||
|
+{
|
||||||
|
+ int i, ret;
|
||||||
|
+ bool combined_radio = false;
|
||||||
|
+
|
||||||
|
+ if (wiphy->n_radio) {
|
||||||
|
+ for (i = 0; i < wiphy->n_radio; i++) {
|
||||||
|
+ const struct wiphy_radio *radio = &wiphy->radio[i];
|
||||||
|
+
|
||||||
|
+ ret = wiphy_verify_iface_combinations(wiphy,
|
||||||
|
+ radio->iface_combinations,
|
||||||
|
+ radio->n_iface_combinations,
|
||||||
|
+ false);
|
||||||
|
+ if (ret)
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ combined_radio = true;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ret = wiphy_verify_iface_combinations(wiphy,
|
||||||
|
+ wiphy->iface_combinations,
|
||||||
|
+ wiphy->n_iface_combinations,
|
||||||
|
+ combined_radio);
|
||||||
|
+
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int wiphy_register(struct wiphy *wiphy)
|
||||||
|
{
|
||||||
|
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
|
||||||
@ -0,0 +1,309 @@
|
|||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Date: Wed, 17 Jul 2024 15:43:52 +0200
|
||||||
|
Subject: [PATCH] wifi: cfg80211: add option for vif allowed radios
|
||||||
|
|
||||||
|
This allows users to prevent a vif from affecting radios other than the
|
||||||
|
configured ones. This can be useful in cases where e.g. an AP is running
|
||||||
|
on one radio, and triggering a scan on another radio should not disturb it.
|
||||||
|
|
||||||
|
Changing the allowed radios list for a vif is supported, but only while
|
||||||
|
it is down.
|
||||||
|
|
||||||
|
While it is possible to achieve the same by always explicitly specifying
|
||||||
|
a frequency list for scan requests and ensuring that the wrong channel/band
|
||||||
|
is never accidentally set on an unrelated interface, this change makes
|
||||||
|
multi-radio wiphy setups a lot easier to deal with for CLI users.
|
||||||
|
|
||||||
|
By itself, this patch only enforces the radio mask for scanning requests
|
||||||
|
and remain-on-channel. Follow-up changes build on this to limit configured
|
||||||
|
frequencies.
|
||||||
|
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/include/net/cfg80211.h
|
||||||
|
+++ b/include/net/cfg80211.h
|
||||||
|
@@ -6227,6 +6227,7 @@ enum ieee80211_ap_reg_power {
|
||||||
|
* entered.
|
||||||
|
* @links[].cac_time_ms: CAC time in ms
|
||||||
|
* @valid_links: bitmap describing what elements of @links are valid
|
||||||
|
+ * @radio_mask: Bitmask of radios that this interface is allowed to operate on.
|
||||||
|
*/
|
||||||
|
struct wireless_dev {
|
||||||
|
struct wiphy *wiphy;
|
||||||
|
@@ -6339,6 +6340,8 @@ struct wireless_dev {
|
||||||
|
unsigned int cac_time_ms;
|
||||||
|
} links[IEEE80211_MLD_MAX_NUM_LINKS];
|
||||||
|
u16 valid_links;
|
||||||
|
+
|
||||||
|
+ u32 radio_mask;
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline const u8 *wdev_address(struct wireless_dev *wdev)
|
||||||
|
@@ -6525,6 +6528,17 @@ bool cfg80211_radio_chandef_valid(const
|
||||||
|
const struct cfg80211_chan_def *chandef);
|
||||||
|
|
||||||
|
/**
|
||||||
|
+ * cfg80211_wdev_channel_allowed - Check if the wdev may use the channel
|
||||||
|
+ *
|
||||||
|
+ * @wdev: the wireless device
|
||||||
|
+ * @chan: channel to check
|
||||||
|
+ *
|
||||||
|
+ * Return: whether or not the wdev may use the channel
|
||||||
|
+ */
|
||||||
|
+bool cfg80211_wdev_channel_allowed(struct wireless_dev *wdev,
|
||||||
|
+ struct ieee80211_channel *chan);
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
* ieee80211_get_response_rate - get basic rate for a given rate
|
||||||
|
*
|
||||||
|
* @sband: the band to look for rates in
|
||||||
|
--- a/include/uapi/linux/nl80211.h
|
||||||
|
+++ b/include/uapi/linux/nl80211.h
|
||||||
|
@@ -2868,6 +2868,9 @@ enum nl80211_commands {
|
||||||
|
* nested item, it contains attributes defined in
|
||||||
|
* &enum nl80211_if_combination_attrs.
|
||||||
|
*
|
||||||
|
+ * @NL80211_ATTR_VIF_RADIO_MASK: Bitmask of allowed radios (u32).
|
||||||
|
+ * A value of 0 means all radios.
|
||||||
|
+ *
|
||||||
|
* @NUM_NL80211_ATTR: total number of nl80211_attrs available
|
||||||
|
* @NL80211_ATTR_MAX: highest attribute number currently defined
|
||||||
|
* @__NL80211_ATTR_AFTER_LAST: internal use
|
||||||
|
@@ -3416,6 +3419,8 @@ enum nl80211_attrs {
|
||||||
|
NL80211_ATTR_WIPHY_RADIOS,
|
||||||
|
NL80211_ATTR_WIPHY_INTERFACE_COMBINATIONS,
|
||||||
|
|
||||||
|
+ NL80211_ATTR_VIF_RADIO_MASK,
|
||||||
|
+
|
||||||
|
/* add attributes here, update the policy in nl80211.c */
|
||||||
|
|
||||||
|
__NL80211_ATTR_AFTER_LAST,
|
||||||
|
--- a/net/wireless/nl80211.c
|
||||||
|
+++ b/net/wireless/nl80211.c
|
||||||
|
@@ -829,6 +829,7 @@ static const struct nla_policy nl80211_p
|
||||||
|
[NL80211_ATTR_MLO_TTLM_DLINK] = NLA_POLICY_EXACT_LEN(sizeof(u16) * 8),
|
||||||
|
[NL80211_ATTR_MLO_TTLM_ULINK] = NLA_POLICY_EXACT_LEN(sizeof(u16) * 8),
|
||||||
|
[NL80211_ATTR_ASSOC_SPP_AMSDU] = { .type = NLA_FLAG },
|
||||||
|
+ [NL80211_ATTR_VIF_RADIO_MASK] = { .type = NLA_U32 },
|
||||||
|
};
|
||||||
|
|
||||||
|
/* policy for the key attributes */
|
||||||
|
@@ -3996,7 +3997,8 @@ static int nl80211_send_iface(struct sk_
|
||||||
|
nla_put_u32(msg, NL80211_ATTR_GENERATION,
|
||||||
|
rdev->devlist_generation ^
|
||||||
|
(cfg80211_rdev_list_generation << 2)) ||
|
||||||
|
- nla_put_u8(msg, NL80211_ATTR_4ADDR, wdev->use_4addr))
|
||||||
|
+ nla_put_u8(msg, NL80211_ATTR_4ADDR, wdev->use_4addr) ||
|
||||||
|
+ nla_put_u32(msg, NL80211_ATTR_VIF_RADIO_MASK, wdev->radio_mask))
|
||||||
|
goto nla_put_failure;
|
||||||
|
|
||||||
|
if (rdev->ops->get_channel && !wdev->valid_links) {
|
||||||
|
@@ -4312,6 +4314,29 @@ static int nl80211_valid_4addr(struct cf
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int nl80211_parse_vif_radio_mask(struct genl_info *info,
|
||||||
|
+ u32 *radio_mask)
|
||||||
|
+{
|
||||||
|
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
|
||||||
|
+ struct nlattr *attr = info->attrs[NL80211_ATTR_VIF_RADIO_MASK];
|
||||||
|
+ u32 mask, allowed;
|
||||||
|
+
|
||||||
|
+ if (!attr) {
|
||||||
|
+ *radio_mask = 0;
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ allowed = BIT(rdev->wiphy.n_radio) - 1;
|
||||||
|
+ mask = nla_get_u32(attr);
|
||||||
|
+ if (mask & ~allowed)
|
||||||
|
+ return -EINVAL;
|
||||||
|
+ if (!mask)
|
||||||
|
+ mask = allowed;
|
||||||
|
+ *radio_mask = mask;
|
||||||
|
+
|
||||||
|
+ return 1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
|
||||||
|
{
|
||||||
|
struct cfg80211_registered_device *rdev = info->user_ptr[0];
|
||||||
|
@@ -4319,6 +4344,8 @@ static int nl80211_set_interface(struct
|
||||||
|
int err;
|
||||||
|
enum nl80211_iftype otype, ntype;
|
||||||
|
struct net_device *dev = info->user_ptr[1];
|
||||||
|
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||||
|
+ u32 radio_mask = 0;
|
||||||
|
bool change = false;
|
||||||
|
|
||||||
|
memset(¶ms, 0, sizeof(params));
|
||||||
|
@@ -4332,8 +4359,6 @@ static int nl80211_set_interface(struct
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info->attrs[NL80211_ATTR_MESH_ID]) {
|
||||||
|
- struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||||
|
-
|
||||||
|
if (ntype != NL80211_IFTYPE_MESH_POINT)
|
||||||
|
return -EINVAL;
|
||||||
|
if (otype != NL80211_IFTYPE_MESH_POINT)
|
||||||
|
@@ -4364,6 +4389,12 @@ static int nl80211_set_interface(struct
|
||||||
|
if (err > 0)
|
||||||
|
change = true;
|
||||||
|
|
||||||
|
+ err = nl80211_parse_vif_radio_mask(info, &radio_mask);
|
||||||
|
+ if (err < 0)
|
||||||
|
+ return err;
|
||||||
|
+ if (err && netif_running(dev))
|
||||||
|
+ return -EBUSY;
|
||||||
|
+
|
||||||
|
if (change)
|
||||||
|
err = cfg80211_change_iface(rdev, dev, ntype, ¶ms);
|
||||||
|
else
|
||||||
|
@@ -4372,11 +4403,11 @@ static int nl80211_set_interface(struct
|
||||||
|
if (!err && params.use_4addr != -1)
|
||||||
|
dev->ieee80211_ptr->use_4addr = params.use_4addr;
|
||||||
|
|
||||||
|
- if (change && !err) {
|
||||||
|
- struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||||
|
+ if (radio_mask)
|
||||||
|
+ wdev->radio_mask = radio_mask;
|
||||||
|
|
||||||
|
+ if (change && !err)
|
||||||
|
nl80211_notify_iface(rdev, wdev, NL80211_CMD_SET_INTERFACE);
|
||||||
|
- }
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
@@ -4387,6 +4418,7 @@ static int _nl80211_new_interface(struct
|
||||||
|
struct vif_params params;
|
||||||
|
struct wireless_dev *wdev;
|
||||||
|
struct sk_buff *msg;
|
||||||
|
+ u32 radio_mask;
|
||||||
|
int err;
|
||||||
|
enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED;
|
||||||
|
|
||||||
|
@@ -4424,6 +4456,10 @@ static int _nl80211_new_interface(struct
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
+ err = nl80211_parse_vif_radio_mask(info, &radio_mask);
|
||||||
|
+ if (err < 0)
|
||||||
|
+ return err;
|
||||||
|
+
|
||||||
|
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
|
||||||
|
if (!msg)
|
||||||
|
return -ENOMEM;
|
||||||
|
@@ -4465,6 +4501,9 @@ static int _nl80211_new_interface(struct
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (radio_mask)
|
||||||
|
+ wdev->radio_mask = radio_mask;
|
||||||
|
+
|
||||||
|
if (nl80211_send_iface(msg, info->snd_portid, info->snd_seq, 0,
|
||||||
|
rdev, wdev, NL80211_CMD_NEW_INTERFACE) < 0) {
|
||||||
|
nlmsg_free(msg);
|
||||||
|
@@ -9180,6 +9219,9 @@ static bool cfg80211_off_channel_oper_al
|
||||||
|
|
||||||
|
lockdep_assert_wiphy(wdev->wiphy);
|
||||||
|
|
||||||
|
+ if (!cfg80211_wdev_channel_allowed(wdev, chan))
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
if (!cfg80211_beaconing_iface_active(wdev))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
@@ -9392,7 +9434,8 @@ static int nl80211_trigger_scan(struct s
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ignore disabled channels */
|
||||||
|
- if (chan->flags & IEEE80211_CHAN_DISABLED)
|
||||||
|
+ if (chan->flags & IEEE80211_CHAN_DISABLED ||
|
||||||
|
+ !cfg80211_wdev_channel_allowed(wdev, chan))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
request->channels[i] = chan;
|
||||||
|
@@ -9412,7 +9455,8 @@ static int nl80211_trigger_scan(struct s
|
||||||
|
|
||||||
|
chan = &wiphy->bands[band]->channels[j];
|
||||||
|
|
||||||
|
- if (chan->flags & IEEE80211_CHAN_DISABLED)
|
||||||
|
+ if (chan->flags & IEEE80211_CHAN_DISABLED ||
|
||||||
|
+ !cfg80211_wdev_channel_allowed(wdev, chan))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
request->channels[i] = chan;
|
||||||
|
--- a/net/wireless/scan.c
|
||||||
|
+++ b/net/wireless/scan.c
|
||||||
|
@@ -956,7 +956,8 @@ static int cfg80211_scan_6ghz(struct cfg
|
||||||
|
struct ieee80211_channel *chan =
|
||||||
|
ieee80211_get_channel(&rdev->wiphy, ap->center_freq);
|
||||||
|
|
||||||
|
- if (!chan || chan->flags & IEEE80211_CHAN_DISABLED)
|
||||||
|
+ if (!chan || chan->flags & IEEE80211_CHAN_DISABLED ||
|
||||||
|
+ !cfg80211_wdev_channel_allowed(rdev_req->wdev, chan))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (i = 0; i < rdev_req->n_channels; i++) {
|
||||||
|
@@ -3490,9 +3491,12 @@ int cfg80211_wext_siwscan(struct net_dev
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
|
||||||
|
+ struct ieee80211_channel *chan;
|
||||||
|
+
|
||||||
|
/* ignore disabled channels */
|
||||||
|
- if (wiphy->bands[band]->channels[j].flags &
|
||||||
|
- IEEE80211_CHAN_DISABLED)
|
||||||
|
+ chan = &wiphy->bands[band]->channels[j];
|
||||||
|
+ if (chan->flags & IEEE80211_CHAN_DISABLED ||
|
||||||
|
+ !cfg80211_wdev_channel_allowed(creq->wdev, chan))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* If we have a wireless request structure and the
|
||||||
|
--- a/net/wireless/util.c
|
||||||
|
+++ b/net/wireless/util.c
|
||||||
|
@@ -2923,3 +2923,32 @@ bool cfg80211_radio_chandef_valid(const
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(cfg80211_radio_chandef_valid);
|
||||||
|
+
|
||||||
|
+bool cfg80211_wdev_channel_allowed(struct wireless_dev *wdev,
|
||||||
|
+ struct ieee80211_channel *chan)
|
||||||
|
+{
|
||||||
|
+ struct wiphy *wiphy = wdev->wiphy;
|
||||||
|
+ const struct wiphy_radio *radio;
|
||||||
|
+ struct cfg80211_chan_def chandef;
|
||||||
|
+ u32 radio_mask;
|
||||||
|
+ int i;
|
||||||
|
+
|
||||||
|
+ radio_mask = wdev->radio_mask;
|
||||||
|
+ if (!wiphy->n_radio || radio_mask == BIT(wiphy->n_radio) - 1)
|
||||||
|
+ return true;
|
||||||
|
+
|
||||||
|
+ cfg80211_chandef_create(&chandef, chan, NL80211_CHAN_HT20);
|
||||||
|
+ for (i = 0; i < wiphy->n_radio; i++) {
|
||||||
|
+ if (!(radio_mask & BIT(i)))
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ radio = &wiphy->radio[i];
|
||||||
|
+ if (!cfg80211_radio_chandef_valid(radio, &chandef))
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ return true;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return false;
|
||||||
|
+}
|
||||||
|
+EXPORT_SYMBOL(cfg80211_wdev_channel_allowed);
|
||||||
|
--- a/net/wireless/core.c
|
||||||
|
+++ b/net/wireless/core.c
|
||||||
|
@@ -1415,6 +1415,8 @@ void cfg80211_init_wdev(struct wireless_
|
||||||
|
/* allow mac80211 to determine the timeout */
|
||||||
|
wdev->ps_timeout = -1;
|
||||||
|
|
||||||
|
+ wdev->radio_mask = BIT(wdev->wiphy->n_radio) - 1;
|
||||||
|
+
|
||||||
|
if ((wdev->iftype == NL80211_IFTYPE_STATION ||
|
||||||
|
wdev->iftype == NL80211_IFTYPE_P2P_CLIENT ||
|
||||||
|
wdev->iftype == NL80211_IFTYPE_ADHOC) && !wdev->use_4addr)
|
||||||
@ -0,0 +1,79 @@
|
|||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Date: Thu, 26 Sep 2024 14:06:11 +0200
|
||||||
|
Subject: [PATCH] wifi: mac80211: use vif radio mask to limit ibss scan
|
||||||
|
frequencies
|
||||||
|
|
||||||
|
Reject frequencies not supported by any radio that the vif is allowed to use.
|
||||||
|
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/net/mac80211/scan.c
|
||||||
|
+++ b/net/mac80211/scan.c
|
||||||
|
@@ -1178,14 +1178,14 @@ int ieee80211_request_ibss_scan(struct i
|
||||||
|
unsigned int n_channels)
|
||||||
|
{
|
||||||
|
struct ieee80211_local *local = sdata->local;
|
||||||
|
- int ret = -EBUSY, i, n_ch = 0;
|
||||||
|
+ int i, n_ch = 0;
|
||||||
|
enum nl80211_band band;
|
||||||
|
|
||||||
|
lockdep_assert_wiphy(local->hw.wiphy);
|
||||||
|
|
||||||
|
/* busy scanning */
|
||||||
|
if (local->scan_req)
|
||||||
|
- goto unlock;
|
||||||
|
+ return -EBUSY;
|
||||||
|
|
||||||
|
/* fill internal scan request */
|
||||||
|
if (!channels) {
|
||||||
|
@@ -1202,7 +1202,9 @@ int ieee80211_request_ibss_scan(struct i
|
||||||
|
&local->hw.wiphy->bands[band]->channels[i];
|
||||||
|
|
||||||
|
if (tmp_ch->flags & (IEEE80211_CHAN_NO_IR |
|
||||||
|
- IEEE80211_CHAN_DISABLED))
|
||||||
|
+ IEEE80211_CHAN_DISABLED) ||
|
||||||
|
+ !cfg80211_wdev_channel_allowed(&sdata->wdev,
|
||||||
|
+ tmp_ch))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
local->int_scan_req->channels[n_ch] = tmp_ch;
|
||||||
|
@@ -1211,21 +1213,23 @@ int ieee80211_request_ibss_scan(struct i
|
||||||
|
}
|
||||||
|
|
||||||
|
if (WARN_ON_ONCE(n_ch == 0))
|
||||||
|
- goto unlock;
|
||||||
|
+ return -EINVAL;
|
||||||
|
|
||||||
|
local->int_scan_req->n_channels = n_ch;
|
||||||
|
} else {
|
||||||
|
for (i = 0; i < n_channels; i++) {
|
||||||
|
if (channels[i]->flags & (IEEE80211_CHAN_NO_IR |
|
||||||
|
- IEEE80211_CHAN_DISABLED))
|
||||||
|
+ IEEE80211_CHAN_DISABLED) ||
|
||||||
|
+ !cfg80211_wdev_channel_allowed(&sdata->wdev,
|
||||||
|
+ channels[i]))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
local->int_scan_req->channels[n_ch] = channels[i];
|
||||||
|
n_ch++;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (WARN_ON_ONCE(n_ch == 0))
|
||||||
|
- goto unlock;
|
||||||
|
+ if (n_ch == 0)
|
||||||
|
+ return -EINVAL;
|
||||||
|
|
||||||
|
local->int_scan_req->n_channels = n_ch;
|
||||||
|
}
|
||||||
|
@@ -1235,9 +1239,7 @@ int ieee80211_request_ibss_scan(struct i
|
||||||
|
memcpy(local->int_scan_req->ssids[0].ssid, ssid, IEEE80211_MAX_SSID_LEN);
|
||||||
|
local->int_scan_req->ssids[0].ssid_len = ssid_len;
|
||||||
|
|
||||||
|
- ret = __ieee80211_start_scan(sdata, sdata->local->int_scan_req);
|
||||||
|
- unlock:
|
||||||
|
- return ret;
|
||||||
|
+ return __ieee80211_start_scan(sdata, sdata->local->int_scan_req);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ieee80211_scan_cancel(struct ieee80211_local *local)
|
||||||
@ -0,0 +1,52 @@
|
|||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Date: Thu, 26 Sep 2024 14:07:50 +0200
|
||||||
|
Subject: [PATCH] wifi: mac80211: use vif radio mask to limit creating chanctx
|
||||||
|
|
||||||
|
Reject frequencies not supported by any radio that the vif is allowed to use.
|
||||||
|
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/net/mac80211/chan.c
|
||||||
|
+++ b/net/mac80211/chan.c
|
||||||
|
@@ -1167,7 +1167,7 @@ ieee80211_replace_chanctx(struct ieee802
|
||||||
|
static bool
|
||||||
|
ieee80211_find_available_radio(struct ieee80211_local *local,
|
||||||
|
const struct ieee80211_chan_req *chanreq,
|
||||||
|
- int *radio_idx)
|
||||||
|
+ u32 radio_mask, int *radio_idx)
|
||||||
|
{
|
||||||
|
struct wiphy *wiphy = local->hw.wiphy;
|
||||||
|
const struct wiphy_radio *radio;
|
||||||
|
@@ -1178,6 +1178,9 @@ ieee80211_find_available_radio(struct ie
|
||||||
|
return true;
|
||||||
|
|
||||||
|
for (i = 0; i < wiphy->n_radio; i++) {
|
||||||
|
+ if (!(radio_mask & BIT(i)))
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
radio = &wiphy->radio[i];
|
||||||
|
if (!cfg80211_radio_chandef_valid(radio, &chanreq->oper))
|
||||||
|
continue;
|
||||||
|
@@ -1211,7 +1214,9 @@ int ieee80211_link_reserve_chanctx(struc
|
||||||
|
new_ctx = ieee80211_find_reservation_chanctx(local, chanreq, mode);
|
||||||
|
if (!new_ctx) {
|
||||||
|
if (ieee80211_can_create_new_chanctx(local, -1) &&
|
||||||
|
- ieee80211_find_available_radio(local, chanreq, &radio_idx))
|
||||||
|
+ ieee80211_find_available_radio(local, chanreq,
|
||||||
|
+ sdata->wdev.radio_mask,
|
||||||
|
+ &radio_idx))
|
||||||
|
new_ctx = ieee80211_new_chanctx(local, chanreq, mode,
|
||||||
|
false, radio_idx);
|
||||||
|
else
|
||||||
|
@@ -1881,7 +1886,9 @@ int _ieee80211_link_use_channel(struct i
|
||||||
|
/* Note: context is now reserved */
|
||||||
|
if (ctx)
|
||||||
|
reserved = true;
|
||||||
|
- else if (!ieee80211_find_available_radio(local, chanreq, &radio_idx))
|
||||||
|
+ else if (!ieee80211_find_available_radio(local, chanreq,
|
||||||
|
+ sdata->wdev.radio_mask,
|
||||||
|
+ &radio_idx))
|
||||||
|
ctx = ERR_PTR(-EBUSY);
|
||||||
|
else
|
||||||
|
ctx = ieee80211_new_chanctx(local, chanreq, mode,
|
||||||
@ -0,0 +1,67 @@
|
|||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Date: Wed, 17 Jul 2024 22:49:16 +0200
|
||||||
|
Subject: [PATCH] wifi: mac80211: remove status->ampdu_delimiter_crc
|
||||||
|
|
||||||
|
This was never used by any driver, so remove it to free up some space.
|
||||||
|
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/include/net/mac80211.h
|
||||||
|
+++ b/include/net/mac80211.h
|
||||||
|
@@ -1448,8 +1448,6 @@ ieee80211_tx_info_clear_status(struct ie
|
||||||
|
* @RX_FLAG_AMPDU_IS_LAST: this subframe is the last subframe of the A-MPDU
|
||||||
|
* @RX_FLAG_AMPDU_DELIM_CRC_ERROR: A delimiter CRC error has been detected
|
||||||
|
* on this subframe
|
||||||
|
- * @RX_FLAG_AMPDU_DELIM_CRC_KNOWN: The delimiter CRC field is known (the CRC
|
||||||
|
- * is stored in the @ampdu_delimiter_crc field)
|
||||||
|
* @RX_FLAG_MIC_STRIPPED: The mic was stripped of this packet. Decryption was
|
||||||
|
* done by the hardware
|
||||||
|
* @RX_FLAG_ONLY_MONITOR: Report frame only to monitor interfaces without
|
||||||
|
@@ -1521,7 +1519,7 @@ enum mac80211_rx_flags {
|
||||||
|
RX_FLAG_AMPDU_LAST_KNOWN = BIT(12),
|
||||||
|
RX_FLAG_AMPDU_IS_LAST = BIT(13),
|
||||||
|
RX_FLAG_AMPDU_DELIM_CRC_ERROR = BIT(14),
|
||||||
|
- RX_FLAG_AMPDU_DELIM_CRC_KNOWN = BIT(15),
|
||||||
|
+ /* one free bit at 15 */
|
||||||
|
RX_FLAG_MACTIME = BIT(16) | BIT(17),
|
||||||
|
RX_FLAG_MACTIME_PLCP_START = 1 << 16,
|
||||||
|
RX_FLAG_MACTIME_START = 2 << 16,
|
||||||
|
@@ -1618,7 +1616,6 @@ enum mac80211_rx_encoding {
|
||||||
|
* @rx_flags: internal RX flags for mac80211
|
||||||
|
* @ampdu_reference: A-MPDU reference number, must be a different value for
|
||||||
|
* each A-MPDU but the same for each subframe within one A-MPDU
|
||||||
|
- * @ampdu_delimiter_crc: A-MPDU delimiter CRC
|
||||||
|
* @zero_length_psdu_type: radiotap type of the 0-length PSDU
|
||||||
|
* @link_valid: if the link which is identified by @link_id is valid. This flag
|
||||||
|
* is set only when connection is MLO.
|
||||||
|
@@ -1656,7 +1653,6 @@ struct ieee80211_rx_status {
|
||||||
|
s8 signal;
|
||||||
|
u8 chains;
|
||||||
|
s8 chain_signal[IEEE80211_MAX_CHAINS];
|
||||||
|
- u8 ampdu_delimiter_crc;
|
||||||
|
u8 zero_length_psdu_type;
|
||||||
|
u8 link_valid:1, link_id:4;
|
||||||
|
};
|
||||||
|
--- a/net/mac80211/rx.c
|
||||||
|
+++ b/net/mac80211/rx.c
|
||||||
|
@@ -508,18 +508,13 @@ ieee80211_add_rx_radiotap_header(struct
|
||||||
|
flags |= IEEE80211_RADIOTAP_AMPDU_IS_LAST;
|
||||||
|
if (status->flag & RX_FLAG_AMPDU_DELIM_CRC_ERROR)
|
||||||
|
flags |= IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_ERR;
|
||||||
|
- if (status->flag & RX_FLAG_AMPDU_DELIM_CRC_KNOWN)
|
||||||
|
- flags |= IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_KNOWN;
|
||||||
|
if (status->flag & RX_FLAG_AMPDU_EOF_BIT_KNOWN)
|
||||||
|
flags |= IEEE80211_RADIOTAP_AMPDU_EOF_KNOWN;
|
||||||
|
if (status->flag & RX_FLAG_AMPDU_EOF_BIT)
|
||||||
|
flags |= IEEE80211_RADIOTAP_AMPDU_EOF;
|
||||||
|
put_unaligned_le16(flags, pos);
|
||||||
|
pos += 2;
|
||||||
|
- if (status->flag & RX_FLAG_AMPDU_DELIM_CRC_KNOWN)
|
||||||
|
- *pos++ = status->ampdu_delimiter_crc;
|
||||||
|
- else
|
||||||
|
- *pos++ = 0;
|
||||||
|
+ *pos++ = 0;
|
||||||
|
*pos++ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,165 @@
|
|||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Date: Thu, 26 Sep 2024 19:52:30 +0200
|
||||||
|
Subject: [PATCH] wifi: cfg80211: pass net_device to .set_monitor_channel
|
||||||
|
|
||||||
|
Preparation for allowing multiple monitor interfaces with different channels
|
||||||
|
on a multi-radio wiphy.
|
||||||
|
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/drivers/net/wireless/ath/wil6210/cfg80211.c
|
||||||
|
+++ b/drivers/net/wireless/ath/wil6210/cfg80211.c
|
||||||
|
@@ -1493,6 +1493,7 @@ out:
|
||||||
|
}
|
||||||
|
|
||||||
|
static int wil_cfg80211_set_channel(struct wiphy *wiphy,
|
||||||
|
+ struct net_device *dev,
|
||||||
|
struct cfg80211_chan_def *chandef)
|
||||||
|
{
|
||||||
|
struct wil6210_priv *wil = wiphy_to_wil(wiphy);
|
||||||
|
--- a/drivers/net/wireless/marvell/libertas/cfg.c
|
||||||
|
+++ b/drivers/net/wireless/marvell/libertas/cfg.c
|
||||||
|
@@ -486,6 +486,7 @@ static int lbs_add_wps_enrollee_tlv(u8 *
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int lbs_cfg_set_monitor_channel(struct wiphy *wiphy,
|
||||||
|
+ struct net_device *dev,
|
||||||
|
struct cfg80211_chan_def *chandef)
|
||||||
|
{
|
||||||
|
struct lbs_private *priv = wiphy_priv(wiphy);
|
||||||
|
--- a/drivers/net/wireless/microchip/wilc1000/cfg80211.c
|
||||||
|
+++ b/drivers/net/wireless/microchip/wilc1000/cfg80211.c
|
||||||
|
@@ -231,6 +231,7 @@ struct wilc_vif *wilc_get_wl_to_vif(stru
|
||||||
|
}
|
||||||
|
|
||||||
|
static int set_channel(struct wiphy *wiphy,
|
||||||
|
+ struct net_device *dev,
|
||||||
|
struct cfg80211_chan_def *chandef)
|
||||||
|
{
|
||||||
|
struct wilc *wl = wiphy_priv(wiphy);
|
||||||
|
@@ -1424,7 +1425,7 @@ static int start_ap(struct wiphy *wiphy,
|
||||||
|
struct wilc_vif *vif = netdev_priv(dev);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
- ret = set_channel(wiphy, &settings->chandef);
|
||||||
|
+ ret = set_channel(wiphy, dev, &settings->chandef);
|
||||||
|
if (ret != 0)
|
||||||
|
netdev_err(dev, "Error in setting channel\n");
|
||||||
|
|
||||||
|
--- a/include/net/cfg80211.h
|
||||||
|
+++ b/include/net/cfg80211.h
|
||||||
|
@@ -4700,6 +4700,7 @@ struct cfg80211_ops {
|
||||||
|
struct ieee80211_channel *chan);
|
||||||
|
|
||||||
|
int (*set_monitor_channel)(struct wiphy *wiphy,
|
||||||
|
+ struct net_device *dev,
|
||||||
|
struct cfg80211_chan_def *chandef);
|
||||||
|
|
||||||
|
int (*scan)(struct wiphy *wiphy,
|
||||||
|
--- a/net/mac80211/cfg.c
|
||||||
|
+++ b/net/mac80211/cfg.c
|
||||||
|
@@ -879,6 +879,7 @@ static int ieee80211_get_station(struct
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ieee80211_set_monitor_channel(struct wiphy *wiphy,
|
||||||
|
+ struct net_device *dev,
|
||||||
|
struct cfg80211_chan_def *chandef)
|
||||||
|
{
|
||||||
|
struct ieee80211_local *local = wiphy_priv(wiphy);
|
||||||
|
--- a/net/wireless/chan.c
|
||||||
|
+++ b/net/wireless/chan.c
|
||||||
|
@@ -1673,6 +1673,7 @@ bool cfg80211_reg_check_beaconing(struct
|
||||||
|
EXPORT_SYMBOL(cfg80211_reg_check_beaconing);
|
||||||
|
|
||||||
|
int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev,
|
||||||
|
+ struct net_device *dev,
|
||||||
|
struct cfg80211_chan_def *chandef)
|
||||||
|
{
|
||||||
|
if (!rdev->ops->set_monitor_channel)
|
||||||
|
@@ -1680,7 +1681,7 @@ int cfg80211_set_monitor_channel(struct
|
||||||
|
if (!cfg80211_has_monitors_only(rdev))
|
||||||
|
return -EBUSY;
|
||||||
|
|
||||||
|
- return rdev_set_monitor_channel(rdev, chandef);
|
||||||
|
+ return rdev_set_monitor_channel(rdev, dev, chandef);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cfg80211_any_usable_channels(struct wiphy *wiphy,
|
||||||
|
--- a/net/wireless/core.h
|
||||||
|
+++ b/net/wireless/core.h
|
||||||
|
@@ -510,6 +510,7 @@ static inline unsigned int elapsed_jiffi
|
||||||
|
}
|
||||||
|
|
||||||
|
int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev,
|
||||||
|
+ struct net_device *dev,
|
||||||
|
struct cfg80211_chan_def *chandef);
|
||||||
|
|
||||||
|
int ieee80211_get_ratemask(struct ieee80211_supported_band *sband,
|
||||||
|
--- a/net/wireless/nl80211.c
|
||||||
|
+++ b/net/wireless/nl80211.c
|
||||||
|
@@ -3562,7 +3562,7 @@ static int __nl80211_set_channel(struct
|
||||||
|
case NL80211_IFTYPE_MESH_POINT:
|
||||||
|
return cfg80211_set_mesh_channel(rdev, wdev, &chandef);
|
||||||
|
case NL80211_IFTYPE_MONITOR:
|
||||||
|
- return cfg80211_set_monitor_channel(rdev, &chandef);
|
||||||
|
+ return cfg80211_set_monitor_channel(rdev, dev, &chandef);
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
--- a/net/wireless/rdev-ops.h
|
||||||
|
+++ b/net/wireless/rdev-ops.h
|
||||||
|
@@ -445,11 +445,12 @@ rdev_libertas_set_mesh_channel(struct cf
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
rdev_set_monitor_channel(struct cfg80211_registered_device *rdev,
|
||||||
|
+ struct net_device *dev,
|
||||||
|
struct cfg80211_chan_def *chandef)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
- trace_rdev_set_monitor_channel(&rdev->wiphy, chandef);
|
||||||
|
- ret = rdev->ops->set_monitor_channel(&rdev->wiphy, chandef);
|
||||||
|
+ trace_rdev_set_monitor_channel(&rdev->wiphy, dev, chandef);
|
||||||
|
+ ret = rdev->ops->set_monitor_channel(&rdev->wiphy, dev, chandef);
|
||||||
|
trace_rdev_return_int(&rdev->wiphy, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
--- a/net/wireless/trace.h
|
||||||
|
+++ b/net/wireless/trace.h
|
||||||
|
@@ -1318,19 +1318,21 @@ TRACE_EVENT(rdev_libertas_set_mesh_chann
|
||||||
|
);
|
||||||
|
|
||||||
|
TRACE_EVENT(rdev_set_monitor_channel,
|
||||||
|
- TP_PROTO(struct wiphy *wiphy,
|
||||||
|
+ TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
|
||||||
|
struct cfg80211_chan_def *chandef),
|
||||||
|
- TP_ARGS(wiphy, chandef),
|
||||||
|
+ TP_ARGS(wiphy, netdev, chandef),
|
||||||
|
TP_STRUCT__entry(
|
||||||
|
WIPHY_ENTRY
|
||||||
|
+ NETDEV_ENTRY
|
||||||
|
CHAN_DEF_ENTRY
|
||||||
|
),
|
||||||
|
TP_fast_assign(
|
||||||
|
WIPHY_ASSIGN;
|
||||||
|
+ NETDEV_ASSIGN;
|
||||||
|
CHAN_DEF_ASSIGN(chandef);
|
||||||
|
),
|
||||||
|
- TP_printk(WIPHY_PR_FMT ", " CHAN_DEF_PR_FMT,
|
||||||
|
- WIPHY_PR_ARG, CHAN_DEF_PR_ARG)
|
||||||
|
+ TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", " CHAN_DEF_PR_FMT,
|
||||||
|
+ WIPHY_PR_ARG, NETDEV_PR_ARG, CHAN_DEF_PR_ARG)
|
||||||
|
);
|
||||||
|
|
||||||
|
TRACE_EVENT(rdev_auth,
|
||||||
|
--- a/net/wireless/wext-compat.c
|
||||||
|
+++ b/net/wireless/wext-compat.c
|
||||||
|
@@ -830,7 +830,7 @@ static int cfg80211_wext_siwfreq(struct
|
||||||
|
ret = -EINVAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
- ret = cfg80211_set_monitor_channel(rdev, &chandef);
|
||||||
|
+ ret = cfg80211_set_monitor_channel(rdev, dev, &chandef);
|
||||||
|
break;
|
||||||
|
case NL80211_IFTYPE_MESH_POINT:
|
||||||
|
freq = cfg80211_wext_freq(wextfreq);
|
||||||
@ -0,0 +1,337 @@
|
|||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Date: Mon, 30 Sep 2024 15:09:45 +0200
|
||||||
|
Subject: [PATCH] wifi: mac80211: add flag to opt out of virtual monitor
|
||||||
|
support
|
||||||
|
|
||||||
|
This is useful for multi-radio devices that are capable of monitoring on
|
||||||
|
multiple channels simultanenously. When this flag is set, each monitor
|
||||||
|
interface is passed to the driver individually and can have a configured
|
||||||
|
channel.
|
||||||
|
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/include/net/mac80211.h
|
||||||
|
+++ b/include/net/mac80211.h
|
||||||
|
@@ -2679,6 +2679,11 @@ struct ieee80211_txq {
|
||||||
|
* a virtual monitor interface when monitor interfaces are the only
|
||||||
|
* active interfaces.
|
||||||
|
*
|
||||||
|
+ * @IEEE80211_HW_NO_VIRTUAL_MONITOR: The driver would like to be informed
|
||||||
|
+ * of any monitor interface, as well as their configured channel.
|
||||||
|
+ * This is useful for supporting multiple monitor interfaces on different
|
||||||
|
+ * channels.
|
||||||
|
+ *
|
||||||
|
* @IEEE80211_HW_NO_AUTO_VIF: The driver would like for no wlanX to
|
||||||
|
* be created. It is expected user-space will create vifs as
|
||||||
|
* desired (and thus have them named as desired).
|
||||||
|
@@ -2838,6 +2843,7 @@ enum ieee80211_hw_flags {
|
||||||
|
IEEE80211_HW_SUPPORTS_DYNAMIC_PS,
|
||||||
|
IEEE80211_HW_MFP_CAPABLE,
|
||||||
|
IEEE80211_HW_WANT_MONITOR_VIF,
|
||||||
|
+ IEEE80211_HW_NO_VIRTUAL_MONITOR,
|
||||||
|
IEEE80211_HW_NO_AUTO_VIF,
|
||||||
|
IEEE80211_HW_SW_CRYPTO_CONTROL,
|
||||||
|
IEEE80211_HW_SUPPORT_FAST_XMIT,
|
||||||
|
--- a/net/mac80211/cfg.c
|
||||||
|
+++ b/net/mac80211/cfg.c
|
||||||
|
@@ -105,8 +105,11 @@ static int ieee80211_set_mon_options(str
|
||||||
|
}
|
||||||
|
|
||||||
|
/* also validate MU-MIMO change */
|
||||||
|
- monitor_sdata = wiphy_dereference(local->hw.wiphy,
|
||||||
|
- local->monitor_sdata);
|
||||||
|
+ if (ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR))
|
||||||
|
+ monitor_sdata = sdata;
|
||||||
|
+ else
|
||||||
|
+ monitor_sdata = wiphy_dereference(local->hw.wiphy,
|
||||||
|
+ local->monitor_sdata);
|
||||||
|
|
||||||
|
if (!monitor_sdata &&
|
||||||
|
(params->vht_mumimo_groups || params->vht_mumimo_follow_addr))
|
||||||
|
@@ -114,7 +117,9 @@ static int ieee80211_set_mon_options(str
|
||||||
|
|
||||||
|
/* apply all changes now - no failures allowed */
|
||||||
|
|
||||||
|
- if (monitor_sdata && ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF))
|
||||||
|
+ if (monitor_sdata &&
|
||||||
|
+ (ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF) ||
|
||||||
|
+ ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR)))
|
||||||
|
ieee80211_set_mu_mimo_follow(monitor_sdata, params);
|
||||||
|
|
||||||
|
if (params->flags) {
|
||||||
|
@@ -889,22 +894,25 @@ static int ieee80211_set_monitor_channel
|
||||||
|
|
||||||
|
lockdep_assert_wiphy(local->hw.wiphy);
|
||||||
|
|
||||||
|
- if (cfg80211_chandef_identical(&local->monitor_chanreq.oper,
|
||||||
|
- &chanreq.oper))
|
||||||
|
- return 0;
|
||||||
|
+ sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
||||||
|
+ if (!ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR)) {
|
||||||
|
+ if (cfg80211_chandef_identical(&local->monitor_chanreq.oper,
|
||||||
|
+ &chanreq.oper))
|
||||||
|
+ return 0;
|
||||||
|
|
||||||
|
- sdata = wiphy_dereference(local->hw.wiphy,
|
||||||
|
- local->monitor_sdata);
|
||||||
|
- if (!sdata)
|
||||||
|
- goto done;
|
||||||
|
+ sdata = wiphy_dereference(wiphy, local->monitor_sdata);
|
||||||
|
+ if (!sdata)
|
||||||
|
+ goto done;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- if (cfg80211_chandef_identical(&sdata->vif.bss_conf.chanreq.oper,
|
||||||
|
+ if (rcu_access_pointer(sdata->deflink.conf->chanctx_conf) &&
|
||||||
|
+ cfg80211_chandef_identical(&sdata->vif.bss_conf.chanreq.oper,
|
||||||
|
&chanreq.oper))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
ieee80211_link_release_channel(&sdata->deflink);
|
||||||
|
ret = ieee80211_link_use_channel(&sdata->deflink, &chanreq,
|
||||||
|
- IEEE80211_CHANCTX_EXCLUSIVE);
|
||||||
|
+ IEEE80211_CHANCTX_SHARED);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
done:
|
||||||
|
@@ -3049,7 +3057,8 @@ static int ieee80211_set_tx_power(struct
|
||||||
|
if (wdev) {
|
||||||
|
sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
|
||||||
|
|
||||||
|
- if (sdata->vif.type == NL80211_IFTYPE_MONITOR) {
|
||||||
|
+ if (sdata->vif.type == NL80211_IFTYPE_MONITOR &&
|
||||||
|
+ !ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR)) {
|
||||||
|
if (!ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF))
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
|
@@ -3097,7 +3106,8 @@ static int ieee80211_set_tx_power(struct
|
||||||
|
}
|
||||||
|
|
||||||
|
list_for_each_entry(sdata, &local->interfaces, list) {
|
||||||
|
- if (sdata->vif.type == NL80211_IFTYPE_MONITOR) {
|
||||||
|
+ if (sdata->vif.type == NL80211_IFTYPE_MONITOR &&
|
||||||
|
+ !ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR)) {
|
||||||
|
has_monitor = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
@@ -3107,7 +3117,8 @@ static int ieee80211_set_tx_power(struct
|
||||||
|
sdata->vif.bss_conf.txpower_type = txp_type;
|
||||||
|
}
|
||||||
|
list_for_each_entry(sdata, &local->interfaces, list) {
|
||||||
|
- if (sdata->vif.type == NL80211_IFTYPE_MONITOR)
|
||||||
|
+ if (sdata->vif.type == NL80211_IFTYPE_MONITOR &&
|
||||||
|
+ !ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR))
|
||||||
|
continue;
|
||||||
|
ieee80211_recalc_txpower(sdata, update_txp_type);
|
||||||
|
}
|
||||||
|
@@ -4299,7 +4310,8 @@ static int ieee80211_cfg_get_channel(str
|
||||||
|
if (chanctx_conf) {
|
||||||
|
*chandef = link->conf->chanreq.oper;
|
||||||
|
ret = 0;
|
||||||
|
- } else if (local->open_count > 0 &&
|
||||||
|
+ } else if (!ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR) &&
|
||||||
|
+ local->open_count > 0 &&
|
||||||
|
local->open_count == local->monitors &&
|
||||||
|
sdata->vif.type == NL80211_IFTYPE_MONITOR) {
|
||||||
|
*chandef = local->monitor_chanreq.oper;
|
||||||
|
--- a/net/mac80211/chan.c
|
||||||
|
+++ b/net/mac80211/chan.c
|
||||||
|
@@ -337,6 +337,10 @@ ieee80211_get_chanctx_max_required_bw(st
|
||||||
|
case NL80211_IFTYPE_P2P_DEVICE:
|
||||||
|
case NL80211_IFTYPE_NAN:
|
||||||
|
continue;
|
||||||
|
+ case NL80211_IFTYPE_MONITOR:
|
||||||
|
+ WARN_ON_ONCE(!ieee80211_hw_check(&local->hw,
|
||||||
|
+ NO_VIRTUAL_MONITOR));
|
||||||
|
+ fallthrough;
|
||||||
|
case NL80211_IFTYPE_ADHOC:
|
||||||
|
case NL80211_IFTYPE_MESH_POINT:
|
||||||
|
case NL80211_IFTYPE_OCB:
|
||||||
|
@@ -345,7 +349,6 @@ ieee80211_get_chanctx_max_required_bw(st
|
||||||
|
case NL80211_IFTYPE_WDS:
|
||||||
|
case NL80211_IFTYPE_UNSPECIFIED:
|
||||||
|
case NUM_NL80211_IFTYPES:
|
||||||
|
- case NL80211_IFTYPE_MONITOR:
|
||||||
|
case NL80211_IFTYPE_P2P_CLIENT:
|
||||||
|
case NL80211_IFTYPE_P2P_GO:
|
||||||
|
WARN_ON_ONCE(1);
|
||||||
|
@@ -954,6 +957,10 @@ void ieee80211_recalc_smps_chanctx(struc
|
||||||
|
if (!link->sdata->u.mgd.associated)
|
||||||
|
continue;
|
||||||
|
break;
|
||||||
|
+ case NL80211_IFTYPE_MONITOR:
|
||||||
|
+ if (!ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR))
|
||||||
|
+ continue;
|
||||||
|
+ break;
|
||||||
|
case NL80211_IFTYPE_AP:
|
||||||
|
case NL80211_IFTYPE_ADHOC:
|
||||||
|
case NL80211_IFTYPE_MESH_POINT:
|
||||||
|
@@ -966,6 +973,11 @@ void ieee80211_recalc_smps_chanctx(struc
|
||||||
|
if (rcu_access_pointer(link->conf->chanctx_conf) != &chanctx->conf)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
+ if (link->sdata->vif.type == NL80211_IFTYPE_MONITOR) {
|
||||||
|
+ rx_chains_dynamic = rx_chains_static = local->rx_chains;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
switch (link->smps_mode) {
|
||||||
|
default:
|
||||||
|
WARN_ONCE(1, "Invalid SMPS mode %d\n",
|
||||||
|
--- a/net/mac80211/debugfs.c
|
||||||
|
+++ b/net/mac80211/debugfs.c
|
||||||
|
@@ -465,6 +465,7 @@ static const char *hw_flag_names[] = {
|
||||||
|
FLAG(SUPPORTS_DYNAMIC_PS),
|
||||||
|
FLAG(MFP_CAPABLE),
|
||||||
|
FLAG(WANT_MONITOR_VIF),
|
||||||
|
+ FLAG(NO_VIRTUAL_MONITOR),
|
||||||
|
FLAG(NO_AUTO_VIF),
|
||||||
|
FLAG(SW_CRYPTO_CONTROL),
|
||||||
|
FLAG(SUPPORT_FAST_XMIT),
|
||||||
|
--- a/net/mac80211/driver-ops.c
|
||||||
|
+++ b/net/mac80211/driver-ops.c
|
||||||
|
@@ -65,6 +65,7 @@ int drv_add_interface(struct ieee80211_l
|
||||||
|
if (WARN_ON(sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
|
||||||
|
(sdata->vif.type == NL80211_IFTYPE_MONITOR &&
|
||||||
|
!ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF) &&
|
||||||
|
+ !ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR) &&
|
||||||
|
!(sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE))))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
--- a/net/mac80211/iface.c
|
||||||
|
+++ b/net/mac80211/iface.c
|
||||||
|
@@ -279,8 +279,13 @@ static int _ieee80211_change_mac(struct
|
||||||
|
ret = eth_mac_addr(sdata->dev, sa);
|
||||||
|
|
||||||
|
if (ret == 0) {
|
||||||
|
- memcpy(sdata->vif.addr, sa->sa_data, ETH_ALEN);
|
||||||
|
- ether_addr_copy(sdata->vif.bss_conf.addr, sdata->vif.addr);
|
||||||
|
+ if (check_dup) {
|
||||||
|
+ memcpy(sdata->vif.addr, sa->sa_data, ETH_ALEN);
|
||||||
|
+ ether_addr_copy(sdata->vif.bss_conf.addr, sdata->vif.addr);
|
||||||
|
+ } else {
|
||||||
|
+ memset(sdata->vif.addr, 0, ETH_ALEN);
|
||||||
|
+ memset(sdata->vif.bss_conf.addr, 0, ETH_ALEN);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Regardless of eth_mac_addr() return we still want to add the
|
||||||
|
@@ -699,9 +704,11 @@ static void ieee80211_do_stop(struct iee
|
||||||
|
ieee80211_recalc_idle(local);
|
||||||
|
ieee80211_recalc_offload(local);
|
||||||
|
|
||||||
|
- if (!(sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE))
|
||||||
|
+ if (!(sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE) &&
|
||||||
|
+ !ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR))
|
||||||
|
break;
|
||||||
|
|
||||||
|
+ ieee80211_link_release_channel(&sdata->deflink);
|
||||||
|
fallthrough;
|
||||||
|
default:
|
||||||
|
if (!going_down)
|
||||||
|
@@ -1131,7 +1138,8 @@ int ieee80211_add_virtual_monitor(struct
|
||||||
|
ASSERT_RTNL();
|
||||||
|
lockdep_assert_wiphy(local->hw.wiphy);
|
||||||
|
|
||||||
|
- if (local->monitor_sdata)
|
||||||
|
+ if (local->monitor_sdata ||
|
||||||
|
+ ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
sdata = kzalloc(sizeof(*sdata) + local->hw.vif_data_size, GFP_KERNEL);
|
||||||
|
@@ -1193,6 +1201,9 @@ void ieee80211_del_virtual_monitor(struc
|
||||||
|
{
|
||||||
|
struct ieee80211_sub_if_data *sdata;
|
||||||
|
|
||||||
|
+ if (ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR))
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
ASSERT_RTNL();
|
||||||
|
lockdep_assert_wiphy(local->hw.wiphy);
|
||||||
|
|
||||||
|
@@ -1328,7 +1339,8 @@ int ieee80211_do_open(struct wireless_de
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE) {
|
||||||
|
+ if ((sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE) ||
|
||||||
|
+ ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR)) {
|
||||||
|
res = drv_add_interface(local, sdata);
|
||||||
|
if (res)
|
||||||
|
goto err_stop;
|
||||||
|
--- a/net/mac80211/rx.c
|
||||||
|
+++ b/net/mac80211/rx.c
|
||||||
|
@@ -840,6 +840,9 @@ ieee80211_rx_monitor(struct ieee80211_lo
|
||||||
|
bool last_monitor = list_is_last(&sdata->u.mntr.list,
|
||||||
|
&local->mon_list);
|
||||||
|
|
||||||
|
+ if (ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR))
|
||||||
|
+ ieee80211_handle_mu_mimo_mon(sdata, origskb, rtap_space);
|
||||||
|
+
|
||||||
|
if (!monskb)
|
||||||
|
monskb = ieee80211_make_monitor_skb(local, &origskb,
|
||||||
|
rate, rtap_space,
|
||||||
|
--- a/net/mac80211/tx.c
|
||||||
|
+++ b/net/mac80211/tx.c
|
||||||
|
@@ -1763,7 +1763,8 @@ static bool __ieee80211_tx(struct ieee80
|
||||||
|
|
||||||
|
switch (sdata->vif.type) {
|
||||||
|
case NL80211_IFTYPE_MONITOR:
|
||||||
|
- if (sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE) {
|
||||||
|
+ if ((sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE) ||
|
||||||
|
+ ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR)) {
|
||||||
|
vif = &sdata->vif;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
@@ -3952,7 +3953,8 @@ begin:
|
||||||
|
|
||||||
|
switch (tx.sdata->vif.type) {
|
||||||
|
case NL80211_IFTYPE_MONITOR:
|
||||||
|
- if (tx.sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE) {
|
||||||
|
+ if ((tx.sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE) ||
|
||||||
|
+ ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR)) {
|
||||||
|
vif = &tx.sdata->vif;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
--- a/net/mac80211/util.c
|
||||||
|
+++ b/net/mac80211/util.c
|
||||||
|
@@ -754,7 +754,8 @@ static void __iterate_interfaces(struct
|
||||||
|
list_for_each_entry_rcu(sdata, &local->interfaces, list) {
|
||||||
|
switch (sdata->vif.type) {
|
||||||
|
case NL80211_IFTYPE_MONITOR:
|
||||||
|
- if (!(sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE))
|
||||||
|
+ if (!(sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE) &&
|
||||||
|
+ !ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR))
|
||||||
|
continue;
|
||||||
|
break;
|
||||||
|
case NL80211_IFTYPE_AP_VLAN:
|
||||||
|
@@ -1857,8 +1858,10 @@ int ieee80211_reconfig(struct ieee80211_
|
||||||
|
}
|
||||||
|
|
||||||
|
list_for_each_entry(sdata, &local->interfaces, list) {
|
||||||
|
+ if (sdata->vif.type == NL80211_IFTYPE_MONITOR &&
|
||||||
|
+ !ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR))
|
||||||
|
+ continue;
|
||||||
|
if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
|
||||||
|
- sdata->vif.type != NL80211_IFTYPE_MONITOR &&
|
||||||
|
ieee80211_sdata_running(sdata)) {
|
||||||
|
res = drv_add_interface(local, sdata);
|
||||||
|
if (WARN_ON(res))
|
||||||
|
@@ -1871,11 +1874,14 @@ int ieee80211_reconfig(struct ieee80211_
|
||||||
|
*/
|
||||||
|
if (res) {
|
||||||
|
list_for_each_entry_continue_reverse(sdata, &local->interfaces,
|
||||||
|
- list)
|
||||||
|
+ list) {
|
||||||
|
+ if (sdata->vif.type == NL80211_IFTYPE_MONITOR &&
|
||||||
|
+ !ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR))
|
||||||
|
+ continue;
|
||||||
|
if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
|
||||||
|
- sdata->vif.type != NL80211_IFTYPE_MONITOR &&
|
||||||
|
ieee80211_sdata_running(sdata))
|
||||||
|
drv_remove_interface(local, sdata);
|
||||||
|
+ }
|
||||||
|
ieee80211_handle_reconfig_failure(local);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
@ -0,0 +1,56 @@
|
|||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Date: Mon, 30 Sep 2024 17:04:09 +0200
|
||||||
|
Subject: [PATCH] wifi: cfg80211: add monitor SKIP_TX flag
|
||||||
|
|
||||||
|
This can be used to indicate that the user is not interested in receiving
|
||||||
|
locally sent packets on the monitor interface.
|
||||||
|
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/include/net/cfg80211.h
|
||||||
|
+++ b/include/net/cfg80211.h
|
||||||
|
@@ -2272,6 +2272,7 @@ static inline int cfg80211_get_station(s
|
||||||
|
* @MONITOR_FLAG_OTHER_BSS: disable BSSID filtering
|
||||||
|
* @MONITOR_FLAG_COOK_FRAMES: report frames after processing
|
||||||
|
* @MONITOR_FLAG_ACTIVE: active monitor, ACKs frames on its MAC address
|
||||||
|
+ * @MONITOR_FLAG_SKIP_TX: do not pass locally transmitted frames
|
||||||
|
*/
|
||||||
|
enum monitor_flags {
|
||||||
|
MONITOR_FLAG_CHANGED = BIT(__NL80211_MNTR_FLAG_INVALID),
|
||||||
|
@@ -2281,6 +2282,7 @@ enum monitor_flags {
|
||||||
|
MONITOR_FLAG_OTHER_BSS = BIT(NL80211_MNTR_FLAG_OTHER_BSS),
|
||||||
|
MONITOR_FLAG_COOK_FRAMES = BIT(NL80211_MNTR_FLAG_COOK_FRAMES),
|
||||||
|
MONITOR_FLAG_ACTIVE = BIT(NL80211_MNTR_FLAG_ACTIVE),
|
||||||
|
+ MONITOR_FLAG_SKIP_TX = BIT(NL80211_MNTR_FLAG_SKIP_TX),
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
--- a/include/uapi/linux/nl80211.h
|
||||||
|
+++ b/include/uapi/linux/nl80211.h
|
||||||
|
@@ -4703,6 +4703,7 @@ enum nl80211_survey_info {
|
||||||
|
* overrides all other flags.
|
||||||
|
* @NL80211_MNTR_FLAG_ACTIVE: use the configured MAC address
|
||||||
|
* and ACK incoming unicast packets.
|
||||||
|
+ * @NL80211_MNTR_FLAG_SKIP_TX: do not pass local tx packets
|
||||||
|
*
|
||||||
|
* @__NL80211_MNTR_FLAG_AFTER_LAST: internal use
|
||||||
|
* @NL80211_MNTR_FLAG_MAX: highest possible monitor flag
|
||||||
|
@@ -4715,6 +4716,7 @@ enum nl80211_mntr_flags {
|
||||||
|
NL80211_MNTR_FLAG_OTHER_BSS,
|
||||||
|
NL80211_MNTR_FLAG_COOK_FRAMES,
|
||||||
|
NL80211_MNTR_FLAG_ACTIVE,
|
||||||
|
+ NL80211_MNTR_FLAG_SKIP_TX,
|
||||||
|
|
||||||
|
/* keep last */
|
||||||
|
__NL80211_MNTR_FLAG_AFTER_LAST,
|
||||||
|
--- a/net/wireless/nl80211.c
|
||||||
|
+++ b/net/wireless/nl80211.c
|
||||||
|
@@ -4201,6 +4201,7 @@ static const struct nla_policy mntr_flag
|
||||||
|
[NL80211_MNTR_FLAG_OTHER_BSS] = { .type = NLA_FLAG },
|
||||||
|
[NL80211_MNTR_FLAG_COOK_FRAMES] = { .type = NLA_FLAG },
|
||||||
|
[NL80211_MNTR_FLAG_ACTIVE] = { .type = NLA_FLAG },
|
||||||
|
+ [NL80211_MNTR_FLAG_SKIP_TX] = { .type = NLA_FLAG },
|
||||||
|
};
|
||||||
|
|
||||||
|
static int parse_monitor_flags(struct nlattr *nla, u32 *mntrflags)
|
||||||
@ -0,0 +1,54 @@
|
|||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Date: Mon, 30 Sep 2024 17:05:18 +0200
|
||||||
|
Subject: [PATCH] wifi: mac80211: add support for the monitor SKIP_TX flag
|
||||||
|
|
||||||
|
Do not pass locally sent packets to monitor interfaces with this flag set.
|
||||||
|
Skip processing tx packets on the status call entirely if no monitor
|
||||||
|
interfaces without this flag are present.
|
||||||
|
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/net/mac80211/ieee80211_i.h
|
||||||
|
+++ b/net/mac80211/ieee80211_i.h
|
||||||
|
@@ -1374,7 +1374,7 @@ struct ieee80211_local {
|
||||||
|
spinlock_t queue_stop_reason_lock;
|
||||||
|
|
||||||
|
int open_count;
|
||||||
|
- int monitors, cooked_mntrs;
|
||||||
|
+ int monitors, cooked_mntrs, tx_mntrs;
|
||||||
|
/* number of interfaces with corresponding FIF_ flags */
|
||||||
|
int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss, fif_pspoll,
|
||||||
|
fif_probe_req;
|
||||||
|
--- a/net/mac80211/iface.c
|
||||||
|
+++ b/net/mac80211/iface.c
|
||||||
|
@@ -1094,6 +1094,8 @@ void ieee80211_adjust_monitor_flags(stru
|
||||||
|
ADJUST(CONTROL, control);
|
||||||
|
ADJUST(CONTROL, pspoll);
|
||||||
|
ADJUST(OTHER_BSS, other_bss);
|
||||||
|
+ if (!(flags & MONITOR_FLAG_SKIP_TX))
|
||||||
|
+ local->tx_mntrs += offset;
|
||||||
|
|
||||||
|
#undef ADJUST
|
||||||
|
}
|
||||||
|
--- a/net/mac80211/status.c
|
||||||
|
+++ b/net/mac80211/status.c
|
||||||
|
@@ -927,6 +927,9 @@ void ieee80211_tx_monitor(struct ieee802
|
||||||
|
if (!ieee80211_sdata_running(sdata))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
+ if (sdata->u.mntr.flags & MONITOR_FLAG_SKIP_TX)
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
if ((sdata->u.mntr.flags & MONITOR_FLAG_COOK_FRAMES) &&
|
||||||
|
!send_to_cooked)
|
||||||
|
continue;
|
||||||
|
@@ -1099,7 +1102,7 @@ static void __ieee80211_tx_status(struct
|
||||||
|
* This is a bit racy but we can avoid a lot of work
|
||||||
|
* with this test...
|
||||||
|
*/
|
||||||
|
- if (!local->monitors && (!send_to_cooked || !local->cooked_mntrs)) {
|
||||||
|
+ if (!local->tx_mntrs && (!send_to_cooked || !local->cooked_mntrs)) {
|
||||||
|
if (status->free_list)
|
||||||
|
list_add_tail(&skb->list, status->free_list);
|
||||||
|
else
|
||||||
@ -0,0 +1,94 @@
|
|||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Date: Wed, 2 Oct 2024 12:31:22 +0200
|
||||||
|
Subject: [PATCH] wifi: mac80211: refactor ieee80211_rx_monitor
|
||||||
|
|
||||||
|
Rework the monitor mode interface iteration to get rid of the last_monitor
|
||||||
|
condition. Preparation for further filtering received monitor packets.
|
||||||
|
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/net/mac80211/rx.c
|
||||||
|
+++ b/net/mac80211/rx.c
|
||||||
|
@@ -762,8 +762,8 @@ ieee80211_rx_monitor(struct ieee80211_lo
|
||||||
|
struct ieee80211_rate *rate)
|
||||||
|
{
|
||||||
|
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(origskb);
|
||||||
|
- struct ieee80211_sub_if_data *sdata;
|
||||||
|
- struct sk_buff *monskb = NULL;
|
||||||
|
+ struct ieee80211_sub_if_data *sdata, *prev_sdata = NULL;
|
||||||
|
+ struct sk_buff *skb, *monskb = NULL;
|
||||||
|
int present_fcs_len = 0;
|
||||||
|
unsigned int rtap_space = 0;
|
||||||
|
struct ieee80211_sub_if_data *monitor_sdata =
|
||||||
|
@@ -837,8 +837,10 @@ ieee80211_rx_monitor(struct ieee80211_lo
|
||||||
|
ieee80211_handle_mu_mimo_mon(monitor_sdata, origskb, rtap_space);
|
||||||
|
|
||||||
|
list_for_each_entry_rcu(sdata, &local->mon_list, u.mntr.list) {
|
||||||
|
- bool last_monitor = list_is_last(&sdata->u.mntr.list,
|
||||||
|
- &local->mon_list);
|
||||||
|
+ if (!prev_sdata) {
|
||||||
|
+ prev_sdata = sdata;
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
if (ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR))
|
||||||
|
ieee80211_handle_mu_mimo_mon(sdata, origskb, rtap_space);
|
||||||
|
@@ -846,34 +848,34 @@ ieee80211_rx_monitor(struct ieee80211_lo
|
||||||
|
if (!monskb)
|
||||||
|
monskb = ieee80211_make_monitor_skb(local, &origskb,
|
||||||
|
rate, rtap_space,
|
||||||
|
- only_monitor &&
|
||||||
|
- last_monitor);
|
||||||
|
-
|
||||||
|
- if (monskb) {
|
||||||
|
- struct sk_buff *skb;
|
||||||
|
+ false);
|
||||||
|
+ if (!monskb)
|
||||||
|
+ continue;
|
||||||
|
|
||||||
|
- if (last_monitor) {
|
||||||
|
- skb = monskb;
|
||||||
|
- monskb = NULL;
|
||||||
|
- } else {
|
||||||
|
- skb = skb_clone(monskb, GFP_ATOMIC);
|
||||||
|
- }
|
||||||
|
+ skb = skb_clone(monskb, GFP_ATOMIC);
|
||||||
|
+ if (!skb)
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ skb->dev = prev_sdata->dev;
|
||||||
|
+ dev_sw_netstats_rx_add(skb->dev, skb->len);
|
||||||
|
+ netif_receive_skb(skb);
|
||||||
|
+ prev_sdata = sdata;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- if (skb) {
|
||||||
|
- skb->dev = sdata->dev;
|
||||||
|
- dev_sw_netstats_rx_add(skb->dev, skb->len);
|
||||||
|
- netif_receive_skb(skb);
|
||||||
|
- }
|
||||||
|
+ if (prev_sdata) {
|
||||||
|
+ if (monskb)
|
||||||
|
+ skb = monskb;
|
||||||
|
+ else
|
||||||
|
+ skb = ieee80211_make_monitor_skb(local, &origskb,
|
||||||
|
+ rate, rtap_space,
|
||||||
|
+ only_monitor);
|
||||||
|
+ if (skb) {
|
||||||
|
+ skb->dev = prev_sdata->dev;
|
||||||
|
+ dev_sw_netstats_rx_add(skb->dev, skb->len);
|
||||||
|
+ netif_receive_skb(skb);
|
||||||
|
}
|
||||||
|
-
|
||||||
|
- if (last_monitor)
|
||||||
|
- break;
|
||||||
|
}
|
||||||
|
|
||||||
|
- /* this happens if last_monitor was erroneously false */
|
||||||
|
- dev_kfree_skb(monskb);
|
||||||
|
-
|
||||||
|
- /* ditto */
|
||||||
|
if (!origskb)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
@ -0,0 +1,29 @@
|
|||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Date: Wed, 2 Oct 2024 12:35:13 +0200
|
||||||
|
Subject: [PATCH] wifi: mac80211: filter on monitor interfaces based on
|
||||||
|
configured channel
|
||||||
|
|
||||||
|
When a monitor interface has an assigned channel (only happens with the
|
||||||
|
NO_VIRTUAL_MONITOR feature), only pass packets received on that channel.
|
||||||
|
This is useful for monitoring on multiple channels at the same time using
|
||||||
|
multiple monitor interfaces.
|
||||||
|
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/net/mac80211/rx.c
|
||||||
|
+++ b/net/mac80211/rx.c
|
||||||
|
@@ -837,6 +837,13 @@ ieee80211_rx_monitor(struct ieee80211_lo
|
||||||
|
ieee80211_handle_mu_mimo_mon(monitor_sdata, origskb, rtap_space);
|
||||||
|
|
||||||
|
list_for_each_entry_rcu(sdata, &local->mon_list, u.mntr.list) {
|
||||||
|
+ struct cfg80211_chan_def *chandef;
|
||||||
|
+
|
||||||
|
+ chandef = &sdata->vif.bss_conf.chanreq.oper;
|
||||||
|
+ if (chandef->chan &&
|
||||||
|
+ chandef->chan->center_freq != status->freq)
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
if (!prev_sdata) {
|
||||||
|
prev_sdata = sdata;
|
||||||
|
continue;
|
||||||
@ -0,0 +1,64 @@
|
|||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Date: Wed, 7 Aug 2024 13:31:07 +0200
|
||||||
|
Subject: [PATCH] wifi: cfg80211: report per wiphy radio antenna mask
|
||||||
|
|
||||||
|
With multi-radio devices, each radio typically gets a fixed set of antennas.
|
||||||
|
In order to be able to disable specific antennas for some radios, user space
|
||||||
|
needs to know which antenna mask bits are assigned to which radio.
|
||||||
|
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/include/net/cfg80211.h
|
||||||
|
+++ b/include/net/cfg80211.h
|
||||||
|
@@ -5443,6 +5443,8 @@ struct wiphy_radio_freq_range {
|
||||||
|
* @iface_combinations: Valid interface combinations array, should not
|
||||||
|
* list single interface types.
|
||||||
|
* @n_iface_combinations: number of entries in @iface_combinations array.
|
||||||
|
+ *
|
||||||
|
+ * @antenna_mask: bitmask of antennas connected to this radio.
|
||||||
|
*/
|
||||||
|
struct wiphy_radio {
|
||||||
|
const struct wiphy_radio_freq_range *freq_range;
|
||||||
|
@@ -5450,6 +5452,8 @@ struct wiphy_radio {
|
||||||
|
|
||||||
|
const struct ieee80211_iface_combination *iface_combinations;
|
||||||
|
int n_iface_combinations;
|
||||||
|
+
|
||||||
|
+ u32 antenna_mask;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define CFG80211_HW_TIMESTAMP_ALL_PEERS 0xffff
|
||||||
|
--- a/include/uapi/linux/nl80211.h
|
||||||
|
+++ b/include/uapi/linux/nl80211.h
|
||||||
|
@@ -8038,6 +8038,8 @@ enum nl80211_ap_settings_flags {
|
||||||
|
* @NL80211_WIPHY_RADIO_ATTR_INTERFACE_COMBINATION: Supported interface
|
||||||
|
* combination for this radio. Attribute may be present multiple times
|
||||||
|
* and contains attributes defined in &enum nl80211_if_combination_attrs.
|
||||||
|
+ * @NL80211_WIPHY_RADIO_ATTR_ANTENNA_MASK: bitmask (u32) of antennas
|
||||||
|
+ * connected to this radio.
|
||||||
|
*
|
||||||
|
* @__NL80211_WIPHY_RADIO_ATTR_LAST: Internal
|
||||||
|
* @NL80211_WIPHY_RADIO_ATTR_MAX: Highest attribute
|
||||||
|
@@ -8048,6 +8050,7 @@ enum nl80211_wiphy_radio_attrs {
|
||||||
|
NL80211_WIPHY_RADIO_ATTR_INDEX,
|
||||||
|
NL80211_WIPHY_RADIO_ATTR_FREQ_RANGE,
|
||||||
|
NL80211_WIPHY_RADIO_ATTR_INTERFACE_COMBINATION,
|
||||||
|
+ NL80211_WIPHY_RADIO_ATTR_ANTENNA_MASK,
|
||||||
|
|
||||||
|
/* keep last */
|
||||||
|
__NL80211_WIPHY_RADIO_ATTR_LAST,
|
||||||
|
--- a/net/wireless/nl80211.c
|
||||||
|
+++ b/net/wireless/nl80211.c
|
||||||
|
@@ -2431,6 +2431,11 @@ static int nl80211_put_radio(struct wiph
|
||||||
|
if (nla_put_u32(msg, NL80211_WIPHY_RADIO_ATTR_INDEX, idx))
|
||||||
|
goto nla_put_failure;
|
||||||
|
|
||||||
|
+ if (r->antenna_mask &&
|
||||||
|
+ nla_put_u32(msg, NL80211_WIPHY_RADIO_ATTR_ANTENNA_MASK,
|
||||||
|
+ r->antenna_mask))
|
||||||
|
+ goto nla_put_failure;
|
||||||
|
+
|
||||||
|
for (i = 0; i < r->n_freq_range; i++) {
|
||||||
|
const struct wiphy_radio_freq_range *range = &r->freq_range[i];
|
||||||
|
|
||||||
@ -1,12 +1,12 @@
|
|||||||
include $(TOPDIR)/rules.mk
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
PKG_NAME:=r8168
|
PKG_NAME:=r8168
|
||||||
PKG_VERSION:=8.053.00
|
PKG_VERSION:=8.054.00
|
||||||
PKG_RELEASE:=2
|
PKG_RELEASE:=1
|
||||||
|
|
||||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
|
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
|
||||||
PKG_SOURCE_URL:=https://github.com/openwrt/rtl8168/releases/download/$(PKG_VERSION)
|
PKG_SOURCE_URL:=https://github.com/openwrt/rtl8168/releases/download/$(PKG_VERSION)
|
||||||
PKG_HASH:=52f1e6200672b598a04d4ac21ac92a8a9e128b38208c7b03a464bfa93bbfcc8f
|
PKG_HASH:=5480120cf823e991e8cbd325118c1ec0c57d8f42760ba1a7334bd07d291d235d
|
||||||
|
|
||||||
PKG_BUILD_PARALLEL:=1
|
PKG_BUILD_PARALLEL:=1
|
||||||
PKG_LICENSE:=GPLv2
|
PKG_LICENSE:=GPLv2
|
||||||
|
|||||||
@ -5,9 +5,9 @@ PKG_RELEASE=1
|
|||||||
|
|
||||||
PKG_SOURCE_PROTO:=git
|
PKG_SOURCE_PROTO:=git
|
||||||
PKG_SOURCE_URL=$(PROJECT_GIT)/project/uclient.git
|
PKG_SOURCE_URL=$(PROJECT_GIT)/project/uclient.git
|
||||||
PKG_MIRROR_HASH:=0a0ea0752d534db87f2a13342d1b1b33fb94e43b934bdd015f96f19c635aa08c
|
PKG_MIRROR_HASH:=13af83ef1db3665d38d3c0cf30b5223216b05eaeca4880d7ef7494610ddd7458
|
||||||
PKG_SOURCE_DATE:=2024-04-19
|
PKG_SOURCE_DATE:=2024-10-22
|
||||||
PKG_SOURCE_VERSION:=e8780fa7792aaa2d68af21c0df91cd9c05e1f73a
|
PKG_SOURCE_VERSION:=88ae8f208dd313f69e268234f7db55956aef1cb9
|
||||||
CMAKE_INSTALL:=1
|
CMAKE_INSTALL:=1
|
||||||
|
|
||||||
PKG_BUILD_DEPENDS:=ustream-ssl
|
PKG_BUILD_DEPENDS:=ustream-ssl
|
||||||
|
|||||||
@ -10,7 +10,7 @@ include $(INCLUDE_DIR)/kernel.mk
|
|||||||
|
|
||||||
PKG_NAME:=dsl_cpe_control_danube
|
PKG_NAME:=dsl_cpe_control_danube
|
||||||
PKG_VERSION:=3.24.4.4
|
PKG_VERSION:=3.24.4.4
|
||||||
PKG_RELEASE:=11
|
PKG_RELEASE:=13
|
||||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||||
PKG_BUILD_DIR:=$(BUILD_DIR)/dsl_cpe_control-$(PKG_VERSION)
|
PKG_BUILD_DIR:=$(BUILD_DIR)/dsl_cpe_control-$(PKG_VERSION)
|
||||||
PKG_SOURCE_URL:=@OPENWRT
|
PKG_SOURCE_URL:=@OPENWRT
|
||||||
@ -54,25 +54,15 @@ CONFIGURE_ARGS += \
|
|||||||
--with-channels-per-line="$(LTQ_DSL_CHANNELS_PER_LINE)" \
|
--with-channels-per-line="$(LTQ_DSL_CHANNELS_PER_LINE)" \
|
||||||
--enable-danube \
|
--enable-danube \
|
||||||
--enable-driver-include="-I$(STAGING_DIR)/usr/include/adsl/" \
|
--enable-driver-include="-I$(STAGING_DIR)/usr/include/adsl/" \
|
||||||
--enable-debug-prints \
|
|
||||||
--enable-add-appl-cflags="-DMAX_CLI_PIPES=2" \
|
--enable-add-appl-cflags="-DMAX_CLI_PIPES=2" \
|
||||||
--enable-cli-support \
|
--enable-model=full \
|
||||||
--enable-cmv-scripts \
|
--disable-dsl-pm-retx-counters \
|
||||||
--enable-debug-tool-interface \
|
--disable-dsl-pm-retx-thresholds \
|
||||||
--enable-adsl-led \
|
--disable-soap-support \
|
||||||
--enable-dsl-ceoc \
|
--disable-dti \
|
||||||
--enable-script-notification \
|
--disable-adsl-mib-support \
|
||||||
--enable-dsl-pm \
|
--disable-adsl-trace \
|
||||||
--enable-dsl-pm-total \
|
--enable-adsl-led
|
||||||
--enable-dsl-pm-history \
|
|
||||||
--enable-dsl-pm-showtime \
|
|
||||||
--enable-dsl-pm-channel-counters \
|
|
||||||
--enable-dsl-pm-datapath-counters \
|
|
||||||
--enable-dsl-pm-line-counters \
|
|
||||||
--enable-dsl-pm-channel-thresholds \
|
|
||||||
--enable-dsl-pm-datapath-thresholds \
|
|
||||||
--enable-dsl-pm-line-thresholds \
|
|
||||||
--enable-dsl-pm-optional-parameters
|
|
||||||
|
|
||||||
TARGET_CFLAGS += -I$(LINUX_DIR)/include
|
TARGET_CFLAGS += -I$(LINUX_DIR)/include
|
||||||
|
|
||||||
@ -87,6 +77,7 @@ define Package/ltq-adsl-app/install
|
|||||||
$(INSTALL_BIN) ./files/10_atm.sh $(1)/etc/hotplug.d/dsl
|
$(INSTALL_BIN) ./files/10_atm.sh $(1)/etc/hotplug.d/dsl
|
||||||
$(INSTALL_BIN) ./files/10_ptm.sh $(1)/etc/hotplug.d/dsl
|
$(INSTALL_BIN) ./files/10_ptm.sh $(1)/etc/hotplug.d/dsl
|
||||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/src/dsl_cpe_control $(1)/sbin
|
$(INSTALL_BIN) $(PKG_BUILD_DIR)/src/dsl_cpe_control $(1)/sbin
|
||||||
|
$(INSTALL_BIN) ./files/dsl_cpe_pipe.sh $(1)/sbin/
|
||||||
endef
|
endef
|
||||||
|
|
||||||
$(eval $(call BuildPackage,ltq-adsl-app))
|
$(eval $(call BuildPackage,ltq-adsl-app))
|
||||||
|
|||||||
18
package/network/config/ltq-adsl-app/files/dsl_cpe_pipe.sh
Executable file
18
package/network/config/ltq-adsl-app/files/dsl_cpe_pipe.sh
Executable file
@ -0,0 +1,18 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
pipe_no=0
|
||||||
|
|
||||||
|
# use specified pipe no
|
||||||
|
case "$1" in
|
||||||
|
0|1|2)
|
||||||
|
pipe_no=$1; shift; ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
|
||||||
|
#echo "Call dsl_pipe with $*"
|
||||||
|
lock /var/lock/dsl_pipe
|
||||||
|
echo $* > /tmp/pipe/dsl_cpe${pipe_no}_cmd
|
||||||
|
result=$(cat /tmp/pipe/dsl_cpe${pipe_no}_ack)
|
||||||
|
lock -u /var/lock/dsl_pipe
|
||||||
|
|
||||||
|
echo "$result"
|
||||||
@ -661,12 +661,12 @@ hostapd_set_bss_options() {
|
|||||||
sae|owe|eap2|eap192)
|
sae|owe|eap2|eap192)
|
||||||
set_default ieee80211w 2
|
set_default ieee80211w 2
|
||||||
set_default sae_require_mfp 1
|
set_default sae_require_mfp 1
|
||||||
set_default sae_pwe 2
|
[ "$ppsk" -eq 0 ] && set_default sae_pwe 2
|
||||||
;;
|
;;
|
||||||
psk-sae|eap-eap2)
|
psk-sae|eap-eap2)
|
||||||
set_default ieee80211w 1
|
set_default ieee80211w 1
|
||||||
set_default sae_require_mfp 1
|
set_default sae_require_mfp 1
|
||||||
set_default sae_pwe 2
|
[ "$ppsk" -eq 0 ] && set_default sae_pwe 2
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
[ -n "$sae_require_mfp" ] && append bss_conf "sae_require_mfp=$sae_require_mfp" "$N"
|
[ -n "$sae_require_mfp" ] && append bss_conf "sae_require_mfp=$sae_require_mfp" "$N"
|
||||||
@ -689,7 +689,7 @@ hostapd_set_bss_options() {
|
|||||||
;;
|
;;
|
||||||
psk|sae|psk-sae)
|
psk|sae|psk-sae)
|
||||||
json_get_vars key wpa_psk_file
|
json_get_vars key wpa_psk_file
|
||||||
if [ "$auth_type" = "psk" ] && [ "$ppsk" -ne 0 ] ; then
|
if [ "$ppsk" -ne 0 ]; then
|
||||||
json_get_vars auth_secret auth_port
|
json_get_vars auth_secret auth_port
|
||||||
set_default auth_port 1812
|
set_default auth_port 1812
|
||||||
json_for_each_item append_auth_server auth_server
|
json_for_each_item append_auth_server auth_server
|
||||||
|
|||||||
@ -29,7 +29,7 @@ drv_mac80211_init_device_config() {
|
|||||||
config_add_string path phy 'macaddr:macaddr'
|
config_add_string path phy 'macaddr:macaddr'
|
||||||
config_add_string tx_burst
|
config_add_string tx_burst
|
||||||
config_add_string distance
|
config_add_string distance
|
||||||
config_add_int beacon_int chanbw frag rts
|
config_add_int radio beacon_int chanbw frag rts
|
||||||
config_add_int rxantenna txantenna txpower min_tx_power
|
config_add_int rxantenna txantenna txpower min_tx_power
|
||||||
config_add_int num_global_macaddr multiple_bssid
|
config_add_int num_global_macaddr multiple_bssid
|
||||||
config_add_boolean noscan ht_coex acs_exclude_dfs background_radar
|
config_add_boolean noscan ht_coex acs_exclude_dfs background_radar
|
||||||
@ -556,7 +556,7 @@ mac80211_hostapd_setup_bss() {
|
|||||||
}
|
}
|
||||||
[ "$staidx" -gt 0 -o "$start_disabled" -eq 1 ] && append hostapd_cfg "start_disabled=1" "$N"
|
[ "$staidx" -gt 0 -o "$start_disabled" -eq 1 ] && append hostapd_cfg "start_disabled=1" "$N"
|
||||||
|
|
||||||
cat >> /var/run/hostapd-$phy.conf <<EOF
|
cat >> /var/run/hostapd-$phy$vif_phy_suffix.conf <<EOF
|
||||||
$hostapd_cfg
|
$hostapd_cfg
|
||||||
bssid=$macaddr
|
bssid=$macaddr
|
||||||
${default_macaddr:+#default_macaddr}
|
${default_macaddr:+#default_macaddr}
|
||||||
@ -576,7 +576,7 @@ mac80211_generate_mac() {
|
|||||||
local phy="$1"
|
local phy="$1"
|
||||||
local id="${macidx:-0}"
|
local id="${macidx:-0}"
|
||||||
|
|
||||||
wdev_tool "$phy" get_macaddr id=$id num_global=$num_global_macaddr mbssid=${multiple_bssid:-0}
|
wdev_tool "$phy$phy_suffix" get_macaddr id=$id num_global=$num_global_macaddr mbssid=${multiple_bssid:-0}
|
||||||
}
|
}
|
||||||
|
|
||||||
get_board_phy_name() (
|
get_board_phy_name() (
|
||||||
@ -679,7 +679,7 @@ mac80211_prepare_vif() {
|
|||||||
monitor) prefix=mon;;
|
monitor) prefix=mon;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
mac80211_set_ifname "$phy" "$prefix"
|
mac80211_set_ifname "$phy$vif_phy_suffix" "$prefix"
|
||||||
}
|
}
|
||||||
|
|
||||||
append active_ifnames "$ifname"
|
append active_ifnames "$ifname"
|
||||||
@ -880,7 +880,12 @@ mac80211_set_vif_txpower() {
|
|||||||
json_get_vars vif_txpower
|
json_get_vars vif_txpower
|
||||||
json_select ..
|
json_select ..
|
||||||
|
|
||||||
[ -z "$vif_txpower" ] || iw dev "$ifname" set txpower fixed "${vif_txpower%%.*}00"
|
set_default vif_txpower "$txpower"
|
||||||
|
if [ -n "$vif_txpower" ]; then
|
||||||
|
iw dev "$ifname" set txpower fixed "${vif_txpower%%.*}00"
|
||||||
|
else
|
||||||
|
iw dev "$ifname" set txpower auto
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
wpa_supplicant_init_config() {
|
wpa_supplicant_init_config() {
|
||||||
@ -920,11 +925,13 @@ wpa_supplicant_add_interface() {
|
|||||||
|
|
||||||
wpa_supplicant_set_config() {
|
wpa_supplicant_set_config() {
|
||||||
local phy="$1"
|
local phy="$1"
|
||||||
|
local radio="$2"
|
||||||
local prev
|
local prev
|
||||||
|
|
||||||
json_set_namespace wpa_supp prev
|
json_set_namespace wpa_supp prev
|
||||||
json_close_array
|
json_close_array
|
||||||
json_add_string phy "$phy"
|
json_add_string phy "$phy"
|
||||||
|
json_add_int radio "$radio"
|
||||||
json_add_int num_global_macaddr "$num_global_macaddr"
|
json_add_int num_global_macaddr "$num_global_macaddr"
|
||||||
json_add_boolean defer 1
|
json_add_boolean defer 1
|
||||||
local data="$(json_dump)"
|
local data="$(json_dump)"
|
||||||
@ -947,13 +954,16 @@ wpa_supplicant_set_config() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
hostapd_set_config() {
|
hostapd_set_config() {
|
||||||
|
local phy="$1"
|
||||||
|
local radio="$2"
|
||||||
|
|
||||||
[ -n "$hostapd_ctrl" ] || {
|
[ -n "$hostapd_ctrl" ] || {
|
||||||
ubus_call hostapd config_set '{ "phy": "'"$phy"'", "config": "", "prev_config": "'"${hostapd_conf_file}.prev"'" }' > /dev/null
|
ubus_call hostapd config_set '{ "phy": "'"$phy"'", "radio": '"$radio"', "config": "", "prev_config": "'"${hostapd_conf_file}.prev"'" }' > /dev/null
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ubus wait_for hostapd
|
ubus wait_for hostapd
|
||||||
local hostapd_res="$(ubus_call hostapd config_set "{ \"phy\": \"$phy\", \"config\":\"${hostapd_conf_file}\", \"prev_config\": \"${hostapd_conf_file}.prev\"}")"
|
local hostapd_res="$(ubus_call hostapd config_set "{ \"phy\": \"$phy\", \"radio\": $radio, \"config\":\"${hostapd_conf_file}\", \"prev_config\": \"${hostapd_conf_file}.prev\"}")"
|
||||||
ret="$?"
|
ret="$?"
|
||||||
[ "$ret" != 0 -o -z "$hostapd_res" ] && {
|
[ "$ret" != 0 -o -z "$hostapd_res" ] && {
|
||||||
wireless_setup_failed HOSTAPD_START_FAILED
|
wireless_setup_failed HOSTAPD_START_FAILED
|
||||||
@ -965,10 +975,11 @@ hostapd_set_config() {
|
|||||||
|
|
||||||
wpa_supplicant_start() {
|
wpa_supplicant_start() {
|
||||||
local phy="$1"
|
local phy="$1"
|
||||||
|
local radio="$2"
|
||||||
|
|
||||||
[ -n "$wpa_supp_init" ] || return 0
|
[ -n "$wpa_supp_init" ] || return 0
|
||||||
|
|
||||||
ubus_call wpa_supplicant config_set '{ "phy": "'"$phy"'", "num_global_macaddr": '"$num_global_macaddr"' }' > /dev/null
|
ubus_call wpa_supplicant config_set '{ "phy": "'"$phy"'", "radio": '"$radio"', "num_global_macaddr": '"$num_global_macaddr"' }' > /dev/null
|
||||||
}
|
}
|
||||||
|
|
||||||
mac80211_setup_supplicant() {
|
mac80211_setup_supplicant() {
|
||||||
@ -1073,18 +1084,23 @@ drv_mac80211_cleanup() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mac80211_reset_config() {
|
mac80211_reset_config() {
|
||||||
local phy="$1"
|
hostapd_conf_file="/var/run/hostapd-$phy$vif_phy_suffix.conf"
|
||||||
|
ubus_call hostapd config_set '{ "phy": "'"$phy"'", "radio": '"$radio"', "config": "", "prev_config": "'"$hostapd_conf_file"'" }' > /dev/null
|
||||||
|
ubus_call wpa_supplicant config_set '{ "phy": "'"$phy"'", "radio": '"$radio"', "config": [] }' > /dev/null
|
||||||
|
wdev_tool "$phy$phy_suffix" set_config '{}'
|
||||||
|
}
|
||||||
|
|
||||||
hostapd_conf_file="/var/run/hostapd-$phy.conf"
|
mac80211_set_suffix() {
|
||||||
ubus_call hostapd config_set '{ "phy": "'"$phy"'", "config": "", "prev_config": "'"$hostapd_conf_file"'" }' > /dev/null
|
[ "$radio" = "-1" ] && radio=
|
||||||
ubus_call wpa_supplicant config_set '{ "phy": "'"$phy"'", "config": [] }' > /dev/null
|
phy_suffix="${radio:+:$radio}"
|
||||||
wdev_tool "$phy" set_config '{}'
|
vif_phy_suffix="${radio:+.$radio}"
|
||||||
|
set_default radio -1
|
||||||
}
|
}
|
||||||
|
|
||||||
drv_mac80211_setup() {
|
drv_mac80211_setup() {
|
||||||
json_select config
|
json_select config
|
||||||
json_get_vars \
|
json_get_vars \
|
||||||
phy macaddr path \
|
radio phy macaddr path \
|
||||||
country chanbw distance \
|
country chanbw distance \
|
||||||
txpower \
|
txpower \
|
||||||
rxantenna txantenna \
|
rxantenna txantenna \
|
||||||
@ -1094,6 +1110,8 @@ drv_mac80211_setup() {
|
|||||||
json_get_values scan_list scan_list
|
json_get_values scan_list scan_list
|
||||||
json_select ..
|
json_select ..
|
||||||
|
|
||||||
|
mac80211_set_suffix
|
||||||
|
|
||||||
json_select data && {
|
json_select data && {
|
||||||
json_get_var prev_rxantenna rxantenna
|
json_get_var prev_rxantenna rxantenna
|
||||||
json_get_var prev_txantenna txantenna
|
json_get_var prev_txantenna txantenna
|
||||||
@ -1120,7 +1138,7 @@ drv_mac80211_setup() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hostapd_conf_file="/var/run/hostapd-$phy.conf"
|
hostapd_conf_file="/var/run/hostapd-$phy$vif_phy_suffix.conf"
|
||||||
|
|
||||||
macidx=0
|
macidx=0
|
||||||
staidx=0
|
staidx=0
|
||||||
@ -1139,17 +1157,11 @@ drv_mac80211_setup() {
|
|||||||
[ "$rxantenna" = "all" ] && rxantenna=0xffffffff
|
[ "$rxantenna" = "all" ] && rxantenna=0xffffffff
|
||||||
|
|
||||||
[ "$rxantenna" = "$prev_rxantenna" -a "$txantenna" = "$prev_txantenna" ] || mac80211_reset_config "$phy"
|
[ "$rxantenna" = "$prev_rxantenna" -a "$txantenna" = "$prev_txantenna" ] || mac80211_reset_config "$phy"
|
||||||
wireless_set_data phy="$phy" txantenna="$txantenna" rxantenna="$rxantenna"
|
wireless_set_data phy="$phy" radio="$radio" txantenna="$txantenna" rxantenna="$rxantenna"
|
||||||
|
|
||||||
iw phy "$phy" set antenna $txantenna $rxantenna >/dev/null 2>&1
|
iw phy "$phy" set antenna $txantenna $rxantenna >/dev/null 2>&1
|
||||||
iw phy "$phy" set distance "$distance" >/dev/null 2>&1
|
iw phy "$phy" set distance "$distance" >/dev/null 2>&1
|
||||||
|
|
||||||
if [ -n "$txpower" ]; then
|
|
||||||
iw phy "$phy" set txpower fixed "${txpower%%.*}00"
|
|
||||||
else
|
|
||||||
iw phy "$phy" set txpower auto
|
|
||||||
fi
|
|
||||||
|
|
||||||
[ -n "$frag" ] && iw phy "$phy" set frag "${frag%%.*}"
|
[ -n "$frag" ] && iw phy "$phy" set frag "${frag%%.*}"
|
||||||
[ -n "$rts" ] && iw phy "$phy" set rts "${rts%%.*}"
|
[ -n "$rts" ] && iw phy "$phy" set rts "${rts%%.*}"
|
||||||
|
|
||||||
@ -1177,13 +1189,13 @@ drv_mac80211_setup() {
|
|||||||
for_each_interface "ap sta adhoc mesh monitor" mac80211_prepare_vif
|
for_each_interface "ap sta adhoc mesh monitor" mac80211_prepare_vif
|
||||||
for_each_interface "ap sta adhoc mesh monitor" mac80211_setup_vif
|
for_each_interface "ap sta adhoc mesh monitor" mac80211_setup_vif
|
||||||
|
|
||||||
[ -x /usr/sbin/wpa_supplicant ] && wpa_supplicant_set_config "$phy"
|
[ -x /usr/sbin/wpa_supplicant ] && wpa_supplicant_set_config "$phy" "$radio"
|
||||||
[ -x /usr/sbin/hostapd ] && hostapd_set_config "$phy"
|
[ -x /usr/sbin/hostapd ] && hostapd_set_config "$phy" "$radio"
|
||||||
|
|
||||||
[ -x /usr/sbin/wpa_supplicant ] && wpa_supplicant_start "$phy"
|
[ -x /usr/sbin/wpa_supplicant ] && wpa_supplicant_start "$phy" "$radio"
|
||||||
|
|
||||||
json_set_namespace wdev_uc prev
|
json_set_namespace wdev_uc prev
|
||||||
wdev_tool "$phy" set_config "$(json_dump)" $active_ifnames
|
wdev_tool "$phy$phy_suffix" set_config "$(json_dump)" $active_ifnames
|
||||||
json_set_namespace "$prev"
|
json_set_namespace "$prev"
|
||||||
|
|
||||||
for_each_interface "ap sta adhoc mesh monitor" mac80211_set_vif_txpower
|
for_each_interface "ap sta adhoc mesh monitor" mac80211_set_vif_txpower
|
||||||
@ -1210,19 +1222,15 @@ list_phy_interfaces() {
|
|||||||
|
|
||||||
drv_mac80211_teardown() {
|
drv_mac80211_teardown() {
|
||||||
json_select data
|
json_select data
|
||||||
json_get_vars phy
|
json_get_vars phy radio
|
||||||
json_select ..
|
json_select ..
|
||||||
[ -n "$phy" ] || {
|
[ -n "$phy" ] || {
|
||||||
echo "Bug: PHY is undefined for device '$1'"
|
echo "Bug: PHY is undefined for device '$1'"
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mac80211_set_suffix
|
||||||
mac80211_reset_config "$phy"
|
mac80211_reset_config "$phy"
|
||||||
|
|
||||||
for wdev in $(list_phy_interfaces "$phy"); do
|
|
||||||
ip link set dev "$wdev" down
|
|
||||||
iw dev "$wdev" del
|
|
||||||
done
|
|
||||||
}
|
}
|
||||||
|
|
||||||
add_driver mac80211
|
add_driver mac80211
|
||||||
|
|||||||
@ -14,10 +14,12 @@ let commit;
|
|||||||
|
|
||||||
let config = uci.cursor().get_all("wireless") ?? {};
|
let config = uci.cursor().get_all("wireless") ?? {};
|
||||||
|
|
||||||
function radio_exists(path, macaddr, phy) {
|
function radio_exists(path, macaddr, phy, radio) {
|
||||||
for (let name, s in config) {
|
for (let name, s in config) {
|
||||||
if (s[".type"] != "wifi-device")
|
if (s[".type"] != "wifi-device")
|
||||||
continue;
|
continue;
|
||||||
|
if (radio != null && int(s.radio) != radio)
|
||||||
|
continue;
|
||||||
if (s.macaddr & lc(s.macaddr) == lc(macaddr))
|
if (s.macaddr & lc(s.macaddr) == lc(macaddr))
|
||||||
return true;
|
return true;
|
||||||
if (s.phy == phy)
|
if (s.phy == phy)
|
||||||
@ -34,55 +36,61 @@ for (let phy_name, phy in board.wlan) {
|
|||||||
if (!info || !length(info.bands))
|
if (!info || !length(info.bands))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
while (config[`radio${idx}`])
|
let radios = length(info.radios) > 0 ? info.radios : [{ bands: info.bands }];
|
||||||
idx++;
|
for (let radio in radios) {
|
||||||
let name = "radio" + idx++;
|
while (config[`radio${idx}`])
|
||||||
|
idx++;
|
||||||
|
let name = "radio" + idx;
|
||||||
|
|
||||||
let s = "wireless." + name;
|
let s = "wireless." + name;
|
||||||
let si = "wireless.default_" + name;
|
let si = "wireless.default_" + name;
|
||||||
|
|
||||||
let band_name = filter(bands_order, (b) => info.bands[b])[0];
|
let band_name = filter(bands_order, (b) => radio.bands[b])[0];
|
||||||
if (!band_name)
|
if (!band_name)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
let band = info.bands[band_name];
|
let band = info.bands[band_name];
|
||||||
let channel = band.default_channel ?? "auto";
|
let rband = radio.bands[band_name];
|
||||||
|
let channel = rband.default_channel ?? "auto";
|
||||||
|
|
||||||
let width = band.max_width;
|
let width = band.max_width;
|
||||||
if (band_name == "2G")
|
if (band_name == "2G")
|
||||||
width = 20;
|
width = 20;
|
||||||
else if (width > 80)
|
else if (width > 80)
|
||||||
width = 80;
|
width = 80;
|
||||||
|
|
||||||
let htmode = filter(htmode_order, (m) => band[lc(m)])[0];
|
let htmode = filter(htmode_order, (m) => band[lc(m)])[0];
|
||||||
if (htmode)
|
if (htmode)
|
||||||
htmode += width;
|
htmode += width;
|
||||||
else
|
else
|
||||||
htmode = "NOHT";
|
htmode = "NOHT";
|
||||||
|
|
||||||
if (!phy.path)
|
if (!phy.path)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
let macaddr = trim(readfile(`/sys/class/ieee80211/${phy_name}/macaddress`));
|
let macaddr = trim(readfile(`/sys/class/ieee80211/${phy_name}/macaddress`));
|
||||||
if (radio_exists(phy.path, macaddr, phy_name))
|
if (radio_exists(phy.path, macaddr, phy_name, radio.index))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
let id = `phy='${phy_name}'`;
|
let id = `phy='${phy_name}'`;
|
||||||
if (match(phy_name, /^phy[0-9]/))
|
if (match(phy_name, /^phy[0-9]/))
|
||||||
id = `path='${phy.path}'`;
|
id = `path='${phy.path}'`;
|
||||||
|
|
||||||
band_name = lc(band_name);
|
band_name = lc(band_name);
|
||||||
|
|
||||||
let country, defaults, num_global_macaddr;
|
let country, defaults, num_global_macaddr;
|
||||||
if (board.wlan.defaults) {
|
if (board.wlan.defaults) {
|
||||||
defaults = board.wlan.defaults.ssids?.[band_name]?.ssid ? board.wlan.defaults.ssids?.[band_name] : board.wlan.defaults.ssids?.all;
|
defaults = board.wlan.defaults.ssids?.[band_name]?.ssid ? board.wlan.defaults.ssids?.[band_name] : board.wlan.defaults.ssids?.all;
|
||||||
country = board.wlan.defaults.country;
|
country = board.wlan.defaults.country;
|
||||||
if (!country && band_name != '2g')
|
if (!country && band_name != '2g')
|
||||||
defaults = null;
|
defaults = null;
|
||||||
num_global_macaddr = board.wlan.defaults.ssids?.[band_name]?.mac_count;
|
num_global_macaddr = board.wlan.defaults.ssids?.[band_name]?.mac_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
print(`set ${s}=wifi-device
|
if (length(info.radios) > 0)
|
||||||
|
id += `\nset ${s}.radio='${radio.index}'`;
|
||||||
|
|
||||||
|
print(`set ${s}=wifi-device
|
||||||
set ${s}.type='mac80211'
|
set ${s}.type='mac80211'
|
||||||
set ${s}.${id}
|
set ${s}.${id}
|
||||||
set ${s}.band='${band_name}'
|
set ${s}.band='${band_name}'
|
||||||
@ -101,7 +109,9 @@ set ${si}.encryption='${defaults?.encryption || "none"}'
|
|||||||
set ${si}.key='${defaults?.key || ""}'
|
set ${si}.key='${defaults?.key || ""}'
|
||||||
|
|
||||||
`);
|
`);
|
||||||
commit = true;
|
config[name] = {};
|
||||||
|
commit = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (commit)
|
if (commit)
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import * as nl80211 from "nl80211";
|
import * as nl80211 from "nl80211";
|
||||||
import * as rtnl from "rtnl";
|
import * as rtnl from "rtnl";
|
||||||
import { readfile, glob, basename, readlink } from "fs";
|
import { readfile, glob, basename, readlink, open } from "fs";
|
||||||
|
|
||||||
const iftypes = {
|
const iftypes = {
|
||||||
ap: nl80211.const.NL80211_IFTYPE_AP,
|
ap: nl80211.const.NL80211_IFTYPE_AP,
|
||||||
@ -74,6 +74,14 @@ function find_reusable_wdev(phyidx)
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function wdev_set_radio_mask(name, mask)
|
||||||
|
{
|
||||||
|
nl80211.request(nl80211.const.NL80211_CMD_SET_INTERFACE, 0, {
|
||||||
|
dev: name,
|
||||||
|
vif_radio_mask: mask
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function wdev_create(phy, name, data)
|
function wdev_create(phy, name, data)
|
||||||
{
|
{
|
||||||
let phyidx = int(readfile(`/sys/class/ieee80211/${phy}/index`));
|
let phyidx = int(readfile(`/sys/class/ieee80211/${phy}/index`));
|
||||||
@ -93,24 +101,24 @@ function wdev_create(phy, name, data)
|
|||||||
req["4addr"] = data["4addr"];
|
req["4addr"] = data["4addr"];
|
||||||
if (data.macaddr)
|
if (data.macaddr)
|
||||||
req.mac = data.macaddr;
|
req.mac = data.macaddr;
|
||||||
|
if (data.radio != null && data.radio >= 0)
|
||||||
|
req.vif_radio_mask = 1 << data.radio;
|
||||||
|
|
||||||
nl80211.error();
|
nl80211.error();
|
||||||
|
|
||||||
let reuse_ifname = find_reusable_wdev(phyidx);
|
let reuse_ifname = find_reusable_wdev(phyidx);
|
||||||
if (reuse_ifname &&
|
if (reuse_ifname &&
|
||||||
(reuse_ifname == name ||
|
(reuse_ifname == name ||
|
||||||
rtnl.request(rtnl.const.RTM_SETLINK, 0, { dev: reuse_ifname, ifname: name}) != false))
|
rtnl.request(rtnl.const.RTM_SETLINK, 0, { dev: reuse_ifname, ifname: name}) != false)) {
|
||||||
nl80211.request(
|
req.dev = req.ifname;
|
||||||
nl80211.const.NL80211_CMD_SET_INTERFACE, 0, {
|
delete req.ifname;
|
||||||
wiphy: phyidx,
|
nl80211.request(nl80211.const.NL80211_CMD_SET_INTERFACE, 0, req);
|
||||||
dev: name,
|
} else {
|
||||||
iftype: iftypes[data.mode],
|
|
||||||
});
|
|
||||||
else
|
|
||||||
nl80211.request(
|
nl80211.request(
|
||||||
nl80211.const.NL80211_CMD_NEW_INTERFACE,
|
nl80211.const.NL80211_CMD_NEW_INTERFACE,
|
||||||
nl80211.const.NLM_F_CREATE,
|
nl80211.const.NLM_F_CREATE,
|
||||||
req);
|
req);
|
||||||
|
}
|
||||||
|
|
||||||
let error = nl80211.error();
|
let error = nl80211.error();
|
||||||
if (error)
|
if (error)
|
||||||
@ -190,7 +198,8 @@ const phy_proto = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
macaddr_generate: function(data) {
|
macaddr_generate: function(data) {
|
||||||
let phy = this.name;
|
let phy = this.phy;
|
||||||
|
let radio_idx = this.radio;
|
||||||
let idx = int(data.id ?? 0);
|
let idx = int(data.id ?? 0);
|
||||||
let mbssid = int(data.mbssid ?? 0) > 0;
|
let mbssid = int(data.mbssid ?? 0) > 0;
|
||||||
let num_global = int(data.num_global ?? 1);
|
let num_global = int(data.num_global ?? 1);
|
||||||
@ -200,22 +209,30 @@ const phy_proto = {
|
|||||||
if (!base_addr)
|
if (!base_addr)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
if (!idx && !mbssid)
|
|
||||||
return base_addr;
|
|
||||||
|
|
||||||
let base_mask = phy_sysfs_file(phy, "address_mask");
|
let base_mask = phy_sysfs_file(phy, "address_mask");
|
||||||
if (!base_mask)
|
if (!base_mask)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
if (base_mask == "00:00:00:00:00:00" && idx >= num_global) {
|
if (base_mask == "00:00:00:00:00:00" &&
|
||||||
|
(radio_idx > 0 || idx >= num_global)) {
|
||||||
let addrs = split(phy_sysfs_file(phy, "addresses"), "\n");
|
let addrs = split(phy_sysfs_file(phy, "addresses"), "\n");
|
||||||
|
|
||||||
if (idx < length(addrs))
|
if (radio_idx != null) {
|
||||||
return addrs[idx];
|
if (radio_idx && radio_idx < length(addrs))
|
||||||
|
base_addr = addrs[radio_idx];
|
||||||
|
else
|
||||||
|
idx += radio_idx * 16;
|
||||||
|
} else {
|
||||||
|
if (idx < length(addrs))
|
||||||
|
return addrs[idx];
|
||||||
|
|
||||||
base_mask = "ff:ff:ff:ff:ff:ff";
|
base_mask = "ff:ff:ff:ff:ff:ff";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!idx && !mbssid)
|
||||||
|
return base_addr;
|
||||||
|
|
||||||
let addr = macaddr_split(base_addr);
|
let addr = macaddr_split(base_addr);
|
||||||
let mask = macaddr_split(base_mask);
|
let mask = macaddr_split(base_mask);
|
||||||
let type;
|
let type;
|
||||||
@ -275,27 +292,55 @@ const phy_proto = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
wdev_add: function(name, data) {
|
||||||
|
let phydev = this;
|
||||||
|
wdev_create(this.phy, name, {
|
||||||
|
...data,
|
||||||
|
radio: this.radio,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
for_each_wdev: function(cb) {
|
for_each_wdev: function(cb) {
|
||||||
let wdevs = glob(`/sys/class/ieee80211/${this.name}/device/net/*`);
|
let wdevs = nl80211.request(
|
||||||
wdevs = map(wdevs, (arg) => basename(arg));
|
nl80211.const.NL80211_CMD_GET_INTERFACE,
|
||||||
|
nl80211.const.NLM_F_DUMP,
|
||||||
|
{ wiphy: this.idx }
|
||||||
|
);
|
||||||
|
|
||||||
|
let mac_wdev = {};
|
||||||
for (let wdev in wdevs) {
|
for (let wdev in wdevs) {
|
||||||
if (basename(readlink(`/sys/class/net/${wdev}/phy80211`)) != this.name)
|
if (wdev.iftype == nl80211.const.NL80211_IFTYPE_AP_VLAN)
|
||||||
|
continue;
|
||||||
|
if (this.radio != null && wdev.vif_radio_mask != null &&
|
||||||
|
!(wdev.vif_radio_mask & (1 << this.radio)))
|
||||||
|
continue;
|
||||||
|
mac_wdev[wdev.mac] = wdev;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let wdev in wdevs) {
|
||||||
|
if (!mac_wdev[wdev.mac])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
cb(wdev);
|
cb(wdev.ifname);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function phy_open(phy)
|
function phy_open(phy, radio)
|
||||||
{
|
{
|
||||||
let phyidx = readfile(`/sys/class/ieee80211/${phy}/index`);
|
let phyidx = readfile(`/sys/class/ieee80211/${phy}/index`);
|
||||||
if (!phyidx)
|
if (!phyidx)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
|
let name = phy;
|
||||||
|
if (radio === "" || radio < 0)
|
||||||
|
radio = null;
|
||||||
|
if (radio != null)
|
||||||
|
name += "." + radio;
|
||||||
|
|
||||||
return proto({
|
return proto({
|
||||||
name: phy,
|
phy, name, radio,
|
||||||
idx: int(phyidx)
|
idx: int(phyidx),
|
||||||
}, phy_proto);
|
}, phy_proto);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -365,9 +410,9 @@ function is_equal(val1, val2) {
|
|||||||
|
|
||||||
function vlist_new(cb) {
|
function vlist_new(cb) {
|
||||||
return proto({
|
return proto({
|
||||||
cb: cb,
|
cb: cb,
|
||||||
data: {}
|
data: {}
|
||||||
}, vlist_proto);
|
}, vlist_proto);
|
||||||
}
|
}
|
||||||
|
|
||||||
export { wdev_remove, wdev_create, wdev_set_mesh_params, wdev_set_up, is_equal, vlist_new, phy_is_fullmac, phy_open };
|
export { wdev_remove, wdev_create, wdev_set_mesh_params, wdev_set_radio_mask, wdev_set_up, is_equal, vlist_new, phy_is_fullmac, phy_open };
|
||||||
|
|||||||
@ -1,13 +1,13 @@
|
|||||||
#!/usr/bin/env ucode
|
#!/usr/bin/env ucode
|
||||||
'use strict';
|
'use strict';
|
||||||
import { vlist_new, is_equal, wdev_create, wdev_set_mesh_params, wdev_remove, wdev_set_up, phy_open } from "/usr/share/hostap/common.uc";
|
import { vlist_new, is_equal, wdev_set_mesh_params, wdev_remove, wdev_set_up, phy_open } from "/usr/share/hostap/common.uc";
|
||||||
import { readfile, writefile, basename, readlink, glob } from "fs";
|
import { readfile, writefile, basename, readlink, glob } from "fs";
|
||||||
let libubus = require("ubus");
|
let libubus = require("ubus");
|
||||||
|
|
||||||
let keep_devices = {};
|
let keep_devices = {};
|
||||||
let phy = shift(ARGV);
|
let phy_name = shift(ARGV);
|
||||||
let command = shift(ARGV);
|
let command = shift(ARGV);
|
||||||
let phydev;
|
let phy, phydev;
|
||||||
|
|
||||||
function iface_stop(wdev)
|
function iface_stop(wdev)
|
||||||
{
|
{
|
||||||
@ -30,7 +30,7 @@ function iface_start(wdev)
|
|||||||
wdev_config[key] = wdev[key];
|
wdev_config[key] = wdev[key];
|
||||||
if (!wdev_config.macaddr && wdev.mode != "monitor")
|
if (!wdev_config.macaddr && wdev.mode != "monitor")
|
||||||
wdev_config.macaddr = phydev.macaddr_next();
|
wdev_config.macaddr = phydev.macaddr_next();
|
||||||
wdev_create(phy, ifname, wdev_config);
|
phydev.wdev_add(ifname, wdev_config);
|
||||||
wdev_set_up(ifname, true);
|
wdev_set_up(ifname, true);
|
||||||
let htmode = wdev.htmode || "NOHT";
|
let htmode = wdev.htmode || "NOHT";
|
||||||
if (wdev.freq)
|
if (wdev.freq)
|
||||||
@ -85,20 +85,15 @@ function delete_ifname(config)
|
|||||||
delete config[key].ifname;
|
delete config[key].ifname;
|
||||||
}
|
}
|
||||||
|
|
||||||
function add_existing(phy, config)
|
function add_existing(phydev, config)
|
||||||
{
|
{
|
||||||
let wdevs = glob(`/sys/class/ieee80211/${phy}/device/net/*`);
|
phydev.for_each_wdev((wdev) => {
|
||||||
wdevs = map(wdevs, (arg) => basename(arg));
|
|
||||||
for (let wdev in wdevs) {
|
|
||||||
if (config[wdev])
|
if (config[wdev])
|
||||||
continue;
|
return;
|
||||||
|
|
||||||
if (basename(readlink(`/sys/class/net/${wdev}/phy80211`)) != phy)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (trim(readfile(`/sys/class/net/${wdev}/operstate`)) == "down")
|
if (trim(readfile(`/sys/class/net/${wdev}/operstate`)) == "down")
|
||||||
config[wdev] = {};
|
config[wdev] = {};
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function usage()
|
function usage()
|
||||||
@ -114,7 +109,7 @@ Commands:
|
|||||||
|
|
||||||
const commands = {
|
const commands = {
|
||||||
set_config: function(args) {
|
set_config: function(args) {
|
||||||
let statefile = `/var/run/wdev-${phy}.json`;
|
let statefile = `/var/run/wdev-${phy_name}.json`;
|
||||||
|
|
||||||
let new_config = shift(args);
|
let new_config = shift(args);
|
||||||
for (let dev in ARGV)
|
for (let dev in ARGV)
|
||||||
@ -137,12 +132,12 @@ const commands = {
|
|||||||
if (type(old_config) == "object")
|
if (type(old_config) == "object")
|
||||||
config.data = old_config;
|
config.data = old_config;
|
||||||
|
|
||||||
add_existing(phy, config.data);
|
add_existing(phydev, config.data);
|
||||||
add_ifname(config.data);
|
add_ifname(config.data);
|
||||||
drop_inactive(config.data);
|
drop_inactive(config.data);
|
||||||
|
|
||||||
let ubus = libubus.connect();
|
let ubus = libubus.connect();
|
||||||
let data = ubus.call("hostapd", "config_get_macaddr_list", { phy: phy });
|
let data = ubus.call("hostapd", "config_get_macaddr_list", { phy: phydev.name, radio: phydev.radio ?? -1 });
|
||||||
let macaddr_list = [];
|
let macaddr_list = [];
|
||||||
if (type(data) == "object" && data.macaddr)
|
if (type(data) == "object" && data.macaddr)
|
||||||
macaddr_list = data.macaddr;
|
macaddr_list = data.macaddr;
|
||||||
@ -166,7 +161,7 @@ const commands = {
|
|||||||
|
|
||||||
let macaddr = phydev.macaddr_generate(data);
|
let macaddr = phydev.macaddr_generate(data);
|
||||||
if (!macaddr) {
|
if (!macaddr) {
|
||||||
warn(`Could not get MAC address for phy ${phy}\n`);
|
warn(`Could not get MAC address for phy ${phy_name}\n`);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -174,12 +169,14 @@ const commands = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!phy || !command | !commands[command])
|
if (!phy_name || !command | !commands[command])
|
||||||
usage();
|
usage();
|
||||||
|
|
||||||
phydev = phy_open(phy);
|
let phy_split = split(phy_name, ":");
|
||||||
|
phydev = phy_open(phy_split[0], phy_split[1]);
|
||||||
|
phy = phydev.phy;
|
||||||
if (!phydev) {
|
if (!phydev) {
|
||||||
warn(`PHY ${phy} does not exist\n`);
|
warn(`PHY ${phy_name} does not exist\n`);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -73,6 +73,15 @@ function freq_to_channel(freq) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function freq_range_match(ranges, freq) {
|
||||||
|
freq *= 1000;
|
||||||
|
for (let range in ranges) {
|
||||||
|
if (freq >= range[0] && freq <= range[1])
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
function wiphy_detect() {
|
function wiphy_detect() {
|
||||||
let phys = nl.request(nl.const.NL80211_CMD_GET_WIPHY, nl.const.NLM_F_DUMP, { split_wiphy_dump: true });
|
let phys = nl.request(nl.const.NL80211_CMD_GET_WIPHY, nl.const.NLM_F_DUMP, { split_wiphy_dump: true });
|
||||||
if (!phys)
|
if (!phys)
|
||||||
@ -88,8 +97,27 @@ function wiphy_detect() {
|
|||||||
antenna_rx: phy.wiphy_antenna_avail_rx,
|
antenna_rx: phy.wiphy_antenna_avail_rx,
|
||||||
antenna_tx: phy.wiphy_antenna_avail_tx,
|
antenna_tx: phy.wiphy_antenna_avail_tx,
|
||||||
bands: {},
|
bands: {},
|
||||||
|
radios: []
|
||||||
};
|
};
|
||||||
|
|
||||||
|
for (let radio in phy.radios) {
|
||||||
|
// S1G is not supported yet
|
||||||
|
radio.freq_ranges = filter(radio.freq_ranges,
|
||||||
|
(range) => range.end > 2000000
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!length(radio.freq_ranges))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
push(info.radios, {
|
||||||
|
index: radio.index,
|
||||||
|
freq_ranges: map(radio.freq_ranges,
|
||||||
|
(range) => [ range.start, range.end ]
|
||||||
|
),
|
||||||
|
bands: {}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
let bands = info.bands;
|
let bands = info.bands;
|
||||||
for (let band in phy.wiphy_bands) {
|
for (let band in phy.wiphy_bands) {
|
||||||
if (!band || !band.freqs)
|
if (!band || !band.freqs)
|
||||||
@ -160,6 +188,25 @@ function wiphy_detect() {
|
|||||||
if (eht_phy_cap && he_phy_cap & 2)
|
if (eht_phy_cap && he_phy_cap & 2)
|
||||||
push(modes, "EHT40");
|
push(modes, "EHT40");
|
||||||
|
|
||||||
|
for (let radio in info.radios) {
|
||||||
|
let freq_match = filter(band.freqs,
|
||||||
|
(freq) => freq_range_match(radio.freq_ranges, freq.freq)
|
||||||
|
);
|
||||||
|
if (!length(freq_match))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
let radio_band = {};
|
||||||
|
radio.bands[band_name] = radio_band;
|
||||||
|
|
||||||
|
freq_match = filter(freq_match,
|
||||||
|
(freq) => !freq.disabled
|
||||||
|
);
|
||||||
|
|
||||||
|
let freq = freq_match[0];
|
||||||
|
if (freq)
|
||||||
|
radio_band.default_channel = freq_to_channel(freq.freq);
|
||||||
|
}
|
||||||
|
|
||||||
for (let freq in band.freqs) {
|
for (let freq in band.freqs) {
|
||||||
if (freq.disabled)
|
if (freq.disabled)
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@ -12,6 +12,7 @@ ADD_WAN_FQDN=0
|
|||||||
ADD_LOCAL_FQDN=""
|
ADD_LOCAL_FQDN=""
|
||||||
|
|
||||||
BASECONFIGFILE="/var/etc/dnsmasq.conf"
|
BASECONFIGFILE="/var/etc/dnsmasq.conf"
|
||||||
|
EXTRACONFFILE="extraconfig.conf"
|
||||||
BASEHOSTFILE="/tmp/hosts/dhcp"
|
BASEHOSTFILE="/tmp/hosts/dhcp"
|
||||||
TRUSTANCHORSFILE="/usr/share/dnsmasq/trust-anchors.conf"
|
TRUSTANCHORSFILE="/usr/share/dnsmasq/trust-anchors.conf"
|
||||||
TIMEVALIDFILE="/var/state/dnsmasqsec"
|
TIMEVALIDFILE="/var/state/dnsmasqsec"
|
||||||
@ -68,7 +69,7 @@ xappend() {
|
|||||||
local opt="${value%%=*}"
|
local opt="${value%%=*}"
|
||||||
|
|
||||||
if ! dnsmasq_ignore_opt "$opt"; then
|
if ! dnsmasq_ignore_opt "$opt"; then
|
||||||
echo "$value" >>$CONFIGFILE_TMP
|
echo "$value" >>"$CONFIGFILE_TMP"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -353,7 +354,7 @@ dhcp_host_add() {
|
|||||||
|
|
||||||
config_get_bool dns "$cfg" dns 0
|
config_get_bool dns "$cfg" dns 0
|
||||||
[ "$dns" = "1" ] && [ -n "$ip" ] && [ -n "$name" ] && {
|
[ "$dns" = "1" ] && [ -n "$ip" ] && [ -n "$name" ] && {
|
||||||
echo "$ip $name${DOMAIN:+.$DOMAIN}" >> $HOSTFILE_TMP
|
echo "$ip $name${DOMAIN:+.$DOMAIN}" >> "$HOSTFILE_TMP"
|
||||||
}
|
}
|
||||||
|
|
||||||
config_get mac "$cfg" mac
|
config_get mac "$cfg" mac
|
||||||
@ -713,7 +714,7 @@ dhcp_domain_add() {
|
|||||||
record="${record:+$record }$name"
|
record="${record:+$record }$name"
|
||||||
done
|
done
|
||||||
|
|
||||||
echo "$ip $record" >> $HOSTFILE_TMP
|
echo "$ip $record" >> "$HOSTFILE_TMP"
|
||||||
}
|
}
|
||||||
|
|
||||||
dhcp_srv_add() {
|
dhcp_srv_add() {
|
||||||
@ -787,6 +788,29 @@ dhcp_hostrecord_add() {
|
|||||||
xappend "--host-record=$record"
|
xappend "--host-record=$record"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dhcp_dnsrr_add() {
|
||||||
|
#This adds arbitrary resource record types (of IN class) whose optional data must be hex
|
||||||
|
local cfg="$1"
|
||||||
|
local rrname rrnumber hexdata
|
||||||
|
|
||||||
|
config_get rrname "$cfg" rrname
|
||||||
|
[ -n "$rrname" ] || return 0
|
||||||
|
|
||||||
|
config_get rrnumber "$cfg" rrnumber
|
||||||
|
[ -n "$rrnumber" ] && [ "$rrnumber" -gt 0 ] || return 0
|
||||||
|
|
||||||
|
config_get hexdata "$cfg" hexdata
|
||||||
|
|
||||||
|
# dnsmasq accepts colon XX:XX:.., space XX XX .., or contiguous XXXX.. hex forms or mixtures thereof
|
||||||
|
if [ -n "${hexdata//[0-9a-fA-F\:\ ]/}" ]; then
|
||||||
|
# is invalid hex literal
|
||||||
|
echo "dnsmasq: \"$hexdata\" is malformed hexadecimal (separate hex with colon, space or not at all)." >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
xappend "--dns-rr=${rrname},${rrnumber}${hexdata:+,$hexdata}"
|
||||||
|
}
|
||||||
|
|
||||||
dhcp_relay_add() {
|
dhcp_relay_add() {
|
||||||
local cfg="$1"
|
local cfg="$1"
|
||||||
local local_addr server_addr interface
|
local local_addr server_addr interface
|
||||||
@ -881,13 +905,13 @@ dnsmasq_start()
|
|||||||
# before we can call xappend
|
# before we can call xappend
|
||||||
umask u=rwx,g=rx,o=rx
|
umask u=rwx,g=rx,o=rx
|
||||||
mkdir -p /var/run/dnsmasq/
|
mkdir -p /var/run/dnsmasq/
|
||||||
mkdir -p $(dirname $CONFIGFILE)
|
mkdir -p "$(dirname "$CONFIGFILE")"
|
||||||
mkdir -p "$HOSTFILE_DIR"
|
mkdir -p "$HOSTFILE_DIR"
|
||||||
mkdir -p /var/lib/misc
|
mkdir -p /var/lib/misc
|
||||||
chown dnsmasq:dnsmasq /var/run/dnsmasq
|
chown dnsmasq:dnsmasq /var/run/dnsmasq
|
||||||
|
|
||||||
echo "# auto-generated config file from /etc/config/dhcp" > $CONFIGFILE_TMP
|
echo "# auto-generated config file from /etc/config/dhcp" > "$CONFIGFILE_TMP"
|
||||||
echo "# auto-generated config file from /etc/config/dhcp" > $HOSTFILE_TMP
|
echo "# auto-generated config file from /etc/config/dhcp" > "$HOSTFILE_TMP"
|
||||||
|
|
||||||
local dnsmasqconffile="/etc/dnsmasq.${cfg}.conf"
|
local dnsmasqconffile="/etc/dnsmasq.${cfg}.conf"
|
||||||
if [ ! -r "$dnsmasqconffile" ]; then
|
if [ ! -r "$dnsmasqconffile" ]; then
|
||||||
@ -973,8 +997,11 @@ dnsmasq_start()
|
|||||||
append_bool "$cfg" rapidcommit "--dhcp-rapid-commit"
|
append_bool "$cfg" rapidcommit "--dhcp-rapid-commit"
|
||||||
append_bool "$cfg" scriptarp "--script-arp"
|
append_bool "$cfg" scriptarp "--script-arp"
|
||||||
|
|
||||||
append_bool "$cfg" filter_a "--filter-A"
|
# deprecate or remove filter-X in favor of filter-rr?
|
||||||
append_bool "$cfg" filter_aaaa "--filter-AAAA"
|
append_bool "$cfg" filter_aaaa "--filter-AAAA"
|
||||||
|
append_bool "$cfg" filter_a "--filter-A"
|
||||||
|
append_parm "$cfg" filter_rr "--filter-rr"
|
||||||
|
append_parm "$cfg" cache_rr "--cache-rr"
|
||||||
|
|
||||||
append_parm "$cfg" logfacility "--log-facility"
|
append_parm "$cfg" logfacility "--log-facility"
|
||||||
config_get logfacility "$cfg" "logfacility"
|
config_get logfacility "$cfg" "logfacility"
|
||||||
@ -1118,13 +1145,21 @@ dnsmasq_start()
|
|||||||
xappend "--dhcp-broadcast=tag:needs-broadcast"
|
xappend "--dhcp-broadcast=tag:needs-broadcast"
|
||||||
|
|
||||||
|
|
||||||
config_get dnsmasqconfdir "$cfg" confdir "/tmp/dnsmasq.d"
|
# Create a dnsmasq.d dir for each instance
|
||||||
xappend "--conf-dir=$dnsmasqconfdir"
|
config_get dnsmasqconfdir "$cfg" confdir "/tmp/dnsmasq${cfg:+.$cfg}.d"
|
||||||
dnsmasqconfdir="${dnsmasqconfdir%%,*}"
|
# Ensure dnsmasqconfdir is an absolute path
|
||||||
[ ! -d "$dnsmasqconfdir" ] && mkdir -p $dnsmasqconfdir
|
[ "${dnsmasqconfdir:0:1}" = '/' ] && {
|
||||||
xappend "--user=dnsmasq"
|
xappend "--conf-dir=$dnsmasqconfdir"
|
||||||
xappend "--group=dnsmasq"
|
dnsmasqconfdir="${dnsmasqconfdir%%,*}"
|
||||||
echo >> $CONFIGFILE_TMP
|
[ ! -d "$dnsmasqconfdir" ] && mkdir -p "$dnsmasqconfdir"
|
||||||
|
xappend "--user=dnsmasq"
|
||||||
|
xappend "--group=dnsmasq"
|
||||||
|
echo >> "$CONFIGFILE_TMP"
|
||||||
|
|
||||||
|
# EXTRACONFFILE allows new dnsmasq parameters before they are natively handled in this init file
|
||||||
|
config_get extraconftext "$cfg" extraconftext
|
||||||
|
[ -n "$extraconftext" ] && echo -e "$extraconftext" > "$dnsmasqconfdir"/"$EXTRACONFFILE"
|
||||||
|
}
|
||||||
|
|
||||||
config_get_bool enable_tftp "$cfg" enable_tftp 0
|
config_get_bool enable_tftp "$cfg" enable_tftp 0
|
||||||
[ "$enable_tftp" -gt 0 ] && {
|
[ "$enable_tftp" -gt 0 ] && {
|
||||||
@ -1133,7 +1168,7 @@ dnsmasq_start()
|
|||||||
}
|
}
|
||||||
|
|
||||||
config_foreach filter_dnsmasq host dhcp_host_add "$cfg"
|
config_foreach filter_dnsmasq host dhcp_host_add "$cfg"
|
||||||
echo >> $CONFIGFILE_TMP
|
echo >> "$CONFIGFILE_TMP"
|
||||||
|
|
||||||
config_get_bool dhcpbogushostname "$cfg" dhcpbogushostname 1
|
config_get_bool dhcpbogushostname "$cfg" dhcpbogushostname 1
|
||||||
[ "$dhcpbogushostname" -gt 0 ] && {
|
[ "$dhcpbogushostname" -gt 0 ] && {
|
||||||
@ -1152,12 +1187,13 @@ dnsmasq_start()
|
|||||||
config_foreach filter_dnsmasq match dhcp_match_add "$cfg"
|
config_foreach filter_dnsmasq match dhcp_match_add "$cfg"
|
||||||
config_foreach filter_dnsmasq domain dhcp_domain_add "$cfg"
|
config_foreach filter_dnsmasq domain dhcp_domain_add "$cfg"
|
||||||
config_foreach filter_dnsmasq hostrecord dhcp_hostrecord_add "$cfg"
|
config_foreach filter_dnsmasq hostrecord dhcp_hostrecord_add "$cfg"
|
||||||
|
config_foreach filter_dnsmasq dnsrr dhcp_dnsrr_add "$cfg"
|
||||||
[ -n "$BOOT" ] || config_foreach filter_dnsmasq relay dhcp_relay_add "$cfg"
|
[ -n "$BOOT" ] || config_foreach filter_dnsmasq relay dhcp_relay_add "$cfg"
|
||||||
|
|
||||||
echo >> $CONFIGFILE_TMP
|
echo >> "$CONFIGFILE_TMP"
|
||||||
config_foreach filter_dnsmasq srvhost dhcp_srv_add "$cfg"
|
config_foreach filter_dnsmasq srvhost dhcp_srv_add "$cfg"
|
||||||
config_foreach filter_dnsmasq mxhost dhcp_mx_add "$cfg"
|
config_foreach filter_dnsmasq mxhost dhcp_mx_add "$cfg"
|
||||||
echo >> $CONFIGFILE_TMP
|
echo >> "$CONFIGFILE_TMP"
|
||||||
|
|
||||||
config_get_bool boguspriv "$cfg" boguspriv 1
|
config_get_bool boguspriv "$cfg" boguspriv 1
|
||||||
[ "$boguspriv" -gt 0 ] && {
|
[ "$boguspriv" -gt 0 ] && {
|
||||||
@ -1179,16 +1215,16 @@ dnsmasq_start()
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
echo >> $CONFIGFILE_TMP
|
echo >> "$CONFIGFILE_TMP"
|
||||||
config_foreach filter_dnsmasq cname dhcp_cname_add "$cfg"
|
config_foreach filter_dnsmasq cname dhcp_cname_add "$cfg"
|
||||||
echo >> $CONFIGFILE_TMP
|
echo >> "$CONFIGFILE_TMP"
|
||||||
|
|
||||||
echo >> $CONFIGFILE_TMP
|
echo >> "$CONFIGFILE_TMP"
|
||||||
config_foreach filter_dnsmasq ipset dnsmasq_ipset_add "$cfg"
|
config_foreach filter_dnsmasq ipset dnsmasq_ipset_add "$cfg"
|
||||||
echo >> $CONFIGFILE_TMP
|
echo >> "$CONFIGFILE_TMP"
|
||||||
|
|
||||||
mv -f $CONFIGFILE_TMP $CONFIGFILE
|
mv -f "$CONFIGFILE_TMP" "$CONFIGFILE"
|
||||||
mv -f $HOSTFILE_TMP $HOSTFILE
|
mv -f "$HOSTFILE_TMP" "$HOSTFILE"
|
||||||
|
|
||||||
[ "$localuse" -gt 0 ] && {
|
[ "$localuse" -gt 0 ] && {
|
||||||
rm -f /tmp/resolv.conf
|
rm -f /tmp/resolv.conf
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
let libubus = require("ubus");
|
let libubus = require("ubus");
|
||||||
import { open, readfile } from "fs";
|
import { open, readfile } from "fs";
|
||||||
import { wdev_create, wdev_remove, is_equal, vlist_new, phy_is_fullmac, phy_open } from "common";
|
import { wdev_remove, is_equal, vlist_new, phy_is_fullmac, phy_open, wdev_set_radio_mask } from "common";
|
||||||
|
|
||||||
let ubus = libubus.connect(null, 60);
|
let ubus = libubus.connect(null, 60);
|
||||||
|
|
||||||
@ -30,6 +30,23 @@ hostapd.data.iface_fields = {
|
|||||||
iapp_interface: true,
|
iapp_interface: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
hostapd.data.bss_info_fields = {
|
||||||
|
// radio
|
||||||
|
hw_mode: true,
|
||||||
|
channel: true,
|
||||||
|
ieee80211ac: true,
|
||||||
|
ieee80211ax: true,
|
||||||
|
|
||||||
|
// bss
|
||||||
|
bssid: true,
|
||||||
|
ssid: true,
|
||||||
|
wpa: true,
|
||||||
|
wpa_key_mgmt: true,
|
||||||
|
wpa_pairwise: true,
|
||||||
|
auth_algs: true,
|
||||||
|
ieee80211w: true,
|
||||||
|
};
|
||||||
|
|
||||||
function iface_remove(cfg)
|
function iface_remove(cfg)
|
||||||
{
|
{
|
||||||
if (!cfg || !cfg.bss || !cfg.bss[0] || !cfg.bss[0].ifname)
|
if (!cfg || !cfg.bss || !cfg.bss[0] || !cfg.bss[0].ifname)
|
||||||
@ -39,7 +56,7 @@ function iface_remove(cfg)
|
|||||||
wdev_remove(bss.ifname);
|
wdev_remove(bss.ifname);
|
||||||
}
|
}
|
||||||
|
|
||||||
function iface_gen_config(phy, config, start_disabled)
|
function iface_gen_config(config, start_disabled)
|
||||||
{
|
{
|
||||||
let str = `data:
|
let str = `data:
|
||||||
${join("\n", config.radio.data)}
|
${join("\n", config.radio.data)}
|
||||||
@ -100,7 +117,7 @@ function iface_freq_info(iface, config, params)
|
|||||||
|
|
||||||
function iface_add(phy, config, phy_status)
|
function iface_add(phy, config, phy_status)
|
||||||
{
|
{
|
||||||
let config_inline = iface_gen_config(phy, config, !!phy_status);
|
let config_inline = iface_gen_config(config, !!phy_status);
|
||||||
|
|
||||||
let bss = config.bss[0];
|
let bss = config.bss[0];
|
||||||
let ret = hostapd.add_iface(`bss_config=${phy}:${config_inline}`);
|
let ret = hostapd.add_iface(`bss_config=${phy}:${config_inline}`);
|
||||||
@ -131,12 +148,16 @@ function iface_config_macaddr_list(config)
|
|||||||
return macaddr_list;
|
return macaddr_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
function iface_update_supplicant_macaddr(phy, config)
|
function iface_update_supplicant_macaddr(phydev, config)
|
||||||
{
|
{
|
||||||
let macaddr_list = [];
|
let macaddr_list = [];
|
||||||
for (let i = 0; i < length(config.bss); i++)
|
for (let i = 0; i < length(config.bss); i++)
|
||||||
push(macaddr_list, config.bss[i].bssid);
|
push(macaddr_list, config.bss[i].bssid);
|
||||||
ubus.defer("wpa_supplicant", "phy_set_macaddr_list", { phy: phy, macaddr: macaddr_list });
|
ubus.defer("wpa_supplicant", "phy_set_macaddr_list", {
|
||||||
|
phy: phydev.name,
|
||||||
|
radio: phydev.radio ?? -1,
|
||||||
|
macaddr: macaddr_list
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function __iface_pending_next(pending, state, ret, data)
|
function __iface_pending_next(pending, state, ret, data)
|
||||||
@ -151,19 +172,22 @@ function __iface_pending_next(pending, state, ret, data)
|
|||||||
delete pending.defer;
|
delete pending.defer;
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case "init":
|
case "init":
|
||||||
let macaddr_list = [];
|
iface_update_supplicant_macaddr(phydev, config);
|
||||||
for (let i = 0; i < length(config.bss); i++)
|
|
||||||
push(macaddr_list, config.bss[i].bssid);
|
|
||||||
pending.call("wpa_supplicant", "phy_set_macaddr_list", { phy: phy, macaddr: macaddr_list });
|
|
||||||
return "create_bss";
|
return "create_bss";
|
||||||
case "create_bss":
|
case "create_bss":
|
||||||
let err = wdev_create(phy, bss.ifname, { mode: "ap" });
|
let err = phydev.wdev_add(bss.ifname, {
|
||||||
|
mode: "ap",
|
||||||
|
radio: phydev.radio,
|
||||||
|
});
|
||||||
if (err) {
|
if (err) {
|
||||||
hostapd.printf(`Failed to create ${bss.ifname} on phy ${phy}: ${err}`);
|
hostapd.printf(`Failed to create ${bss.ifname} on phy ${phy}: ${err}`);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
pending.call("wpa_supplicant", "phy_status", { phy: phy });
|
pending.call("wpa_supplicant", "phy_status", {
|
||||||
|
phy: phydev.phy,
|
||||||
|
radio: phydev.radio,
|
||||||
|
});
|
||||||
return "check_phy";
|
return "check_phy";
|
||||||
case "check_phy":
|
case "check_phy":
|
||||||
let phy_status = data;
|
let phy_status = data;
|
||||||
@ -173,12 +197,20 @@ function __iface_pending_next(pending, state, ret, data)
|
|||||||
|
|
||||||
hostapd.printf(`Failed to bring up phy ${phy} ifname=${bss.ifname} with supplicant provided frequency`);
|
hostapd.printf(`Failed to bring up phy ${phy} ifname=${bss.ifname} with supplicant provided frequency`);
|
||||||
}
|
}
|
||||||
pending.call("wpa_supplicant", "phy_set_state", { phy: phy, stop: true });
|
pending.call("wpa_supplicant", "phy_set_state", {
|
||||||
|
phy: phydev.phy,
|
||||||
|
radio: phydev.radio,
|
||||||
|
stop: true
|
||||||
|
});
|
||||||
return "wpas_stopped";
|
return "wpas_stopped";
|
||||||
case "wpas_stopped":
|
case "wpas_stopped":
|
||||||
if (!iface_add(phy, config))
|
if (!iface_add(phy, config))
|
||||||
hostapd.printf(`hostapd.add_iface failed for phy ${phy} ifname=${bss.ifname}`);
|
hostapd.printf(`hostapd.add_iface failed for phy ${phy} ifname=${bss.ifname}`);
|
||||||
pending.call("wpa_supplicant", "phy_set_state", { phy: phy, stop: false });
|
pending.call("wpa_supplicant", "phy_set_state", {
|
||||||
|
phy: phydev.phy,
|
||||||
|
radio: phydev.radio,
|
||||||
|
stop: false
|
||||||
|
});
|
||||||
return null;
|
return null;
|
||||||
case "done":
|
case "done":
|
||||||
default:
|
default:
|
||||||
@ -193,9 +225,14 @@ function iface_pending_next(ret, data)
|
|||||||
let cfg = this;
|
let cfg = this;
|
||||||
|
|
||||||
while (pending) {
|
while (pending) {
|
||||||
this.next_state = __iface_pending_next(cfg, this.next_state, ret, data);
|
try {
|
||||||
if (!this.next_state) {
|
this.next_state = __iface_pending_next(cfg, this.next_state, ret, data);
|
||||||
__iface_pending_next(cfg, "done");
|
if (!this.next_state) {
|
||||||
|
__iface_pending_next(cfg, "done");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch(e) {
|
||||||
|
hostapd.printf(`Exception: ${e}\n${e.stacktrace[0].context}`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
pending = !this.defer;
|
pending = !this.defer;
|
||||||
@ -381,7 +418,7 @@ function get_config_bss(config, idx)
|
|||||||
return hostapd.bss[ifname];
|
return hostapd.bss[ifname];
|
||||||
}
|
}
|
||||||
|
|
||||||
function iface_reload_config(phydev, config, old_config)
|
function iface_reload_config(name, phydev, config, old_config)
|
||||||
{
|
{
|
||||||
let phy = phydev.name;
|
let phy = phydev.name;
|
||||||
|
|
||||||
@ -391,13 +428,13 @@ function iface_reload_config(phydev, config, old_config)
|
|||||||
if (is_equal(old_config.bss, config.bss))
|
if (is_equal(old_config.bss, config.bss))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (hostapd.data.pending_config[phy])
|
if (hostapd.data.pending_config[name])
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!old_config.bss || !old_config.bss[0])
|
if (!old_config.bss || !old_config.bss[0])
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
let iface = hostapd.interfaces[phy];
|
let iface = hostapd.interfaces[name];
|
||||||
let iface_name = old_config.bss[0].ifname;
|
let iface_name = old_config.bss[0].ifname;
|
||||||
if (!iface) {
|
if (!iface) {
|
||||||
hostapd.printf(`Could not find previous interface ${iface_name}`);
|
hostapd.printf(`Could not find previous interface ${iface_name}`);
|
||||||
@ -492,7 +529,7 @@ function iface_reload_config(phydev, config, old_config)
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
let ifname = old_config.bss[i].ifname;
|
let ifname = old_config.bss[i].ifname;
|
||||||
hostapd.printf(`Remove bss '${ifname}' on phy '${phy}'`);
|
hostapd.printf(`Remove bss '${ifname}' on phy '${name}'`);
|
||||||
prev_bss.delete();
|
prev_bss.delete();
|
||||||
wdev_remove(ifname);
|
wdev_remove(ifname);
|
||||||
}
|
}
|
||||||
@ -557,13 +594,13 @@ function iface_reload_config(phydev, config, old_config)
|
|||||||
|
|
||||||
let addr = phydev.macaddr_next(i);
|
let addr = phydev.macaddr_next(i);
|
||||||
if (!addr) {
|
if (!addr) {
|
||||||
hostapd.printf(`Failed to generate mac address for phy ${phy}`);
|
hostapd.printf(`Failed to generate mac address for phy ${name}`);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bsscfg.bssid = addr;
|
bsscfg.bssid = addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
let config_inline = iface_gen_config(phy, config);
|
let config_inline = iface_gen_config(config);
|
||||||
|
|
||||||
// Step 7: fill in the gaps with new interfaces
|
// Step 7: fill in the gaps with new interfaces
|
||||||
for (let i = 0; i < length(config.bss); i++) {
|
for (let i = 0; i < length(config.bss); i++) {
|
||||||
@ -573,17 +610,17 @@ function iface_reload_config(phydev, config, old_config)
|
|||||||
if (bss)
|
if (bss)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
hostapd.printf(`Add bss ${ifname} on phy ${phy}`);
|
hostapd.printf(`Add bss ${ifname} on phy ${name}`);
|
||||||
bss_list[i] = iface.add_bss(config_inline, i);
|
bss_list[i] = iface.add_bss(config_inline, i);
|
||||||
if (!bss_list[i]) {
|
if (!bss_list[i]) {
|
||||||
hostapd.printf(`Failed to add new bss ${ifname} on phy ${phy}`);
|
hostapd.printf(`Failed to add new bss ${ifname} on phy ${name}`);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 8: update interface bss order
|
// Step 8: update interface bss order
|
||||||
if (!iface.set_bss_order(bss_list)) {
|
if (!iface.set_bss_order(bss_list)) {
|
||||||
hostapd.printf(`Failed to update BSS order on phy '${phy}'`);
|
hostapd.printf(`Failed to update BSS order on phy '${name}'`);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -614,7 +651,7 @@ function iface_reload_config(phydev, config, old_config)
|
|||||||
if (is_equal(config.bss[i], bss_list_cfg[i]))
|
if (is_equal(config.bss[i], bss_list_cfg[i]))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
hostapd.printf(`Reload config for bss '${config.bss[0].ifname}' on phy '${phy}'`);
|
hostapd.printf(`Reload config for bss '${config.bss[0].ifname}' on phy '${name}'`);
|
||||||
if (bss.set_config(config_inline, i) < 0) {
|
if (bss.set_config(config_inline, i) < 0) {
|
||||||
hostapd.printf(`Failed to set config for bss ${ifname}`);
|
hostapd.printf(`Failed to set config for bss ${ifname}`);
|
||||||
return false;
|
return false;
|
||||||
@ -624,35 +661,36 @@ function iface_reload_config(phydev, config, old_config)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function iface_set_config(phy, config)
|
function iface_set_config(name, config)
|
||||||
{
|
{
|
||||||
let old_config = hostapd.data.config[phy];
|
let old_config = hostapd.data.config[name];
|
||||||
|
|
||||||
hostapd.data.config[phy] = config;
|
hostapd.data.config[name] = config;
|
||||||
|
|
||||||
if (!config) {
|
if (!config) {
|
||||||
hostapd.remove_iface(phy);
|
hostapd.remove_iface(name);
|
||||||
return iface_remove(old_config);
|
return iface_remove(old_config);
|
||||||
}
|
}
|
||||||
|
|
||||||
let phydev = phy_open(phy);
|
let phy = config.phy;
|
||||||
|
let phydev = phy_open(phy, config.radio_idx);
|
||||||
if (!phydev) {
|
if (!phydev) {
|
||||||
hostapd.printf(`Failed to open phy ${phy}`);
|
hostapd.printf(`Failed to open phy ${phy}`);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let ret = iface_reload_config(phydev, config, old_config);
|
let ret = iface_reload_config(name, phydev, config, old_config);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
iface_update_supplicant_macaddr(phy, config);
|
iface_update_supplicant_macaddr(phydev, config);
|
||||||
hostapd.printf(`Reloaded settings for phy ${phy}`);
|
hostapd.printf(`Reloaded settings for phy ${name}`);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
hostapd.printf(`Error reloading config: ${e}\n${e.stacktrace[0].context}`);
|
hostapd.printf(`Error reloading config: ${e}\n${e.stacktrace[0].context}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
hostapd.printf(`Restart interface for phy ${phy}`);
|
hostapd.printf(`Restart interface for phy ${name}`);
|
||||||
let ret = iface_restart(phydev, config, old_config);
|
let ret = iface_restart(phydev, config, old_config);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -671,13 +709,18 @@ function config_add_bss(config, name)
|
|||||||
return bss;
|
return bss;
|
||||||
}
|
}
|
||||||
|
|
||||||
function iface_load_config(filename)
|
function iface_load_config(phy, radio, filename)
|
||||||
{
|
{
|
||||||
let f = open(filename, "r");
|
let f = open(filename, "r");
|
||||||
if (!f)
|
if (!f)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
|
if (radio < 0)
|
||||||
|
radio = null;
|
||||||
|
|
||||||
let config = {
|
let config = {
|
||||||
|
phy,
|
||||||
|
radio_idx: radio,
|
||||||
radio: {
|
radio: {
|
||||||
data: []
|
data: []
|
||||||
},
|
},
|
||||||
@ -752,16 +795,39 @@ function ex_wrap(func) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function phy_name(phy, radio)
|
||||||
|
{
|
||||||
|
if (!phy)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if (radio != null && radio >= 0)
|
||||||
|
phy += "." + radio;
|
||||||
|
|
||||||
|
return phy;
|
||||||
|
}
|
||||||
|
|
||||||
|
function bss_config(bss_name) {
|
||||||
|
for (let phy, config in hostapd.data.config) {
|
||||||
|
if (!config)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (let bss in config.bss)
|
||||||
|
if (bss.ifname == bss_name)
|
||||||
|
return [ config, bss ];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let main_obj = {
|
let main_obj = {
|
||||||
reload: {
|
reload: {
|
||||||
args: {
|
args: {
|
||||||
phy: "",
|
phy: "",
|
||||||
|
radio: 0,
|
||||||
},
|
},
|
||||||
call: ex_wrap(function(req) {
|
call: ex_wrap(function(req) {
|
||||||
let phy_list = req.args.phy ? [ req.args.phy ] : keys(hostapd.data.config);
|
let phy_list = req.args.phy ? [ phy_name(req.args.phy, req.args.radio) ] : keys(hostapd.data.config);
|
||||||
for (let phy_name in phy_list) {
|
for (let phy_name in phy_list) {
|
||||||
let phy = hostapd.data.config[phy_name];
|
let phy = hostapd.data.config[phy_name];
|
||||||
let config = iface_load_config(phy.orig_file);
|
let config = iface_load_config(phy.phy, radio, phy.orig_file);
|
||||||
iface_set_config(phy_name, config);
|
iface_set_config(phy_name, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -771,6 +837,7 @@ let main_obj = {
|
|||||||
apsta_state: {
|
apsta_state: {
|
||||||
args: {
|
args: {
|
||||||
phy: "",
|
phy: "",
|
||||||
|
radio: 0,
|
||||||
up: true,
|
up: true,
|
||||||
frequency: 0,
|
frequency: 0,
|
||||||
sec_chan_offset: 0,
|
sec_chan_offset: 0,
|
||||||
@ -778,10 +845,10 @@ let main_obj = {
|
|||||||
csa_count: 0,
|
csa_count: 0,
|
||||||
},
|
},
|
||||||
call: ex_wrap(function(req) {
|
call: ex_wrap(function(req) {
|
||||||
if (req.args.up == null || !req.args.phy)
|
let phy = phy_name(req.args.phy, req.args.radio);
|
||||||
|
if (req.args.up == null || !phy)
|
||||||
return libubus.STATUS_INVALID_ARGUMENT;
|
return libubus.STATUS_INVALID_ARGUMENT;
|
||||||
|
|
||||||
let phy = req.args.phy;
|
|
||||||
let config = hostapd.data.config[phy];
|
let config = hostapd.data.config[phy];
|
||||||
if (!config || !config.bss || !config.bss[0] || !config.bss[0].ifname)
|
if (!config || !config.bss || !config.bss[0] || !config.bss[0].ifname)
|
||||||
return 0;
|
return 0;
|
||||||
@ -817,10 +884,11 @@ let main_obj = {
|
|||||||
},
|
},
|
||||||
config_get_macaddr_list: {
|
config_get_macaddr_list: {
|
||||||
args: {
|
args: {
|
||||||
phy: ""
|
phy: "",
|
||||||
|
radio: 0,
|
||||||
},
|
},
|
||||||
call: ex_wrap(function(req) {
|
call: ex_wrap(function(req) {
|
||||||
let phy = req.args.phy;
|
let phy = phy_name(req.args.phy, req.args.radio);
|
||||||
if (!phy)
|
if (!phy)
|
||||||
return libubus.STATUS_INVALID_ARGUMENT;
|
return libubus.STATUS_INVALID_ARGUMENT;
|
||||||
|
|
||||||
@ -839,28 +907,34 @@ let main_obj = {
|
|||||||
config_set: {
|
config_set: {
|
||||||
args: {
|
args: {
|
||||||
phy: "",
|
phy: "",
|
||||||
|
radio: 0,
|
||||||
config: "",
|
config: "",
|
||||||
prev_config: "",
|
prev_config: "",
|
||||||
},
|
},
|
||||||
call: ex_wrap(function(req) {
|
call: ex_wrap(function(req) {
|
||||||
let phy = req.args.phy;
|
let phy = req.args.phy;
|
||||||
|
let radio = req.args.radio;
|
||||||
|
let name = phy_name(phy, radio);
|
||||||
let file = req.args.config;
|
let file = req.args.config;
|
||||||
let prev_file = req.args.prev_config;
|
let prev_file = req.args.prev_config;
|
||||||
|
|
||||||
if (!phy)
|
if (!phy)
|
||||||
return libubus.STATUS_INVALID_ARGUMENT;
|
return libubus.STATUS_INVALID_ARGUMENT;
|
||||||
|
|
||||||
if (prev_file && !hostapd.data.config[phy]) {
|
if (prev_file && !hostapd.data.config[name]) {
|
||||||
let config = iface_load_config(prev_file);
|
let config = iface_load_config(phy, radio, prev_file);
|
||||||
if (config)
|
if (config)
|
||||||
config.radio.data = [];
|
config.radio.data = [];
|
||||||
hostapd.data.config[phy] = config;
|
hostapd.data.config[name] = config;
|
||||||
}
|
}
|
||||||
|
|
||||||
let config = iface_load_config(file);
|
let config = iface_load_config(phy, radio, file);
|
||||||
|
|
||||||
hostapd.printf(`Set new config for phy ${phy}: ${file}`);
|
hostapd.printf(`Set new config for phy ${name}: ${file}`);
|
||||||
iface_set_config(phy, config);
|
iface_set_config(name, config);
|
||||||
|
|
||||||
|
if (hostapd.data.auth_obj)
|
||||||
|
hostapd.data.auth_obj.notify("reload", { phy, radio });
|
||||||
|
|
||||||
return {
|
return {
|
||||||
pid: hostapd.getpid()
|
pid: hostapd.getpid()
|
||||||
@ -896,10 +970,40 @@ let main_obj = {
|
|||||||
return 0;
|
return 0;
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
bss_info: {
|
||||||
|
args: {
|
||||||
|
iface: ""
|
||||||
|
},
|
||||||
|
call: ex_wrap(function(req) {
|
||||||
|
if (!req.args.iface)
|
||||||
|
return libubus.STATUS_INVALID_ARGUMENT;
|
||||||
|
|
||||||
|
let config = bss_config(req.args.iface);
|
||||||
|
if (!config)
|
||||||
|
return libubus.STATUS_NOT_FOUND;
|
||||||
|
|
||||||
|
let bss = config[1];
|
||||||
|
config = config[0];
|
||||||
|
let ret = {};
|
||||||
|
|
||||||
|
for (let line in [ ...config.radio.data, ...bss.data ]) {
|
||||||
|
let fields = split(line, "=", 2);
|
||||||
|
let name = fields[0];
|
||||||
|
if (hostapd.data.bss_info_fields[name])
|
||||||
|
ret[name] = fields[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
})
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
hostapd.data.ubus = ubus;
|
hostapd.data.ubus = ubus;
|
||||||
hostapd.data.obj = ubus.publish("hostapd", main_obj);
|
hostapd.data.obj = ubus.publish("hostapd", main_obj);
|
||||||
|
|
||||||
|
|
||||||
|
let auth_obj = {};
|
||||||
|
hostapd.data.auth_obj = ubus.publish("hostapd-auth", auth_obj);
|
||||||
hostapd.udebug_set("hostapd", hostapd.data.ubus);
|
hostapd.udebug_set("hostapd", hostapd.data.ubus);
|
||||||
|
|
||||||
function bss_event(type, name, data) {
|
function bss_event(type, name, data) {
|
||||||
@ -914,10 +1018,18 @@ function bss_event(type, name, data) {
|
|||||||
return {
|
return {
|
||||||
shutdown: function() {
|
shutdown: function() {
|
||||||
for (let phy in hostapd.data.config)
|
for (let phy in hostapd.data.config)
|
||||||
iface_set_config(phy, null);
|
iface_set_config(phy);
|
||||||
hostapd.udebug_set(null);
|
hostapd.udebug_set(null);
|
||||||
hostapd.ubus.disconnect();
|
hostapd.ubus.disconnect();
|
||||||
},
|
},
|
||||||
|
bss_create: function(phy, name, obj) {
|
||||||
|
phy = hostapd.data.config[phy];
|
||||||
|
if (!phy)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (phy.radio_idx != null && phy.radio_idx >= 0)
|
||||||
|
wdev_set_radio_mask(name, 1 << phy.radio_idx);
|
||||||
|
},
|
||||||
bss_add: function(phy, name, obj) {
|
bss_add: function(phy, name, obj) {
|
||||||
bss_event("add", name);
|
bss_event("add", name);
|
||||||
},
|
},
|
||||||
@ -926,5 +1038,25 @@ return {
|
|||||||
},
|
},
|
||||||
bss_remove: function(phy, name, obj) {
|
bss_remove: function(phy, name, obj) {
|
||||||
bss_event("remove", name);
|
bss_event("remove", name);
|
||||||
}
|
},
|
||||||
|
sta_auth: function(iface, sta) {
|
||||||
|
let msg = { iface, sta };
|
||||||
|
let ret = {};
|
||||||
|
let data_cb = (type, data) => {
|
||||||
|
ret = { ...ret, ...data };
|
||||||
|
};
|
||||||
|
if (hostapd.data.auth_obj)
|
||||||
|
hostapd.data.auth_obj.notify("sta_auth", msg, data_cb, null, null, 1000);
|
||||||
|
return ret;
|
||||||
|
},
|
||||||
|
sta_connected: function(iface, sta, data) {
|
||||||
|
let msg = { iface, sta, ...data };
|
||||||
|
let ret = {};
|
||||||
|
let data_cb = (type, data) => {
|
||||||
|
ret = { ...ret, ...data };
|
||||||
|
};
|
||||||
|
if (hostapd.data.auth_obj)
|
||||||
|
hostapd.data.auth_obj.notify("sta_connected", msg, data_cb, null, null, 1000);
|
||||||
|
return ret;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@ -37,7 +37,7 @@ function iface_start(phydev, iface, macaddr_list)
|
|||||||
|
|
||||||
wpas.data.iface_phy[ifname] = phy;
|
wpas.data.iface_phy[ifname] = phy;
|
||||||
wdev_remove(ifname);
|
wdev_remove(ifname);
|
||||||
let ret = wdev_create(phy, ifname, wdev_config);
|
let ret = phydev.wdev_add(ifname, wdev_config);
|
||||||
if (ret)
|
if (ret)
|
||||||
wpas.printf(`Failed to create device ${ifname}: ${ret}`);
|
wpas.printf(`Failed to create device ${ifname}: ${ret}`);
|
||||||
wdev_set_up(ifname, true);
|
wdev_set_up(ifname, true);
|
||||||
@ -61,22 +61,27 @@ function iface_cb(new_if, old_if)
|
|||||||
iface_stop(old_if);
|
iface_stop(old_if);
|
||||||
}
|
}
|
||||||
|
|
||||||
function prepare_config(config)
|
function prepare_config(config, radio)
|
||||||
{
|
{
|
||||||
config.config_data = readfile(config.config);
|
config.config_data = readfile(config.config);
|
||||||
|
|
||||||
return { config: config };
|
return { config };
|
||||||
}
|
}
|
||||||
|
|
||||||
function set_config(phy_name, num_global_macaddr, config_list)
|
function set_config(config_name, phy_name, radio, num_global_macaddr, config_list)
|
||||||
{
|
{
|
||||||
let phy = wpas.data.config[phy_name];
|
let phy = wpas.data.config[config_name];
|
||||||
|
|
||||||
|
if (radio < 0)
|
||||||
|
radio = null;
|
||||||
|
|
||||||
if (!phy) {
|
if (!phy) {
|
||||||
phy = vlist_new(iface_cb, false);
|
phy = vlist_new(iface_cb, false);
|
||||||
wpas.data.config[phy_name] = phy;
|
phy.name = phy_name;
|
||||||
|
wpas.data.config[config_name] = phy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
phy.radio = radio;
|
||||||
phy.num_global_macaddr = num_global_macaddr;
|
phy.num_global_macaddr = num_global_macaddr;
|
||||||
|
|
||||||
let values = [];
|
let values = [];
|
||||||
@ -94,7 +99,7 @@ function start_pending(phy_name)
|
|||||||
if (!phy || !phy.data)
|
if (!phy || !phy.data)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
let phydev = phy_open(phy_name);
|
let phydev = phy_open(phy.name, phy.radio);
|
||||||
if (!phydev) {
|
if (!phydev) {
|
||||||
wpas.printf(`Could not open phy ${phy_name}`);
|
wpas.printf(`Could not open phy ${phy_name}`);
|
||||||
return;
|
return;
|
||||||
@ -107,17 +112,30 @@ function start_pending(phy_name)
|
|||||||
iface_start(phydev, phy.data[ifname]);
|
iface_start(phydev, phy.data[ifname]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function phy_name(phy, radio)
|
||||||
|
{
|
||||||
|
if (!phy)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if (radio != null && radio >= 0)
|
||||||
|
phy += "." + radio;
|
||||||
|
|
||||||
|
return phy;
|
||||||
|
}
|
||||||
|
|
||||||
let main_obj = {
|
let main_obj = {
|
||||||
phy_set_state: {
|
phy_set_state: {
|
||||||
args: {
|
args: {
|
||||||
phy: "",
|
phy: "",
|
||||||
|
radio: 0,
|
||||||
stop: true,
|
stop: true,
|
||||||
},
|
},
|
||||||
call: function(req) {
|
call: function(req) {
|
||||||
if (!req.args.phy || req.args.stop == null)
|
let name = phy_name(req.args.phy, req.args.radio);
|
||||||
|
if (!name || req.args.stop == null)
|
||||||
return libubus.STATUS_INVALID_ARGUMENT;
|
return libubus.STATUS_INVALID_ARGUMENT;
|
||||||
|
|
||||||
let phy = wpas.data.config[req.args.phy];
|
let phy = wpas.data.config[name];
|
||||||
if (!phy)
|
if (!phy)
|
||||||
return libubus.STATUS_NOT_FOUND;
|
return libubus.STATUS_NOT_FOUND;
|
||||||
|
|
||||||
@ -126,7 +144,7 @@ let main_obj = {
|
|||||||
for (let ifname in phy.data)
|
for (let ifname in phy.data)
|
||||||
iface_stop(phy.data[ifname]);
|
iface_stop(phy.data[ifname]);
|
||||||
} else {
|
} else {
|
||||||
start_pending(req.args.phy);
|
start_pending(name);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
wpas.printf(`Error chaging state: ${e}\n${e.stacktrace[0].context}`);
|
wpas.printf(`Error chaging state: ${e}\n${e.stacktrace[0].context}`);
|
||||||
@ -138,10 +156,11 @@ let main_obj = {
|
|||||||
phy_set_macaddr_list: {
|
phy_set_macaddr_list: {
|
||||||
args: {
|
args: {
|
||||||
phy: "",
|
phy: "",
|
||||||
|
radio: 0,
|
||||||
macaddr: [],
|
macaddr: [],
|
||||||
},
|
},
|
||||||
call: function(req) {
|
call: function(req) {
|
||||||
let phy = req.args.phy;
|
let phy = phy_name(req.args.phy, req.args.radio);
|
||||||
if (!phy)
|
if (!phy)
|
||||||
return libubus.STATUS_INVALID_ARGUMENT;
|
return libubus.STATUS_INVALID_ARGUMENT;
|
||||||
|
|
||||||
@ -151,13 +170,15 @@ let main_obj = {
|
|||||||
},
|
},
|
||||||
phy_status: {
|
phy_status: {
|
||||||
args: {
|
args: {
|
||||||
phy: ""
|
phy: "",
|
||||||
|
radio: 0,
|
||||||
},
|
},
|
||||||
call: function(req) {
|
call: function(req) {
|
||||||
if (!req.args.phy)
|
let phy = phy_name(req.args.phy, req.args.radio);
|
||||||
|
if (!phy)
|
||||||
return libubus.STATUS_INVALID_ARGUMENT;
|
return libubus.STATUS_INVALID_ARGUMENT;
|
||||||
|
|
||||||
let phy = wpas.data.config[req.args.phy];
|
phy = wpas.data.config[phy];
|
||||||
if (!phy)
|
if (!phy)
|
||||||
return libubus.STATUS_NOT_FOUND;
|
return libubus.STATUS_NOT_FOUND;
|
||||||
|
|
||||||
@ -187,21 +208,23 @@ let main_obj = {
|
|||||||
config_set: {
|
config_set: {
|
||||||
args: {
|
args: {
|
||||||
phy: "",
|
phy: "",
|
||||||
|
radio: 0,
|
||||||
num_global_macaddr: 0,
|
num_global_macaddr: 0,
|
||||||
config: [],
|
config: [],
|
||||||
defer: true,
|
defer: true,
|
||||||
},
|
},
|
||||||
call: function(req) {
|
call: function(req) {
|
||||||
if (!req.args.phy)
|
let phy = phy_name(req.args.phy, req.args.radio);
|
||||||
|
if (!phy)
|
||||||
return libubus.STATUS_INVALID_ARGUMENT;
|
return libubus.STATUS_INVALID_ARGUMENT;
|
||||||
|
|
||||||
wpas.printf(`Set new config for phy ${req.args.phy}`);
|
wpas.printf(`Set new config for phy ${phy}`);
|
||||||
try {
|
try {
|
||||||
if (req.args.config)
|
if (req.args.config)
|
||||||
set_config(req.args.phy, req.args.num_global_macaddr, req.args.config);
|
set_config(phy, req.args.phy, req.args.radio, req.args.num_global_macaddr, req.args.config);
|
||||||
|
|
||||||
if (!req.args.defer)
|
if (!req.args.defer)
|
||||||
start_pending(req.args.phy);
|
start_pending(phy);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
wpas.printf(`Error loading config: ${e}\n${e.stacktrace[0].context}`);
|
wpas.printf(`Error loading config: ${e}\n${e.stacktrace[0].context}`);
|
||||||
return libubus.STATUS_INVALID_ARGUMENT;
|
return libubus.STATUS_INVALID_ARGUMENT;
|
||||||
@ -245,6 +268,33 @@ let main_obj = {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
bss_info: {
|
||||||
|
args: {
|
||||||
|
iface: "",
|
||||||
|
},
|
||||||
|
call: function(req) {
|
||||||
|
let ifname = req.args.iface;
|
||||||
|
if (!ifname)
|
||||||
|
return libubus.STATUS_INVALID_ARGUMENT;
|
||||||
|
|
||||||
|
let iface = wpas.interfaces[ifname];
|
||||||
|
if (!iface)
|
||||||
|
return libubus.STATUS_NOT_FOUND;
|
||||||
|
|
||||||
|
let status = iface.ctrl("STATUS");
|
||||||
|
if (!status)
|
||||||
|
return libubus.STATUS_NOT_FOUND;
|
||||||
|
|
||||||
|
let ret = {};
|
||||||
|
status = split(status, "\n");
|
||||||
|
for (let line in status) {
|
||||||
|
line = split(line, "=", 2);
|
||||||
|
ret[line[0]] = line[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
wpas.data.ubus = ubus;
|
wpas.data.ubus = ubus;
|
||||||
|
|||||||
@ -15,6 +15,6 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"subscribe": [ "udebug" ],
|
"subscribe": [ "udebug" ],
|
||||||
"publish": [ "hostapd", "hostapd.*", "wpa_supplicant", "wpa_supplicant.*" ],
|
"publish": [ "hostapd", "hostapd.*", "wpa_supplicant", "wpa_supplicant.*", "hostapd-auth" ],
|
||||||
"send": [ "bss.*", "wps_credentials" ]
|
"send": [ "bss.*", "wps_credentials" ]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -704,3 +704,138 @@ as adding/removing interfaces.
|
|||||||
#ifdef CONFIG_MATCH_IFACE
|
#ifdef CONFIG_MATCH_IFACE
|
||||||
int matched;
|
int matched;
|
||||||
#endif /* CONFIG_MATCH_IFACE */
|
#endif /* CONFIG_MATCH_IFACE */
|
||||||
|
--- a/src/ap/ieee802_11.c
|
||||||
|
+++ b/src/ap/ieee802_11.c
|
||||||
|
@@ -555,12 +555,17 @@ const char * sae_get_password(struct hos
|
||||||
|
struct sae_pt **s_pt,
|
||||||
|
const struct sae_pk **s_pk)
|
||||||
|
{
|
||||||
|
+ struct hostapd_bss_config *conf = hapd->conf;
|
||||||
|
+ struct hostapd_ssid *ssid = &conf->ssid;
|
||||||
|
const char *password = NULL;
|
||||||
|
- struct sae_password_entry *pw;
|
||||||
|
+ struct sae_password_entry *pw = NULL;
|
||||||
|
struct sae_pt *pt = NULL;
|
||||||
|
const struct sae_pk *pk = NULL;
|
||||||
|
struct hostapd_sta_wpa_psk_short *psk = NULL;
|
||||||
|
|
||||||
|
+ if (sta && sta->use_sta_psk)
|
||||||
|
+ goto use_sta_psk;
|
||||||
|
+
|
||||||
|
for (pw = hapd->conf->sae_passwords; pw; pw = pw->next) {
|
||||||
|
if (!is_broadcast_ether_addr(pw->peer_addr) &&
|
||||||
|
(!sta ||
|
||||||
|
@@ -582,12 +587,28 @@ const char * sae_get_password(struct hos
|
||||||
|
pt = hapd->conf->ssid.pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
+use_sta_psk:
|
||||||
|
if (!password && sta) {
|
||||||
|
for (psk = sta->psk; psk; psk = psk->next) {
|
||||||
|
- if (psk->is_passphrase) {
|
||||||
|
- password = psk->passphrase;
|
||||||
|
+ if (!psk->is_passphrase)
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ password = psk->passphrase;
|
||||||
|
+ if (!sta->use_sta_psk)
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ if (sta->sae_pt) {
|
||||||
|
+ pt = sta->sae_pt;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ pt = sae_derive_pt(conf->sae_groups, ssid->ssid,
|
||||||
|
+ ssid->ssid_len,
|
||||||
|
+ (const u8 *) password,
|
||||||
|
+ os_strlen(password),
|
||||||
|
+ NULL);
|
||||||
|
+ sta->sae_pt = pt;
|
||||||
|
+ break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -3229,6 +3250,12 @@ static void handle_auth(struct hostapd_d
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ res = hostapd_ucode_sta_auth(hapd, sta);
|
||||||
|
+ if (res) {
|
||||||
|
+ resp = res;
|
||||||
|
+ goto fail;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
sta->flags &= ~WLAN_STA_PREAUTH;
|
||||||
|
ieee802_1x_notify_pre_auth(sta->eapol_sm, 0);
|
||||||
|
|
||||||
|
--- a/src/ap/sta_info.c
|
||||||
|
+++ b/src/ap/sta_info.c
|
||||||
|
@@ -474,6 +474,9 @@ void ap_free_sta(struct hostapd_data *ha
|
||||||
|
forced_memzero(sta->last_tk, WPA_TK_MAX_LEN);
|
||||||
|
#endif /* CONFIG_TESTING_OPTIONS */
|
||||||
|
|
||||||
|
+ if (sta->sae_pt)
|
||||||
|
+ sae_deinit_pt(sta->sae_pt);
|
||||||
|
+
|
||||||
|
os_free(sta);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1507,6 +1510,8 @@ void ap_sta_set_authorized_event(struct
|
||||||
|
#endif /* CONFIG_P2P */
|
||||||
|
const u8 *ip_ptr = NULL;
|
||||||
|
|
||||||
|
+ if (authorized)
|
||||||
|
+ hostapd_ucode_sta_connected(hapd, sta);
|
||||||
|
#ifdef CONFIG_P2P
|
||||||
|
if (hapd->p2p_group == NULL) {
|
||||||
|
if (sta->p2p_ie != NULL &&
|
||||||
|
--- a/src/ap/sta_info.h
|
||||||
|
+++ b/src/ap/sta_info.h
|
||||||
|
@@ -180,6 +180,9 @@ struct sta_info {
|
||||||
|
int vlan_id_bound; /* updated by ap_sta_bind_vlan() */
|
||||||
|
/* PSKs from RADIUS authentication server */
|
||||||
|
struct hostapd_sta_wpa_psk_short *psk;
|
||||||
|
+ struct sae_pt *sae_pt;
|
||||||
|
+ int use_sta_psk;
|
||||||
|
+ int psk_idx;
|
||||||
|
|
||||||
|
char *identity; /* User-Name from RADIUS */
|
||||||
|
char *radius_cui; /* Chargeable-User-Identity from RADIUS */
|
||||||
|
--- a/src/ap/wpa_auth_glue.c
|
||||||
|
+++ b/src/ap/wpa_auth_glue.c
|
||||||
|
@@ -400,6 +400,7 @@ static const u8 * hostapd_wpa_auth_get_p
|
||||||
|
struct sta_info *sta = ap_get_sta(hapd, addr);
|
||||||
|
const u8 *psk;
|
||||||
|
|
||||||
|
+ sta->psk_idx = 0;
|
||||||
|
if (vlan_id)
|
||||||
|
*vlan_id = 0;
|
||||||
|
if (psk_len)
|
||||||
|
@@ -446,13 +447,16 @@ static const u8 * hostapd_wpa_auth_get_p
|
||||||
|
* returned psk which should not be returned again.
|
||||||
|
* logic list (all hostapd_get_psk; all sta->psk)
|
||||||
|
*/
|
||||||
|
+ if (sta && sta->use_sta_psk)
|
||||||
|
+ psk = NULL;
|
||||||
|
if (sta && sta->psk && !psk) {
|
||||||
|
struct hostapd_sta_wpa_psk_short *pos;
|
||||||
|
+ int psk_idx = 1;
|
||||||
|
|
||||||
|
if (vlan_id)
|
||||||
|
*vlan_id = 0;
|
||||||
|
psk = sta->psk->psk;
|
||||||
|
- for (pos = sta->psk; pos; pos = pos->next) {
|
||||||
|
+ for (pos = sta->psk; pos; pos = pos->next, psk_idx++) {
|
||||||
|
if (pos->is_passphrase) {
|
||||||
|
if (pbkdf2_sha1(pos->passphrase,
|
||||||
|
hapd->conf->ssid.ssid,
|
||||||
|
@@ -469,6 +473,8 @@ static const u8 * hostapd_wpa_auth_get_p
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+ if (psk)
|
||||||
|
+ sta->psk_idx = psk_idx;
|
||||||
|
}
|
||||||
|
return psk;
|
||||||
|
}
|
||||||
|
|||||||
@ -9,6 +9,7 @@
|
|||||||
#include "ap_drv_ops.h"
|
#include "ap_drv_ops.h"
|
||||||
#include "dfs.h"
|
#include "dfs.h"
|
||||||
#include "acs.h"
|
#include "acs.h"
|
||||||
|
#include "ieee802_11_auth.h"
|
||||||
#include <libubox/uloop.h>
|
#include <libubox/uloop.h>
|
||||||
|
|
||||||
static uc_resource_type_t *global_type, *bss_type, *iface_type;
|
static uc_resource_type_t *global_type, *bss_type, *iface_type;
|
||||||
@ -711,6 +712,110 @@ out:
|
|||||||
return ret ? NULL : ucv_boolean_new(true);
|
return ret ? NULL : ucv_boolean_new(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int hostapd_ucode_sta_auth(struct hostapd_data *hapd, struct sta_info *sta)
|
||||||
|
{
|
||||||
|
char addr[sizeof(MACSTR)];
|
||||||
|
uc_value_t *val, *cur;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (wpa_ucode_call_prepare("sta_auth"))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
uc_value_push(ucv_get(ucv_string_new(hapd->conf->iface)));
|
||||||
|
|
||||||
|
snprintf(addr, sizeof(addr), MACSTR, MAC2STR(sta->addr));
|
||||||
|
val = ucv_string_new(addr);
|
||||||
|
uc_value_push(ucv_get(val));
|
||||||
|
|
||||||
|
val = wpa_ucode_call(2);
|
||||||
|
|
||||||
|
cur = ucv_object_get(val, "psk", NULL);
|
||||||
|
if (ucv_type(cur) == UC_ARRAY) {
|
||||||
|
struct hostapd_sta_wpa_psk_short *p, **next;
|
||||||
|
size_t len = ucv_array_length(cur);
|
||||||
|
|
||||||
|
next = &sta->psk;
|
||||||
|
hostapd_free_psk_list(*next);
|
||||||
|
*next = NULL;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < len; i++) {
|
||||||
|
uc_value_t *cur_psk;
|
||||||
|
const char *str;
|
||||||
|
size_t str_len;
|
||||||
|
|
||||||
|
cur_psk = ucv_array_get(cur, i);
|
||||||
|
str = ucv_string_get(cur_psk);
|
||||||
|
str_len = strlen(str);
|
||||||
|
if (!str || str_len < 8 || str_len > 64)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
p = os_zalloc(sizeof(*p));
|
||||||
|
if (len == 64) {
|
||||||
|
if (hexstr2bin(str, p->psk, PMK_LEN) < 0) {
|
||||||
|
free(p);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
p->is_passphrase = 1;
|
||||||
|
memcpy(p->passphrase, str, str_len + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
*next = p;
|
||||||
|
next = &p->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cur = ucv_object_get(val, "force_psk", NULL);
|
||||||
|
sta->use_sta_psk = ucv_is_truish(cur);
|
||||||
|
|
||||||
|
cur = ucv_object_get(val, "status", NULL);
|
||||||
|
if (ucv_type(cur) == UC_INTEGER)
|
||||||
|
ret = ucv_int64_get(cur);
|
||||||
|
|
||||||
|
ucv_put(val);
|
||||||
|
ucv_gc(vm);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void hostapd_ucode_sta_connected(struct hostapd_data *hapd, struct sta_info *sta)
|
||||||
|
{
|
||||||
|
char addr[sizeof(MACSTR)];
|
||||||
|
uc_value_t *val, *cur;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (wpa_ucode_call_prepare("sta_connected"))
|
||||||
|
return;
|
||||||
|
|
||||||
|
uc_value_push(ucv_get(ucv_string_new(hapd->conf->iface)));
|
||||||
|
|
||||||
|
snprintf(addr, sizeof(addr), MACSTR, MAC2STR(sta->addr));
|
||||||
|
val = ucv_string_new(addr);
|
||||||
|
uc_value_push(ucv_get(val));
|
||||||
|
|
||||||
|
val = ucv_object_new(vm);
|
||||||
|
if (sta->psk_idx)
|
||||||
|
ucv_object_add(val, "psk_idx", ucv_int64_new(sta->psk_idx - 1));
|
||||||
|
uc_value_push(ucv_get(val));
|
||||||
|
|
||||||
|
val = wpa_ucode_call(3);
|
||||||
|
if (ucv_type(val) != UC_OBJECT)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
cur = ucv_object_get(val, "vlan", NULL);
|
||||||
|
if (ucv_type(cur) == UC_INTEGER) {
|
||||||
|
struct vlan_description vdesc = {
|
||||||
|
.notempty = 1,
|
||||||
|
.untagged = ucv_int64_get(cur),
|
||||||
|
};
|
||||||
|
|
||||||
|
ap_sta_set_vlan(hapd, sta, &vdesc);
|
||||||
|
ap_sta_bind_vlan(hapd, sta);
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
ucv_put(val);
|
||||||
|
}
|
||||||
|
|
||||||
int hostapd_ucode_init(struct hapd_interfaces *ifaces)
|
int hostapd_ucode_init(struct hapd_interfaces *ifaces)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -25,6 +25,8 @@ void hostapd_ucode_free(void);
|
|||||||
void hostapd_ucode_free_iface(struct hostapd_iface *iface);
|
void hostapd_ucode_free_iface(struct hostapd_iface *iface);
|
||||||
void hostapd_ucode_free_bss(struct hostapd_data *hapd);
|
void hostapd_ucode_free_bss(struct hostapd_data *hapd);
|
||||||
void hostapd_ucode_bss_cb(struct hostapd_data *hapd, const char *type);
|
void hostapd_ucode_bss_cb(struct hostapd_data *hapd, const char *type);
|
||||||
|
int hostapd_ucode_sta_auth(struct hostapd_data *hapd, struct sta_info *sta);
|
||||||
|
void hostapd_ucode_sta_connected(struct hostapd_data *hapd, struct sta_info *sta);
|
||||||
|
|
||||||
#ifdef CONFIG_APUP
|
#ifdef CONFIG_APUP
|
||||||
void hostapd_ucode_apup_newpeer(struct hostapd_data *hapd, const char *ifname);
|
void hostapd_ucode_apup_newpeer(struct hostapd_data *hapd, const char *ifname);
|
||||||
@ -45,6 +47,13 @@ static inline void hostapd_ucode_free_iface(struct hostapd_iface *iface)
|
|||||||
static inline void hostapd_ucode_bss_cb(struct hostapd_data *hapd, const char *type)
|
static inline void hostapd_ucode_bss_cb(struct hostapd_data *hapd, const char *type)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
static inline int hostapd_ucode_sta_auth(struct hostapd_data *hapd, struct sta_info *sta)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
static inline void hostapd_ucode_sta_connected(struct hostapd_data *hapd, struct sta_info *sta)
|
||||||
|
{
|
||||||
|
}
|
||||||
static inline void hostapd_ucode_free_bss(struct hostapd_data *hapd)
|
static inline void hostapd_ucode_free_bss(struct hostapd_data *hapd)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
#include "ap/hostapd.h"
|
#include "ap/hostapd.h"
|
||||||
#include "wpa_supplicant_i.h"
|
#include "wpa_supplicant_i.h"
|
||||||
#include "wps_supplicant.h"
|
#include "wps_supplicant.h"
|
||||||
|
#include "ctrl_iface.h"
|
||||||
#include "bss.h"
|
#include "bss.h"
|
||||||
#include "ucode.h"
|
#include "ucode.h"
|
||||||
|
|
||||||
@ -255,6 +256,31 @@ uc_wpas_iface_status(uc_vm_t *vm, size_t nargs)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uc_value_t *
|
||||||
|
uc_wpas_iface_ctrl(uc_vm_t *vm, size_t nargs)
|
||||||
|
{
|
||||||
|
struct wpa_supplicant *wpa_s = uc_fn_thisval("wpas.iface");
|
||||||
|
uc_value_t *arg = uc_fn_arg(0);
|
||||||
|
size_t reply_len;
|
||||||
|
uc_value_t *ret;
|
||||||
|
char *reply;
|
||||||
|
|
||||||
|
if (!wpa_s || ucv_type(arg) != UC_STRING)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
reply = wpa_supplicant_ctrl_iface_process(wpa_s, ucv_string_get(arg), &reply_len);
|
||||||
|
if (reply_len < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (reply_len && reply[reply_len - 1] == '\n')
|
||||||
|
reply_len--;
|
||||||
|
|
||||||
|
ret = ucv_string_new_length(reply, reply_len);
|
||||||
|
free(reply);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int wpas_ucode_init(struct wpa_global *gl)
|
int wpas_ucode_init(struct wpa_global *gl)
|
||||||
{
|
{
|
||||||
static const uc_function_list_t global_fns[] = {
|
static const uc_function_list_t global_fns[] = {
|
||||||
@ -266,6 +292,7 @@ int wpas_ucode_init(struct wpa_global *gl)
|
|||||||
};
|
};
|
||||||
static const uc_function_list_t iface_fns[] = {
|
static const uc_function_list_t iface_fns[] = {
|
||||||
{ "status", uc_wpas_iface_status },
|
{ "status", uc_wpas_iface_status },
|
||||||
|
{ "ctrl", uc_wpas_iface_ctrl },
|
||||||
};
|
};
|
||||||
uc_value_t *data, *proto;
|
uc_value_t *data, *proto;
|
||||||
|
|
||||||
|
|||||||
@ -9,12 +9,12 @@ include $(TOPDIR)/rules.mk
|
|||||||
include $(INCLUDE_DIR)/kernel.mk
|
include $(INCLUDE_DIR)/kernel.mk
|
||||||
|
|
||||||
PKG_NAME:=iptables
|
PKG_NAME:=iptables
|
||||||
PKG_VERSION:=1.8.8
|
PKG_VERSION:=1.8.10
|
||||||
PKG_RELEASE:=3
|
PKG_RELEASE:=1
|
||||||
|
|
||||||
PKG_SOURCE_URL:=https://netfilter.org/projects/iptables/files
|
PKG_SOURCE_URL:=https://netfilter.org/projects/iptables/files
|
||||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
|
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
|
||||||
PKG_HASH:=71c75889dc710676631553eb1511da0177bbaaf1b551265b912d236c3f51859f
|
PKG_HASH:=5cc255c189356e317d070755ce9371eb63a1b783c34498fb8c30264f3cc59c9c
|
||||||
|
|
||||||
PKG_FIXUP:=autoreconf
|
PKG_FIXUP:=autoreconf
|
||||||
PKG_FLAGS:=nonshared
|
PKG_FLAGS:=nonshared
|
||||||
|
|||||||
@ -334,7 +334,7 @@ Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
|
|||||||
static int connmark_tg_xlate(struct xt_xlate *xl,
|
static int connmark_tg_xlate(struct xt_xlate *xl,
|
||||||
const struct xt_xlate_tg_params *params)
|
const struct xt_xlate_tg_params *params)
|
||||||
{
|
{
|
||||||
@@ -639,6 +876,66 @@ static int connmark_tg_xlate_v2(struct x
|
@@ -644,6 +881,66 @@ static int connmark_tg_xlate_v2(struct x
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -401,7 +401,7 @@ Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
|
|||||||
static struct xtables_target connmark_tg_reg[] = {
|
static struct xtables_target connmark_tg_reg[] = {
|
||||||
{
|
{
|
||||||
.family = NFPROTO_UNSPEC,
|
.family = NFPROTO_UNSPEC,
|
||||||
@@ -687,6 +984,22 @@ static struct xtables_target connmark_tg
|
@@ -692,6 +989,22 @@ static struct xtables_target connmark_tg
|
||||||
.x6_options = connmark_tg_opts_v2,
|
.x6_options = connmark_tg_opts_v2,
|
||||||
.xlate = connmark_tg_xlate_v2,
|
.xlate = connmark_tg_xlate_v2,
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,144 +0,0 @@
|
|||||||
From f319389525b066b7dc6d389c88f16a0df3b8f189 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Nick Hainke <vincent@systemli.org>
|
|
||||||
Date: Mon, 16 May 2022 18:16:41 +0200
|
|
||||||
Subject: treewide: use uint* instead of u_int*
|
|
||||||
|
|
||||||
Gcc complains about missing types. Some commits introduced u_int* instead
|
|
||||||
of uint*. Use uint treewide.
|
|
||||||
|
|
||||||
Fixes errors in the form of:
|
|
||||||
In file included from xtables-legacy-multi.c:5:
|
|
||||||
xshared.h:83:56: error: unknown type name 'u_int16_t'; did you mean 'uint16_t'?
|
|
||||||
83 | set_option(unsigned int *options, unsigned int option, u_int16_t *invflg,
|
|
||||||
| ^~~~~~~~~
|
|
||||||
| uint16_t
|
|
||||||
make[6]: *** [Makefile:712: xtables_legacy_multi-xtables-legacy-multi.o] Error 1
|
|
||||||
|
|
||||||
Avoid libipq API breakage by adjusting libipq.h include accordingly. For
|
|
||||||
arpt_mangle.h kernel uAPI header, apply same change as in kernel commit
|
|
||||||
e91ded8db5747 ("uapi: netfilter_arp: use __u8 instead of u_int8_t").
|
|
||||||
|
|
||||||
Signed-off-by: Nick Hainke <vincent@systemli.org>
|
|
||||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
||||||
---
|
|
||||||
extensions/libxt_conntrack.c | 2 +-
|
|
||||||
include/libipq/libipq.h | 8 ++++----
|
|
||||||
include/libiptc/libxtc.h | 2 +-
|
|
||||||
include/linux/netfilter_arp/arpt_mangle.h | 2 +-
|
|
||||||
iptables/xshared.c | 2 +-
|
|
||||||
iptables/xshared.h | 2 +-
|
|
||||||
libipq/ipq_create_handle.3 | 2 +-
|
|
||||||
libipq/ipq_set_mode.3 | 2 +-
|
|
||||||
8 files changed, 11 insertions(+), 11 deletions(-)
|
|
||||||
|
|
||||||
--- a/extensions/libxt_conntrack.c
|
|
||||||
+++ b/extensions/libxt_conntrack.c
|
|
||||||
@@ -778,7 +778,7 @@ matchinfo_print(const void *ip, const st
|
|
||||||
|
|
||||||
static void
|
|
||||||
conntrack_dump_ports(const char *prefix, const char *opt,
|
|
||||||
- u_int16_t port_low, u_int16_t port_high)
|
|
||||||
+ uint16_t port_low, uint16_t port_high)
|
|
||||||
{
|
|
||||||
if (port_high == 0 || port_low == port_high)
|
|
||||||
printf(" %s%s %u", prefix, opt, port_low);
|
|
||||||
--- a/include/libipq/libipq.h
|
|
||||||
+++ b/include/libipq/libipq.h
|
|
||||||
@@ -24,7 +24,7 @@
|
|
||||||
#include <errno.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
-#include <sys/types.h>
|
|
||||||
+#include <stdint.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <sys/uio.h>
|
|
||||||
#include <asm/types.h>
|
|
||||||
@@ -48,19 +48,19 @@ typedef unsigned long ipq_id_t;
|
|
||||||
struct ipq_handle
|
|
||||||
{
|
|
||||||
int fd;
|
|
||||||
- u_int8_t blocking;
|
|
||||||
+ uint8_t blocking;
|
|
||||||
struct sockaddr_nl local;
|
|
||||||
struct sockaddr_nl peer;
|
|
||||||
};
|
|
||||||
|
|
||||||
-struct ipq_handle *ipq_create_handle(u_int32_t flags, u_int32_t protocol);
|
|
||||||
+struct ipq_handle *ipq_create_handle(uint32_t flags, uint32_t protocol);
|
|
||||||
|
|
||||||
int ipq_destroy_handle(struct ipq_handle *h);
|
|
||||||
|
|
||||||
ssize_t ipq_read(const struct ipq_handle *h,
|
|
||||||
unsigned char *buf, size_t len, int timeout);
|
|
||||||
|
|
||||||
-int ipq_set_mode(const struct ipq_handle *h, u_int8_t mode, size_t len);
|
|
||||||
+int ipq_set_mode(const struct ipq_handle *h, uint8_t mode, size_t len);
|
|
||||||
|
|
||||||
ipq_packet_msg_t *ipq_get_packet(const unsigned char *buf);
|
|
||||||
|
|
||||||
--- a/include/libiptc/libxtc.h
|
|
||||||
+++ b/include/libiptc/libxtc.h
|
|
||||||
@@ -10,7 +10,7 @@ extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef XT_MIN_ALIGN
|
|
||||||
-/* xt_entry has pointers and u_int64_t's in it, so if you align to
|
|
||||||
+/* xt_entry has pointers and uint64_t's in it, so if you align to
|
|
||||||
it, you'll also align to any crazy matches and targets someone
|
|
||||||
might write */
|
|
||||||
#define XT_MIN_ALIGN (__alignof__(struct xt_entry))
|
|
||||||
--- a/include/linux/netfilter_arp/arpt_mangle.h
|
|
||||||
+++ b/include/linux/netfilter_arp/arpt_mangle.h
|
|
||||||
@@ -13,7 +13,7 @@ struct arpt_mangle
|
|
||||||
union {
|
|
||||||
struct in_addr tgt_ip;
|
|
||||||
} u_t;
|
|
||||||
- u_int8_t flags;
|
|
||||||
+ __u8 flags;
|
|
||||||
int target;
|
|
||||||
};
|
|
||||||
|
|
||||||
--- a/iptables/xshared.c
|
|
||||||
+++ b/iptables/xshared.c
|
|
||||||
@@ -1025,7 +1025,7 @@ static const int inverse_for_options[NUM
|
|
||||||
};
|
|
||||||
|
|
||||||
void
|
|
||||||
-set_option(unsigned int *options, unsigned int option, u_int16_t *invflg,
|
|
||||||
+set_option(unsigned int *options, unsigned int option, uint16_t *invflg,
|
|
||||||
bool invert)
|
|
||||||
{
|
|
||||||
if (*options & option)
|
|
||||||
--- a/iptables/xshared.h
|
|
||||||
+++ b/iptables/xshared.h
|
|
||||||
@@ -80,7 +80,7 @@ struct xtables_target;
|
|
||||||
#define IPT_INV_ARPHRD 0x0800
|
|
||||||
|
|
||||||
void
|
|
||||||
-set_option(unsigned int *options, unsigned int option, u_int16_t *invflg,
|
|
||||||
+set_option(unsigned int *options, unsigned int option, uint16_t *invflg,
|
|
||||||
bool invert);
|
|
||||||
|
|
||||||
/**
|
|
||||||
--- a/libipq/ipq_create_handle.3
|
|
||||||
+++ b/libipq/ipq_create_handle.3
|
|
||||||
@@ -24,7 +24,7 @@ ipq_create_handle, ipq_destroy_handle \(
|
|
||||||
.br
|
|
||||||
.B #include <libipq.h>
|
|
||||||
.sp
|
|
||||||
-.BI "struct ipq_handle *ipq_create_handle(u_int32_t " flags ", u_int32_t " protocol ");"
|
|
||||||
+.BI "struct ipq_handle *ipq_create_handle(uint32_t " flags ", uint32_t " protocol ");"
|
|
||||||
.br
|
|
||||||
.BI "int ipq_destroy_handle(struct ipq_handle *" h );
|
|
||||||
.SH DESCRIPTION
|
|
||||||
--- a/libipq/ipq_set_mode.3
|
|
||||||
+++ b/libipq/ipq_set_mode.3
|
|
||||||
@@ -24,7 +24,7 @@ ipq_set_mode \(em set the ip_queue queui
|
|
||||||
.br
|
|
||||||
.B #include <libipq.h>
|
|
||||||
.sp
|
|
||||||
-.BI "int ipq_set_mode(const struct ipq_handle *" h ", u_int8_t " mode ", size_t " range );
|
|
||||||
+.BI "int ipq_set_mode(const struct ipq_handle *" h ", uint8_t " mode ", size_t " range );
|
|
||||||
.SH DESCRIPTION
|
|
||||||
The
|
|
||||||
.B ipq_set_mode
|
|
||||||
@ -1,60 +0,0 @@
|
|||||||
From 0e7cf0ad306cdf95dc3c28d15a254532206a888e Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <phil@nwl.cc>
|
|
||||||
Date: Wed, 18 May 2022 16:04:09 +0200
|
|
||||||
Subject: Revert "fix build for missing ETH_ALEN definition"
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
This reverts commit c5d9a723b5159a28f547b577711787295a14fd84 as it broke
|
|
||||||
compiling against musl libc. Might be a bug in the latter, but for the
|
|
||||||
time being try to please both by avoiding the include and instead
|
|
||||||
defining ETH_ALEN if unset.
|
|
||||||
|
|
||||||
While being at it, move netinet/ether.h include up.
|
|
||||||
|
|
||||||
Fixes: 1bdb5535f561a ("libxtables: Extend MAC address printing/parsing support")
|
|
||||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
||||||
Reviewed-by: Maciej Żenczykowski <maze@google.com>
|
|
||||||
---
|
|
||||||
libxtables/xtables.c | 8 +++++---
|
|
||||||
1 file changed, 5 insertions(+), 3 deletions(-)
|
|
||||||
|
|
||||||
--- a/libxtables/xtables.c
|
|
||||||
+++ b/libxtables/xtables.c
|
|
||||||
@@ -28,6 +28,7 @@
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
+#include <netinet/ether.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/statfs.h>
|
|
||||||
@@ -45,7 +46,6 @@
|
|
||||||
|
|
||||||
#include <xtables.h>
|
|
||||||
#include <limits.h> /* INT_MAX in ip_tables.h/ip6_tables.h */
|
|
||||||
-#include <linux/if_ether.h> /* ETH_ALEN */
|
|
||||||
#include <linux/netfilter_ipv4/ip_tables.h>
|
|
||||||
#include <linux/netfilter_ipv6/ip6_tables.h>
|
|
||||||
#include <libiptc/libxtc.h>
|
|
||||||
@@ -72,6 +72,10 @@
|
|
||||||
#define PROC_SYS_MODPROBE "/proc/sys/kernel/modprobe"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
+#ifndef ETH_ALEN
|
|
||||||
+#define ETH_ALEN 6
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
/* we need this for ip6?tables-restore. ip6?tables-restore.c sets line to the
|
|
||||||
* current line of the input file, in order to give a more precise error
|
|
||||||
* message. ip6?tables itself doesn't need this, so it is initialized to the
|
|
||||||
@@ -2245,8 +2249,6 @@ void xtables_print_num(uint64_t number,
|
|
||||||
printf(FMT("%4lluT ","%lluT "), (unsigned long long)number);
|
|
||||||
}
|
|
||||||
|
|
||||||
-#include <netinet/ether.h>
|
|
||||||
-
|
|
||||||
static const unsigned char mac_type_unicast[ETH_ALEN] = {};
|
|
||||||
static const unsigned char msk_type_unicast[ETH_ALEN] = {1};
|
|
||||||
static const unsigned char mac_type_multicast[ETH_ALEN] = {1};
|
|
||||||
@ -1,23 +0,0 @@
|
|||||||
From b72eb12ea5a61df0655ad99d5048994e916be83a Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <phil@nwl.cc>
|
|
||||||
Date: Fri, 13 May 2022 16:51:58 +0200
|
|
||||||
Subject: [PATCH] xshared: Fix build for -Werror=format-security
|
|
||||||
|
|
||||||
Gcc complains about the omitted format string.
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
||||||
---
|
|
||||||
iptables/xshared.c | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
--- a/iptables/xshared.c
|
|
||||||
+++ b/iptables/xshared.c
|
|
||||||
@@ -1307,7 +1307,7 @@ static void check_empty_interface(struct
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (args->family != NFPROTO_ARP)
|
|
||||||
- xtables_error(PARAMETER_PROBLEM, msg);
|
|
||||||
+ xtables_error(PARAMETER_PROBLEM, "%s", msg);
|
|
||||||
|
|
||||||
fprintf(stderr, "%s", msg);
|
|
||||||
}
|
|
||||||
@ -1,28 +0,0 @@
|
|||||||
From 0ebf52fc951b2a4d98a166afb34af4f364bbeece Mon Sep 17 00:00:00 2001
|
|
||||||
From: Ben Brown <ben@demerara.io>
|
|
||||||
Date: Wed, 25 May 2022 16:26:13 +0100
|
|
||||||
Subject: build: Fix error during out of tree build
|
|
||||||
|
|
||||||
Fixes the following error:
|
|
||||||
|
|
||||||
../../libxtables/xtables.c:52:10: fatal error: libiptc/linux_list.h: No such file or directory
|
|
||||||
52 | #include <libiptc/linux_list.h>
|
|
||||||
|
|
||||||
Fixes: f58b0d7406451 ("libxtables: Implement notargets hash table")
|
|
||||||
Signed-off-by: Ben Brown <ben@demerara.io>
|
|
||||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
||||||
---
|
|
||||||
libxtables/Makefile.am | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
--- a/libxtables/Makefile.am
|
|
||||||
+++ b/libxtables/Makefile.am
|
|
||||||
@@ -1,7 +1,7 @@
|
|
||||||
# -*- Makefile -*-
|
|
||||||
|
|
||||||
AM_CFLAGS = ${regular_CFLAGS}
|
|
||||||
-AM_CPPFLAGS = ${regular_CPPFLAGS} -I${top_builddir}/include -I${top_srcdir}/include -I${top_srcdir}/iptables ${kinclude_CPPFLAGS}
|
|
||||||
+AM_CPPFLAGS = ${regular_CPPFLAGS} -I${top_builddir}/include -I${top_srcdir}/include -I${top_srcdir}/iptables -I${top_srcdir} ${kinclude_CPPFLAGS}
|
|
||||||
|
|
||||||
lib_LTLIBRARIES = libxtables.la
|
|
||||||
libxtables_la_SOURCES = xtables.c xtoptions.c getethertype.c
|
|
||||||
@ -1,82 +0,0 @@
|
|||||||
From ef108943f69a6e20533d58823740d3f0534ea8ec Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <phil@nwl.cc>
|
|
||||||
Date: Wed, 1 Jun 2022 19:15:06 +0200
|
|
||||||
Subject: libxtables: Unexport init_extensions*() declarations
|
|
||||||
|
|
||||||
The functions are used for static builds to initialize extensions after
|
|
||||||
libxtables init. Regular library users should not need them, but the
|
|
||||||
empty declarations introduced in #else case (and therefore present in
|
|
||||||
user's env) may clash with existing symbol names.
|
|
||||||
|
|
||||||
Avoid problems and guard the whole block declaring the function
|
|
||||||
prototypes and mangling extensions' _init functions by XTABLES_INTERNAL.
|
|
||||||
|
|
||||||
Reported-by: Nick Hainke <vincent@systemli.org>
|
|
||||||
Fixes: 6c689b639cf8e ("Simplify static build extension loading")
|
|
||||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
||||||
---
|
|
||||||
include/xtables.h | 44 ++++++++++++++++++++++----------------------
|
|
||||||
1 file changed, 22 insertions(+), 22 deletions(-)
|
|
||||||
|
|
||||||
--- a/include/xtables.h
|
|
||||||
+++ b/include/xtables.h
|
|
||||||
@@ -585,27 +585,6 @@ static inline void xtables_print_mark_ma
|
|
||||||
xtables_print_val_mask(mark, mask, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
-#if defined(ALL_INCLUSIVE) || defined(NO_SHARED_LIBS)
|
|
||||||
-# ifdef _INIT
|
|
||||||
-# undef _init
|
|
||||||
-# define _init _INIT
|
|
||||||
-# endif
|
|
||||||
- extern void init_extensions(void);
|
|
||||||
- extern void init_extensions4(void);
|
|
||||||
- extern void init_extensions6(void);
|
|
||||||
- extern void init_extensionsa(void);
|
|
||||||
- extern void init_extensionsb(void);
|
|
||||||
-#else
|
|
||||||
-# define _init __attribute__((constructor)) _INIT
|
|
||||||
-# define EMPTY_FUNC_DEF(x) static inline void x(void) {}
|
|
||||||
- EMPTY_FUNC_DEF(init_extensions)
|
|
||||||
- EMPTY_FUNC_DEF(init_extensions4)
|
|
||||||
- EMPTY_FUNC_DEF(init_extensions6)
|
|
||||||
- EMPTY_FUNC_DEF(init_extensionsa)
|
|
||||||
- EMPTY_FUNC_DEF(init_extensionsb)
|
|
||||||
-# undef EMPTY_FUNC_DEF
|
|
||||||
-#endif
|
|
||||||
-
|
|
||||||
extern const struct xtables_pprot xtables_chain_protos[];
|
|
||||||
extern uint16_t xtables_parse_protocol(const char *s);
|
|
||||||
|
|
||||||
@@ -663,9 +642,30 @@ void xtables_announce_chain(const char *
|
|
||||||
# define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x)))
|
|
||||||
# endif
|
|
||||||
|
|
||||||
+#if defined(ALL_INCLUSIVE) || defined(NO_SHARED_LIBS)
|
|
||||||
+# ifdef _INIT
|
|
||||||
+# undef _init
|
|
||||||
+# define _init _INIT
|
|
||||||
+# endif
|
|
||||||
+ extern void init_extensions(void);
|
|
||||||
+ extern void init_extensions4(void);
|
|
||||||
+ extern void init_extensions6(void);
|
|
||||||
+ extern void init_extensionsa(void);
|
|
||||||
+ extern void init_extensionsb(void);
|
|
||||||
+#else
|
|
||||||
+# define _init __attribute__((constructor)) _INIT
|
|
||||||
+# define EMPTY_FUNC_DEF(x) static inline void x(void) {}
|
|
||||||
+ EMPTY_FUNC_DEF(init_extensions)
|
|
||||||
+ EMPTY_FUNC_DEF(init_extensions4)
|
|
||||||
+ EMPTY_FUNC_DEF(init_extensions6)
|
|
||||||
+ EMPTY_FUNC_DEF(init_extensionsa)
|
|
||||||
+ EMPTY_FUNC_DEF(init_extensionsb)
|
|
||||||
+# undef EMPTY_FUNC_DEF
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
extern void _init(void);
|
|
||||||
|
|
||||||
-#endif
|
|
||||||
+#endif /* XTABLES_INTERNAL */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} /* extern "C" */
|
|
||||||
@ -1,40 +0,0 @@
|
|||||||
From da5b32fb4656ab69fe1156eb7e36c7c961839e8a Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <phil@nwl.cc>
|
|
||||||
Date: Wed, 8 Jun 2022 13:45:13 +0200
|
|
||||||
Subject: [PATCH] extensions: string: Review parse_string() function
|
|
||||||
|
|
||||||
* Compare against sizeof(info->pattern) which is more clear than having
|
|
||||||
to know that this buffer is of size XT_STRING_MAX_PATTERN_SIZE
|
|
||||||
|
|
||||||
* Invert the check and error early to reduce indenting
|
|
||||||
|
|
||||||
* Pass info->patlen to memcpy() to avoid reading past end of 's'
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
||||||
---
|
|
||||||
extensions/libxt_string.c | 13 ++++++-------
|
|
||||||
1 file changed, 6 insertions(+), 7 deletions(-)
|
|
||||||
|
|
||||||
--- a/extensions/libxt_string.c
|
|
||||||
+++ b/extensions/libxt_string.c
|
|
||||||
@@ -78,14 +78,13 @@ static void string_init(struct xt_entry_
|
|
||||||
|
|
||||||
static void
|
|
||||||
parse_string(const char *s, struct xt_string_info *info)
|
|
||||||
-{
|
|
||||||
+{
|
|
||||||
/* xt_string does not need \0 at the end of the pattern */
|
|
||||||
- if (strlen(s) <= XT_STRING_MAX_PATTERN_SIZE) {
|
|
||||||
- memcpy(info->pattern, s, XT_STRING_MAX_PATTERN_SIZE);
|
|
||||||
- info->patlen = strnlen(s, XT_STRING_MAX_PATTERN_SIZE);
|
|
||||||
- return;
|
|
||||||
- }
|
|
||||||
- xtables_error(PARAMETER_PROBLEM, "STRING too long \"%s\"", s);
|
|
||||||
+ if (strlen(s) > sizeof(info->pattern))
|
|
||||||
+ xtables_error(PARAMETER_PROBLEM, "STRING too long \"%s\"", s);
|
|
||||||
+
|
|
||||||
+ info->patlen = strnlen(s, sizeof(info->pattern));
|
|
||||||
+ memcpy(info->pattern, s, info->patlen);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
@ -1,6 +1,6 @@
|
|||||||
--- a/libxtables/xtables.c
|
--- a/libxtables/xtables.c
|
||||||
+++ b/libxtables/xtables.c
|
+++ b/libxtables/xtables.c
|
||||||
@@ -1093,12 +1093,6 @@ void xtables_register_match(struct xtabl
|
@@ -1095,12 +1095,6 @@ void xtables_register_match(struct xtabl
|
||||||
struct xtables_match **pos;
|
struct xtables_match **pos;
|
||||||
bool seen_myself = false;
|
bool seen_myself = false;
|
||||||
|
|
||||||
@ -13,7 +13,7 @@
|
|||||||
if (me->version == NULL) {
|
if (me->version == NULL) {
|
||||||
fprintf(stderr, "%s: match %s<%u> is missing a version\n",
|
fprintf(stderr, "%s: match %s<%u> is missing a version\n",
|
||||||
xt_params->program_name, me->name, me->revision);
|
xt_params->program_name, me->name, me->revision);
|
||||||
@@ -1277,12 +1271,6 @@ void xtables_register_target(struct xtab
|
@@ -1279,12 +1273,6 @@ void xtables_register_target(struct xtab
|
||||||
struct xtables_target **pos;
|
struct xtables_target **pos;
|
||||||
bool seen_myself = false;
|
bool seen_myself = false;
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
--- a/libxtables/xtables.c
|
--- a/libxtables/xtables.c
|
||||||
+++ b/libxtables/xtables.c
|
+++ b/libxtables/xtables.c
|
||||||
@@ -476,7 +476,7 @@ char *xtables_strdup(const char *s)
|
@@ -475,7 +475,7 @@ char *xtables_strdup(const char *s)
|
||||||
return dup;
|
return dup;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -9,7 +9,7 @@
|
|||||||
{
|
{
|
||||||
int procfile;
|
int procfile;
|
||||||
char *ret;
|
char *ret;
|
||||||
@@ -511,6 +511,7 @@ static char *get_modprobe(void)
|
@@ -505,6 +505,7 @@ static char *get_modprobe(void)
|
||||||
|
|
||||||
int xtables_insmod(const char *modname, const char *modprobe, bool quiet)
|
int xtables_insmod(const char *modname, const char *modprobe, bool quiet)
|
||||||
{
|
{
|
||||||
@ -17,7 +17,7 @@
|
|||||||
char *buf = NULL;
|
char *buf = NULL;
|
||||||
char *argv[4];
|
char *argv[4];
|
||||||
int status;
|
int status;
|
||||||
@@ -545,6 +546,7 @@ int xtables_insmod(const char *modname,
|
@@ -539,6 +540,7 @@ int xtables_insmod(const char *modname,
|
||||||
free(buf);
|
free(buf);
|
||||||
if (WIFEXITED(status) && WEXITSTATUS(status) == 0)
|
if (WIFEXITED(status) && WEXITSTATUS(status) == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
--- a/iptables/xtables-legacy-multi.c
|
--- a/iptables/xtables-legacy-multi.c
|
||||||
+++ b/iptables/xtables-legacy-multi.c
|
+++ b/iptables/xtables-legacy-multi.c
|
||||||
@@ -32,8 +32,10 @@ static const struct subcommand multi_sub
|
@@ -28,8 +28,10 @@ static const struct subcommand multi_sub
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -60,7 +60,7 @@
|
|||||||
|
|
||||||
.SECONDARY:
|
.SECONDARY:
|
||||||
|
|
||||||
@@ -163,11 +183,11 @@ libext4.a: initext4.o ${libext4_objs}
|
@@ -170,11 +190,11 @@ libext4.a: initext4.o ${libext4_objs}
|
||||||
libext6.a: initext6.o ${libext6_objs}
|
libext6.a: initext6.o ${libext6_objs}
|
||||||
${AM_VERBOSE_AR} ${AR} crs $@ $^;
|
${AM_VERBOSE_AR} ${AR} crs $@ $^;
|
||||||
|
|
||||||
@ -75,5 +75,5 @@
|
|||||||
+initext4_func := $(addprefix ipt_,${pf4_build_static})
|
+initext4_func := $(addprefix ipt_,${pf4_build_static})
|
||||||
+initext6_func := $(addprefix ip6t_,${pf6_build_static})
|
+initext6_func := $(addprefix ip6t_,${pf6_build_static})
|
||||||
|
|
||||||
.initext.dd: FORCE
|
initexts := ext exta extb ext4 ext6
|
||||||
@echo "${initext_func}" >$@.tmp; \
|
initext_depfiles = $(patsubst %,.init%.dd,${initexts})
|
||||||
|
|||||||
@ -9,7 +9,7 @@
|
|||||||
targets_install :=
|
targets_install :=
|
||||||
libext_objs := ${pfx_objs}
|
libext_objs := ${pfx_objs}
|
||||||
libext_ebt_objs := ${pfb_objs}
|
libext_ebt_objs := ${pfb_objs}
|
||||||
@@ -132,7 +132,7 @@ clean:
|
@@ -133,7 +133,7 @@ clean:
|
||||||
distclean: clean
|
distclean: clean
|
||||||
|
|
||||||
init%.o: init%.c
|
init%.o: init%.c
|
||||||
@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
-include .*.d
|
-include .*.d
|
||||||
|
|
||||||
@@ -166,22 +166,22 @@ xt_connlabel_LIBADD = @libnetfilter_conn
|
@@ -173,22 +173,22 @@ xt_connlabel_LIBADD = @libnetfilter_conn
|
||||||
# handling code in the Makefiles.
|
# handling code in the Makefiles.
|
||||||
#
|
#
|
||||||
lib%.o: ${srcdir}/lib%.c
|
lib%.o: ${srcdir}/lib%.c
|
||||||
@ -54,49 +54,47 @@
|
|||||||
initextb_func := $(addprefix ebt_,${pfb_build_static})
|
initextb_func := $(addprefix ebt_,${pfb_build_static})
|
||||||
--- a/iptables/Makefile.am
|
--- a/iptables/Makefile.am
|
||||||
+++ b/iptables/Makefile.am
|
+++ b/iptables/Makefile.am
|
||||||
@@ -7,19 +7,22 @@ BUILT_SOURCES =
|
@@ -7,7 +7,7 @@ AM_LDFLAGS = ${regular_LDFLAGS}
|
||||||
|
BUILT_SOURCES =
|
||||||
|
|
||||||
xtables_legacy_multi_SOURCES = xtables-legacy-multi.c iptables-xml.c
|
common_sources = iptables-xml.c xtables-multi.h xshared.c xshared.h
|
||||||
xtables_legacy_multi_CFLAGS = ${AM_CFLAGS}
|
-common_ldadd = ../extensions/libext.a ../libxtables/libxtables.la -lm
|
||||||
-xtables_legacy_multi_LDADD = ../extensions/libext.a
|
+common_ldadd = ../libxtables/libxtables.la -lm
|
||||||
+xtables_legacy_multi_LDADD =
|
common_cflags = ${AM_CFLAGS}
|
||||||
+xtables_legacy_multi_LDFLAGS = -L../extensions/ -liptext
|
|
||||||
if ENABLE_STATIC
|
if ENABLE_STATIC
|
||||||
xtables_legacy_multi_CFLAGS += -DALL_INCLUSIVE
|
common_cflags += -DALL_INCLUSIVE
|
||||||
endif
|
@@ -17,15 +17,18 @@ xtables_legacy_multi_SOURCES = ${common
|
||||||
|
iptables-restore.c iptables-save.c
|
||||||
|
xtables_legacy_multi_CFLAGS = ${common_cflags}
|
||||||
|
xtables_legacy_multi_LDADD = ${common_ldadd}
|
||||||
|
+xtables_legacy_multi_LDFLAGS = -L../extensions/ -liptext
|
||||||
if ENABLE_IPV4
|
if ENABLE_IPV4
|
||||||
xtables_legacy_multi_SOURCES += iptables-standalone.c iptables.c
|
xtables_legacy_multi_SOURCES += iptables-standalone.c iptables.c iptables-multi.h
|
||||||
xtables_legacy_multi_CFLAGS += -DENABLE_IPV4
|
xtables_legacy_multi_CFLAGS += -DENABLE_IPV4
|
||||||
-xtables_legacy_multi_LDADD += ../libiptc/libip4tc.la ../extensions/libext4.a
|
-xtables_legacy_multi_LDADD += ../libiptc/libip4tc.la ../extensions/libext4.a
|
||||||
+xtables_legacy_multi_LDADD += ../libiptc/libip4tc.la
|
+xtables_legacy_multi_LDADD += ../libiptc/libip4tc.la
|
||||||
+xtables_legacy_multi_LDFLAGS += -liptext4
|
+xtables_legacy_multi_LDFLAGS += -liptext4
|
||||||
endif
|
endif
|
||||||
if ENABLE_IPV6
|
if ENABLE_IPV6
|
||||||
xtables_legacy_multi_SOURCES += ip6tables-standalone.c ip6tables.c
|
xtables_legacy_multi_SOURCES += ip6tables-standalone.c ip6tables.c ip6tables-multi.h
|
||||||
xtables_legacy_multi_CFLAGS += -DENABLE_IPV6
|
xtables_legacy_multi_CFLAGS += -DENABLE_IPV6
|
||||||
-xtables_legacy_multi_LDADD += ../libiptc/libip6tc.la ../extensions/libext6.a
|
-xtables_legacy_multi_LDADD += ../libiptc/libip6tc.la ../extensions/libext6.a
|
||||||
+xtables_legacy_multi_LDADD += ../libiptc/libip6tc.la
|
+xtables_legacy_multi_LDADD += ../libiptc/libip6tc.la
|
||||||
+xtables_legacy_multi_LDFLAGS += -liptext6
|
+xtables_legacy_multi_LDFLAGS += -liptext6
|
||||||
endif
|
endif
|
||||||
xtables_legacy_multi_SOURCES += xshared.c iptables-restore.c iptables-save.c
|
|
||||||
xtables_legacy_multi_LDADD += ../libxtables/libxtables.la -lm
|
# iptables using nf_tables api
|
||||||
@@ -28,7 +31,8 @@ xtables_legacy_multi_LDADD += ../libxt
|
@@ -33,12 +36,9 @@ if ENABLE_NFTABLES
|
||||||
if ENABLE_NFTABLES
|
xtables_nft_multi_SOURCES = ${common_sources} xtables-nft-multi.c
|
||||||
xtables_nft_multi_SOURCES = xtables-nft-multi.c iptables-xml.c
|
xtables_nft_multi_CFLAGS = ${common_cflags}
|
||||||
xtables_nft_multi_CFLAGS = ${AM_CFLAGS}
|
xtables_nft_multi_LDADD = ${common_ldadd} \
|
||||||
-xtables_nft_multi_LDADD = ../extensions/libext.a ../extensions/libext_ebt.a
|
- ../extensions/libext_arpt.a \
|
||||||
+xtables_nft_multi_LDADD =
|
- ../extensions/libext_ebt.a \
|
||||||
+xtables_nft_multi_LDFLAGS = -L../extensions/ -liptext -liptext_ebt
|
- ../extensions/libext4.a \
|
||||||
if ENABLE_STATIC
|
- ../extensions/libext6.a \
|
||||||
xtables_nft_multi_CFLAGS += -DALL_INCLUSIVE
|
${libmnl_LIBS} ${libnftnl_LIBS} \
|
||||||
endif
|
${libnetfilter_conntrack_LIBS}
|
||||||
@@ -42,7 +46,8 @@ xtables_nft_multi_SOURCES += xtables-sav
|
+xtables_nft_multi_LDFLAGS = -L../extensions/ -liptext -liptext_arpt -liptext_ebt -liptext4 -liptext6
|
||||||
xtables-eb-standalone.c xtables-eb.c \
|
xtables_nft_multi_CFLAGS += -DENABLE_NFTABLES -DENABLE_IPV4 -DENABLE_IPV6
|
||||||
xtables-eb-translate.c \
|
xtables_nft_multi_SOURCES += nft.c nft.h \
|
||||||
xtables-translate.c
|
nft-arp.c nft-ipv4.c nft-ipv6.c \
|
||||||
-xtables_nft_multi_LDADD += ${libmnl_LIBS} ${libnftnl_LIBS} ${libnetfilter_conntrack_LIBS} ../extensions/libext4.a ../extensions/libext6.a ../extensions/libext_ebt.a ../extensions/libext_arpt.a
|
|
||||||
+xtables_nft_multi_LDADD += ${libmnl_LIBS} ${libnftnl_LIBS} ${libnetfilter_conntrack_LIBS}
|
|
||||||
+xtables_nft_multi_LDFLAGS += -liptext4 -liptext6 -liptext_arpt
|
|
||||||
xtables_nft_multi_SOURCES += xshared.c
|
|
||||||
xtables_nft_multi_LDADD += ../libxtables/libxtables.la -lm
|
|
||||||
endif
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
--- a/extensions/libxt_conntrack.c
|
--- a/extensions/libxt_conntrack.c
|
||||||
+++ b/extensions/libxt_conntrack.c
|
+++ b/extensions/libxt_conntrack.c
|
||||||
@@ -1399,6 +1399,7 @@ static int conntrack3_mt6_xlate(struct x
|
@@ -1385,6 +1385,7 @@ static int conntrack3_mt6_xlate(struct x
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct xtables_match conntrack_mt_reg[] = {
|
static struct xtables_match conntrack_mt_reg[] = {
|
||||||
@ -8,7 +8,7 @@
|
|||||||
{
|
{
|
||||||
.version = XTABLES_VERSION,
|
.version = XTABLES_VERSION,
|
||||||
.name = "conntrack",
|
.name = "conntrack",
|
||||||
@@ -1474,6 +1475,7 @@ static struct xtables_match conntrack_mt
|
@@ -1460,6 +1461,7 @@ static struct xtables_match conntrack_mt
|
||||||
.alias = conntrack_print_name_alias,
|
.alias = conntrack_print_name_alias,
|
||||||
.x6_options = conntrack2_mt_opts,
|
.x6_options = conntrack2_mt_opts,
|
||||||
},
|
},
|
||||||
@ -16,7 +16,7 @@
|
|||||||
{
|
{
|
||||||
.version = XTABLES_VERSION,
|
.version = XTABLES_VERSION,
|
||||||
.name = "conntrack",
|
.name = "conntrack",
|
||||||
@@ -1506,6 +1508,7 @@ static struct xtables_match conntrack_mt
|
@@ -1492,6 +1494,7 @@ static struct xtables_match conntrack_mt
|
||||||
.x6_options = conntrack3_mt_opts,
|
.x6_options = conntrack3_mt_opts,
|
||||||
.xlate = conntrack3_mt6_xlate,
|
.xlate = conntrack3_mt6_xlate,
|
||||||
},
|
},
|
||||||
@ -24,7 +24,7 @@
|
|||||||
{
|
{
|
||||||
.family = NFPROTO_UNSPEC,
|
.family = NFPROTO_UNSPEC,
|
||||||
.name = "state",
|
.name = "state",
|
||||||
@@ -1536,6 +1539,8 @@ static struct xtables_match conntrack_mt
|
@@ -1522,6 +1525,8 @@ static struct xtables_match conntrack_mt
|
||||||
.x6_parse = state_ct23_parse,
|
.x6_parse = state_ct23_parse,
|
||||||
.x6_options = state_opts,
|
.x6_options = state_opts,
|
||||||
},
|
},
|
||||||
@ -33,7 +33,7 @@
|
|||||||
{
|
{
|
||||||
.family = NFPROTO_UNSPEC,
|
.family = NFPROTO_UNSPEC,
|
||||||
.name = "state",
|
.name = "state",
|
||||||
@@ -1565,6 +1570,7 @@ static struct xtables_match conntrack_mt
|
@@ -1551,6 +1556,7 @@ static struct xtables_match conntrack_mt
|
||||||
.x6_parse = state_parse,
|
.x6_parse = state_parse,
|
||||||
.x6_options = state_opts,
|
.x6_options = state_opts,
|
||||||
},
|
},
|
||||||
|
|||||||
98
package/network/utils/iw/patches/001-nl80211_h_sync.patch
Normal file
98
package/network/utils/iw/patches/001-nl80211_h_sync.patch
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
--- a/nl80211.h
|
||||||
|
+++ b/nl80211.h
|
||||||
|
@@ -2061,6 +2061,10 @@ enum nl80211_commands {
|
||||||
|
* @NL80211_ATTR_INTERFACE_COMBINATIONS: Nested attribute listing the supported
|
||||||
|
* interface combinations. In each nested item, it contains attributes
|
||||||
|
* defined in &enum nl80211_if_combination_attrs.
|
||||||
|
+ * If the wiphy uses multiple radios (@NL80211_ATTR_WIPHY_RADIOS is set),
|
||||||
|
+ * this attribute contains the interface combinations of the first radio.
|
||||||
|
+ * See @NL80211_ATTR_WIPHY_INTERFACE_COMBINATIONS for the global wiphy
|
||||||
|
+ * combinations for the sum of all radios.
|
||||||
|
* @NL80211_ATTR_SOFTWARE_IFTYPES: Nested attribute (just like
|
||||||
|
* %NL80211_ATTR_SUPPORTED_IFTYPES) containing the interface types that
|
||||||
|
* are managed in software: interfaces of these types aren't subject to
|
||||||
|
@@ -2856,6 +2860,17 @@ enum nl80211_commands {
|
||||||
|
* %NL80211_CMD_ASSOCIATE indicating the SPP A-MSDUs
|
||||||
|
* are used on this connection
|
||||||
|
*
|
||||||
|
+ * @NL80211_ATTR_WIPHY_RADIOS: Nested attribute describing physical radios
|
||||||
|
+ * belonging to this wiphy. See &enum nl80211_wiphy_radio_attrs.
|
||||||
|
+ *
|
||||||
|
+ * @NL80211_ATTR_WIPHY_INTERFACE_COMBINATIONS: Nested attribute listing the
|
||||||
|
+ * supported interface combinations for all radios combined. In each
|
||||||
|
+ * nested item, it contains attributes defined in
|
||||||
|
+ * &enum nl80211_if_combination_attrs.
|
||||||
|
+ *
|
||||||
|
+ * @NL80211_ATTR_VIF_RADIO_MASK: Bitmask of allowed radios (u32).
|
||||||
|
+ * A value of 0 means all radios.
|
||||||
|
+ *
|
||||||
|
* @NUM_NL80211_ATTR: total number of nl80211_attrs available
|
||||||
|
* @NL80211_ATTR_MAX: highest attribute number currently defined
|
||||||
|
* @__NL80211_ATTR_AFTER_LAST: internal use
|
||||||
|
@@ -3401,6 +3416,11 @@ enum nl80211_attrs {
|
||||||
|
|
||||||
|
NL80211_ATTR_ASSOC_SPP_AMSDU,
|
||||||
|
|
||||||
|
+ NL80211_ATTR_WIPHY_RADIOS,
|
||||||
|
+ NL80211_ATTR_WIPHY_INTERFACE_COMBINATIONS,
|
||||||
|
+
|
||||||
|
+ NL80211_ATTR_VIF_RADIO_MASK,
|
||||||
|
+
|
||||||
|
/* add attributes here, update the policy in nl80211.c */
|
||||||
|
|
||||||
|
__NL80211_ATTR_AFTER_LAST,
|
||||||
|
@@ -7987,4 +8007,54 @@ enum nl80211_ap_settings_flags {
|
||||||
|
NL80211_AP_SETTINGS_SA_QUERY_OFFLOAD_SUPPORT = 1 << 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
+/**
|
||||||
|
+ * enum nl80211_wiphy_radio_attrs - wiphy radio attributes
|
||||||
|
+ *
|
||||||
|
+ * @__NL80211_WIPHY_RADIO_ATTR_INVALID: Invalid
|
||||||
|
+ *
|
||||||
|
+ * @NL80211_WIPHY_RADIO_ATTR_INDEX: Index of this radio (u32)
|
||||||
|
+ * @NL80211_WIPHY_RADIO_ATTR_FREQ_RANGE: Frequency range supported by this
|
||||||
|
+ * radio. Attribute may be present multiple times.
|
||||||
|
+ * @NL80211_WIPHY_RADIO_ATTR_INTERFACE_COMBINATION: Supported interface
|
||||||
|
+ * combination for this radio. Attribute may be present multiple times
|
||||||
|
+ * and contains attributes defined in &enum nl80211_if_combination_attrs.
|
||||||
|
+ *
|
||||||
|
+ * @__NL80211_WIPHY_RADIO_ATTR_LAST: Internal
|
||||||
|
+ * @NL80211_WIPHY_RADIO_ATTR_MAX: Highest attribute
|
||||||
|
+ */
|
||||||
|
+enum nl80211_wiphy_radio_attrs {
|
||||||
|
+ __NL80211_WIPHY_RADIO_ATTR_INVALID,
|
||||||
|
+
|
||||||
|
+ NL80211_WIPHY_RADIO_ATTR_INDEX,
|
||||||
|
+ NL80211_WIPHY_RADIO_ATTR_FREQ_RANGE,
|
||||||
|
+ NL80211_WIPHY_RADIO_ATTR_INTERFACE_COMBINATION,
|
||||||
|
+
|
||||||
|
+ /* keep last */
|
||||||
|
+ __NL80211_WIPHY_RADIO_ATTR_LAST,
|
||||||
|
+ NL80211_WIPHY_RADIO_ATTR_MAX = __NL80211_WIPHY_RADIO_ATTR_LAST - 1,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * enum nl80211_wiphy_radio_freq_range - wiphy radio frequency range
|
||||||
|
+ *
|
||||||
|
+ * @__NL80211_WIPHY_RADIO_FREQ_ATTR_INVALID: Invalid
|
||||||
|
+ *
|
||||||
|
+ * @NL80211_WIPHY_RADIO_FREQ_ATTR_START: Frequency range start (u32).
|
||||||
|
+ * The unit is kHz.
|
||||||
|
+ * @NL80211_WIPHY_RADIO_FREQ_ATTR_END: Frequency range end (u32).
|
||||||
|
+ * The unit is kHz.
|
||||||
|
+ *
|
||||||
|
+ * @__NL80211_WIPHY_RADIO_FREQ_ATTR_LAST: Internal
|
||||||
|
+ * @NL80211_WIPHY_RADIO_FREQ_ATTR_MAX: Highest attribute
|
||||||
|
+ */
|
||||||
|
+enum nl80211_wiphy_radio_freq_range {
|
||||||
|
+ __NL80211_WIPHY_RADIO_FREQ_ATTR_INVALID,
|
||||||
|
+
|
||||||
|
+ NL80211_WIPHY_RADIO_FREQ_ATTR_START,
|
||||||
|
+ NL80211_WIPHY_RADIO_FREQ_ATTR_END,
|
||||||
|
+
|
||||||
|
+ __NL80211_WIPHY_RADIO_FREQ_ATTR_LAST,
|
||||||
|
+ NL80211_WIPHY_RADIO_FREQ_ATTR_MAX = __NL80211_WIPHY_RADIO_FREQ_ATTR_LAST - 1,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
#endif /* __LINUX_NL80211_H */
|
||||||
252
package/network/utils/iw/patches/300-wiphy_radios.patch
Normal file
252
package/network/utils/iw/patches/300-wiphy_radios.patch
Normal file
@ -0,0 +1,252 @@
|
|||||||
|
--- a/info.c
|
||||||
|
+++ b/info.c
|
||||||
|
@@ -295,6 +295,151 @@ static void print_pmsr_capabilities(stru
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void print_interface_combinations(struct nlattr *ifcomb, bool radio)
|
||||||
|
+{
|
||||||
|
+ const char *indent = radio ? "\t" : "";
|
||||||
|
+ struct nlattr *nl_combi;
|
||||||
|
+ bool have_combinations = false;
|
||||||
|
+ int rem;
|
||||||
|
+
|
||||||
|
+ nla_for_each_nested(nl_combi, ifcomb, rem) {
|
||||||
|
+ static struct nla_policy iface_combination_policy[NUM_NL80211_IFACE_COMB] = {
|
||||||
|
+ [NL80211_IFACE_COMB_LIMITS] = { .type = NLA_NESTED },
|
||||||
|
+ [NL80211_IFACE_COMB_MAXNUM] = { .type = NLA_U32 },
|
||||||
|
+ [NL80211_IFACE_COMB_STA_AP_BI_MATCH] = { .type = NLA_FLAG },
|
||||||
|
+ [NL80211_IFACE_COMB_NUM_CHANNELS] = { .type = NLA_U32 },
|
||||||
|
+ [NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS] = { .type = NLA_U32 },
|
||||||
|
+ };
|
||||||
|
+ struct nlattr *tb_comb[NUM_NL80211_IFACE_COMB];
|
||||||
|
+ static struct nla_policy iface_limit_policy[NUM_NL80211_IFACE_LIMIT] = {
|
||||||
|
+ [NL80211_IFACE_LIMIT_TYPES] = { .type = NLA_NESTED },
|
||||||
|
+ [NL80211_IFACE_LIMIT_MAX] = { .type = NLA_U32 },
|
||||||
|
+ };
|
||||||
|
+ struct nlattr *tb_limit[NUM_NL80211_IFACE_LIMIT];
|
||||||
|
+ struct nlattr *nl_limit;
|
||||||
|
+ int err, rem_limit;
|
||||||
|
+ bool comma = false;
|
||||||
|
+
|
||||||
|
+ if (radio && nla_type(nl_combi) !=
|
||||||
|
+ NL80211_WIPHY_RADIO_ATTR_INTERFACE_COMBINATION)
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ if (!have_combinations) {
|
||||||
|
+ printf("\t%svalid interface combinations:\n", indent);
|
||||||
|
+ have_combinations = true;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ printf("\t\t%s * ", indent);
|
||||||
|
+
|
||||||
|
+ err = nla_parse_nested(tb_comb, MAX_NL80211_IFACE_COMB,
|
||||||
|
+ nl_combi, iface_combination_policy);
|
||||||
|
+ if (err || !tb_comb[NL80211_IFACE_COMB_LIMITS] ||
|
||||||
|
+ !tb_comb[NL80211_IFACE_COMB_MAXNUM] ||
|
||||||
|
+ !tb_comb[NL80211_IFACE_COMB_NUM_CHANNELS]) {
|
||||||
|
+ printf(" <failed to parse>\n");
|
||||||
|
+ goto broken_combination;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ nla_for_each_nested(nl_limit, tb_comb[NL80211_IFACE_COMB_LIMITS], rem_limit) {
|
||||||
|
+ err = nla_parse_nested(tb_limit, MAX_NL80211_IFACE_LIMIT,
|
||||||
|
+ nl_limit, iface_limit_policy);
|
||||||
|
+ if (err || !tb_limit[NL80211_IFACE_LIMIT_TYPES]) {
|
||||||
|
+ printf("<failed to parse>\n");
|
||||||
|
+ goto broken_combination;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (comma)
|
||||||
|
+ printf(", ");
|
||||||
|
+ comma = true;
|
||||||
|
+ printf("#{ ");
|
||||||
|
+ print_iftype_line(tb_limit[NL80211_IFACE_LIMIT_TYPES]);
|
||||||
|
+ printf(" } <= %u", nla_get_u32(tb_limit[NL80211_IFACE_LIMIT_MAX]));
|
||||||
|
+ }
|
||||||
|
+ printf(",\n\t\t%s ", indent);
|
||||||
|
+
|
||||||
|
+ printf("total <= %d, #channels <= %d%s",
|
||||||
|
+ nla_get_u32(tb_comb[NL80211_IFACE_COMB_MAXNUM]),
|
||||||
|
+ nla_get_u32(tb_comb[NL80211_IFACE_COMB_NUM_CHANNELS]),
|
||||||
|
+ tb_comb[NL80211_IFACE_COMB_STA_AP_BI_MATCH] ?
|
||||||
|
+ ", STA/AP BI must match" : "");
|
||||||
|
+ if (tb_comb[NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS]) {
|
||||||
|
+ unsigned long widths = nla_get_u32(tb_comb[NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS]);
|
||||||
|
+
|
||||||
|
+ if (widths) {
|
||||||
|
+ int width;
|
||||||
|
+ bool first = true;
|
||||||
|
+
|
||||||
|
+ printf(", radar detect widths: {");
|
||||||
|
+ for (width = 0; width < 32; width++)
|
||||||
|
+ if (widths & (1 << width)) {
|
||||||
|
+ printf("%s %s",
|
||||||
|
+ first ? "":",",
|
||||||
|
+ channel_width_name(width));
|
||||||
|
+ first = false;
|
||||||
|
+ }
|
||||||
|
+ printf(" }\n");
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ printf("\n");
|
||||||
|
+broken_combination:
|
||||||
|
+ ;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!have_combinations)
|
||||||
|
+ printf("\t%sinterface combinations are not supported\n", indent);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void print_radio_freq(struct nlattr *freqs)
|
||||||
|
+{
|
||||||
|
+ struct nlattr *freq;
|
||||||
|
+ int rem;
|
||||||
|
+
|
||||||
|
+ nla_for_each_nested(freq, freqs, rem) {
|
||||||
|
+ static struct nla_policy freq_policy[NL80211_WIPHY_RADIO_FREQ_ATTR_MAX + 1] = {
|
||||||
|
+ [NL80211_WIPHY_RADIO_FREQ_ATTR_START] = { .type = NLA_U32 },
|
||||||
|
+ [NL80211_WIPHY_RADIO_FREQ_ATTR_END] = { .type = NLA_U32 },
|
||||||
|
+ };
|
||||||
|
+ struct nlattr *tb[NL80211_WIPHY_RADIO_FREQ_ATTR_MAX + 1];
|
||||||
|
+ uint32_t start, end;
|
||||||
|
+
|
||||||
|
+ if (nla_type(freq) != NL80211_WIPHY_RADIO_ATTR_FREQ_RANGE)
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ if (nla_parse_nested(tb, NL80211_WIPHY_RADIO_ATTR_MAX + 1,
|
||||||
|
+ freq, freq_policy) ||
|
||||||
|
+ !tb[NL80211_WIPHY_RADIO_FREQ_ATTR_START] ||
|
||||||
|
+ !tb[NL80211_WIPHY_RADIO_FREQ_ATTR_END])
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ start = nla_get_u32(tb[NL80211_WIPHY_RADIO_FREQ_ATTR_START]);
|
||||||
|
+ end = nla_get_u32(tb[NL80211_WIPHY_RADIO_FREQ_ATTR_END]);
|
||||||
|
+
|
||||||
|
+ printf("\t\tfreq range: %.1f MHz - %.1f MHz\n", (float)start / 1000, (float)end / 1000);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void print_radios(struct nlattr *radios)
|
||||||
|
+{
|
||||||
|
+ struct nlattr *radio;
|
||||||
|
+ int rem, idx = 0;
|
||||||
|
+
|
||||||
|
+ nla_for_each_nested(radio, radios, rem) {
|
||||||
|
+ static struct nla_policy radio_policy[NL80211_WIPHY_RADIO_ATTR_MAX + 1] = {
|
||||||
|
+ [NL80211_WIPHY_RADIO_ATTR_INDEX] = { .type = NLA_U32 },
|
||||||
|
+ };
|
||||||
|
+ struct nlattr *tb[NL80211_WIPHY_RADIO_ATTR_MAX + 1];
|
||||||
|
+
|
||||||
|
+ if (nla_parse_nested(tb, NL80211_WIPHY_RADIO_ATTR_MAX + 1,
|
||||||
|
+ radio, radio_policy) ||
|
||||||
|
+ !tb[NL80211_WIPHY_RADIO_ATTR_INDEX])
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ printf("\twiphy radio %d:\n", nla_get_u32(tb[NL80211_WIPHY_RADIO_ATTR_INDEX]));
|
||||||
|
+ print_radio_freq(radio);
|
||||||
|
+ print_interface_combinations(radio, true);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int print_phy_handler(struct nl_msg *msg, void *arg)
|
||||||
|
{
|
||||||
|
struct nlattr *tb_msg[NL80211_ATTR_MAX + 1];
|
||||||
|
@@ -565,93 +710,11 @@ next:
|
||||||
|
"\t\t", tb_msg[NL80211_ATTR_SOFTWARE_IFTYPES]);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
- if (tb_msg[NL80211_ATTR_INTERFACE_COMBINATIONS]) {
|
||||||
|
- struct nlattr *nl_combi;
|
||||||
|
- int rem_combi;
|
||||||
|
- bool have_combinations = false;
|
||||||
|
-
|
||||||
|
- nla_for_each_nested(nl_combi, tb_msg[NL80211_ATTR_INTERFACE_COMBINATIONS], rem_combi) {
|
||||||
|
- static struct nla_policy iface_combination_policy[NUM_NL80211_IFACE_COMB] = {
|
||||||
|
- [NL80211_IFACE_COMB_LIMITS] = { .type = NLA_NESTED },
|
||||||
|
- [NL80211_IFACE_COMB_MAXNUM] = { .type = NLA_U32 },
|
||||||
|
- [NL80211_IFACE_COMB_STA_AP_BI_MATCH] = { .type = NLA_FLAG },
|
||||||
|
- [NL80211_IFACE_COMB_NUM_CHANNELS] = { .type = NLA_U32 },
|
||||||
|
- [NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS] = { .type = NLA_U32 },
|
||||||
|
- };
|
||||||
|
- struct nlattr *tb_comb[NUM_NL80211_IFACE_COMB];
|
||||||
|
- static struct nla_policy iface_limit_policy[NUM_NL80211_IFACE_LIMIT] = {
|
||||||
|
- [NL80211_IFACE_LIMIT_TYPES] = { .type = NLA_NESTED },
|
||||||
|
- [NL80211_IFACE_LIMIT_MAX] = { .type = NLA_U32 },
|
||||||
|
- };
|
||||||
|
- struct nlattr *tb_limit[NUM_NL80211_IFACE_LIMIT];
|
||||||
|
- struct nlattr *nl_limit;
|
||||||
|
- int err, rem_limit;
|
||||||
|
- bool comma = false;
|
||||||
|
-
|
||||||
|
- if (!have_combinations) {
|
||||||
|
- printf("\tvalid interface combinations:\n");
|
||||||
|
- have_combinations = true;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- printf("\t\t * ");
|
||||||
|
+ if (tb_msg[NL80211_ATTR_INTERFACE_COMBINATIONS])
|
||||||
|
+ print_interface_combinations(tb_msg[NL80211_ATTR_INTERFACE_COMBINATIONS], false);
|
||||||
|
|
||||||
|
- err = nla_parse_nested(tb_comb, MAX_NL80211_IFACE_COMB,
|
||||||
|
- nl_combi, iface_combination_policy);
|
||||||
|
- if (err || !tb_comb[NL80211_IFACE_COMB_LIMITS] ||
|
||||||
|
- !tb_comb[NL80211_IFACE_COMB_MAXNUM] ||
|
||||||
|
- !tb_comb[NL80211_IFACE_COMB_NUM_CHANNELS]) {
|
||||||
|
- printf(" <failed to parse>\n");
|
||||||
|
- goto broken_combination;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- nla_for_each_nested(nl_limit, tb_comb[NL80211_IFACE_COMB_LIMITS], rem_limit) {
|
||||||
|
- err = nla_parse_nested(tb_limit, MAX_NL80211_IFACE_LIMIT,
|
||||||
|
- nl_limit, iface_limit_policy);
|
||||||
|
- if (err || !tb_limit[NL80211_IFACE_LIMIT_TYPES]) {
|
||||||
|
- printf("<failed to parse>\n");
|
||||||
|
- goto broken_combination;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (comma)
|
||||||
|
- printf(", ");
|
||||||
|
- comma = true;
|
||||||
|
- printf("#{ ");
|
||||||
|
- print_iftype_line(tb_limit[NL80211_IFACE_LIMIT_TYPES]);
|
||||||
|
- printf(" } <= %u", nla_get_u32(tb_limit[NL80211_IFACE_LIMIT_MAX]));
|
||||||
|
- }
|
||||||
|
- printf(",\n\t\t ");
|
||||||
|
-
|
||||||
|
- printf("total <= %d, #channels <= %d%s",
|
||||||
|
- nla_get_u32(tb_comb[NL80211_IFACE_COMB_MAXNUM]),
|
||||||
|
- nla_get_u32(tb_comb[NL80211_IFACE_COMB_NUM_CHANNELS]),
|
||||||
|
- tb_comb[NL80211_IFACE_COMB_STA_AP_BI_MATCH] ?
|
||||||
|
- ", STA/AP BI must match" : "");
|
||||||
|
- if (tb_comb[NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS]) {
|
||||||
|
- unsigned long widths = nla_get_u32(tb_comb[NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS]);
|
||||||
|
-
|
||||||
|
- if (widths) {
|
||||||
|
- int width;
|
||||||
|
- bool first = true;
|
||||||
|
-
|
||||||
|
- printf(", radar detect widths: {");
|
||||||
|
- for (width = 0; width < 32; width++)
|
||||||
|
- if (widths & (1 << width)) {
|
||||||
|
- printf("%s %s",
|
||||||
|
- first ? "":",",
|
||||||
|
- channel_width_name(width));
|
||||||
|
- first = false;
|
||||||
|
- }
|
||||||
|
- printf(" }\n");
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- printf("\n");
|
||||||
|
-broken_combination:
|
||||||
|
- ;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (!have_combinations)
|
||||||
|
- printf("\tinterface combinations are not supported\n");
|
||||||
|
- }
|
||||||
|
+ if (tb_msg[NL80211_ATTR_WIPHY_RADIOS])
|
||||||
|
+ print_radios(tb_msg[NL80211_ATTR_WIPHY_RADIOS]);
|
||||||
|
|
||||||
|
#ifdef IW_FULL
|
||||||
|
if (tb_msg[NL80211_ATTR_SUPPORTED_COMMANDS]) {
|
||||||
99
package/network/utils/iw/patches/310-vif_radio_mask.patch
Normal file
99
package/network/utils/iw/patches/310-vif_radio_mask.patch
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
--- a/interface.c
|
||||||
|
+++ b/interface.c
|
||||||
|
@@ -226,6 +226,43 @@ nla_put_failure:
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int parse_radio_list(char *str, struct nl_msg *msg)
|
||||||
|
+{
|
||||||
|
+ unsigned int mask = 0;
|
||||||
|
+ unsigned long id;
|
||||||
|
+ char *end;
|
||||||
|
+
|
||||||
|
+ if (!str)
|
||||||
|
+ return 1;
|
||||||
|
+
|
||||||
|
+ if (!strcmp(str, "all"))
|
||||||
|
+ goto out;
|
||||||
|
+
|
||||||
|
+ while (1) {
|
||||||
|
+ if (!*str)
|
||||||
|
+ return 1;
|
||||||
|
+
|
||||||
|
+ id = strtoul(str, &end, 0);
|
||||||
|
+ if (id > 31)
|
||||||
|
+ return 1;
|
||||||
|
+
|
||||||
|
+ mask |= 1 << id;
|
||||||
|
+ if (!*end)
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ if (end == str || *end != ',')
|
||||||
|
+ return 1;
|
||||||
|
+
|
||||||
|
+ str = end + 1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+out:
|
||||||
|
+ NLA_PUT_U32(msg, NL80211_ATTR_VIF_RADIO_MASK, mask);
|
||||||
|
+ return 0;
|
||||||
|
+nla_put_failure:
|
||||||
|
+ return 1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int handle_interface_add(struct nl80211_state *state,
|
||||||
|
struct nl_msg *msg,
|
||||||
|
int argc, char **argv,
|
||||||
|
@@ -287,6 +324,15 @@ try_another:
|
||||||
|
fprintf(stderr, "flags error\n");
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
+ } else if (strcmp(argv[0], "radios") == 0) {
|
||||||
|
+ argc--;
|
||||||
|
+ argv++;
|
||||||
|
+ if (parse_radio_list(argv[0], msg)) {
|
||||||
|
+ fprintf(stderr, "Invalid radio list\n");
|
||||||
|
+ return 2;
|
||||||
|
+ }
|
||||||
|
+ argc--;
|
||||||
|
+ argv++;
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
@@ -306,14 +352,14 @@ try_another:
|
||||||
|
nla_put_failure:
|
||||||
|
return -ENOBUFS;
|
||||||
|
}
|
||||||
|
-COMMAND(interface, add, "<name> type <type> [mesh_id <meshid>] [4addr on|off] [flags <flag>*] [addr <mac-addr>]",
|
||||||
|
+COMMAND(interface, add, "<name> type <type> [mesh_id <meshid>] [4addr on|off] [flags <flag>*] [addr <mac-addr>] [radios all|<id>[,<id>...]]",
|
||||||
|
NL80211_CMD_NEW_INTERFACE, 0, CIB_PHY, handle_interface_add,
|
||||||
|
"Add a new virtual interface with the given configuration.\n"
|
||||||
|
IFACE_TYPES "\n\n"
|
||||||
|
"The flags are only used for monitor interfaces, valid flags are:\n"
|
||||||
|
VALID_FLAGS "\n\n"
|
||||||
|
"The mesh_id is used only for mesh mode.");
|
||||||
|
-COMMAND(interface, add, "<name> type <type> [mesh_id <meshid>] [4addr on|off] [flags <flag>*] [addr <mac-addr>]",
|
||||||
|
+COMMAND(interface, add, "<name> type <type> [mesh_id <meshid>] [4addr on|off] [flags <flag>*] [addr <mac-addr>] [radios all|<id>[,<id>...]]",
|
||||||
|
NL80211_CMD_NEW_INTERFACE, 0, CIB_NETDEV, handle_interface_add, NULL);
|
||||||
|
|
||||||
|
static int handle_interface_del(struct nl80211_state *state,
|
||||||
|
@@ -493,6 +539,19 @@ static int print_iface_handler(struct nl
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ if (tb_msg[NL80211_ATTR_VIF_RADIO_MASK]) {
|
||||||
|
+ uint32_t mask = nla_get_u32(tb_msg[NL80211_ATTR_VIF_RADIO_MASK]);
|
||||||
|
+ int i;
|
||||||
|
+
|
||||||
|
+ if (mask) {
|
||||||
|
+ printf("%s\tRadios:", indent);
|
||||||
|
+ for (i = 0; mask; i++, mask >>= 1)
|
||||||
|
+ if (mask & 1)
|
||||||
|
+ printf(" %d", i);
|
||||||
|
+ printf("\n");
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
|
||||||
|
return NL_SKIP;
|
||||||
|
}
|
||||||
@ -11,9 +11,9 @@ PKG_RELEASE:=1
|
|||||||
|
|
||||||
PKG_SOURCE_PROTO:=git
|
PKG_SOURCE_PROTO:=git
|
||||||
PKG_SOURCE_URL=$(PROJECT_GIT)/project/iwinfo.git
|
PKG_SOURCE_URL=$(PROJECT_GIT)/project/iwinfo.git
|
||||||
PKG_SOURCE_DATE:=2024-10-01
|
PKG_SOURCE_DATE:=2024-10-20
|
||||||
PKG_SOURCE_VERSION:=714e419919d00dd1b3cdce08d9f28a28b2de69ed
|
PKG_SOURCE_VERSION:=b94f066e3f5839b8509483cdd8f4f582a45fa233
|
||||||
PKG_MIRROR_HASH:=e70c179f45ab075dc9216d9cf64e0c0161a89444ae9bd7622e5f877b36adf6d3
|
PKG_MIRROR_HASH:=ee0bce167707fe78f68a951b7ee1e0e61a92cae281e0e24eb709857ae849777e
|
||||||
PKG_MAINTAINER:=Jo-Philipp Wich <jo@mein.io>
|
PKG_MAINTAINER:=Jo-Philipp Wich <jo@mein.io>
|
||||||
PKG_LICENSE:=GPL-2.0
|
PKG_LICENSE:=GPL-2.0
|
||||||
|
|
||||||
|
|||||||
1498
package/network/utils/iwinfo/patches/100-multi_radio.patch
Normal file
1498
package/network/utils/iwinfo/patches/100-multi_radio.patch
Normal file
File diff suppressed because it is too large
Load Diff
@ -12,9 +12,9 @@ PKG_RELEASE:=1
|
|||||||
|
|
||||||
PKG_SOURCE_PROTO:=git
|
PKG_SOURCE_PROTO:=git
|
||||||
PKG_SOURCE_URL=$(PROJECT_GIT)/project/procd.git
|
PKG_SOURCE_URL=$(PROJECT_GIT)/project/procd.git
|
||||||
PKG_MIRROR_HASH:=9a0f7a5dfc883e7ea2f7f779e2e68f93507477ca780945219f808b145db5e71d
|
PKG_MIRROR_HASH:=3d15a68fb614c4d7e129dc1bbe8a79adcb3115753c2fc95a36fd03855efc7a58
|
||||||
PKG_SOURCE_DATE:=2024-07-07
|
PKG_SOURCE_DATE:=2024-10-20
|
||||||
PKG_SOURCE_VERSION:=f230c11771875adc1f74bef013e8cea1fa1867bc
|
PKG_SOURCE_VERSION:=ef3ab8bc8fb18216793dd0c8106dd222c560453a
|
||||||
CMAKE_INSTALL:=1
|
CMAKE_INSTALL:=1
|
||||||
|
|
||||||
PKG_LICENSE:=GPL-2.0
|
PKG_LICENSE:=GPL-2.0
|
||||||
|
|||||||
@ -5,9 +5,9 @@ PKG_RELEASE:=1
|
|||||||
|
|
||||||
PKG_SOURCE_PROTO:=git
|
PKG_SOURCE_PROTO:=git
|
||||||
PKG_SOURCE_URL=$(PROJECT_GIT)/project/ubus.git
|
PKG_SOURCE_URL=$(PROJECT_GIT)/project/ubus.git
|
||||||
PKG_SOURCE_DATE:=2023-11-28
|
PKG_SOURCE_DATE:=2024-10-20
|
||||||
PKG_SOURCE_VERSION:=f84eb5998c6ea2d34989ca2d3254e56c66139313
|
PKG_SOURCE_VERSION:=252a9b0c1774790fb9c25735d5a09c27dba895db
|
||||||
PKG_MIRROR_HASH:=c9f6118b98550802893c7c0b497f2215dbfd863d819fabc9df2aa57ce29a5fd2
|
PKG_MIRROR_HASH:=72c21f02710d2314447670f1f1ea1833d2961f65fea3f9f94c060dda7c9d5914
|
||||||
PKG_ABI_VERSION:=$(call abi_version_str,$(PKG_SOURCE_DATE))
|
PKG_ABI_VERSION:=$(call abi_version_str,$(PKG_SOURCE_DATE))
|
||||||
CMAKE_INSTALL:=1
|
CMAKE_INSTALL:=1
|
||||||
|
|
||||||
|
|||||||
40
package/utils/ucode/patches/100-nl80211_vif_radio_mask.patch
Normal file
40
package/utils/ucode/patches/100-nl80211_vif_radio_mask.patch
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
--- a/include/linux/nl80211.h
|
||||||
|
+++ b/include/linux/nl80211.h
|
||||||
|
@@ -2868,6 +2868,9 @@ enum nl80211_commands {
|
||||||
|
* nested item, it contains attributes defined in
|
||||||
|
* &enum nl80211_if_combination_attrs.
|
||||||
|
*
|
||||||
|
+ * @NL80211_ATTR_VIF_RADIO_MASK: Bitmask of allowed radios (u32).
|
||||||
|
+ * A value of 0 means all radios.
|
||||||
|
+ *
|
||||||
|
* @NUM_NL80211_ATTR: total number of nl80211_attrs available
|
||||||
|
* @NL80211_ATTR_MAX: highest attribute number currently defined
|
||||||
|
* @__NL80211_ATTR_AFTER_LAST: internal use
|
||||||
|
@@ -3416,6 +3419,8 @@ enum nl80211_attrs {
|
||||||
|
NL80211_ATTR_WIPHY_RADIOS,
|
||||||
|
NL80211_ATTR_WIPHY_INTERFACE_COMBINATIONS,
|
||||||
|
|
||||||
|
+ NL80211_ATTR_VIF_RADIO_MASK,
|
||||||
|
+
|
||||||
|
/* add attributes here, update the policy in nl80211.c */
|
||||||
|
|
||||||
|
__NL80211_ATTR_AFTER_LAST,
|
||||||
|
--- a/lib/nl80211.c
|
||||||
|
+++ b/lib/nl80211.c
|
||||||
|
@@ -829,7 +829,7 @@ static const uc_nl_nested_spec_t nl80211
|
||||||
|
|
||||||
|
static const uc_nl_nested_spec_t nl80211_msg = {
|
||||||
|
.headsize = 0,
|
||||||
|
- .nattrs = 128,
|
||||||
|
+ .nattrs = 129,
|
||||||
|
.attrs = {
|
||||||
|
{ NL80211_ATTR_4ADDR, "4addr", DT_U8, 0, NULL },
|
||||||
|
{ NL80211_ATTR_AIRTIME_WEIGHT, "airtime_weight", DT_U16, 0, NULL },
|
||||||
|
@@ -959,6 +959,7 @@ static const uc_nl_nested_spec_t nl80211
|
||||||
|
{ NL80211_ATTR_MAX_AP_ASSOC_STA, "max_ap_assoc", DT_U16, 0, NULL },
|
||||||
|
{ NL80211_ATTR_SURVEY_INFO, "survey_info", DT_NESTED, 0, &nl80211_survey_info_nla },
|
||||||
|
{ NL80211_ATTR_WIPHY_RADIOS, "radios", DT_NESTED, DF_MULTIPLE|DF_AUTOIDX, &nl80211_wiphy_radio_nla },
|
||||||
|
+ { NL80211_ATTR_VIF_RADIO_MASK, "vif_radio_mask", DT_U32, 0, NULL },
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
@ -38,8 +38,8 @@ gen_fwinfo() {
|
|||||||
echo 'FW_VERSION=1.01.100\nBOOT_VERSION=01.00.01'
|
echo 'FW_VERSION=1.01.100\nBOOT_VERSION=01.00.01'
|
||||||
}
|
}
|
||||||
|
|
||||||
# The central upgrade script. It allows to install OpenWrt only to first partition.
|
# NOR upgrade script. It allows to install OpenWrt only to first partition.
|
||||||
gen_imageupgrade() {
|
gen_nor_upgrade() {
|
||||||
echo '#!/bin/sh'
|
echo '#!/bin/sh'
|
||||||
echo 'flash_bank=65536'
|
echo 'flash_bank=65536'
|
||||||
echo 'filesize=`stat --format=%s ./series_vmlinux.bix`'
|
echo 'filesize=`stat --format=%s ./series_vmlinux.bix`'
|
||||||
@ -58,16 +58,34 @@ gen_imageupgrade() {
|
|||||||
echo 'esac'
|
echo 'esac'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# NAND upgrade script. It allows to install OpenWrt only to first partition.
|
||||||
|
gen_nand_upgrade() {
|
||||||
|
echo '#!/bin/sh'
|
||||||
|
echo 'case $1 in'
|
||||||
|
echo '1)'
|
||||||
|
echo 'flash_eraseall $2 >/dev/null 2>&1'
|
||||||
|
echo 'nandwrite -p $2 ./series_vmlinux.bix >/dev/null 2>&1'
|
||||||
|
echo 'mtd_debug read $2 0 100 image1.img >/dev/null 2>&1'
|
||||||
|
echo 'CreateImage -r ./image1.img > /tmp/app/image1.txt'
|
||||||
|
echo 'echo 0'
|
||||||
|
echo ';;'
|
||||||
|
echo '*)'
|
||||||
|
echo 'echo 1'
|
||||||
|
echo 'esac'
|
||||||
|
}
|
||||||
|
|
||||||
tmpdir="$( mktemp -d 2> /dev/null )"
|
tmpdir="$( mktemp -d 2> /dev/null )"
|
||||||
imgdir=$tmpdir/image
|
imgdir=$tmpdir/image
|
||||||
mkdir $imgdir
|
mkdir $imgdir
|
||||||
|
|
||||||
gen_imagecheck $3 > $imgdir/iss_imagecheck.sh
|
gen_imagecheck $3 > $imgdir/iss_imagecheck.sh
|
||||||
gen_imageupgrade > $imgdir/iss_imageupgrade.sh
|
gen_nor_upgrade > $imgdir/iss_imageupgrade.sh
|
||||||
|
gen_nand_upgrade > $imgdir/iss_nand_imageupgrade.sh
|
||||||
gen_fwinfo > $imgdir/firmware_information.txt
|
gen_fwinfo > $imgdir/firmware_information.txt
|
||||||
|
|
||||||
chmod +x $imgdir/iss_imagecheck.sh
|
chmod +x $imgdir/iss_imagecheck.sh
|
||||||
chmod +x $imgdir/iss_imageupgrade.sh
|
chmod +x $imgdir/iss_imageupgrade.sh
|
||||||
|
chmod +x $imgdir/iss_nand_imageupgrade.sh
|
||||||
|
|
||||||
cp $1 $imgdir/series_vmlinux.bix
|
cp $1 $imgdir/series_vmlinux.bix
|
||||||
|
|
||||||
|
|||||||
@ -114,6 +114,7 @@ endif
|
|||||||
rm -f $(IB_KDIR)/vmlinux.debug
|
rm -f $(IB_KDIR)/vmlinux.debug
|
||||||
# remove any file for initramfs and Per Device Rootfs initramfs files
|
# remove any file for initramfs and Per Device Rootfs initramfs files
|
||||||
rm -f $(IB_KDIR)/vmlinux-initramfs*
|
rm -f $(IB_KDIR)/vmlinux-initramfs*
|
||||||
|
rm -f $(IB_KDIR)/vmlinuz-initramfs*
|
||||||
rm -f $(IB_KDIR)/Image-initramfs*
|
rm -f $(IB_KDIR)/Image-initramfs*
|
||||||
if [ -x $(LINUX_DIR)/scripts/dtc/dtc ]; then \
|
if [ -x $(LINUX_DIR)/scripts/dtc/dtc ]; then \
|
||||||
$(INSTALL_DIR) $(IB_LDIR)/scripts/dtc; \
|
$(INSTALL_DIR) $(IB_LDIR)/scripts/dtc; \
|
||||||
|
|||||||
@ -3,13 +3,11 @@ include $(TOPDIR)/rules.mk
|
|||||||
ARCH:=arm
|
ARCH:=arm
|
||||||
BOARD:=airoha
|
BOARD:=airoha
|
||||||
BOARDNAME:=Airoha ARM
|
BOARDNAME:=Airoha ARM
|
||||||
CPU_TYPE:=cortex-a7
|
SUBTARGETS:=en7523 en7581
|
||||||
FEATURES:=dt squashfs nand ramdisk gpio source-only
|
FEATURES:=dt squashfs nand ramdisk gpio
|
||||||
|
|
||||||
KERNEL_PATCHVER:=6.6
|
KERNEL_PATCHVER:=6.6
|
||||||
|
|
||||||
include $(INCLUDE_DIR)/target.mk
|
include $(INCLUDE_DIR)/target.mk
|
||||||
|
|
||||||
KERNELNAME:=Image dtbs
|
|
||||||
|
|
||||||
$(eval $(call BuildTarget))
|
$(eval $(call BuildTarget))
|
||||||
|
|||||||
210
target/linux/airoha/dts/en7581-evb-emmc.dts
Normal file
210
target/linux/airoha/dts/en7581-evb-emmc.dts
Normal file
@ -0,0 +1,210 @@
|
|||||||
|
// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||||
|
/dts-v1/;
|
||||||
|
|
||||||
|
/* Bootloader installs ATF here */
|
||||||
|
/memreserve/ 0x80000000 0x200000;
|
||||||
|
|
||||||
|
#include <dt-bindings/leds/common.h>
|
||||||
|
#include <dt-bindings/gpio/gpio.h>
|
||||||
|
#include "en7581.dtsi"
|
||||||
|
|
||||||
|
/ {
|
||||||
|
model = "Airoha EN7581 Evaluation Board";
|
||||||
|
compatible = "airoha,en7581-evb", "airoha,en7581";
|
||||||
|
|
||||||
|
aliases {
|
||||||
|
serial0 = &uart1;
|
||||||
|
};
|
||||||
|
|
||||||
|
chosen {
|
||||||
|
bootargs = "console=ttyS0,115200 earlycon";
|
||||||
|
stdout-path = "serial0:115200n8";
|
||||||
|
linux,usable-memory-range = <0x0 0x80200000 0x0 0x1fe00000>;
|
||||||
|
};
|
||||||
|
|
||||||
|
memory@80000000 {
|
||||||
|
device_type = "memory";
|
||||||
|
reg = <0x0 0x80000000 0x2 0x00000000>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
&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;
|
||||||
|
};
|
||||||
|
|
||||||
|
mmc_pins: mmc-pins {
|
||||||
|
mux {
|
||||||
|
function = "emmc";
|
||||||
|
groups = "emmc";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
&mmc0 {
|
||||||
|
pinctrl-names = "default";
|
||||||
|
pinctrl-0 = <&mmc_pins>;
|
||||||
|
status = "okay";
|
||||||
|
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
|
||||||
|
card@0 {
|
||||||
|
compatible = "mmc-card";
|
||||||
|
reg = <0>;
|
||||||
|
|
||||||
|
partitions {
|
||||||
|
compatible = "fixed-partitions";
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <1>;
|
||||||
|
|
||||||
|
bootloader@0 {
|
||||||
|
label = "bootloader";
|
||||||
|
reg = <0x00000000 0x00080000>;
|
||||||
|
};
|
||||||
|
|
||||||
|
tclinux@80000 {
|
||||||
|
label = "tclinux";
|
||||||
|
reg = <0x00080000 0x02800000>;
|
||||||
|
};
|
||||||
|
|
||||||
|
tclinux_slave@2880000 {
|
||||||
|
label = "tclinux_slave";
|
||||||
|
reg = <0x02880000 0x02800000>;
|
||||||
|
};
|
||||||
|
|
||||||
|
rootfs_data@5080000 {
|
||||||
|
label = "rootfs_data";
|
||||||
|
reg = <0x5080000 0x00800000>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
&i2c0 {
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
|
&pcie0 {
|
||||||
|
pinctrl-names = "default";
|
||||||
|
pinctrl-0 = <&pcie0_rst_pins>;
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
|
&pcie1 {
|
||||||
|
pinctrl-names = "default";
|
||||||
|
pinctrl-0 = <&pcie1_rst_pins>;
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
|
ð {
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
|
&gdm1 {
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
|
&switch {
|
||||||
|
pinctrl-names = "default";
|
||||||
|
pinctrl-0 = <&mdio_pins>;
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
|
&gsw_phy1 {
|
||||||
|
pinctrl-names = "led";
|
||||||
|
pinctrl-0 = <&gswp1_led0_pins>;
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
|
&gsw_phy1_led0 {
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
|
&gsw_phy2 {
|
||||||
|
pinctrl-names = "led";
|
||||||
|
pinctrl-0 = <&gswp2_led0_pins>;
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
|
&gsw_phy2_led0 {
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
|
&gsw_phy3 {
|
||||||
|
pinctrl-names = "led";
|
||||||
|
pinctrl-0 = <&gswp3_led0_pins>;
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
|
&gsw_phy3_led0 {
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
|
&gsw_phy4 {
|
||||||
|
pinctrl-names = "led";
|
||||||
|
pinctrl-0 = <&gswp4_led0_pins>;
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
|
&gsw_phy4_led0 {
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
254
target/linux/airoha/dts/en7581-evb.dts
Normal file
254
target/linux/airoha/dts/en7581-evb.dts
Normal file
@ -0,0 +1,254 @@
|
|||||||
|
// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||||
|
/dts-v1/;
|
||||||
|
|
||||||
|
/* Bootloader installs ATF here */
|
||||||
|
/memreserve/ 0x80000000 0x200000;
|
||||||
|
|
||||||
|
#include <dt-bindings/leds/common.h>
|
||||||
|
#include <dt-bindings/gpio/gpio.h>
|
||||||
|
#include <dt-bindings/input/input.h>
|
||||||
|
#include "en7581.dtsi"
|
||||||
|
|
||||||
|
/ {
|
||||||
|
model = "Airoha EN7581 Evaluation Board";
|
||||||
|
compatible = "airoha,en7581-evb", "airoha,en7581";
|
||||||
|
|
||||||
|
aliases {
|
||||||
|
serial0 = &uart1;
|
||||||
|
};
|
||||||
|
|
||||||
|
chosen {
|
||||||
|
bootargs = "console=ttyS0,115200 earlycon";
|
||||||
|
stdout-path = "serial0:115200n8";
|
||||||
|
linux,usable-memory-range = <0x0 0x80200000 0x0 0x1fe00000>;
|
||||||
|
};
|
||||||
|
|
||||||
|
memory@80000000 {
|
||||||
|
device_type = "memory";
|
||||||
|
reg = <0x0 0x80000000 0x2 0x00000000>;
|
||||||
|
};
|
||||||
|
|
||||||
|
gpio-keys-polled {
|
||||||
|
compatible = "gpio-keys-polled";
|
||||||
|
poll-interval = <100>;
|
||||||
|
btn0 {
|
||||||
|
label = "reset";
|
||||||
|
linux,code = <KEY_RESTART>;
|
||||||
|
gpios = <&en7581_pinctrl 0 GPIO_ACTIVE_LOW>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
pwmleds {
|
||||||
|
compatible = "pwm-leds";
|
||||||
|
pinctrl-names = "default";
|
||||||
|
pinctrl-0 = <&pwm_gpio18_idx10_pins>;
|
||||||
|
lan4_green {
|
||||||
|
label = "pon:green";
|
||||||
|
pwms = <&en7581_pwm 10 4000000 0>;
|
||||||
|
max-brightness = <255>;
|
||||||
|
active-low;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
leds {
|
||||||
|
compatible = "gpio-leds";
|
||||||
|
|
||||||
|
pwr_led: led-0 {
|
||||||
|
label = "pwr";
|
||||||
|
color = <LED_COLOR_ID_RED>;
|
||||||
|
function = LED_FUNCTION_POWER;
|
||||||
|
gpios = <&en7581_pinctrl 17 GPIO_ACTIVE_LOW>;
|
||||||
|
default-state = "on";
|
||||||
|
};
|
||||||
|
|
||||||
|
los_led: led-2 {
|
||||||
|
label = "los";
|
||||||
|
color = <LED_COLOR_ID_GREEN>;
|
||||||
|
function = LED_FUNCTION_STATUS;
|
||||||
|
gpios = <&en7581_pinctrl 19 GPIO_ACTIVE_LOW>;
|
||||||
|
default-state = "on";
|
||||||
|
};
|
||||||
|
|
||||||
|
internet_led: led-3 {
|
||||||
|
label = "internet";
|
||||||
|
color = <LED_COLOR_ID_GREEN>;
|
||||||
|
function = LED_FUNCTION_STATUS;
|
||||||
|
gpios = <&en7581_pinctrl 20 GPIO_ACTIVE_LOW>;
|
||||||
|
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 {
|
||||||
|
partitions {
|
||||||
|
compatible = "airoha,fixed-partitions";
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <1>;
|
||||||
|
|
||||||
|
bootloader@0 {
|
||||||
|
label = "bootloader";
|
||||||
|
reg = <0x00000000 0x00080000>;
|
||||||
|
};
|
||||||
|
|
||||||
|
tclinux@80000 {
|
||||||
|
label = "tclinux";
|
||||||
|
compatible = "denx,fit";
|
||||||
|
reg = <0x00080000 0x02800000>;
|
||||||
|
};
|
||||||
|
|
||||||
|
tclinux_slave@2880000 {
|
||||||
|
label = "tclinux_slave";
|
||||||
|
reg = <0x02880000 0x02800000>;
|
||||||
|
};
|
||||||
|
|
||||||
|
rootfs_data@5080000 {
|
||||||
|
label = "rootfs_data";
|
||||||
|
reg = <0x5080000 0x00800000>;
|
||||||
|
};
|
||||||
|
|
||||||
|
art@ffffffff {
|
||||||
|
compatible = "airoha,dynamic-art";
|
||||||
|
label = "art";
|
||||||
|
reg = <0xffffffff 0x00300000>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
&i2c0 {
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
|
&pcie0 {
|
||||||
|
pinctrl-names = "default";
|
||||||
|
pinctrl-0 = <&pcie0_rst_pins>;
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
|
&pcie1 {
|
||||||
|
pinctrl-names = "default";
|
||||||
|
pinctrl-0 = <&pcie1_rst_pins>;
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
|
ð {
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
|
&gdm1 {
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
|
&switch {
|
||||||
|
pinctrl-names = "default";
|
||||||
|
pinctrl-0 = <&mdio_pins>;
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
|
&gsw_phy1 {
|
||||||
|
pinctrl-names = "led";
|
||||||
|
pinctrl-0 = <&gswp1_led0_pins>;
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
|
&gsw_phy1_led0 {
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
|
&gsw_phy2 {
|
||||||
|
pinctrl-names = "led";
|
||||||
|
pinctrl-0 = <&gswp2_led0_pins>;
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
|
&gsw_phy2_led0 {
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
|
&gsw_phy3 {
|
||||||
|
pinctrl-names = "led";
|
||||||
|
pinctrl-0 = <&gswp3_led0_pins>;
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
|
&gsw_phy3_led0 {
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
|
&gsw_phy4 {
|
||||||
|
pinctrl-names = "led";
|
||||||
|
pinctrl-0 = <&gswp4_led0_pins>;
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
|
&gsw_phy4_led0 {
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
756
target/linux/airoha/dts/en7581.dtsi
Normal file
756
target/linux/airoha/dts/en7581.dtsi
Normal file
@ -0,0 +1,756 @@
|
|||||||
|
// 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/reset/airoha,en7581-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;
|
||||||
|
|
||||||
|
npu-binary@84000000 {
|
||||||
|
no-map;
|
||||||
|
reg = <0x0 0x84000000 0x0 0xa00000>;
|
||||||
|
};
|
||||||
|
|
||||||
|
npu-flag@84b0000 {
|
||||||
|
no-map;
|
||||||
|
reg = <0x0 0x84b00000 0x0 0x100000>;
|
||||||
|
};
|
||||||
|
|
||||||
|
npu-pkt@85000000 {
|
||||||
|
no-map;
|
||||||
|
reg = <0x0 0x85000000 0x0 0x1a00000>;
|
||||||
|
};
|
||||||
|
|
||||||
|
npu-phyaddr@86b00000 {
|
||||||
|
no-map;
|
||||||
|
reg = <0x0 0x86b00000 0x0 0x100000>;
|
||||||
|
};
|
||||||
|
|
||||||
|
npu-rxdesc@86d00000 {
|
||||||
|
no-map;
|
||||||
|
reg = <0x0 0x86d00000 0x0 0x100000>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
psci {
|
||||||
|
compatible = "arm,psci-1.0";
|
||||||
|
method = "smc";
|
||||||
|
};
|
||||||
|
|
||||||
|
cpus {
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
|
||||||
|
cpu-map {
|
||||||
|
cluster0 {
|
||||||
|
core0 {
|
||||||
|
cpu = <&cpu0>;
|
||||||
|
};
|
||||||
|
|
||||||
|
core1 {
|
||||||
|
cpu = <&cpu1>;
|
||||||
|
};
|
||||||
|
|
||||||
|
core2 {
|
||||||
|
cpu = <&cpu2>;
|
||||||
|
};
|
||||||
|
|
||||||
|
core3 {
|
||||||
|
cpu = <&cpu3>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
cpu0: cpu@0 {
|
||||||
|
device_type = "cpu";
|
||||||
|
compatible = "arm,cortex-a53";
|
||||||
|
reg = <0x0>;
|
||||||
|
operating-points-v2 = <&cpu_opp_table>;
|
||||||
|
enable-method = "psci";
|
||||||
|
clock-frequency = <80000000>;
|
||||||
|
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";
|
||||||
|
clock-frequency = <80000000>;
|
||||||
|
next-level-cache = <&l2>;
|
||||||
|
#cooling-cells = <2>;
|
||||||
|
};
|
||||||
|
|
||||||
|
cpu2: cpu@2 {
|
||||||
|
device_type = "cpu";
|
||||||
|
compatible = "arm,cortex-a53";
|
||||||
|
reg = <0x2>;
|
||||||
|
operating-points-v2 = <&cpu_opp_table>;
|
||||||
|
enable-method = "psci";
|
||||||
|
clock-frequency = <80000000>;
|
||||||
|
next-level-cache = <&l2>;
|
||||||
|
#cooling-cells = <2>;
|
||||||
|
};
|
||||||
|
|
||||||
|
cpu3: cpu@3 {
|
||||||
|
device_type = "cpu";
|
||||||
|
compatible = "arm,cortex-a53";
|
||||||
|
reg = <0x3>;
|
||||||
|
operating-points-v2 = <&cpu_opp_table>;
|
||||||
|
enable-method = "psci";
|
||||||
|
clock-frequency = <80000000>;
|
||||||
|
next-level-cache = <&l2>;
|
||||||
|
#cooling-cells = <2>;
|
||||||
|
};
|
||||||
|
|
||||||
|
l2: l2-cache {
|
||||||
|
compatible = "cache";
|
||||||
|
cache-size = <0x80000>;
|
||||||
|
cache-line-size = <64>;
|
||||||
|
cache-level = <2>;
|
||||||
|
cache-unified;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
cpu_opp_table: opp-table {
|
||||||
|
compatible = "operating-points-v2";
|
||||||
|
opp-shared;
|
||||||
|
|
||||||
|
opp-500000000 {
|
||||||
|
opp-hz = /bits/ 64 <500000000>;
|
||||||
|
};
|
||||||
|
|
||||||
|
opp-550000000 {
|
||||||
|
opp-hz = /bits/ 64 <550000000>;
|
||||||
|
};
|
||||||
|
|
||||||
|
opp-600000000 {
|
||||||
|
opp-hz = /bits/ 64 <600000000>;
|
||||||
|
};
|
||||||
|
|
||||||
|
opp-650000000 {
|
||||||
|
opp-hz = /bits/ 64 <650000000>;
|
||||||
|
};
|
||||||
|
|
||||||
|
opp-7000000000 {
|
||||||
|
opp-hz = /bits/ 64 <700000000>;
|
||||||
|
};
|
||||||
|
|
||||||
|
opp-7500000000 {
|
||||||
|
opp-hz = /bits/ 64 <750000000>;
|
||||||
|
};
|
||||||
|
|
||||||
|
opp-8000000000 {
|
||||||
|
opp-hz = /bits/ 64 <800000000>;
|
||||||
|
};
|
||||||
|
|
||||||
|
opp-8500000000 {
|
||||||
|
opp-hz = /bits/ 64 <850000000>;
|
||||||
|
};
|
||||||
|
|
||||||
|
opp-9000000000 {
|
||||||
|
opp-hz = /bits/ 64 <900000000>;
|
||||||
|
};
|
||||||
|
|
||||||
|
opp-9500000000 {
|
||||||
|
opp-hz = /bits/ 64 <950000000>;
|
||||||
|
};
|
||||||
|
|
||||||
|
opp-10000000000 {
|
||||||
|
opp-hz = /bits/ 64 <1000000000>;
|
||||||
|
};
|
||||||
|
|
||||||
|
opp-10500000000 {
|
||||||
|
opp-hz = /bits/ 64 <1050000000>;
|
||||||
|
};
|
||||||
|
|
||||||
|
opp-11000000000 {
|
||||||
|
opp-hz = /bits/ 64 <1100000000>;
|
||||||
|
};
|
||||||
|
|
||||||
|
opp-11500000000 {
|
||||||
|
opp-hz = /bits/ 64 <1150000000>;
|
||||||
|
};
|
||||||
|
|
||||||
|
opp-12000000000 {
|
||||||
|
opp-hz = /bits/ 64 <1200000000>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
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 = <0>;
|
||||||
|
polling-delay = <0>;
|
||||||
|
|
||||||
|
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>,
|
||||||
|
<&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
|
||||||
|
<&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
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>;
|
||||||
|
};
|
||||||
|
|
||||||
|
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 = <&scuclk EN7523_CLK_BUS>;
|
||||||
|
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";
|
||||||
|
};
|
||||||
|
|
||||||
|
chip_scu: syscon@1fa20000 {
|
||||||
|
compatible = "airoha,en7581-chip-scu", "syscon";
|
||||||
|
reg = <0x0 0x1fa20000 0x0 0x388>;
|
||||||
|
};
|
||||||
|
|
||||||
|
syscon@1fbe3400 {
|
||||||
|
compatible = "airoha,en7581-pbus-csr", "syscon";
|
||||||
|
reg = <0x0 0x1fbe3400 0x0 0xff>;
|
||||||
|
};
|
||||||
|
|
||||||
|
scuclk: clock-controller@1fa20000 {
|
||||||
|
compatible = "airoha,en7581-scu";
|
||||||
|
reg = <0x0 0x1fb00000 0x0 0x970>;
|
||||||
|
#clock-cells = <1>;
|
||||||
|
#reset-cells = <1>;
|
||||||
|
};
|
||||||
|
|
||||||
|
rng@1faa1000 {
|
||||||
|
compatible = "airoha,en7581-trng";
|
||||||
|
reg = <0x0 0x1faa1000 0x0 0xc04>;
|
||||||
|
interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
|
};
|
||||||
|
|
||||||
|
crypto@1e004000 {
|
||||||
|
compatible = "inside-secure,safexcel-eip93ies";
|
||||||
|
reg = <0x0 0x1fb70000 0x0 0x1000>;
|
||||||
|
|
||||||
|
interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
|
};
|
||||||
|
|
||||||
|
thermal: thermal-sensor@1efbd800 {
|
||||||
|
compatible = "airoha,en7581-thermal";
|
||||||
|
reg = <0x0 0x1efbd000 0x0 0xd5c>;
|
||||||
|
interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
|
airoha,chip-scu = <&chip_scu>;
|
||||||
|
|
||||||
|
#thermal-sensor-cells = <0>;
|
||||||
|
};
|
||||||
|
|
||||||
|
system-controller@1fbf0200 {
|
||||||
|
compatible = "syscon", "simple-mfd";
|
||||||
|
reg = <0x0 0x1fbf0200 0x0 0xc0>;
|
||||||
|
|
||||||
|
en7581_pinctrl: pinctrl {
|
||||||
|
compatible = "airoha,en7581-pinctrl";
|
||||||
|
|
||||||
|
interrupt-parent = <&gic>;
|
||||||
|
interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
|
|
||||||
|
gpio-controller;
|
||||||
|
#gpio-cells = <2>;
|
||||||
|
|
||||||
|
interrupt-controller;
|
||||||
|
#interrupt-cells = <2>;
|
||||||
|
};
|
||||||
|
|
||||||
|
en7581_pwm: pwm {
|
||||||
|
compatible = "airoha,en7581-pwm";
|
||||||
|
|
||||||
|
#pwm-cells = <3>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
i2cclock: i2cclock@0 {
|
||||||
|
#clock-cells = <0>;
|
||||||
|
compatible = "fixed-clock";
|
||||||
|
|
||||||
|
/* 20 MHz */
|
||||||
|
clock-frequency = <20000000>;
|
||||||
|
};
|
||||||
|
|
||||||
|
i2c0: i2c0@1fbf8000 {
|
||||||
|
compatible = "mediatek,mt7621-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 = "mediatek,mt7621-i2c";
|
||||||
|
reg = <0x0 0x1fbf8100 0x0 0x100>;
|
||||||
|
|
||||||
|
clocks = <&i2cclock>;
|
||||||
|
|
||||||
|
/* 100 kHz */
|
||||||
|
clock-frequency = <100000>;
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
|
||||||
|
status = "disable";
|
||||||
|
};
|
||||||
|
|
||||||
|
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>;
|
||||||
|
airoha,bmt;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
mmc0: mmc@1fa0e000 {
|
||||||
|
compatible = "mediatek,mt7622-mmc";
|
||||||
|
reg = <0x0 0x1fa0e000 0x0 0x1000>,
|
||||||
|
<0x0 0x1fa0c000 0x0 0x60>;
|
||||||
|
interrupts = <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
|
bus-width = <4>;
|
||||||
|
max-frequency = <52000000>;
|
||||||
|
disable-wp;
|
||||||
|
cap-mmc-highspeed;
|
||||||
|
non-removable;
|
||||||
|
|
||||||
|
status = "disabled";
|
||||||
|
};
|
||||||
|
|
||||||
|
pciephy: phy@1fa5a000 {
|
||||||
|
compatible = "airoha,en7581-pcie-phy";
|
||||||
|
reg = <0x0 0x1fa5a000 0x0 0xfff>,
|
||||||
|
<0x0 0x1fa5b000 0x0 0xfff>,
|
||||||
|
<0x0 0x1fa5c000 0x0 0xfff>,
|
||||||
|
<0x0 0x1fc10044 0x0 0x4>,
|
||||||
|
<0x0 0x1fc30044 0x0 0x4>,
|
||||||
|
<0x0 0x1fc15030 0x0 0x104>;
|
||||||
|
reg-names = "csr-2l", "pma0", "pma1",
|
||||||
|
"p0-xr-dtime", "p1-xr-dtime",
|
||||||
|
"rx-aeq";
|
||||||
|
#phy-cells = <0>;
|
||||||
|
};
|
||||||
|
|
||||||
|
pcie0: pcie@1fc00000 {
|
||||||
|
compatible = "airoha,en7581-pcie";
|
||||||
|
device_type = "pci";
|
||||||
|
linux,pci-domain = <0>;
|
||||||
|
#address-cells = <3>;
|
||||||
|
#size-cells = <2>;
|
||||||
|
|
||||||
|
reg = <0x0 0x1fc00000 0x0 0x1670>;
|
||||||
|
reg-names = "pcie-mac";
|
||||||
|
|
||||||
|
clocks = <&scuclk EN7523_CLK_PCIE>;
|
||||||
|
clock-names = "sys-ck";
|
||||||
|
|
||||||
|
phys = <&pciephy>;
|
||||||
|
phy-names = "pcie-phy";
|
||||||
|
|
||||||
|
ranges = <0x02000000 0 0x20000000 0x0 0x20000000 0 0x4000000>;
|
||||||
|
|
||||||
|
resets = <&scuclk EN7581_PCIE0_RST>,
|
||||||
|
<&scuclk EN7581_PCIE1_RST>,
|
||||||
|
<&scuclk EN7581_PCIE2_RST>;
|
||||||
|
reset-names = "phy-lane0", "phy-lane1", "phy-lane2";
|
||||||
|
|
||||||
|
interrupts = <GIC_SPI 39 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_intc0 0>,
|
||||||
|
<0 0 0 2 &pcie_intc0 1>,
|
||||||
|
<0 0 0 3 &pcie_intc0 2>,
|
||||||
|
<0 0 0 4 &pcie_intc0 3>;
|
||||||
|
|
||||||
|
status = "disabled";
|
||||||
|
|
||||||
|
pcie_intc0: interrupt-controller {
|
||||||
|
interrupt-controller;
|
||||||
|
#address-cells = <0>;
|
||||||
|
#interrupt-cells = <1>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
pcie1: pcie@1fc20000 {
|
||||||
|
compatible = "airoha,en7581-pcie";
|
||||||
|
device_type = "pci";
|
||||||
|
linux,pci-domain = <1>;
|
||||||
|
#address-cells = <3>;
|
||||||
|
#size-cells = <2>;
|
||||||
|
|
||||||
|
reg = <0x0 0x1fc20000 0x0 0x1670>;
|
||||||
|
reg-names = "pcie-mac";
|
||||||
|
|
||||||
|
clocks = <&scuclk EN7523_CLK_PCIE>;
|
||||||
|
clock-names = "sys-ck";
|
||||||
|
|
||||||
|
phys = <&pciephy>;
|
||||||
|
phy-names = "pcie-phy";
|
||||||
|
|
||||||
|
ranges = <0x02000000 0 0x24000000 0x0 0x24000000 0 0x4000000>;
|
||||||
|
|
||||||
|
resets = <&scuclk EN7581_PCIE0_RST>,
|
||||||
|
<&scuclk EN7581_PCIE1_RST>,
|
||||||
|
<&scuclk EN7581_PCIE2_RST>;
|
||||||
|
reset-names = "phy-lane0", "phy-lane1", "phy-lane2";
|
||||||
|
|
||||||
|
interrupts = <GIC_SPI 40 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_intc1 0>,
|
||||||
|
<0 0 0 2 &pcie_intc1 1>,
|
||||||
|
<0 0 0 3 &pcie_intc1 2>,
|
||||||
|
<0 0 0 4 &pcie_intc1 3>;
|
||||||
|
|
||||||
|
status = "disabled";
|
||||||
|
|
||||||
|
pcie_intc1: interrupt-controller {
|
||||||
|
interrupt-controller;
|
||||||
|
#address-cells = <0>;
|
||||||
|
#interrupt-cells = <1>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
eth: ethernet@1fb50000 {
|
||||||
|
compatible = "airoha,en7581-eth";
|
||||||
|
reg = <0 0x1fb50000 0 0x2600>,
|
||||||
|
<0 0x1fb54000 0 0x2000>,
|
||||||
|
<0 0x1fb56000 0 0x2000>;
|
||||||
|
reg-names = "fe", "qdma0", "qdma1";
|
||||||
|
|
||||||
|
resets = <&scuclk EN7581_FE_RST>,
|
||||||
|
<&scuclk EN7581_FE_PDMA_RST>,
|
||||||
|
<&scuclk EN7581_FE_QDMA_RST>,
|
||||||
|
<&scuclk EN7581_XSI_MAC_RST>,
|
||||||
|
<&scuclk EN7581_DUAL_HSI0_MAC_RST>,
|
||||||
|
<&scuclk EN7581_DUAL_HSI1_MAC_RST>,
|
||||||
|
<&scuclk EN7581_HSI_MAC_RST>,
|
||||||
|
<&scuclk EN7581_XFP_MAC_RST>;
|
||||||
|
reset-names = "fe", "pdma", "qdma", "xsi-mac",
|
||||||
|
"hsi0-mac", "hsi1-mac", "hsi-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>;
|
||||||
|
|
||||||
|
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 = <1000>;
|
||||||
|
full-duplex;
|
||||||
|
pause;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
switch: switch@1fb58000 {
|
||||||
|
compatible = "airoha,en7581-switch";
|
||||||
|
reg = <0 0x1fb58000 0 0x8000>;
|
||||||
|
resets = <&scuclk EN7581_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 = <1000>;
|
||||||
|
full-duplex;
|
||||||
|
pause;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
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";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
6
target/linux/airoha/en7523/target.mk
Normal file
6
target/linux/airoha/en7523/target.mk
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
ARCH:=arm
|
||||||
|
SUBTARGET:=en7523
|
||||||
|
BOARDNAME:=EN7523
|
||||||
|
CPU_TYPE:=cortex-a7
|
||||||
|
KERNELNAME:=Image dtbs
|
||||||
|
FEATURES+=source-only
|
||||||
616
target/linux/airoha/en7581/config-6.6
Normal file
616
target/linux/airoha/en7581/config-6.6
Normal file
@ -0,0 +1,616 @@
|
|||||||
|
CONFIG_64BIT=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_HIBERNATION_POSSIBLE=y
|
||||||
|
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_USES_HIGH_VMA_FLAGS=y
|
||||||
|
CONFIG_ARCH_USES_PG_ARCH_X=y
|
||||||
|
CONFIG_ARCH_WANTS_NO_INSTR=y
|
||||||
|
CONFIG_ARCH_WANTS_THP_SWAP=y
|
||||||
|
CONFIG_ARM64=y
|
||||||
|
CONFIG_ARM64_4K_PAGES=y
|
||||||
|
CONFIG_ARM64_AMU_EXTN=y
|
||||||
|
CONFIG_ARM64_BTI=y
|
||||||
|
CONFIG_ARM64_E0PD=y
|
||||||
|
CONFIG_ARM64_EPAN=y
|
||||||
|
CONFIG_ARM64_ERRATUM_1024718=y
|
||||||
|
CONFIG_ARM64_ERRATUM_1165522=y
|
||||||
|
CONFIG_ARM64_ERRATUM_1286807=y
|
||||||
|
CONFIG_ARM64_ERRATUM_1319367=y
|
||||||
|
CONFIG_ARM64_ERRATUM_1463225=y
|
||||||
|
CONFIG_ARM64_ERRATUM_1508412=y
|
||||||
|
CONFIG_ARM64_ERRATUM_1530923=y
|
||||||
|
CONFIG_ARM64_ERRATUM_1542419=y
|
||||||
|
CONFIG_ARM64_ERRATUM_2051678=y
|
||||||
|
CONFIG_ARM64_ERRATUM_2054223=y
|
||||||
|
CONFIG_ARM64_ERRATUM_2067961=y
|
||||||
|
CONFIG_ARM64_ERRATUM_2077057=y
|
||||||
|
CONFIG_ARM64_ERRATUM_2441007=y
|
||||||
|
CONFIG_ARM64_ERRATUM_2441009=y
|
||||||
|
CONFIG_ARM64_ERRATUM_2457168=y
|
||||||
|
CONFIG_ARM64_ERRATUM_2658417=y
|
||||||
|
CONFIG_ARM64_ERRATUM_819472=y
|
||||||
|
CONFIG_ARM64_ERRATUM_824069=y
|
||||||
|
CONFIG_ARM64_ERRATUM_826319=y
|
||||||
|
CONFIG_ARM64_ERRATUM_827319=y
|
||||||
|
CONFIG_ARM64_ERRATUM_832075=y
|
||||||
|
CONFIG_ARM64_ERRATUM_843419=y
|
||||||
|
CONFIG_ARM64_ERRATUM_858921=y
|
||||||
|
CONFIG_ARM64_HW_AFDBM=y
|
||||||
|
CONFIG_ARM64_LD_HAS_FIX_ERRATUM_843419=y
|
||||||
|
CONFIG_ARM64_MTE=y
|
||||||
|
CONFIG_ARM64_PAGE_SHIFT=12
|
||||||
|
CONFIG_ARM64_PA_BITS=48
|
||||||
|
CONFIG_ARM64_PA_BITS_48=y
|
||||||
|
CONFIG_ARM64_PTR_AUTH=y
|
||||||
|
CONFIG_ARM64_PTR_AUTH_KERNEL=y
|
||||||
|
CONFIG_ARM64_RAS_EXTN=y
|
||||||
|
CONFIG_ARM64_SME=y
|
||||||
|
CONFIG_ARM64_SVE=y
|
||||||
|
# CONFIG_ARM64_SW_TTBR0_PAN is not set
|
||||||
|
CONFIG_ARM64_TAGGED_ADDR_ABI=y
|
||||||
|
CONFIG_ARM64_TLB_RANGE=y
|
||||||
|
CONFIG_ARM64_VA_BITS=39
|
||||||
|
CONFIG_ARM64_VA_BITS_39=y
|
||||||
|
CONFIG_ARM64_WORKAROUND_CLEAN_CACHE=y
|
||||||
|
CONFIG_ARM64_WORKAROUND_REPEAT_TLBI=y
|
||||||
|
CONFIG_ARM64_WORKAROUND_SPECULATIVE_AT=y
|
||||||
|
CONFIG_ARM64_WORKAROUND_TSB_FLUSH_FAILURE=y
|
||||||
|
CONFIG_ARM_AIROHA_SOC_CPUFREQ=y
|
||||||
|
CONFIG_ARM_AMBA=y
|
||||||
|
CONFIG_ARM_ARCH_TIMER=y
|
||||||
|
CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y
|
||||||
|
CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND=y
|
||||||
|
CONFIG_ARM_GIC=y
|
||||||
|
CONFIG_ARM_GIC_V2M=y
|
||||||
|
CONFIG_ARM_GIC_V3=y
|
||||||
|
CONFIG_ARM_GIC_V3_ITS=y
|
||||||
|
CONFIG_ARM_GIC_V3_ITS_PCI=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_BINFMT_MISC=y
|
||||||
|
# CONFIG_BLK_CGROUP is not set
|
||||||
|
CONFIG_BLK_DEBUG_FS=y
|
||||||
|
# CONFIG_BLK_DEV_INITRD is not set
|
||||||
|
CONFIG_BLK_DEV_RAM=y
|
||||||
|
CONFIG_BLK_DEV_RAM_COUNT=16
|
||||||
|
CONFIG_BLK_DEV_RAM_SIZE=4096
|
||||||
|
CONFIG_BLK_MQ_PCI=y
|
||||||
|
CONFIG_BLK_PM=y
|
||||||
|
CONFIG_BLOCK_LEGACY_AUTOLOAD=y
|
||||||
|
# CONFIG_BPF_JIT is not set
|
||||||
|
# CONFIG_BPF_SYSCALL is not set
|
||||||
|
# CONFIG_BRIDGE_VLAN_FILTERING is not set
|
||||||
|
CONFIG_BUFFER_HEAD=y
|
||||||
|
CONFIG_BUILTIN_RETURN_ADDRESS_STRIPS_PAC=y
|
||||||
|
CONFIG_CAVIUM_ERRATUM_22375=y
|
||||||
|
CONFIG_CAVIUM_ERRATUM_23154=y
|
||||||
|
CONFIG_CAVIUM_ERRATUM_27456=y
|
||||||
|
CONFIG_CAVIUM_ERRATUM_30115=y
|
||||||
|
CONFIG_CAVIUM_TX2_ERRATUM_219=y
|
||||||
|
CONFIG_CC_HAVE_SHADOW_CALL_STACK=y
|
||||||
|
CONFIG_CC_HAVE_STACKPROTECTOR_SYSREG=y
|
||||||
|
CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
|
||||||
|
CONFIG_CC_NO_ARRAY_BOUNDS=y
|
||||||
|
# CONFIG_CFS_BANDWIDTH is not set
|
||||||
|
CONFIG_CGROUPS=y
|
||||||
|
CONFIG_CGROUP_CPUACCT=y
|
||||||
|
CONFIG_CGROUP_DEBUG=y
|
||||||
|
CONFIG_CGROUP_DEVICE=y
|
||||||
|
CONFIG_CGROUP_FREEZER=y
|
||||||
|
# CONFIG_CGROUP_NET_CLASSID is not set
|
||||||
|
# CONFIG_CGROUP_NET_PRIO is not set
|
||||||
|
# CONFIG_CGROUP_PERF is not set
|
||||||
|
# CONFIG_CGROUP_PIDS is not set
|
||||||
|
# CONFIG_CGROUP_RDMA is not set
|
||||||
|
CONFIG_CGROUP_SCHED=y
|
||||||
|
CONFIG_CLONE_BACKWARDS=y
|
||||||
|
CONFIG_COMMON_CLK=y
|
||||||
|
CONFIG_COMMON_CLK_EN7523=y
|
||||||
|
CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
|
||||||
|
CONFIG_COMPAT_32BIT_TIME=y
|
||||||
|
CONFIG_CONTEXT_TRACKING=y
|
||||||
|
CONFIG_CONTEXT_TRACKING_IDLE=y
|
||||||
|
CONFIG_COREDUMP=y
|
||||||
|
CONFIG_CPUSETS=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 is not set
|
||||||
|
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_IDLE=y
|
||||||
|
CONFIG_CPU_IDLE_GOV_MENU=y
|
||||||
|
CONFIG_CPU_ISOLATION=y
|
||||||
|
CONFIG_CPU_LITTLE_ENDIAN=y
|
||||||
|
CONFIG_CPU_MITIGATIONS=y
|
||||||
|
CONFIG_CPU_PM=y
|
||||||
|
CONFIG_CPU_RMAP=y
|
||||||
|
CONFIG_CRC16=y
|
||||||
|
CONFIG_CRC_CCITT=y
|
||||||
|
CONFIG_CROSS_MEMORY_ATTACH=y
|
||||||
|
CONFIG_CRYPTO_AUTHENC=y
|
||||||
|
CONFIG_CRYPTO_CBC=y
|
||||||
|
CONFIG_CRYPTO_CRC32C=y
|
||||||
|
CONFIG_CRYPTO_DEFLATE=y
|
||||||
|
CONFIG_CRYPTO_DES=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_ECHAINIV=y
|
||||||
|
CONFIG_CRYPTO_GENIV=y
|
||||||
|
CONFIG_CRYPTO_HASH_INFO=y
|
||||||
|
CONFIG_CRYPTO_HMAC=y
|
||||||
|
CONFIG_CRYPTO_HW=y
|
||||||
|
CONFIG_CRYPTO_JITTERENTROPY=y
|
||||||
|
CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
|
||||||
|
CONFIG_CRYPTO_LIB_DES=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_MD5=y
|
||||||
|
CONFIG_CRYPTO_MICHAEL_MIC=y
|
||||||
|
# CONFIG_CRYPTO_PCRYPT is not set
|
||||||
|
CONFIG_CRYPTO_RNG=y
|
||||||
|
CONFIG_CRYPTO_RNG2=y
|
||||||
|
CONFIG_CRYPTO_RNG_DEFAULT=y
|
||||||
|
CONFIG_CRYPTO_SEQIV=y
|
||||||
|
CONFIG_CRYPTO_SHA1=y
|
||||||
|
CONFIG_CRYPTO_SHA256=y
|
||||||
|
CONFIG_CRYPTO_SHA3=y
|
||||||
|
CONFIG_CRYPTO_SHA512=y
|
||||||
|
CONFIG_CRYPTO_ZSTD=y
|
||||||
|
CONFIG_DCACHE_WORD_ACCESS=y
|
||||||
|
CONFIG_DEBUG_BUGVERBOSE=y
|
||||||
|
# CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT is not set
|
||||||
|
CONFIG_DEBUG_INFO_NONE=y
|
||||||
|
CONFIG_DEBUG_MISC=y
|
||||||
|
CONFIG_DEVMEM=y
|
||||||
|
CONFIG_DMADEVICES=y
|
||||||
|
CONFIG_DMA_BOUNCE_UNALIGNED_KMALLOC=y
|
||||||
|
CONFIG_DMA_DIRECT_REMAP=y
|
||||||
|
CONFIG_DMA_ENGINE=y
|
||||||
|
CONFIG_DMA_OF=y
|
||||||
|
CONFIG_DMA_OPS=y
|
||||||
|
CONFIG_DTC=y
|
||||||
|
CONFIG_EDAC_SUPPORT=y
|
||||||
|
CONFIG_EXT2_FS=y
|
||||||
|
CONFIG_EXT2_FS_POSIX_ACL=y
|
||||||
|
CONFIG_EXT2_FS_SECURITY=y
|
||||||
|
CONFIG_EXT3_FS=y
|
||||||
|
CONFIG_EXT3_FS_POSIX_ACL=y
|
||||||
|
CONFIG_EXT3_FS_SECURITY=y
|
||||||
|
CONFIG_EXT4_FS=y
|
||||||
|
CONFIG_EXT4_FS_POSIX_ACL=y
|
||||||
|
CONFIG_EXT4_FS_SECURITY=y
|
||||||
|
CONFIG_FAIR_GROUP_SCHED=y
|
||||||
|
CONFIG_FAT_DEFAULT_CODEPAGE=936
|
||||||
|
CONFIG_FAT_DEFAULT_IOCHARSET="utf8"
|
||||||
|
CONFIG_FAT_FS=y
|
||||||
|
CONFIG_FIXED_PHY=y
|
||||||
|
CONFIG_FIX_EARLYCON_MEM=y
|
||||||
|
# CONFIG_FORTIFY_SOURCE is not set
|
||||||
|
CONFIG_FRAME_POINTER=y
|
||||||
|
CONFIG_FREEZER=y
|
||||||
|
CONFIG_FSL_ERRATUM_A008585=y
|
||||||
|
CONFIG_FS_IOMAP=y
|
||||||
|
CONFIG_FS_MBCACHE=y
|
||||||
|
CONFIG_FS_POSIX_ACL=y
|
||||||
|
CONFIG_FUJITSU_ERRATUM_010001=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_GCC10_NO_ARRAY_BOUNDS=y
|
||||||
|
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_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_HARDENED_USERCOPY is not set
|
||||||
|
CONFIG_HARDIRQS_SW_RESEND=y
|
||||||
|
CONFIG_HAS_DMA=y
|
||||||
|
CONFIG_HAS_IOMEM=y
|
||||||
|
CONFIG_HAS_IOPORT=y
|
||||||
|
CONFIG_HAS_IOPORT_MAP=y
|
||||||
|
CONFIG_HISILICON_ERRATUM_161010101=y
|
||||||
|
CONFIG_HISILICON_ERRATUM_161600802=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_PRESERVE_MTIME=y
|
||||||
|
CONFIG_INPUT=y
|
||||||
|
CONFIG_INPUT_EVDEV=y
|
||||||
|
CONFIG_INPUT_KEYBOARD=y
|
||||||
|
# CONFIG_INPUT_MISC is not set
|
||||||
|
CONFIG_INTERVAL_TREE=y
|
||||||
|
CONFIG_INTERVAL_TREE_SPAN_ITER=y
|
||||||
|
CONFIG_IOMMUFD=y
|
||||||
|
CONFIG_IOMMU_API=y
|
||||||
|
# CONFIG_IOMMU_DEBUGFS is not set
|
||||||
|
# CONFIG_IOMMU_DEFAULT_DMA_LAZY is not set
|
||||||
|
CONFIG_IOMMU_DEFAULT_DMA_STRICT=y
|
||||||
|
# CONFIG_IOMMU_DEFAULT_PASSTHROUGH is not set
|
||||||
|
CONFIG_IOMMU_DMA=y
|
||||||
|
CONFIG_IOMMU_IOVA=y
|
||||||
|
# CONFIG_IOMMU_IO_PGTABLE_ARMV7S is not set
|
||||||
|
# CONFIG_IOMMU_IO_PGTABLE_DART is not set
|
||||||
|
# CONFIG_IOMMU_IO_PGTABLE_LPAE is not set
|
||||||
|
CONFIG_IOMMU_SUPPORT=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_IOMMU=y
|
||||||
|
CONFIG_IRQ_WORK=y
|
||||||
|
# CONFIG_ISDN is not set
|
||||||
|
CONFIG_JBD2=y
|
||||||
|
# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
|
||||||
|
# CONFIG_JFFS2_FS_XATTR is not set
|
||||||
|
# CONFIG_JFFS2_SUMMARY is not set
|
||||||
|
CONFIG_JFFS2_ZLIB=y
|
||||||
|
CONFIG_KALLSYMS=y
|
||||||
|
CONFIG_LEGACY_DIRECT_IO=y
|
||||||
|
CONFIG_LEGACY_PTYS=y
|
||||||
|
CONFIG_LEGACY_PTY_COUNT=8
|
||||||
|
CONFIG_LIBCRC32C=y
|
||||||
|
CONFIG_LIBFDT=y
|
||||||
|
CONFIG_LOCALVERSION_AUTO=y
|
||||||
|
CONFIG_LOCK_DEBUGGING_SUPPORT=y
|
||||||
|
CONFIG_LOCK_SPIN_ON_OWNER=y
|
||||||
|
CONFIG_LOG_BUF_SHIFT=14
|
||||||
|
# CONFIG_LRU_GEN is not set
|
||||||
|
CONFIG_LZO_COMPRESS=y
|
||||||
|
CONFIG_LZO_DECOMPRESS=y
|
||||||
|
CONFIG_MDIO_BUS=y
|
||||||
|
CONFIG_MDIO_DEVICE=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_MMU_LAZY_TLB_REFCOUNT=y
|
||||||
|
CONFIG_MODULES_TREE_LOOKUP=y
|
||||||
|
CONFIG_MODULES_USE_ELF_RELA=y
|
||||||
|
CONFIG_MQ_IOSCHED_DEADLINE=y
|
||||||
|
CONFIG_MQ_IOSCHED_KYBER=y
|
||||||
|
CONFIG_MTD_CFI_ADV_OPTIONS=y
|
||||||
|
# CONFIG_MTD_CFI_AMDSTD is not set
|
||||||
|
CONFIG_MTD_CFI_GEOMETRY=y
|
||||||
|
# CONFIG_MTD_CFI_INTELEXT is not set
|
||||||
|
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
|
||||||
|
CONFIG_MTD_JEDECPROBE=y
|
||||||
|
CONFIG_MTD_NAND_CORE=y
|
||||||
|
CONFIG_MTD_NAND_ECC=y
|
||||||
|
CONFIG_MTD_NAND_MTK_BMT=y
|
||||||
|
CONFIG_MTD_OF_PARTS_AIROHA=y
|
||||||
|
CONFIG_MTD_RAW_NAND=y
|
||||||
|
CONFIG_MTD_SPI_NAND=y
|
||||||
|
CONFIG_MTD_SPLIT_FIRMWARE=y
|
||||||
|
CONFIG_MTD_SPLIT_FIRMWARE_NAME="tclinux"
|
||||||
|
CONFIG_MTD_SPLIT_FIT_FW=y
|
||||||
|
CONFIG_MTD_SPLIT_LZMA_FW=y
|
||||||
|
# CONFIG_MTD_SPLIT_SQUASHFS_ROOT is not set
|
||||||
|
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_NAMESPACES=y
|
||||||
|
CONFIG_NEED_DMA_MAP_STATE=y
|
||||||
|
CONFIG_NEED_SG_DMA_FLAGS=y
|
||||||
|
CONFIG_NEED_SG_DMA_LENGTH=y
|
||||||
|
CONFIG_NET_AIROHA=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_KEY=y
|
||||||
|
CONFIG_NET_KEY_MIGRATE=y
|
||||||
|
# CONFIG_NET_MEDIATEK_SOC is not set
|
||||||
|
CONFIG_NET_NS=y
|
||||||
|
# CONFIG_NET_SCHED is not set
|
||||||
|
CONFIG_NET_SELFTESTS=y
|
||||||
|
CONFIG_NET_SWITCHDEV=y
|
||||||
|
# CONFIG_NET_VENDOR_3COM is not set
|
||||||
|
CONFIG_NET_VENDOR_MEDIATEK=y
|
||||||
|
CONFIG_NLS=y
|
||||||
|
CONFIG_NLS_DEFAULT="utf8"
|
||||||
|
CONFIG_NO_HZ_COMMON=y
|
||||||
|
CONFIG_NO_HZ_IDLE=y
|
||||||
|
CONFIG_NR_CPUS=4
|
||||||
|
CONFIG_NTFS_DEBUG=y
|
||||||
|
CONFIG_NTFS_FS=y
|
||||||
|
CONFIG_NTFS_RW=y
|
||||||
|
CONFIG_NVIDIA_CARMEL_CNP_ERRATUM=y
|
||||||
|
CONFIG_OF=y
|
||||||
|
CONFIG_OF_ADDRESS=y
|
||||||
|
CONFIG_OF_EARLY_FLATTREE=y
|
||||||
|
CONFIG_OF_FLATTREE=y
|
||||||
|
CONFIG_OF_GPIO=y
|
||||||
|
CONFIG_OF_IOMMU=y
|
||||||
|
CONFIG_OF_IRQ=y
|
||||||
|
CONFIG_OF_KOBJ=y
|
||||||
|
CONFIG_OF_MDIO=y
|
||||||
|
# CONFIG_OVERLAY_FS_XINO_AUTO is not set
|
||||||
|
CONFIG_PAGE_POOL=y
|
||||||
|
CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
|
||||||
|
CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
|
||||||
|
# CONFIG_PANIC_ON_OOPS is not set
|
||||||
|
CONFIG_PANIC_ON_OOPS_VALUE=0
|
||||||
|
CONFIG_PANIC_TIMEOUT=0
|
||||||
|
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 is not set
|
||||||
|
CONFIG_PCIE_PME=y
|
||||||
|
CONFIG_PCI_DOMAINS=y
|
||||||
|
CONFIG_PCI_DOMAINS_GENERIC=y
|
||||||
|
CONFIG_PCI_MSI=y
|
||||||
|
CONFIG_PCPU_DEV_REFCNT=y
|
||||||
|
CONFIG_PCS_MTK_LYNXI=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_PID_NS=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_OPP=y
|
||||||
|
CONFIG_PM_SLEEP=y
|
||||||
|
CONFIG_PM_SLEEP_SMP=y
|
||||||
|
CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y
|
||||||
|
CONFIG_POSIX_MQUEUE=y
|
||||||
|
CONFIG_POSIX_MQUEUE_SYSCTL=y
|
||||||
|
CONFIG_POWER_RESET=y
|
||||||
|
CONFIG_POWER_RESET_SYSCON=y
|
||||||
|
CONFIG_POWER_SUPPLY=y
|
||||||
|
CONFIG_PREEMPT_NONE_BUILD=y
|
||||||
|
CONFIG_PROC_PAGE_MONITOR=y
|
||||||
|
CONFIG_PROC_PID_CPUSET=y
|
||||||
|
CONFIG_PTP_1588_CLOCK_OPTIONAL=y
|
||||||
|
CONFIG_QCOM_FALKOR_ERRATUM_1003=y
|
||||||
|
CONFIG_QCOM_FALKOR_ERRATUM_1009=y
|
||||||
|
CONFIG_QCOM_FALKOR_ERRATUM_E1041=y
|
||||||
|
CONFIG_QCOM_QDF2400_ERRATUM_0065=y
|
||||||
|
CONFIG_QUEUED_RWLOCKS=y
|
||||||
|
CONFIG_QUEUED_SPINLOCKS=y
|
||||||
|
CONFIG_RANDSTRUCT_NONE=y
|
||||||
|
CONFIG_RAS=y
|
||||||
|
CONFIG_RATIONAL=y
|
||||||
|
CONFIG_RCU_CPU_STALL_TIMEOUT=21
|
||||||
|
CONFIG_REGMAP=y
|
||||||
|
CONFIG_REGMAP_MMIO=y
|
||||||
|
CONFIG_RELOCATABLE=y
|
||||||
|
CONFIG_RESET_CONTROLLER=y
|
||||||
|
CONFIG_RFS_ACCEL=y
|
||||||
|
CONFIG_RODATA_FULL_DEFAULT_ENABLED=y
|
||||||
|
CONFIG_RPS=y
|
||||||
|
CONFIG_RSEQ=y
|
||||||
|
# CONFIG_RT_GROUP_SCHED is not set
|
||||||
|
CONFIG_RWSEM_SPIN_ON_OWNER=y
|
||||||
|
# CONFIG_SCHED_CORE is not set
|
||||||
|
CONFIG_SCHED_DEBUG=y
|
||||||
|
CONFIG_SCHED_MM_CID=y
|
||||||
|
CONFIG_SCHED_SMT=y
|
||||||
|
# CONFIG_SCHED_STACK_END_CHECK is not set
|
||||||
|
CONFIG_SECURITY=y
|
||||||
|
CONFIG_SECURITYFS=y
|
||||||
|
# CONFIG_SECURITY_DMESG_RESTRICT is not set
|
||||||
|
# CONFIG_SECURITY_NETWORK is not set
|
||||||
|
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_SERIO=y
|
||||||
|
CONFIG_SERIO_LIBPS2=y
|
||||||
|
CONFIG_SGETMASK_SYSCALL=y
|
||||||
|
CONFIG_SGL_ALLOC=y
|
||||||
|
CONFIG_SKB_EXTENSIONS=y
|
||||||
|
# CONFIG_SLAB_FREELIST_HARDENED is not set
|
||||||
|
# CONFIG_SLAB_FREELIST_RANDOM is not set
|
||||||
|
CONFIG_SLUB_DEBUG=y
|
||||||
|
CONFIG_SMP=y
|
||||||
|
CONFIG_SOCIONEXT_SYNQUACER_PREITS=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_SQUASHFS_EMBEDDED is not set
|
||||||
|
CONFIG_SQUASHFS_FILE_CACHE=y
|
||||||
|
# CONFIG_SQUASHFS_FILE_DIRECT is not set
|
||||||
|
CONFIG_SQUASHFS_ZLIB=y
|
||||||
|
CONFIG_STACKDEPOT=y
|
||||||
|
CONFIG_STACKPROTECTOR=y
|
||||||
|
CONFIG_STACKPROTECTOR_PER_TASK=y
|
||||||
|
CONFIG_STACKPROTECTOR_STRONG=y
|
||||||
|
CONFIG_STACKTRACE=y
|
||||||
|
# CONFIG_STAGING is not set
|
||||||
|
# CONFIG_STRIP_ASM_SYMS is not set
|
||||||
|
CONFIG_SURFACE_PLATFORMS=y
|
||||||
|
CONFIG_SUSPEND=y
|
||||||
|
CONFIG_SUSPEND_FREEZER=y
|
||||||
|
# CONFIG_SWAP is not set
|
||||||
|
CONFIG_SWIOTLB=y
|
||||||
|
CONFIG_SWPHY=y
|
||||||
|
CONFIG_SYSCTL_EXCEPTION_TRACE=y
|
||||||
|
CONFIG_SYSFS_SYSCALL=y
|
||||||
|
# CONFIG_TCP_CONG_ADVANCED is not set
|
||||||
|
CONFIG_TCP_MD5SIG=y
|
||||||
|
CONFIG_TEXTSEARCH_BM=y
|
||||||
|
CONFIG_TEXTSEARCH_FSM=y
|
||||||
|
CONFIG_TEXTSEARCH_KMP=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_GOV_USER_SPACE=y
|
||||||
|
CONFIG_THERMAL_OF=y
|
||||||
|
CONFIG_THERMAL_WRITABLE_TRIPS=y
|
||||||
|
CONFIG_THREAD_INFO_IN_TASK=y
|
||||||
|
CONFIG_TICK_CPU_ACCOUNTING=y
|
||||||
|
CONFIG_TIMER_OF=y
|
||||||
|
CONFIG_TIMER_PROBE=y
|
||||||
|
CONFIG_TIME_NS=y
|
||||||
|
# CONFIG_TMPFS_XATTR is not set
|
||||||
|
CONFIG_TRACE_IRQFLAGS_NMI_SUPPORT=y
|
||||||
|
CONFIG_TREE_RCU=y
|
||||||
|
CONFIG_TREE_SRCU=y
|
||||||
|
CONFIG_UBIFS_FS=y
|
||||||
|
CONFIG_UBIFS_FS_ADVANCED_COMPR=y
|
||||||
|
CONFIG_UEVENT_HELPER_PATH=""
|
||||||
|
CONFIG_UNMAP_KERNEL_AT_EL0=y
|
||||||
|
CONFIG_USELIB=y
|
||||||
|
CONFIG_USER_NS=y
|
||||||
|
CONFIG_UTS_NS=y
|
||||||
|
CONFIG_VFAT_FS=y
|
||||||
|
CONFIG_VMAP_STACK=y
|
||||||
|
CONFIG_VM_EVENT_COUNTERS=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_XZ_DEC_ARM=y
|
||||||
|
CONFIG_XZ_DEC_ARMTHUMB=y
|
||||||
|
CONFIG_XZ_DEC_BCJ=y
|
||||||
|
CONFIG_XZ_DEC_IA64=y
|
||||||
|
CONFIG_XZ_DEC_POWERPC=y
|
||||||
|
CONFIG_XZ_DEC_SPARC=y
|
||||||
|
CONFIG_XZ_DEC_X86=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
target/linux/airoha/en7581/target.mk
Normal file
11
target/linux/airoha/en7581/target.mk
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
ARCH:=aarch64
|
||||||
|
SUBTARGET:=en7581
|
||||||
|
BOARDNAME:=EN7581
|
||||||
|
CPU_TYPE:=cortex-a53
|
||||||
|
KERNELNAME:=Image dtbs
|
||||||
|
FEATURES+=pwm source-only
|
||||||
|
|
||||||
|
define Target/Description
|
||||||
|
Build firmware images for Airoha en7581 ARM based boards.
|
||||||
|
endef
|
||||||
|
|
||||||
@ -1 +0,0 @@
|
|||||||
BOARDNAME:=Generic
|
|
||||||
@ -1,12 +1,6 @@
|
|||||||
include $(TOPDIR)/rules.mk
|
include $(TOPDIR)/rules.mk
|
||||||
include $(INCLUDE_DIR)/image.mk
|
include $(INCLUDE_DIR)/image.mk
|
||||||
|
|
||||||
KERNEL_LOADADDR := 0x80208000
|
|
||||||
|
|
||||||
define Target/Description
|
|
||||||
Build firmware images for Airoha EN7523 ARM based boards.
|
|
||||||
endef
|
|
||||||
|
|
||||||
# default all platform image(fit) build
|
# default all platform image(fit) build
|
||||||
define Device/Default
|
define Device/Default
|
||||||
PROFILES = Default $$(DEVICE_NAME)
|
PROFILES = Default $$(DEVICE_NAME)
|
||||||
@ -22,16 +16,10 @@ define Device/Default
|
|||||||
pad-rootfs | append-metadata
|
pad-rootfs | append-metadata
|
||||||
endef
|
endef
|
||||||
|
|
||||||
|
include $(SUBTARGET).mk
|
||||||
|
|
||||||
define Image/Build
|
define Image/Build
|
||||||
$(call Image/Build/$(1),$(1))
|
$(call Image/Build/$(1),$(1))
|
||||||
endef
|
endef
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
$(eval $(call BuildImage))
|
$(eval $(call BuildImage))
|
||||||
|
|||||||
@ -0,0 +1,13 @@
|
|||||||
|
KERNEL_LOADADDR := 0x80208000
|
||||||
|
|
||||||
|
define Target/Description
|
||||||
|
Build firmware images for Airoha EN7523 ARM based boards.
|
||||||
|
endef
|
||||||
|
|
||||||
|
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
|
||||||
27
target/linux/airoha/image/en7581.mk
Normal file
27
target/linux/airoha/image/en7581.mk
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
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_en7581-evb
|
||||||
|
$(call Device/FitImageLzma)
|
||||||
|
DEVICE_VENDOR := Airoha
|
||||||
|
DEVICE_MODEL := EN7581 Evaluation Board (SNAND)
|
||||||
|
DEVICE_PACKAGES := kmod-leds-pwm kmod-i2c-en7581 kmod-pwm-airoha kmod-input-gpio-keys-polled
|
||||||
|
DEVICE_DTS := en7581-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
|
||||||
|
endef
|
||||||
|
TARGET_DEVICES += airoha_en7581-evb
|
||||||
|
|
||||||
|
define Device/airoha_en7581-evb-emmc
|
||||||
|
DEVICE_VENDOR := Airoha
|
||||||
|
DEVICE_MODEL := EN7581 Evaluation Board (EMMC)
|
||||||
|
DEVICE_DTS := en7581-evb-emmc
|
||||||
|
DEVICE_DTS_DIR := ../dts
|
||||||
|
DEVICE_PACKAGES := kmod-i2c-en7581
|
||||||
|
endef
|
||||||
|
TARGET_DEVICES += airoha_en7581-evb-emmc
|
||||||
42
target/linux/airoha/modules.mk
Normal file
42
target/linux/airoha/modules.mk
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
# SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
|
||||||
|
OTHER_MENU:=Other modules
|
||||||
|
|
||||||
|
I2C_MT7621_MODULES:= \
|
||||||
|
CONFIG_I2C_MT7621:drivers/i2c/busses/i2c-mt7621
|
||||||
|
|
||||||
|
define KernelPackage/i2c-en7581
|
||||||
|
SUBMENU:=$(OTHER_MENU)
|
||||||
|
$(call i2c_defaults,$(I2C_MT7621_MODULES),79)
|
||||||
|
TITLE:=Airoha I2C Controller
|
||||||
|
DEPENDS:=+kmod-i2c-core \
|
||||||
|
@(TARGET_airoha_en7581)
|
||||||
|
endef
|
||||||
|
|
||||||
|
define KernelPackage/i2c-en7581/description
|
||||||
|
Kernel modules for enable mt7621 i2c controller.
|
||||||
|
endef
|
||||||
|
|
||||||
|
$(eval $(call KernelPackage,i2c-en7581))
|
||||||
|
|
||||||
|
|
||||||
|
define KernelPackage/pwm-en7581
|
||||||
|
SUBMENU:=$(OTHER_MENU)
|
||||||
|
TITLE:=Airoha EN7581 PWM
|
||||||
|
DEPENDS:=@(TARGET_airoha_en7581)
|
||||||
|
KCONFIG:= \
|
||||||
|
CONFIG_PWM=y \
|
||||||
|
CONFIG_PWM_AIROHA=y \
|
||||||
|
CONFIG_PWM_SYSFS=y
|
||||||
|
FILES:= \
|
||||||
|
$(LINUX_DIR)/drivers/pwm/pwm-airoha.ko
|
||||||
|
AUTOLOAD:=$(call AutoProbe,pwm-airoha)
|
||||||
|
endef
|
||||||
|
|
||||||
|
define KernelPackage/pwm-en7581/description
|
||||||
|
Kernel module to use the PWM channel on Airoha SoC
|
||||||
|
endef
|
||||||
|
|
||||||
|
$(eval $(call KernelPackage,pwm-en7581))
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,34 @@
|
|||||||
|
From 428ae88ef519f2009fac37563de76ffa6f93046f Mon Sep 17 00:00:00 2001
|
||||||
|
From: Daniel Danzberger <dd@embedd.com>
|
||||||
|
Date: Sat, 9 Mar 2024 10:32:16 +0100
|
||||||
|
Subject: [PATCH] arm64: add Airoha EN7581 platform
|
||||||
|
|
||||||
|
Introduce the Kconfig entry for the Airoha EN7581 multicore architecture
|
||||||
|
available in the Airoha EN7581 evaluation board.
|
||||||
|
|
||||||
|
Signed-off-by: Daniel Danzberger <dd@embedd.com>
|
||||||
|
Co-developed-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||||
|
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||||
|
Link: https://lore.kernel.org/r/d52d95db313e6a58ba997ba2181faf78a1014bcc.1709975956.git.lorenzo@kernel.org
|
||||||
|
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
|
||||||
|
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
|
||||||
|
---
|
||||||
|
arch/arm64/Kconfig.platforms | 7 +++++++
|
||||||
|
1 file changed, 7 insertions(+)
|
||||||
|
|
||||||
|
--- a/arch/arm64/Kconfig.platforms
|
||||||
|
+++ b/arch/arm64/Kconfig.platforms
|
||||||
|
@@ -8,6 +8,13 @@ config ARCH_ACTIONS
|
||||||
|
help
|
||||||
|
This enables support for the Actions Semiconductor S900 SoC family.
|
||||||
|
|
||||||
|
+config ARCH_AIROHA
|
||||||
|
+ bool "Airoha SoC Support"
|
||||||
|
+ select ARM_PSCI
|
||||||
|
+ select HAVE_ARM_ARCH_TIMER
|
||||||
|
+ help
|
||||||
|
+ This enables support for the ARM64 based Airoha SoCs.
|
||||||
|
+
|
||||||
|
config ARCH_SUNXI
|
||||||
|
bool "Allwinner sunxi 64-bit SoC Family"
|
||||||
|
select ARCH_HAS_RESET_CONTROLLER
|
||||||
@ -0,0 +1,27 @@
|
|||||||
|
From fd6acb0d21b8683fd8804129beeb4fe629488aff Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||||
|
Date: Tue, 9 Jul 2024 00:42:38 +0200
|
||||||
|
Subject: [PATCH] i2c: mt7621: Add Airoha EN7581 i2c support
|
||||||
|
|
||||||
|
Introduce i2c support to Airoha EN7581 SoC through the i2c-mt7621
|
||||||
|
driver.
|
||||||
|
|
||||||
|
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
|
||||||
|
Tested-by: Ray Liu <ray.liu@airoha.com>
|
||||||
|
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||||
|
Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
|
||||||
|
---
|
||||||
|
drivers/i2c/busses/Kconfig | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
--- a/drivers/i2c/busses/Kconfig
|
||||||
|
+++ b/drivers/i2c/busses/Kconfig
|
||||||
|
@@ -839,7 +839,7 @@ config I2C_MT65XX
|
||||||
|
|
||||||
|
config I2C_MT7621
|
||||||
|
tristate "MT7621/MT7628 I2C Controller"
|
||||||
|
- depends on (RALINK && (SOC_MT7620 || SOC_MT7621)) || COMPILE_TEST
|
||||||
|
+ depends on (RALINK && (SOC_MT7620 || SOC_MT7621)) || ARCH_AIROHA || COMPILE_TEST
|
||||||
|
help
|
||||||
|
Say Y here to include support for I2C controller in the
|
||||||
|
MediaTek MT7621/MT7628 SoCs.
|
||||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,46 @@
|
|||||||
|
From 1f038d5897fe6b439039fc28420842abcc0d126b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||||
|
Date: Wed, 17 Jul 2024 10:15:46 +0200
|
||||||
|
Subject: [PATCH] net: airoha: fix error branch in airoha_dev_xmit and
|
||||||
|
airoha_set_gdm_ports
|
||||||
|
|
||||||
|
Fix error case management in airoha_dev_xmit routine since we need to
|
||||||
|
DMA unmap pending buffers starting from q->head.
|
||||||
|
Moreover fix a typo in error case branch in airoha_set_gdm_ports
|
||||||
|
routine.
|
||||||
|
|
||||||
|
Fixes: 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/b628871bc8ae4861b5e2ab4db90aaf373cbb7cee.1721203880.git.lorenzo@kernel.org
|
||||||
|
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||||
|
---
|
||||||
|
drivers/net/ethernet/mediatek/airoha_eth.c | 10 ++++++----
|
||||||
|
1 file changed, 6 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/net/ethernet/mediatek/airoha_eth.c
|
||||||
|
+++ b/drivers/net/ethernet/mediatek/airoha_eth.c
|
||||||
|
@@ -977,7 +977,7 @@ static int airoha_set_gdm_ports(struct a
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
error:
|
||||||
|
- for (i--; i >= 0; i++)
|
||||||
|
+ for (i--; i >= 0; i--)
|
||||||
|
airoha_set_gdm_port(eth, port_list[i], false);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
@@ -2432,9 +2432,11 @@ static netdev_tx_t airoha_dev_xmit(struc
|
||||||
|
return NETDEV_TX_OK;
|
||||||
|
|
||||||
|
error_unmap:
|
||||||
|
- for (i--; i >= 0; i++)
|
||||||
|
- dma_unmap_single(dev->dev.parent, q->entry[i].dma_addr,
|
||||||
|
- q->entry[i].dma_len, DMA_TO_DEVICE);
|
||||||
|
+ 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);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
spin_unlock_bh(&q->lock);
|
||||||
|
error:
|
||||||
@ -0,0 +1,39 @@
|
|||||||
|
From 4e076ff6ad5302c015617da30d877b4cdcbdf613 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||||
|
Date: Wed, 17 Jul 2024 10:47:19 +0200
|
||||||
|
Subject: [PATCH] net: airoha: Fix NULL pointer dereference in
|
||||||
|
airoha_qdma_cleanup_rx_queue()
|
||||||
|
|
||||||
|
Move page_pool_get_dma_dir() inside the while loop of
|
||||||
|
airoha_qdma_cleanup_rx_queue routine in order to avoid possible NULL
|
||||||
|
pointer dereference if airoha_qdma_init_rx_queue() fails before
|
||||||
|
properly allocating the page_pool pointer.
|
||||||
|
|
||||||
|
Fixes: 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/7330a41bba720c33abc039955f6172457a3a34f0.1721205981.git.lorenzo@kernel.org
|
||||||
|
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||||
|
---
|
||||||
|
drivers/net/ethernet/mediatek/airoha_eth.c | 3 +--
|
||||||
|
1 file changed, 1 insertion(+), 2 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/net/ethernet/mediatek/airoha_eth.c
|
||||||
|
+++ b/drivers/net/ethernet/mediatek/airoha_eth.c
|
||||||
|
@@ -1586,7 +1586,6 @@ static int airoha_qdma_init_rx_queue(str
|
||||||
|
|
||||||
|
static void airoha_qdma_cleanup_rx_queue(struct airoha_queue *q)
|
||||||
|
{
|
||||||
|
- enum dma_data_direction dir = page_pool_get_dma_dir(q->page_pool);
|
||||||
|
struct airoha_eth *eth = q->eth;
|
||||||
|
|
||||||
|
while (q->queued) {
|
||||||
|
@@ -1594,7 +1593,7 @@ static void airoha_qdma_cleanup_rx_queue
|
||||||
|
struct page *page = virt_to_head_page(e->buf);
|
||||||
|
|
||||||
|
dma_sync_single_for_cpu(eth->dev, e->dma_addr, e->dma_len,
|
||||||
|
- dir);
|
||||||
|
+ page_pool_get_dma_dir(q->page_pool));
|
||||||
|
page_pool_put_full_page(q->page_pool, page, false);
|
||||||
|
q->tail = (q->tail + 1) % q->ndesc;
|
||||||
|
q->queued--;
|
||||||
@ -0,0 +1,27 @@
|
|||||||
|
From 39a9c25bcdfb5e88995841c47439b74cac74a527 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||||
|
Date: Fri, 19 Jul 2024 22:38:31 +0200
|
||||||
|
Subject: [PATCH] net: airoha: Fix MBI_RX_AGE_SEL_MASK definition
|
||||||
|
|
||||||
|
Fix copy-paste error in MBI_RX_AGE_SEL_MASK macro definition
|
||||||
|
|
||||||
|
Fixes: 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/d27d0465be1bff3369e886e5f10c4d37fefc4934.1721419930.git.lorenzo@kernel.org
|
||||||
|
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||||
|
---
|
||||||
|
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
|
||||||
|
@@ -249,7 +249,7 @@
|
||||||
|
#define REG_FE_GDM_RX_ETH_L1023_CNT_H(_n) (GDM_BASE(_n) + 0x2fc)
|
||||||
|
|
||||||
|
#define REG_GDM2_CHN_RLS (GDM2_BASE + 0x20)
|
||||||
|
-#define MBI_RX_AGE_SEL_MASK GENMASK(18, 17)
|
||||||
|
+#define MBI_RX_AGE_SEL_MASK GENMASK(26, 25)
|
||||||
|
#define MBI_TX_AGE_SEL_MASK GENMASK(18, 17)
|
||||||
|
|
||||||
|
#define REG_GDM3_FWD_CFG GDM3_BASE
|
||||||
@ -0,0 +1,553 @@
|
|||||||
|
From 16874d1cf3818a5804cded8eaff634122b1d6c7c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||||
|
Date: Thu, 1 Aug 2024 16:35:03 +0200
|
||||||
|
Subject: [PATCH 1/8] net: airoha: Introduce airoha_qdma struct
|
||||||
|
|
||||||
|
Introduce airoha_qdma struct and move qdma IO register mapping in
|
||||||
|
airoha_qdma. This is a preliminary patch to enable both QDMA controllers
|
||||||
|
available on EN7581 SoC.
|
||||||
|
|
||||||
|
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||||
|
Link: https://patch.msgid.link/7df163bdc72ee29c3d27a0cbf54522ffeeafe53c.1722522582.git.lorenzo@kernel.org
|
||||||
|
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||||
|
---
|
||||||
|
drivers/net/ethernet/mediatek/airoha_eth.c | 197 ++++++++++++---------
|
||||||
|
1 file changed, 112 insertions(+), 85 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/net/ethernet/mediatek/airoha_eth.c
|
||||||
|
+++ b/drivers/net/ethernet/mediatek/airoha_eth.c
|
||||||
|
@@ -18,6 +18,7 @@
|
||||||
|
#include <uapi/linux/ppp_defs.h>
|
||||||
|
|
||||||
|
#define AIROHA_MAX_NUM_GDM_PORTS 1
|
||||||
|
+#define AIROHA_MAX_NUM_QDMA 1
|
||||||
|
#define AIROHA_MAX_NUM_RSTS 3
|
||||||
|
#define AIROHA_MAX_NUM_XSI_RSTS 5
|
||||||
|
#define AIROHA_MAX_MTU 2000
|
||||||
|
@@ -782,6 +783,10 @@ struct airoha_hw_stats {
|
||||||
|
u64 rx_len[7];
|
||||||
|
};
|
||||||
|
|
||||||
|
+struct airoha_qdma {
|
||||||
|
+ void __iomem *regs;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
struct airoha_gdm_port {
|
||||||
|
struct net_device *dev;
|
||||||
|
struct airoha_eth *eth;
|
||||||
|
@@ -794,8 +799,6 @@ struct airoha_eth {
|
||||||
|
struct device *dev;
|
||||||
|
|
||||||
|
unsigned long state;
|
||||||
|
-
|
||||||
|
- void __iomem *qdma_regs;
|
||||||
|
void __iomem *fe_regs;
|
||||||
|
|
||||||
|
/* protect concurrent irqmask accesses */
|
||||||
|
@@ -806,6 +809,7 @@ struct airoha_eth {
|
||||||
|
struct reset_control_bulk_data rsts[AIROHA_MAX_NUM_RSTS];
|
||||||
|
struct reset_control_bulk_data xsi_rsts[AIROHA_MAX_NUM_XSI_RSTS];
|
||||||
|
|
||||||
|
+ struct airoha_qdma qdma[AIROHA_MAX_NUM_QDMA];
|
||||||
|
struct airoha_gdm_port *ports[AIROHA_MAX_NUM_GDM_PORTS];
|
||||||
|
|
||||||
|
struct net_device *napi_dev;
|
||||||
|
@@ -850,16 +854,16 @@ static u32 airoha_rmw(void __iomem *base
|
||||||
|
#define airoha_fe_clear(eth, offset, val) \
|
||||||
|
airoha_rmw((eth)->fe_regs, (offset), (val), 0)
|
||||||
|
|
||||||
|
-#define airoha_qdma_rr(eth, offset) \
|
||||||
|
- airoha_rr((eth)->qdma_regs, (offset))
|
||||||
|
-#define airoha_qdma_wr(eth, offset, val) \
|
||||||
|
- airoha_wr((eth)->qdma_regs, (offset), (val))
|
||||||
|
-#define airoha_qdma_rmw(eth, offset, mask, val) \
|
||||||
|
- airoha_rmw((eth)->qdma_regs, (offset), (mask), (val))
|
||||||
|
-#define airoha_qdma_set(eth, offset, val) \
|
||||||
|
- airoha_rmw((eth)->qdma_regs, (offset), 0, (val))
|
||||||
|
-#define airoha_qdma_clear(eth, offset, val) \
|
||||||
|
- airoha_rmw((eth)->qdma_regs, (offset), (val), 0)
|
||||||
|
+#define airoha_qdma_rr(qdma, offset) \
|
||||||
|
+ airoha_rr((qdma)->regs, (offset))
|
||||||
|
+#define airoha_qdma_wr(qdma, offset, val) \
|
||||||
|
+ airoha_wr((qdma)->regs, (offset), (val))
|
||||||
|
+#define airoha_qdma_rmw(qdma, offset, mask, val) \
|
||||||
|
+ airoha_rmw((qdma)->regs, (offset), (mask), (val))
|
||||||
|
+#define airoha_qdma_set(qdma, offset, val) \
|
||||||
|
+ airoha_rmw((qdma)->regs, (offset), 0, (val))
|
||||||
|
+#define airoha_qdma_clear(qdma, offset, val) \
|
||||||
|
+ airoha_rmw((qdma)->regs, (offset), (val), 0)
|
||||||
|
|
||||||
|
static void airoha_qdma_set_irqmask(struct airoha_eth *eth, int index,
|
||||||
|
u32 clear, u32 set)
|
||||||
|
@@ -873,11 +877,12 @@ static void airoha_qdma_set_irqmask(stru
|
||||||
|
|
||||||
|
eth->irqmask[index] &= ~clear;
|
||||||
|
eth->irqmask[index] |= set;
|
||||||
|
- airoha_qdma_wr(eth, REG_INT_ENABLE(index), eth->irqmask[index]);
|
||||||
|
+ airoha_qdma_wr(ð->qdma[0], REG_INT_ENABLE(index),
|
||||||
|
+ eth->irqmask[index]);
|
||||||
|
/* Read irq_enable register in order to guarantee the update above
|
||||||
|
* completes in the spinlock critical section.
|
||||||
|
*/
|
||||||
|
- airoha_qdma_rr(eth, REG_INT_ENABLE(index));
|
||||||
|
+ airoha_qdma_rr(ð->qdma[0], REG_INT_ENABLE(index));
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(ð->irq_lock, flags);
|
||||||
|
}
|
||||||
|
@@ -1383,6 +1388,7 @@ static int airoha_fe_init(struct airoha_
|
||||||
|
static int airoha_qdma_fill_rx_queue(struct airoha_queue *q)
|
||||||
|
{
|
||||||
|
enum dma_data_direction dir = page_pool_get_dma_dir(q->page_pool);
|
||||||
|
+ struct airoha_qdma *qdma = &q->eth->qdma[0];
|
||||||
|
struct airoha_eth *eth = q->eth;
|
||||||
|
int qid = q - ð->q_rx[0];
|
||||||
|
int nframes = 0;
|
||||||
|
@@ -1420,7 +1426,8 @@ static int airoha_qdma_fill_rx_queue(str
|
||||||
|
WRITE_ONCE(desc->msg2, 0);
|
||||||
|
WRITE_ONCE(desc->msg3, 0);
|
||||||
|
|
||||||
|
- airoha_qdma_rmw(eth, REG_RX_CPU_IDX(qid), RX_RING_CPU_IDX_MASK,
|
||||||
|
+ airoha_qdma_rmw(qdma, REG_RX_CPU_IDX(qid),
|
||||||
|
+ RX_RING_CPU_IDX_MASK,
|
||||||
|
FIELD_PREP(RX_RING_CPU_IDX_MASK, q->head));
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1529,7 +1536,8 @@ static int airoha_qdma_rx_napi_poll(stru
|
||||||
|
}
|
||||||
|
|
||||||
|
static int airoha_qdma_init_rx_queue(struct airoha_eth *eth,
|
||||||
|
- struct airoha_queue *q, int ndesc)
|
||||||
|
+ struct airoha_queue *q,
|
||||||
|
+ struct airoha_qdma *qdma, int ndesc)
|
||||||
|
{
|
||||||
|
const struct page_pool_params pp_params = {
|
||||||
|
.order = 0,
|
||||||
|
@@ -1569,14 +1577,15 @@ static int airoha_qdma_init_rx_queue(str
|
||||||
|
|
||||||
|
netif_napi_add(eth->napi_dev, &q->napi, airoha_qdma_rx_napi_poll);
|
||||||
|
|
||||||
|
- airoha_qdma_wr(eth, REG_RX_RING_BASE(qid), dma_addr);
|
||||||
|
- airoha_qdma_rmw(eth, REG_RX_RING_SIZE(qid), RX_RING_SIZE_MASK,
|
||||||
|
+ airoha_qdma_wr(qdma, REG_RX_RING_BASE(qid), dma_addr);
|
||||||
|
+ airoha_qdma_rmw(qdma, REG_RX_RING_SIZE(qid),
|
||||||
|
+ RX_RING_SIZE_MASK,
|
||||||
|
FIELD_PREP(RX_RING_SIZE_MASK, ndesc));
|
||||||
|
|
||||||
|
thr = clamp(ndesc >> 3, 1, 32);
|
||||||
|
- airoha_qdma_rmw(eth, REG_RX_RING_SIZE(qid), RX_RING_THR_MASK,
|
||||||
|
+ airoha_qdma_rmw(qdma, REG_RX_RING_SIZE(qid), RX_RING_THR_MASK,
|
||||||
|
FIELD_PREP(RX_RING_THR_MASK, thr));
|
||||||
|
- airoha_qdma_rmw(eth, REG_RX_DMA_IDX(qid), RX_RING_DMA_IDX_MASK,
|
||||||
|
+ airoha_qdma_rmw(qdma, REG_RX_DMA_IDX(qid), RX_RING_DMA_IDX_MASK,
|
||||||
|
FIELD_PREP(RX_RING_DMA_IDX_MASK, q->head));
|
||||||
|
|
||||||
|
airoha_qdma_fill_rx_queue(q);
|
||||||
|
@@ -1600,7 +1609,8 @@ static void airoha_qdma_cleanup_rx_queue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int airoha_qdma_init_rx(struct airoha_eth *eth)
|
||||||
|
+static int airoha_qdma_init_rx(struct airoha_eth *eth,
|
||||||
|
+ struct airoha_qdma *qdma)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
@@ -1613,7 +1623,7 @@ static int airoha_qdma_init_rx(struct ai
|
||||||
|
}
|
||||||
|
|
||||||
|
err = airoha_qdma_init_rx_queue(eth, ð->q_rx[i],
|
||||||
|
- RX_DSCP_NUM(i));
|
||||||
|
+ qdma, RX_DSCP_NUM(i));
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
@@ -1624,11 +1634,13 @@ 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;
|
||||||
|
+ struct airoha_qdma *qdma;
|
||||||
|
struct airoha_eth *eth;
|
||||||
|
int id, done = 0;
|
||||||
|
|
||||||
|
irq_q = container_of(napi, struct airoha_tx_irq_queue, napi);
|
||||||
|
eth = irq_q->eth;
|
||||||
|
+ qdma = ð->qdma[0];
|
||||||
|
id = irq_q - ð->q_tx_irq[0];
|
||||||
|
|
||||||
|
while (irq_q->queued > 0 && done < budget) {
|
||||||
|
@@ -1698,9 +1710,9 @@ static int airoha_qdma_tx_napi_poll(stru
|
||||||
|
int i, len = done >> 7;
|
||||||
|
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
- airoha_qdma_rmw(eth, REG_IRQ_CLEAR_LEN(id),
|
||||||
|
+ airoha_qdma_rmw(qdma, REG_IRQ_CLEAR_LEN(id),
|
||||||
|
IRQ_CLEAR_LEN_MASK, 0x80);
|
||||||
|
- airoha_qdma_rmw(eth, REG_IRQ_CLEAR_LEN(id),
|
||||||
|
+ airoha_qdma_rmw(qdma, REG_IRQ_CLEAR_LEN(id),
|
||||||
|
IRQ_CLEAR_LEN_MASK, (done & 0x7f));
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1712,7 +1724,8 @@ static int airoha_qdma_tx_napi_poll(stru
|
||||||
|
}
|
||||||
|
|
||||||
|
static int airoha_qdma_init_tx_queue(struct airoha_eth *eth,
|
||||||
|
- struct airoha_queue *q, int size)
|
||||||
|
+ struct airoha_queue *q,
|
||||||
|
+ struct airoha_qdma *qdma, int size)
|
||||||
|
{
|
||||||
|
int i, qid = q - ð->q_tx[0];
|
||||||
|
dma_addr_t dma_addr;
|
||||||
|
@@ -1739,10 +1752,10 @@ static int airoha_qdma_init_tx_queue(str
|
||||||
|
WRITE_ONCE(q->desc[i].ctrl, cpu_to_le32(val));
|
||||||
|
}
|
||||||
|
|
||||||
|
- airoha_qdma_wr(eth, REG_TX_RING_BASE(qid), dma_addr);
|
||||||
|
- airoha_qdma_rmw(eth, REG_TX_CPU_IDX(qid), TX_RING_CPU_IDX_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));
|
||||||
|
- airoha_qdma_rmw(eth, REG_TX_DMA_IDX(qid), TX_RING_DMA_IDX_MASK,
|
||||||
|
+ airoha_qdma_rmw(qdma, REG_TX_DMA_IDX(qid), TX_RING_DMA_IDX_MASK,
|
||||||
|
FIELD_PREP(TX_RING_DMA_IDX_MASK, q->head));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
@@ -1750,7 +1763,7 @@ static int airoha_qdma_init_tx_queue(str
|
||||||
|
|
||||||
|
static int airoha_qdma_tx_irq_init(struct airoha_eth *eth,
|
||||||
|
struct airoha_tx_irq_queue *irq_q,
|
||||||
|
- int size)
|
||||||
|
+ struct airoha_qdma *qdma, int size)
|
||||||
|
{
|
||||||
|
int id = irq_q - ð->q_tx_irq[0];
|
||||||
|
dma_addr_t dma_addr;
|
||||||
|
@@ -1766,29 +1779,30 @@ static int airoha_qdma_tx_irq_init(struc
|
||||||
|
irq_q->size = size;
|
||||||
|
irq_q->eth = eth;
|
||||||
|
|
||||||
|
- airoha_qdma_wr(eth, REG_TX_IRQ_BASE(id), dma_addr);
|
||||||
|
- airoha_qdma_rmw(eth, REG_TX_IRQ_CFG(id), TX_IRQ_DEPTH_MASK,
|
||||||
|
+ airoha_qdma_wr(qdma, REG_TX_IRQ_BASE(id), dma_addr);
|
||||||
|
+ airoha_qdma_rmw(qdma, REG_TX_IRQ_CFG(id), TX_IRQ_DEPTH_MASK,
|
||||||
|
FIELD_PREP(TX_IRQ_DEPTH_MASK, size));
|
||||||
|
- airoha_qdma_rmw(eth, REG_TX_IRQ_CFG(id), TX_IRQ_THR_MASK,
|
||||||
|
+ airoha_qdma_rmw(qdma, REG_TX_IRQ_CFG(id), TX_IRQ_THR_MASK,
|
||||||
|
FIELD_PREP(TX_IRQ_THR_MASK, 1));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int airoha_qdma_init_tx(struct airoha_eth *eth)
|
||||||
|
+static int airoha_qdma_init_tx(struct airoha_eth *eth,
|
||||||
|
+ struct airoha_qdma *qdma)
|
||||||
|
{
|
||||||
|
int i, err;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(eth->q_tx_irq); i++) {
|
||||||
|
err = airoha_qdma_tx_irq_init(eth, ð->q_tx_irq[i],
|
||||||
|
- IRQ_QUEUE_LEN(i));
|
||||||
|
+ qdma, IRQ_QUEUE_LEN(i));
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(eth->q_tx); i++) {
|
||||||
|
err = airoha_qdma_init_tx_queue(eth, ð->q_tx[i],
|
||||||
|
- TX_DSCP_NUM);
|
||||||
|
+ qdma, TX_DSCP_NUM);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
@@ -1815,7 +1829,8 @@ static void airoha_qdma_cleanup_tx_queue
|
||||||
|
spin_unlock_bh(&q->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int airoha_qdma_init_hfwd_queues(struct airoha_eth *eth)
|
||||||
|
+static int airoha_qdma_init_hfwd_queues(struct airoha_eth *eth,
|
||||||
|
+ struct airoha_qdma *qdma)
|
||||||
|
{
|
||||||
|
dma_addr_t dma_addr;
|
||||||
|
u32 status;
|
||||||
|
@@ -1827,7 +1842,7 @@ static int airoha_qdma_init_hfwd_queues(
|
||||||
|
if (!eth->hfwd.desc)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
- airoha_qdma_wr(eth, REG_FWD_DSCP_BASE, dma_addr);
|
||||||
|
+ airoha_qdma_wr(qdma, REG_FWD_DSCP_BASE, dma_addr);
|
||||||
|
|
||||||
|
size = AIROHA_MAX_PACKET_SIZE * HW_DSCP_NUM;
|
||||||
|
eth->hfwd.q = dmam_alloc_coherent(eth->dev, size, &dma_addr,
|
||||||
|
@@ -1835,14 +1850,14 @@ static int airoha_qdma_init_hfwd_queues(
|
||||||
|
if (!eth->hfwd.q)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
- airoha_qdma_wr(eth, REG_FWD_BUF_BASE, dma_addr);
|
||||||
|
+ airoha_qdma_wr(qdma, REG_FWD_BUF_BASE, dma_addr);
|
||||||
|
|
||||||
|
- airoha_qdma_rmw(eth, REG_HW_FWD_DSCP_CFG,
|
||||||
|
+ airoha_qdma_rmw(qdma, REG_HW_FWD_DSCP_CFG,
|
||||||
|
HW_FWD_DSCP_PAYLOAD_SIZE_MASK,
|
||||||
|
FIELD_PREP(HW_FWD_DSCP_PAYLOAD_SIZE_MASK, 0));
|
||||||
|
- airoha_qdma_rmw(eth, REG_FWD_DSCP_LOW_THR, FWD_DSCP_LOW_THR_MASK,
|
||||||
|
+ airoha_qdma_rmw(qdma, REG_FWD_DSCP_LOW_THR, FWD_DSCP_LOW_THR_MASK,
|
||||||
|
FIELD_PREP(FWD_DSCP_LOW_THR_MASK, 128));
|
||||||
|
- airoha_qdma_rmw(eth, REG_LMGR_INIT_CFG,
|
||||||
|
+ airoha_qdma_rmw(qdma, REG_LMGR_INIT_CFG,
|
||||||
|
LMGR_INIT_START | LMGR_SRAM_MODE_MASK |
|
||||||
|
HW_FWD_DESC_NUM_MASK,
|
||||||
|
FIELD_PREP(HW_FWD_DESC_NUM_MASK, HW_DSCP_NUM) |
|
||||||
|
@@ -1850,67 +1865,69 @@ static int airoha_qdma_init_hfwd_queues(
|
||||||
|
|
||||||
|
return read_poll_timeout(airoha_qdma_rr, status,
|
||||||
|
!(status & LMGR_INIT_START), USEC_PER_MSEC,
|
||||||
|
- 30 * USEC_PER_MSEC, true, eth,
|
||||||
|
+ 30 * USEC_PER_MSEC, true, qdma,
|
||||||
|
REG_LMGR_INIT_CFG);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void airoha_qdma_init_qos(struct airoha_eth *eth)
|
||||||
|
+static void airoha_qdma_init_qos(struct airoha_eth *eth,
|
||||||
|
+ struct airoha_qdma *qdma)
|
||||||
|
{
|
||||||
|
- airoha_qdma_clear(eth, REG_TXWRR_MODE_CFG, TWRR_WEIGHT_SCALE_MASK);
|
||||||
|
- airoha_qdma_set(eth, REG_TXWRR_MODE_CFG, TWRR_WEIGHT_BASE_MASK);
|
||||||
|
+ airoha_qdma_clear(qdma, REG_TXWRR_MODE_CFG, TWRR_WEIGHT_SCALE_MASK);
|
||||||
|
+ airoha_qdma_set(qdma, REG_TXWRR_MODE_CFG, TWRR_WEIGHT_BASE_MASK);
|
||||||
|
|
||||||
|
- airoha_qdma_clear(eth, REG_PSE_BUF_USAGE_CFG,
|
||||||
|
+ airoha_qdma_clear(qdma, REG_PSE_BUF_USAGE_CFG,
|
||||||
|
PSE_BUF_ESTIMATE_EN_MASK);
|
||||||
|
|
||||||
|
- airoha_qdma_set(eth, REG_EGRESS_RATE_METER_CFG,
|
||||||
|
+ airoha_qdma_set(qdma, REG_EGRESS_RATE_METER_CFG,
|
||||||
|
EGRESS_RATE_METER_EN_MASK |
|
||||||
|
EGRESS_RATE_METER_EQ_RATE_EN_MASK);
|
||||||
|
/* 2047us x 31 = 63.457ms */
|
||||||
|
- airoha_qdma_rmw(eth, REG_EGRESS_RATE_METER_CFG,
|
||||||
|
+ airoha_qdma_rmw(qdma, REG_EGRESS_RATE_METER_CFG,
|
||||||
|
EGRESS_RATE_METER_WINDOW_SZ_MASK,
|
||||||
|
FIELD_PREP(EGRESS_RATE_METER_WINDOW_SZ_MASK, 0x1f));
|
||||||
|
- airoha_qdma_rmw(eth, REG_EGRESS_RATE_METER_CFG,
|
||||||
|
+ airoha_qdma_rmw(qdma, REG_EGRESS_RATE_METER_CFG,
|
||||||
|
EGRESS_RATE_METER_TIMESLICE_MASK,
|
||||||
|
FIELD_PREP(EGRESS_RATE_METER_TIMESLICE_MASK, 0x7ff));
|
||||||
|
|
||||||
|
/* ratelimit init */
|
||||||
|
- airoha_qdma_set(eth, REG_GLB_TRTCM_CFG, GLB_TRTCM_EN_MASK);
|
||||||
|
+ airoha_qdma_set(qdma, REG_GLB_TRTCM_CFG, GLB_TRTCM_EN_MASK);
|
||||||
|
/* fast-tick 25us */
|
||||||
|
- airoha_qdma_rmw(eth, REG_GLB_TRTCM_CFG, GLB_FAST_TICK_MASK,
|
||||||
|
+ airoha_qdma_rmw(qdma, REG_GLB_TRTCM_CFG, GLB_FAST_TICK_MASK,
|
||||||
|
FIELD_PREP(GLB_FAST_TICK_MASK, 25));
|
||||||
|
- airoha_qdma_rmw(eth, REG_GLB_TRTCM_CFG, GLB_SLOW_TICK_RATIO_MASK,
|
||||||
|
+ airoha_qdma_rmw(qdma, REG_GLB_TRTCM_CFG, GLB_SLOW_TICK_RATIO_MASK,
|
||||||
|
FIELD_PREP(GLB_SLOW_TICK_RATIO_MASK, 40));
|
||||||
|
|
||||||
|
- airoha_qdma_set(eth, REG_EGRESS_TRTCM_CFG, EGRESS_TRTCM_EN_MASK);
|
||||||
|
- airoha_qdma_rmw(eth, REG_EGRESS_TRTCM_CFG, EGRESS_FAST_TICK_MASK,
|
||||||
|
+ airoha_qdma_set(qdma, REG_EGRESS_TRTCM_CFG, EGRESS_TRTCM_EN_MASK);
|
||||||
|
+ airoha_qdma_rmw(qdma, REG_EGRESS_TRTCM_CFG, EGRESS_FAST_TICK_MASK,
|
||||||
|
FIELD_PREP(EGRESS_FAST_TICK_MASK, 25));
|
||||||
|
- airoha_qdma_rmw(eth, REG_EGRESS_TRTCM_CFG,
|
||||||
|
+ airoha_qdma_rmw(qdma, REG_EGRESS_TRTCM_CFG,
|
||||||
|
EGRESS_SLOW_TICK_RATIO_MASK,
|
||||||
|
FIELD_PREP(EGRESS_SLOW_TICK_RATIO_MASK, 40));
|
||||||
|
|
||||||
|
- airoha_qdma_set(eth, REG_INGRESS_TRTCM_CFG, INGRESS_TRTCM_EN_MASK);
|
||||||
|
- airoha_qdma_clear(eth, REG_INGRESS_TRTCM_CFG,
|
||||||
|
+ airoha_qdma_set(qdma, REG_INGRESS_TRTCM_CFG, INGRESS_TRTCM_EN_MASK);
|
||||||
|
+ airoha_qdma_clear(qdma, REG_INGRESS_TRTCM_CFG,
|
||||||
|
INGRESS_TRTCM_MODE_MASK);
|
||||||
|
- airoha_qdma_rmw(eth, REG_INGRESS_TRTCM_CFG, INGRESS_FAST_TICK_MASK,
|
||||||
|
+ airoha_qdma_rmw(qdma, REG_INGRESS_TRTCM_CFG, INGRESS_FAST_TICK_MASK,
|
||||||
|
FIELD_PREP(INGRESS_FAST_TICK_MASK, 125));
|
||||||
|
- airoha_qdma_rmw(eth, REG_INGRESS_TRTCM_CFG,
|
||||||
|
+ airoha_qdma_rmw(qdma, REG_INGRESS_TRTCM_CFG,
|
||||||
|
INGRESS_SLOW_TICK_RATIO_MASK,
|
||||||
|
FIELD_PREP(INGRESS_SLOW_TICK_RATIO_MASK, 8));
|
||||||
|
|
||||||
|
- airoha_qdma_set(eth, REG_SLA_TRTCM_CFG, SLA_TRTCM_EN_MASK);
|
||||||
|
- airoha_qdma_rmw(eth, REG_SLA_TRTCM_CFG, SLA_FAST_TICK_MASK,
|
||||||
|
+ airoha_qdma_set(qdma, REG_SLA_TRTCM_CFG, SLA_TRTCM_EN_MASK);
|
||||||
|
+ airoha_qdma_rmw(qdma, REG_SLA_TRTCM_CFG, SLA_FAST_TICK_MASK,
|
||||||
|
FIELD_PREP(SLA_FAST_TICK_MASK, 25));
|
||||||
|
- airoha_qdma_rmw(eth, REG_SLA_TRTCM_CFG, SLA_SLOW_TICK_RATIO_MASK,
|
||||||
|
+ airoha_qdma_rmw(qdma, REG_SLA_TRTCM_CFG, SLA_SLOW_TICK_RATIO_MASK,
|
||||||
|
FIELD_PREP(SLA_SLOW_TICK_RATIO_MASK, 40));
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int airoha_qdma_hw_init(struct airoha_eth *eth)
|
||||||
|
+static int airoha_qdma_hw_init(struct airoha_eth *eth,
|
||||||
|
+ struct airoha_qdma *qdma)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* clear pending irqs */
|
||||||
|
for (i = 0; i < ARRAY_SIZE(eth->irqmask); i++)
|
||||||
|
- airoha_qdma_wr(eth, REG_INT_STATUS(i), 0xffffffff);
|
||||||
|
+ airoha_qdma_wr(qdma, REG_INT_STATUS(i), 0xffffffff);
|
||||||
|
|
||||||
|
/* setup irqs */
|
||||||
|
airoha_qdma_irq_enable(eth, QDMA_INT_REG_IDX0, INT_IDX0_MASK);
|
||||||
|
@@ -1923,14 +1940,14 @@ static int airoha_qdma_hw_init(struct ai
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (TX_RING_IRQ_BLOCKING_MAP_MASK & BIT(i))
|
||||||
|
- airoha_qdma_set(eth, REG_TX_RING_BLOCKING(i),
|
||||||
|
+ airoha_qdma_set(qdma, REG_TX_RING_BLOCKING(i),
|
||||||
|
TX_RING_IRQ_BLOCKING_CFG_MASK);
|
||||||
|
else
|
||||||
|
- airoha_qdma_clear(eth, REG_TX_RING_BLOCKING(i),
|
||||||
|
+ airoha_qdma_clear(qdma, REG_TX_RING_BLOCKING(i),
|
||||||
|
TX_RING_IRQ_BLOCKING_CFG_MASK);
|
||||||
|
}
|
||||||
|
|
||||||
|
- airoha_qdma_wr(eth, REG_QDMA_GLOBAL_CFG,
|
||||||
|
+ airoha_qdma_wr(qdma, REG_QDMA_GLOBAL_CFG,
|
||||||
|
GLOBAL_CFG_RX_2B_OFFSET_MASK |
|
||||||
|
FIELD_PREP(GLOBAL_CFG_DMA_PREFERENCE_MASK, 3) |
|
||||||
|
GLOBAL_CFG_CPU_TXR_RR_MASK |
|
||||||
|
@@ -1941,18 +1958,18 @@ static int airoha_qdma_hw_init(struct ai
|
||||||
|
GLOBAL_CFG_TX_WB_DONE_MASK |
|
||||||
|
FIELD_PREP(GLOBAL_CFG_MAX_ISSUE_NUM_MASK, 2));
|
||||||
|
|
||||||
|
- airoha_qdma_init_qos(eth);
|
||||||
|
+ airoha_qdma_init_qos(eth, qdma);
|
||||||
|
|
||||||
|
/* disable qdma rx delay interrupt */
|
||||||
|
for (i = 0; i < ARRAY_SIZE(eth->q_rx); i++) {
|
||||||
|
if (!eth->q_rx[i].ndesc)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
- airoha_qdma_clear(eth, REG_RX_DELAY_INT_IDX(i),
|
||||||
|
+ airoha_qdma_clear(qdma, REG_RX_DELAY_INT_IDX(i),
|
||||||
|
RX_DELAY_INT_MASK);
|
||||||
|
}
|
||||||
|
|
||||||
|
- airoha_qdma_set(eth, REG_TXQ_CNGST_CFG,
|
||||||
|
+ airoha_qdma_set(qdma, REG_TXQ_CNGST_CFG,
|
||||||
|
TXQ_CNGST_DROP_EN | TXQ_CNGST_DEI_DROP_EN);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
@@ -1962,12 +1979,14 @@ static irqreturn_t airoha_irq_handler(in
|
||||||
|
{
|
||||||
|
struct airoha_eth *eth = dev_instance;
|
||||||
|
u32 intr[ARRAY_SIZE(eth->irqmask)];
|
||||||
|
+ struct airoha_qdma *qdma;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
+ qdma = ð->qdma[0];
|
||||||
|
for (i = 0; i < ARRAY_SIZE(eth->irqmask); i++) {
|
||||||
|
- intr[i] = airoha_qdma_rr(eth, REG_INT_STATUS(i));
|
||||||
|
+ intr[i] = airoha_qdma_rr(qdma, REG_INT_STATUS(i));
|
||||||
|
intr[i] &= eth->irqmask[i];
|
||||||
|
- airoha_qdma_wr(eth, REG_INT_STATUS(i), intr[i]);
|
||||||
|
+ airoha_qdma_wr(qdma, REG_INT_STATUS(i), intr[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!test_bit(DEV_STATE_INITIALIZED, ð->state))
|
||||||
|
@@ -1997,7 +2016,7 @@ static irqreturn_t airoha_irq_handler(in
|
||||||
|
airoha_qdma_irq_disable(eth, QDMA_INT_REG_IDX0,
|
||||||
|
TX_DONE_INT_MASK(i));
|
||||||
|
|
||||||
|
- status = airoha_qdma_rr(eth, REG_IRQ_STATUS(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);
|
||||||
|
@@ -2011,6 +2030,7 @@ static irqreturn_t airoha_irq_handler(in
|
||||||
|
|
||||||
|
static int airoha_qdma_init(struct airoha_eth *eth)
|
||||||
|
{
|
||||||
|
+ struct airoha_qdma *qdma = ð->qdma[0];
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = devm_request_irq(eth->dev, eth->irq, airoha_irq_handler,
|
||||||
|
@@ -2018,19 +2038,19 @@ static int airoha_qdma_init(struct airoh
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
- err = airoha_qdma_init_rx(eth);
|
||||||
|
+ err = airoha_qdma_init_rx(eth, qdma);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
- err = airoha_qdma_init_tx(eth);
|
||||||
|
+ err = airoha_qdma_init_tx(eth, qdma);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
- err = airoha_qdma_init_hfwd_queues(eth);
|
||||||
|
+ err = airoha_qdma_init_hfwd_queues(eth, qdma);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
- err = airoha_qdma_hw_init(eth);
|
||||||
|
+ err = airoha_qdma_hw_init(eth, qdma);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
@@ -2263,8 +2283,9 @@ static int airoha_dev_open(struct net_de
|
||||||
|
airoha_fe_clear(eth, REG_GDM_INGRESS_CFG(port->id),
|
||||||
|
GDM_STAG_EN_MASK);
|
||||||
|
|
||||||
|
- airoha_qdma_set(eth, REG_QDMA_GLOBAL_CFG, GLOBAL_CFG_TX_DMA_EN_MASK);
|
||||||
|
- airoha_qdma_set(eth, REG_QDMA_GLOBAL_CFG, GLOBAL_CFG_RX_DMA_EN_MASK);
|
||||||
|
+ airoha_qdma_set(ð->qdma[0], REG_QDMA_GLOBAL_CFG,
|
||||||
|
+ GLOBAL_CFG_TX_DMA_EN_MASK |
|
||||||
|
+ GLOBAL_CFG_RX_DMA_EN_MASK);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@@ -2280,8 +2301,9 @@ static int airoha_dev_stop(struct net_de
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
- airoha_qdma_clear(eth, REG_QDMA_GLOBAL_CFG, GLOBAL_CFG_TX_DMA_EN_MASK);
|
||||||
|
- airoha_qdma_clear(eth, REG_QDMA_GLOBAL_CFG, GLOBAL_CFG_RX_DMA_EN_MASK);
|
||||||
|
+ airoha_qdma_clear(ð->qdma[0], REG_QDMA_GLOBAL_CFG,
|
||||||
|
+ GLOBAL_CFG_TX_DMA_EN_MASK |
|
||||||
|
+ GLOBAL_CFG_RX_DMA_EN_MASK);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@@ -2341,6 +2363,7 @@ static netdev_tx_t airoha_dev_xmit(struc
|
||||||
|
struct airoha_eth *eth = port->eth;
|
||||||
|
u32 nr_frags = 1 + sinfo->nr_frags;
|
||||||
|
struct netdev_queue *txq;
|
||||||
|
+ struct airoha_qdma *qdma;
|
||||||
|
struct airoha_queue *q;
|
||||||
|
void *data = skb->data;
|
||||||
|
u16 index;
|
||||||
|
@@ -2368,6 +2391,7 @@ static netdev_tx_t airoha_dev_xmit(struc
|
||||||
|
msg1 = FIELD_PREP(QDMA_ETH_TXMSG_FPORT_MASK, fport) |
|
||||||
|
FIELD_PREP(QDMA_ETH_TXMSG_METER_MASK, 0x7f);
|
||||||
|
|
||||||
|
+ qdma = ð->qdma[0];
|
||||||
|
q = ð->q_tx[qid];
|
||||||
|
if (WARN_ON_ONCE(!q->ndesc))
|
||||||
|
goto error;
|
||||||
|
@@ -2412,7 +2436,8 @@ static netdev_tx_t airoha_dev_xmit(struc
|
||||||
|
e->dma_addr = addr;
|
||||||
|
e->dma_len = len;
|
||||||
|
|
||||||
|
- airoha_qdma_rmw(eth, REG_TX_CPU_IDX(qid), TX_RING_CPU_IDX_MASK,
|
||||||
|
+ airoha_qdma_rmw(qdma, REG_TX_CPU_IDX(qid),
|
||||||
|
+ TX_RING_CPU_IDX_MASK,
|
||||||
|
FIELD_PREP(TX_RING_CPU_IDX_MASK, index));
|
||||||
|
|
||||||
|
data = skb_frag_address(frag);
|
||||||
|
@@ -2614,9 +2639,11 @@ static int airoha_probe(struct platform_
|
||||||
|
return dev_err_probe(eth->dev, PTR_ERR(eth->fe_regs),
|
||||||
|
"failed to iomap fe regs\n");
|
||||||
|
|
||||||
|
- eth->qdma_regs = devm_platform_ioremap_resource_byname(pdev, "qdma0");
|
||||||
|
- if (IS_ERR(eth->qdma_regs))
|
||||||
|
- return dev_err_probe(eth->dev, PTR_ERR(eth->qdma_regs),
|
||||||
|
+ eth->qdma[0].regs = devm_platform_ioremap_resource_byname(pdev,
|
||||||
|
+ "qdma0");
|
||||||
|
+ if (IS_ERR(eth->qdma[0].regs))
|
||||||
|
+ return dev_err_probe(eth->dev,
|
||||||
|
+ PTR_ERR(eth->qdma[0].regs),
|
||||||
|
"failed to iomap qdma regs\n");
|
||||||
|
|
||||||
|
eth->rsts[0].id = "fe";
|
||||||
@ -0,0 +1,318 @@
|
|||||||
|
From 245c7bc86b198e5ec227eba6b582da73cb0721c8 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||||
|
Date: Thu, 1 Aug 2024 16:35:04 +0200
|
||||||
|
Subject: [PATCH 2/8] net: airoha: Move airoha_queues in airoha_qdma
|
||||||
|
|
||||||
|
QDMA controllers available in EN7581 SoC have independent tx/rx hw queues
|
||||||
|
so move them in airoha_queues structure.
|
||||||
|
|
||||||
|
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||||
|
Link: https://patch.msgid.link/795fc4797bffbf7f0a1351308aa9bf0e65b5126e.1722522582.git.lorenzo@kernel.org
|
||||||
|
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||||
|
---
|
||||||
|
drivers/net/ethernet/mediatek/airoha_eth.c | 126 +++++++++++----------
|
||||||
|
1 file changed, 65 insertions(+), 61 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/net/ethernet/mediatek/airoha_eth.c
|
||||||
|
+++ b/drivers/net/ethernet/mediatek/airoha_eth.c
|
||||||
|
@@ -785,6 +785,17 @@ struct airoha_hw_stats {
|
||||||
|
|
||||||
|
struct airoha_qdma {
|
||||||
|
void __iomem *regs;
|
||||||
|
+
|
||||||
|
+ struct airoha_tx_irq_queue q_tx_irq[AIROHA_NUM_TX_IRQ];
|
||||||
|
+
|
||||||
|
+ struct airoha_queue q_tx[AIROHA_NUM_TX_RING];
|
||||||
|
+ struct airoha_queue q_rx[AIROHA_NUM_RX_RING];
|
||||||
|
+
|
||||||
|
+ /* descriptor and packet buffers for qdma hw forward */
|
||||||
|
+ struct {
|
||||||
|
+ void *desc;
|
||||||
|
+ void *q;
|
||||||
|
+ } hfwd;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct airoha_gdm_port {
|
||||||
|
@@ -809,20 +820,10 @@ struct airoha_eth {
|
||||||
|
struct reset_control_bulk_data rsts[AIROHA_MAX_NUM_RSTS];
|
||||||
|
struct reset_control_bulk_data xsi_rsts[AIROHA_MAX_NUM_XSI_RSTS];
|
||||||
|
|
||||||
|
- struct airoha_qdma qdma[AIROHA_MAX_NUM_QDMA];
|
||||||
|
- struct airoha_gdm_port *ports[AIROHA_MAX_NUM_GDM_PORTS];
|
||||||
|
-
|
||||||
|
struct net_device *napi_dev;
|
||||||
|
- struct airoha_queue q_tx[AIROHA_NUM_TX_RING];
|
||||||
|
- struct airoha_queue q_rx[AIROHA_NUM_RX_RING];
|
||||||
|
-
|
||||||
|
- struct airoha_tx_irq_queue q_tx_irq[AIROHA_NUM_TX_IRQ];
|
||||||
|
|
||||||
|
- /* descriptor and packet buffers for qdma hw forward */
|
||||||
|
- struct {
|
||||||
|
- void *desc;
|
||||||
|
- void *q;
|
||||||
|
- } hfwd;
|
||||||
|
+ struct airoha_qdma qdma[AIROHA_MAX_NUM_QDMA];
|
||||||
|
+ struct airoha_gdm_port *ports[AIROHA_MAX_NUM_GDM_PORTS];
|
||||||
|
};
|
||||||
|
|
||||||
|
static u32 airoha_rr(void __iomem *base, u32 offset)
|
||||||
|
@@ -1390,7 +1391,7 @@ static int airoha_qdma_fill_rx_queue(str
|
||||||
|
enum dma_data_direction dir = page_pool_get_dma_dir(q->page_pool);
|
||||||
|
struct airoha_qdma *qdma = &q->eth->qdma[0];
|
||||||
|
struct airoha_eth *eth = q->eth;
|
||||||
|
- int qid = q - ð->q_rx[0];
|
||||||
|
+ int qid = q - &qdma->q_rx[0];
|
||||||
|
int nframes = 0;
|
||||||
|
|
||||||
|
while (q->queued < q->ndesc - 1) {
|
||||||
|
@@ -1457,8 +1458,9 @@ static int airoha_qdma_get_gdm_port(stru
|
||||||
|
static int airoha_qdma_rx_process(struct airoha_queue *q, int budget)
|
||||||
|
{
|
||||||
|
enum dma_data_direction dir = page_pool_get_dma_dir(q->page_pool);
|
||||||
|
+ struct airoha_qdma *qdma = &q->eth->qdma[0];
|
||||||
|
struct airoha_eth *eth = q->eth;
|
||||||
|
- int qid = q - ð->q_rx[0];
|
||||||
|
+ int qid = q - &qdma->q_rx[0];
|
||||||
|
int done = 0;
|
||||||
|
|
||||||
|
while (done < budget) {
|
||||||
|
@@ -1550,7 +1552,7 @@ static int airoha_qdma_init_rx_queue(str
|
||||||
|
.dev = eth->dev,
|
||||||
|
.napi = &q->napi,
|
||||||
|
};
|
||||||
|
- int qid = q - ð->q_rx[0], thr;
|
||||||
|
+ int qid = q - &qdma->q_rx[0], thr;
|
||||||
|
dma_addr_t dma_addr;
|
||||||
|
|
||||||
|
q->buf_size = PAGE_SIZE / 2;
|
||||||
|
@@ -1614,7 +1616,7 @@ static int airoha_qdma_init_rx(struct ai
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
- for (i = 0; i < ARRAY_SIZE(eth->q_rx); i++) {
|
||||||
|
+ for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) {
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (!(RX_DONE_INT_MASK & BIT(i))) {
|
||||||
|
@@ -1622,7 +1624,7 @@ static int airoha_qdma_init_rx(struct ai
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
- err = airoha_qdma_init_rx_queue(eth, ð->q_rx[i],
|
||||||
|
+ err = airoha_qdma_init_rx_queue(eth, &qdma->q_rx[i],
|
||||||
|
qdma, RX_DSCP_NUM(i));
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
@@ -1641,7 +1643,7 @@ static int airoha_qdma_tx_napi_poll(stru
|
||||||
|
irq_q = container_of(napi, struct airoha_tx_irq_queue, napi);
|
||||||
|
eth = irq_q->eth;
|
||||||
|
qdma = ð->qdma[0];
|
||||||
|
- id = irq_q - ð->q_tx_irq[0];
|
||||||
|
+ id = irq_q - &qdma->q_tx_irq[0];
|
||||||
|
|
||||||
|
while (irq_q->queued > 0 && done < budget) {
|
||||||
|
u32 qid, last, val = irq_q->q[irq_q->head];
|
||||||
|
@@ -1658,10 +1660,10 @@ static int airoha_qdma_tx_napi_poll(stru
|
||||||
|
last = FIELD_GET(IRQ_DESC_IDX_MASK, val);
|
||||||
|
qid = FIELD_GET(IRQ_RING_IDX_MASK, val);
|
||||||
|
|
||||||
|
- if (qid >= ARRAY_SIZE(eth->q_tx))
|
||||||
|
+ if (qid >= ARRAY_SIZE(qdma->q_tx))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
- q = ð->q_tx[qid];
|
||||||
|
+ q = &qdma->q_tx[qid];
|
||||||
|
if (!q->ndesc)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
@@ -1727,7 +1729,7 @@ static int airoha_qdma_init_tx_queue(str
|
||||||
|
struct airoha_queue *q,
|
||||||
|
struct airoha_qdma *qdma, int size)
|
||||||
|
{
|
||||||
|
- int i, qid = q - ð->q_tx[0];
|
||||||
|
+ int i, qid = q - &qdma->q_tx[0];
|
||||||
|
dma_addr_t dma_addr;
|
||||||
|
|
||||||
|
spin_lock_init(&q->lock);
|
||||||
|
@@ -1765,7 +1767,7 @@ static int airoha_qdma_tx_irq_init(struc
|
||||||
|
struct airoha_tx_irq_queue *irq_q,
|
||||||
|
struct airoha_qdma *qdma, int size)
|
||||||
|
{
|
||||||
|
- int id = irq_q - ð->q_tx_irq[0];
|
||||||
|
+ int id = irq_q - &qdma->q_tx_irq[0];
|
||||||
|
dma_addr_t dma_addr;
|
||||||
|
|
||||||
|
netif_napi_add_tx(eth->napi_dev, &irq_q->napi,
|
||||||
|
@@ -1793,15 +1795,15 @@ static int airoha_qdma_init_tx(struct ai
|
||||||
|
{
|
||||||
|
int i, err;
|
||||||
|
|
||||||
|
- for (i = 0; i < ARRAY_SIZE(eth->q_tx_irq); i++) {
|
||||||
|
- err = airoha_qdma_tx_irq_init(eth, ð->q_tx_irq[i],
|
||||||
|
+ for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++) {
|
||||||
|
+ err = airoha_qdma_tx_irq_init(eth, &qdma->q_tx_irq[i],
|
||||||
|
qdma, IRQ_QUEUE_LEN(i));
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
- for (i = 0; i < ARRAY_SIZE(eth->q_tx); i++) {
|
||||||
|
- err = airoha_qdma_init_tx_queue(eth, ð->q_tx[i],
|
||||||
|
+ for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) {
|
||||||
|
+ err = airoha_qdma_init_tx_queue(eth, &qdma->q_tx[i],
|
||||||
|
qdma, TX_DSCP_NUM);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
@@ -1837,17 +1839,17 @@ static int airoha_qdma_init_hfwd_queues(
|
||||||
|
int size;
|
||||||
|
|
||||||
|
size = HW_DSCP_NUM * sizeof(struct airoha_qdma_fwd_desc);
|
||||||
|
- eth->hfwd.desc = dmam_alloc_coherent(eth->dev, size, &dma_addr,
|
||||||
|
- GFP_KERNEL);
|
||||||
|
- if (!eth->hfwd.desc)
|
||||||
|
+ qdma->hfwd.desc = dmam_alloc_coherent(eth->dev, size, &dma_addr,
|
||||||
|
+ GFP_KERNEL);
|
||||||
|
+ if (!qdma->hfwd.desc)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
airoha_qdma_wr(qdma, REG_FWD_DSCP_BASE, dma_addr);
|
||||||
|
|
||||||
|
size = AIROHA_MAX_PACKET_SIZE * HW_DSCP_NUM;
|
||||||
|
- eth->hfwd.q = dmam_alloc_coherent(eth->dev, size, &dma_addr,
|
||||||
|
- GFP_KERNEL);
|
||||||
|
- if (!eth->hfwd.q)
|
||||||
|
+ qdma->hfwd.q = dmam_alloc_coherent(eth->dev, size, &dma_addr,
|
||||||
|
+ GFP_KERNEL);
|
||||||
|
+ if (!qdma->hfwd.q)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
airoha_qdma_wr(qdma, REG_FWD_BUF_BASE, dma_addr);
|
||||||
|
@@ -1935,8 +1937,8 @@ static int airoha_qdma_hw_init(struct ai
|
||||||
|
airoha_qdma_irq_enable(eth, QDMA_INT_REG_IDX4, INT_IDX4_MASK);
|
||||||
|
|
||||||
|
/* setup irq binding */
|
||||||
|
- for (i = 0; i < ARRAY_SIZE(eth->q_tx); i++) {
|
||||||
|
- if (!eth->q_tx[i].ndesc)
|
||||||
|
+ for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) {
|
||||||
|
+ if (!qdma->q_tx[i].ndesc)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (TX_RING_IRQ_BLOCKING_MAP_MASK & BIT(i))
|
||||||
|
@@ -1961,8 +1963,8 @@ static int airoha_qdma_hw_init(struct ai
|
||||||
|
airoha_qdma_init_qos(eth, qdma);
|
||||||
|
|
||||||
|
/* disable qdma rx delay interrupt */
|
||||||
|
- for (i = 0; i < ARRAY_SIZE(eth->q_rx); i++) {
|
||||||
|
- if (!eth->q_rx[i].ndesc)
|
||||||
|
+ for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) {
|
||||||
|
+ if (!qdma->q_rx[i].ndesc)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
airoha_qdma_clear(qdma, REG_RX_DELAY_INT_IDX(i),
|
||||||
|
@@ -1996,18 +1998,18 @@ static irqreturn_t airoha_irq_handler(in
|
||||||
|
airoha_qdma_irq_disable(eth, QDMA_INT_REG_IDX1,
|
||||||
|
RX_DONE_INT_MASK);
|
||||||
|
|
||||||
|
- for (i = 0; i < ARRAY_SIZE(eth->q_rx); i++) {
|
||||||
|
- if (!eth->q_rx[i].ndesc)
|
||||||
|
+ for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) {
|
||||||
|
+ if (!qdma->q_rx[i].ndesc)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (intr[1] & BIT(i))
|
||||||
|
- napi_schedule(ð->q_rx[i].napi);
|
||||||
|
+ napi_schedule(&qdma->q_rx[i].napi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (intr[0] & INT_TX_MASK) {
|
||||||
|
- for (i = 0; i < ARRAY_SIZE(eth->q_tx_irq); i++) {
|
||||||
|
- struct airoha_tx_irq_queue *irq_q = ð->q_tx_irq[i];
|
||||||
|
+ 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)))
|
||||||
|
@@ -2021,7 +2023,7 @@ static irqreturn_t airoha_irq_handler(in
|
||||||
|
irq_q->head = head % irq_q->size;
|
||||||
|
irq_q->queued = FIELD_GET(IRQ_ENTRY_LEN_MASK, status);
|
||||||
|
|
||||||
|
- napi_schedule(ð->q_tx_irq[i].napi);
|
||||||
|
+ napi_schedule(&qdma->q_tx_irq[i].napi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -2080,44 +2082,46 @@ static int airoha_hw_init(struct airoha_
|
||||||
|
|
||||||
|
static void airoha_hw_cleanup(struct airoha_eth *eth)
|
||||||
|
{
|
||||||
|
+ struct airoha_qdma *qdma = ð->qdma[0];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
- for (i = 0; i < ARRAY_SIZE(eth->q_rx); i++) {
|
||||||
|
- if (!eth->q_rx[i].ndesc)
|
||||||
|
+ for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) {
|
||||||
|
+ if (!qdma->q_rx[i].ndesc)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
- napi_disable(ð->q_rx[i].napi);
|
||||||
|
- netif_napi_del(ð->q_rx[i].napi);
|
||||||
|
- airoha_qdma_cleanup_rx_queue(ð->q_rx[i]);
|
||||||
|
- if (eth->q_rx[i].page_pool)
|
||||||
|
- page_pool_destroy(eth->q_rx[i].page_pool);
|
||||||
|
+ napi_disable(&qdma->q_rx[i].napi);
|
||||||
|
+ netif_napi_del(&qdma->q_rx[i].napi);
|
||||||
|
+ airoha_qdma_cleanup_rx_queue(&qdma->q_rx[i]);
|
||||||
|
+ if (qdma->q_rx[i].page_pool)
|
||||||
|
+ page_pool_destroy(qdma->q_rx[i].page_pool);
|
||||||
|
}
|
||||||
|
|
||||||
|
- for (i = 0; i < ARRAY_SIZE(eth->q_tx_irq); i++) {
|
||||||
|
- napi_disable(ð->q_tx_irq[i].napi);
|
||||||
|
- netif_napi_del(ð->q_tx_irq[i].napi);
|
||||||
|
+ for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++) {
|
||||||
|
+ napi_disable(&qdma->q_tx_irq[i].napi);
|
||||||
|
+ netif_napi_del(&qdma->q_tx_irq[i].napi);
|
||||||
|
}
|
||||||
|
|
||||||
|
- for (i = 0; i < ARRAY_SIZE(eth->q_tx); i++) {
|
||||||
|
- if (!eth->q_tx[i].ndesc)
|
||||||
|
+ for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) {
|
||||||
|
+ if (!qdma->q_tx[i].ndesc)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
- airoha_qdma_cleanup_tx_queue(ð->q_tx[i]);
|
||||||
|
+ airoha_qdma_cleanup_tx_queue(&qdma->q_tx[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void airoha_qdma_start_napi(struct airoha_eth *eth)
|
||||||
|
{
|
||||||
|
+ struct airoha_qdma *qdma = ð->qdma[0];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
- for (i = 0; i < ARRAY_SIZE(eth->q_tx_irq); i++)
|
||||||
|
- napi_enable(ð->q_tx_irq[i].napi);
|
||||||
|
+ for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++)
|
||||||
|
+ napi_enable(&qdma->q_tx_irq[i].napi);
|
||||||
|
|
||||||
|
- for (i = 0; i < ARRAY_SIZE(eth->q_rx); i++) {
|
||||||
|
- if (!eth->q_rx[i].ndesc)
|
||||||
|
+ for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) {
|
||||||
|
+ if (!qdma->q_rx[i].ndesc)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
- napi_enable(ð->q_rx[i].napi);
|
||||||
|
+ napi_enable(&qdma->q_rx[i].napi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -2392,7 +2396,7 @@ static netdev_tx_t airoha_dev_xmit(struc
|
||||||
|
FIELD_PREP(QDMA_ETH_TXMSG_METER_MASK, 0x7f);
|
||||||
|
|
||||||
|
qdma = ð->qdma[0];
|
||||||
|
- q = ð->q_tx[qid];
|
||||||
|
+ q = &qdma->q_tx[qid];
|
||||||
|
if (WARN_ON_ONCE(!q->ndesc))
|
||||||
|
goto error;
|
||||||
|
|
||||||
@ -0,0 +1,236 @@
|
|||||||
|
From 19e47fc2aeda3a657c4f64144ffd6e65f7a66601 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||||
|
Date: Thu, 1 Aug 2024 16:35:05 +0200
|
||||||
|
Subject: [PATCH 3/8] net: airoha: Move irq_mask in airoha_qdma structure
|
||||||
|
|
||||||
|
QDMA controllers have independent irq lines, so move irqmask in
|
||||||
|
airoha_qdma structure. This is a preliminary patch to support multiple
|
||||||
|
QDMA controllers.
|
||||||
|
|
||||||
|
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||||
|
Link: https://patch.msgid.link/1c8a06e8be605278a7b2f3cd8ac06e74bf5ebf2b.1722522582.git.lorenzo@kernel.org
|
||||||
|
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||||
|
---
|
||||||
|
drivers/net/ethernet/mediatek/airoha_eth.c | 84 +++++++++++-----------
|
||||||
|
1 file changed, 42 insertions(+), 42 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/net/ethernet/mediatek/airoha_eth.c
|
||||||
|
+++ b/drivers/net/ethernet/mediatek/airoha_eth.c
|
||||||
|
@@ -786,6 +786,11 @@ struct airoha_hw_stats {
|
||||||
|
struct airoha_qdma {
|
||||||
|
void __iomem *regs;
|
||||||
|
|
||||||
|
+ /* protect concurrent irqmask accesses */
|
||||||
|
+ spinlock_t irq_lock;
|
||||||
|
+ u32 irqmask[QDMA_INT_REG_MAX];
|
||||||
|
+ int irq;
|
||||||
|
+
|
||||||
|
struct airoha_tx_irq_queue q_tx_irq[AIROHA_NUM_TX_IRQ];
|
||||||
|
|
||||||
|
struct airoha_queue q_tx[AIROHA_NUM_TX_RING];
|
||||||
|
@@ -812,11 +817,6 @@ struct airoha_eth {
|
||||||
|
unsigned long state;
|
||||||
|
void __iomem *fe_regs;
|
||||||
|
|
||||||
|
- /* protect concurrent irqmask accesses */
|
||||||
|
- spinlock_t irq_lock;
|
||||||
|
- u32 irqmask[QDMA_INT_REG_MAX];
|
||||||
|
- int irq;
|
||||||
|
-
|
||||||
|
struct reset_control_bulk_data rsts[AIROHA_MAX_NUM_RSTS];
|
||||||
|
struct reset_control_bulk_data xsi_rsts[AIROHA_MAX_NUM_XSI_RSTS];
|
||||||
|
|
||||||
|
@@ -866,38 +866,37 @@ static u32 airoha_rmw(void __iomem *base
|
||||||
|
#define airoha_qdma_clear(qdma, offset, val) \
|
||||||
|
airoha_rmw((qdma)->regs, (offset), (val), 0)
|
||||||
|
|
||||||
|
-static void airoha_qdma_set_irqmask(struct airoha_eth *eth, int index,
|
||||||
|
+static void airoha_qdma_set_irqmask(struct airoha_qdma *qdma, int index,
|
||||||
|
u32 clear, u32 set)
|
||||||
|
{
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
- if (WARN_ON_ONCE(index >= ARRAY_SIZE(eth->irqmask)))
|
||||||
|
+ if (WARN_ON_ONCE(index >= ARRAY_SIZE(qdma->irqmask)))
|
||||||
|
return;
|
||||||
|
|
||||||
|
- spin_lock_irqsave(ð->irq_lock, flags);
|
||||||
|
+ spin_lock_irqsave(&qdma->irq_lock, flags);
|
||||||
|
|
||||||
|
- eth->irqmask[index] &= ~clear;
|
||||||
|
- eth->irqmask[index] |= set;
|
||||||
|
- airoha_qdma_wr(ð->qdma[0], REG_INT_ENABLE(index),
|
||||||
|
- eth->irqmask[index]);
|
||||||
|
+ qdma->irqmask[index] &= ~clear;
|
||||||
|
+ qdma->irqmask[index] |= set;
|
||||||
|
+ airoha_qdma_wr(qdma, REG_INT_ENABLE(index), qdma->irqmask[index]);
|
||||||
|
/* Read irq_enable register in order to guarantee the update above
|
||||||
|
* completes in the spinlock critical section.
|
||||||
|
*/
|
||||||
|
- airoha_qdma_rr(ð->qdma[0], REG_INT_ENABLE(index));
|
||||||
|
+ airoha_qdma_rr(qdma, REG_INT_ENABLE(index));
|
||||||
|
|
||||||
|
- spin_unlock_irqrestore(ð->irq_lock, flags);
|
||||||
|
+ spin_unlock_irqrestore(&qdma->irq_lock, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void airoha_qdma_irq_enable(struct airoha_eth *eth, int index,
|
||||||
|
+static void airoha_qdma_irq_enable(struct airoha_qdma *qdma, int index,
|
||||||
|
u32 mask)
|
||||||
|
{
|
||||||
|
- airoha_qdma_set_irqmask(eth, index, 0, mask);
|
||||||
|
+ airoha_qdma_set_irqmask(qdma, index, 0, mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void airoha_qdma_irq_disable(struct airoha_eth *eth, int index,
|
||||||
|
+static void airoha_qdma_irq_disable(struct airoha_qdma *qdma, int index,
|
||||||
|
u32 mask)
|
||||||
|
{
|
||||||
|
- airoha_qdma_set_irqmask(eth, index, mask, 0);
|
||||||
|
+ airoha_qdma_set_irqmask(qdma, index, mask, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void airoha_set_macaddr(struct airoha_eth *eth, const u8 *addr)
|
||||||
|
@@ -1522,7 +1521,7 @@ static int airoha_qdma_rx_process(struct
|
||||||
|
static int airoha_qdma_rx_napi_poll(struct napi_struct *napi, int budget)
|
||||||
|
{
|
||||||
|
struct airoha_queue *q = container_of(napi, struct airoha_queue, napi);
|
||||||
|
- struct airoha_eth *eth = q->eth;
|
||||||
|
+ struct airoha_qdma *qdma = &q->eth->qdma[0];
|
||||||
|
int cur, done = 0;
|
||||||
|
|
||||||
|
do {
|
||||||
|
@@ -1531,7 +1530,7 @@ static int airoha_qdma_rx_napi_poll(stru
|
||||||
|
} while (cur && done < budget);
|
||||||
|
|
||||||
|
if (done < budget && napi_complete(napi))
|
||||||
|
- airoha_qdma_irq_enable(eth, QDMA_INT_REG_IDX1,
|
||||||
|
+ airoha_qdma_irq_enable(qdma, QDMA_INT_REG_IDX1,
|
||||||
|
RX_DONE_INT_MASK);
|
||||||
|
|
||||||
|
return done;
|
||||||
|
@@ -1719,7 +1718,7 @@ static int airoha_qdma_tx_napi_poll(stru
|
||||||
|
}
|
||||||
|
|
||||||
|
if (done < budget && napi_complete(napi))
|
||||||
|
- airoha_qdma_irq_enable(eth, QDMA_INT_REG_IDX0,
|
||||||
|
+ airoha_qdma_irq_enable(qdma, QDMA_INT_REG_IDX0,
|
||||||
|
TX_DONE_INT_MASK(id));
|
||||||
|
|
||||||
|
return done;
|
||||||
|
@@ -1928,13 +1927,13 @@ static int airoha_qdma_hw_init(struct ai
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* clear pending irqs */
|
||||||
|
- for (i = 0; i < ARRAY_SIZE(eth->irqmask); i++)
|
||||||
|
+ for (i = 0; i < ARRAY_SIZE(qdma->irqmask); i++)
|
||||||
|
airoha_qdma_wr(qdma, REG_INT_STATUS(i), 0xffffffff);
|
||||||
|
|
||||||
|
/* setup irqs */
|
||||||
|
- airoha_qdma_irq_enable(eth, QDMA_INT_REG_IDX0, INT_IDX0_MASK);
|
||||||
|
- airoha_qdma_irq_enable(eth, QDMA_INT_REG_IDX1, INT_IDX1_MASK);
|
||||||
|
- airoha_qdma_irq_enable(eth, QDMA_INT_REG_IDX4, INT_IDX4_MASK);
|
||||||
|
+ airoha_qdma_irq_enable(qdma, QDMA_INT_REG_IDX0, INT_IDX0_MASK);
|
||||||
|
+ airoha_qdma_irq_enable(qdma, QDMA_INT_REG_IDX1, INT_IDX1_MASK);
|
||||||
|
+ airoha_qdma_irq_enable(qdma, QDMA_INT_REG_IDX4, INT_IDX4_MASK);
|
||||||
|
|
||||||
|
/* setup irq binding */
|
||||||
|
for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) {
|
||||||
|
@@ -1980,14 +1979,13 @@ static int airoha_qdma_hw_init(struct ai
|
||||||
|
static irqreturn_t airoha_irq_handler(int irq, void *dev_instance)
|
||||||
|
{
|
||||||
|
struct airoha_eth *eth = dev_instance;
|
||||||
|
- u32 intr[ARRAY_SIZE(eth->irqmask)];
|
||||||
|
- struct airoha_qdma *qdma;
|
||||||
|
+ struct airoha_qdma *qdma = ð->qdma[0];
|
||||||
|
+ u32 intr[ARRAY_SIZE(qdma->irqmask)];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
- qdma = ð->qdma[0];
|
||||||
|
- for (i = 0; i < ARRAY_SIZE(eth->irqmask); i++) {
|
||||||
|
+ for (i = 0; i < ARRAY_SIZE(qdma->irqmask); i++) {
|
||||||
|
intr[i] = airoha_qdma_rr(qdma, REG_INT_STATUS(i));
|
||||||
|
- intr[i] &= eth->irqmask[i];
|
||||||
|
+ intr[i] &= qdma->irqmask[i];
|
||||||
|
airoha_qdma_wr(qdma, REG_INT_STATUS(i), intr[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1995,7 +1993,7 @@ static irqreturn_t airoha_irq_handler(in
|
||||||
|
return IRQ_NONE;
|
||||||
|
|
||||||
|
if (intr[1] & RX_DONE_INT_MASK) {
|
||||||
|
- airoha_qdma_irq_disable(eth, QDMA_INT_REG_IDX1,
|
||||||
|
+ airoha_qdma_irq_disable(qdma, QDMA_INT_REG_IDX1,
|
||||||
|
RX_DONE_INT_MASK);
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) {
|
||||||
|
@@ -2015,7 +2013,7 @@ static irqreturn_t airoha_irq_handler(in
|
||||||
|
if (!(intr[0] & TX_DONE_INT_MASK(i)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
- airoha_qdma_irq_disable(eth, QDMA_INT_REG_IDX0,
|
||||||
|
+ airoha_qdma_irq_disable(qdma, QDMA_INT_REG_IDX0,
|
||||||
|
TX_DONE_INT_MASK(i));
|
||||||
|
|
||||||
|
status = airoha_qdma_rr(qdma, REG_IRQ_STATUS(i));
|
||||||
|
@@ -2030,12 +2028,18 @@ static irqreturn_t airoha_irq_handler(in
|
||||||
|
return IRQ_HANDLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int airoha_qdma_init(struct airoha_eth *eth)
|
||||||
|
+static int airoha_qdma_init(struct platform_device *pdev,
|
||||||
|
+ struct airoha_eth *eth)
|
||||||
|
{
|
||||||
|
struct airoha_qdma *qdma = ð->qdma[0];
|
||||||
|
int err;
|
||||||
|
|
||||||
|
- err = devm_request_irq(eth->dev, eth->irq, airoha_irq_handler,
|
||||||
|
+ spin_lock_init(&qdma->irq_lock);
|
||||||
|
+ qdma->irq = platform_get_irq(pdev, 0);
|
||||||
|
+ if (qdma->irq < 0)
|
||||||
|
+ return qdma->irq;
|
||||||
|
+
|
||||||
|
+ err = devm_request_irq(eth->dev, qdma->irq, airoha_irq_handler,
|
||||||
|
IRQF_SHARED, KBUILD_MODNAME, eth);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
@@ -2061,7 +2065,8 @@ static int airoha_qdma_init(struct airoh
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int airoha_hw_init(struct airoha_eth *eth)
|
||||||
|
+static int airoha_hw_init(struct platform_device *pdev,
|
||||||
|
+ struct airoha_eth *eth)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
@@ -2077,7 +2082,7 @@ static int airoha_hw_init(struct airoha_
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
- return airoha_qdma_init(eth);
|
||||||
|
+ return airoha_qdma_init(pdev, eth);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void airoha_hw_cleanup(struct airoha_eth *eth)
|
||||||
|
@@ -2674,11 +2679,6 @@ static int airoha_probe(struct platform_
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
- spin_lock_init(ð->irq_lock);
|
||||||
|
- eth->irq = platform_get_irq(pdev, 0);
|
||||||
|
- if (eth->irq < 0)
|
||||||
|
- return eth->irq;
|
||||||
|
-
|
||||||
|
eth->napi_dev = alloc_netdev_dummy(0);
|
||||||
|
if (!eth->napi_dev)
|
||||||
|
return -ENOMEM;
|
||||||
|
@@ -2688,7 +2688,7 @@ static int airoha_probe(struct platform_
|
||||||
|
strscpy(eth->napi_dev->name, "qdma_eth", sizeof(eth->napi_dev->name));
|
||||||
|
platform_set_drvdata(pdev, eth);
|
||||||
|
|
||||||
|
- err = airoha_hw_init(eth);
|
||||||
|
+ err = airoha_hw_init(pdev, eth);
|
||||||
|
if (err)
|
||||||
|
goto error;
|
||||||
|
|
||||||
@ -0,0 +1,306 @@
|
|||||||
|
From 9a2500ab22f059e596942172a8e4a60ae8243ce4 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||||
|
Date: Thu, 1 Aug 2024 16:35:06 +0200
|
||||||
|
Subject: [PATCH 4/8] net: airoha: Add airoha_qdma pointer in
|
||||||
|
airoha_tx_irq_queue/airoha_queue structures
|
||||||
|
|
||||||
|
Move airoha_eth pointer in airoha_qdma structure from
|
||||||
|
airoha_tx_irq_queue/airoha_queue ones. This is a preliminary patch to
|
||||||
|
introduce support for multi-QDMA controllers available on EN7581.
|
||||||
|
|
||||||
|
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||||
|
Link: https://patch.msgid.link/074565b82fd0ceefe66e186f21133d825dbd48eb.1722522582.git.lorenzo@kernel.org
|
||||||
|
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||||
|
---
|
||||||
|
drivers/net/ethernet/mediatek/airoha_eth.c | 84 +++++++++++-----------
|
||||||
|
1 file changed, 41 insertions(+), 43 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/net/ethernet/mediatek/airoha_eth.c
|
||||||
|
+++ b/drivers/net/ethernet/mediatek/airoha_eth.c
|
||||||
|
@@ -728,7 +728,7 @@ struct airoha_queue_entry {
|
||||||
|
};
|
||||||
|
|
||||||
|
struct airoha_queue {
|
||||||
|
- struct airoha_eth *eth;
|
||||||
|
+ struct airoha_qdma *qdma;
|
||||||
|
|
||||||
|
/* protect concurrent queue accesses */
|
||||||
|
spinlock_t lock;
|
||||||
|
@@ -747,7 +747,7 @@ struct airoha_queue {
|
||||||
|
};
|
||||||
|
|
||||||
|
struct airoha_tx_irq_queue {
|
||||||
|
- struct airoha_eth *eth;
|
||||||
|
+ struct airoha_qdma *qdma;
|
||||||
|
|
||||||
|
struct napi_struct napi;
|
||||||
|
u32 *q;
|
||||||
|
@@ -784,6 +784,7 @@ struct airoha_hw_stats {
|
||||||
|
};
|
||||||
|
|
||||||
|
struct airoha_qdma {
|
||||||
|
+ struct airoha_eth *eth;
|
||||||
|
void __iomem *regs;
|
||||||
|
|
||||||
|
/* protect concurrent irqmask accesses */
|
||||||
|
@@ -1388,8 +1389,8 @@ static int airoha_fe_init(struct airoha_
|
||||||
|
static int airoha_qdma_fill_rx_queue(struct airoha_queue *q)
|
||||||
|
{
|
||||||
|
enum dma_data_direction dir = page_pool_get_dma_dir(q->page_pool);
|
||||||
|
- struct airoha_qdma *qdma = &q->eth->qdma[0];
|
||||||
|
- struct airoha_eth *eth = q->eth;
|
||||||
|
+ struct airoha_qdma *qdma = q->qdma;
|
||||||
|
+ struct airoha_eth *eth = qdma->eth;
|
||||||
|
int qid = q - &qdma->q_rx[0];
|
||||||
|
int nframes = 0;
|
||||||
|
|
||||||
|
@@ -1457,8 +1458,8 @@ static int airoha_qdma_get_gdm_port(stru
|
||||||
|
static int airoha_qdma_rx_process(struct airoha_queue *q, int budget)
|
||||||
|
{
|
||||||
|
enum dma_data_direction dir = page_pool_get_dma_dir(q->page_pool);
|
||||||
|
- struct airoha_qdma *qdma = &q->eth->qdma[0];
|
||||||
|
- struct airoha_eth *eth = q->eth;
|
||||||
|
+ struct airoha_qdma *qdma = q->qdma;
|
||||||
|
+ struct airoha_eth *eth = qdma->eth;
|
||||||
|
int qid = q - &qdma->q_rx[0];
|
||||||
|
int done = 0;
|
||||||
|
|
||||||
|
@@ -1521,7 +1522,6 @@ static int airoha_qdma_rx_process(struct
|
||||||
|
static int airoha_qdma_rx_napi_poll(struct napi_struct *napi, int budget)
|
||||||
|
{
|
||||||
|
struct airoha_queue *q = container_of(napi, struct airoha_queue, napi);
|
||||||
|
- struct airoha_qdma *qdma = &q->eth->qdma[0];
|
||||||
|
int cur, done = 0;
|
||||||
|
|
||||||
|
do {
|
||||||
|
@@ -1530,14 +1530,13 @@ static int airoha_qdma_rx_napi_poll(stru
|
||||||
|
} while (cur && done < budget);
|
||||||
|
|
||||||
|
if (done < budget && napi_complete(napi))
|
||||||
|
- airoha_qdma_irq_enable(qdma, QDMA_INT_REG_IDX1,
|
||||||
|
+ airoha_qdma_irq_enable(q->qdma, QDMA_INT_REG_IDX1,
|
||||||
|
RX_DONE_INT_MASK);
|
||||||
|
|
||||||
|
return done;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int airoha_qdma_init_rx_queue(struct airoha_eth *eth,
|
||||||
|
- struct airoha_queue *q,
|
||||||
|
+static int airoha_qdma_init_rx_queue(struct airoha_queue *q,
|
||||||
|
struct airoha_qdma *qdma, int ndesc)
|
||||||
|
{
|
||||||
|
const struct page_pool_params pp_params = {
|
||||||
|
@@ -1548,15 +1547,16 @@ static int airoha_qdma_init_rx_queue(str
|
||||||
|
.dma_dir = DMA_FROM_DEVICE,
|
||||||
|
.max_len = PAGE_SIZE,
|
||||||
|
.nid = NUMA_NO_NODE,
|
||||||
|
- .dev = eth->dev,
|
||||||
|
+ .dev = qdma->eth->dev,
|
||||||
|
.napi = &q->napi,
|
||||||
|
};
|
||||||
|
+ struct airoha_eth *eth = qdma->eth;
|
||||||
|
int qid = q - &qdma->q_rx[0], thr;
|
||||||
|
dma_addr_t dma_addr;
|
||||||
|
|
||||||
|
q->buf_size = PAGE_SIZE / 2;
|
||||||
|
q->ndesc = ndesc;
|
||||||
|
- q->eth = eth;
|
||||||
|
+ q->qdma = qdma;
|
||||||
|
|
||||||
|
q->entry = devm_kzalloc(eth->dev, q->ndesc * sizeof(*q->entry),
|
||||||
|
GFP_KERNEL);
|
||||||
|
@@ -1596,7 +1596,7 @@ static int airoha_qdma_init_rx_queue(str
|
||||||
|
|
||||||
|
static void airoha_qdma_cleanup_rx_queue(struct airoha_queue *q)
|
||||||
|
{
|
||||||
|
- struct airoha_eth *eth = q->eth;
|
||||||
|
+ struct airoha_eth *eth = q->qdma->eth;
|
||||||
|
|
||||||
|
while (q->queued) {
|
||||||
|
struct airoha_queue_entry *e = &q->entry[q->tail];
|
||||||
|
@@ -1610,8 +1610,7 @@ static void airoha_qdma_cleanup_rx_queue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int airoha_qdma_init_rx(struct airoha_eth *eth,
|
||||||
|
- struct airoha_qdma *qdma)
|
||||||
|
+static int airoha_qdma_init_rx(struct airoha_qdma *qdma)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
@@ -1623,8 +1622,8 @@ static int airoha_qdma_init_rx(struct ai
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
- err = airoha_qdma_init_rx_queue(eth, &qdma->q_rx[i],
|
||||||
|
- qdma, RX_DSCP_NUM(i));
|
||||||
|
+ err = airoha_qdma_init_rx_queue(&qdma->q_rx[i], qdma,
|
||||||
|
+ RX_DSCP_NUM(i));
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
@@ -1640,9 +1639,9 @@ static int airoha_qdma_tx_napi_poll(stru
|
||||||
|
int id, done = 0;
|
||||||
|
|
||||||
|
irq_q = container_of(napi, struct airoha_tx_irq_queue, napi);
|
||||||
|
- eth = irq_q->eth;
|
||||||
|
- qdma = ð->qdma[0];
|
||||||
|
+ 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];
|
||||||
|
@@ -1724,16 +1723,16 @@ static int airoha_qdma_tx_napi_poll(stru
|
||||||
|
return done;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int airoha_qdma_init_tx_queue(struct airoha_eth *eth,
|
||||||
|
- struct airoha_queue *q,
|
||||||
|
+static int airoha_qdma_init_tx_queue(struct airoha_queue *q,
|
||||||
|
struct airoha_qdma *qdma, int size)
|
||||||
|
{
|
||||||
|
+ struct airoha_eth *eth = qdma->eth;
|
||||||
|
int i, qid = q - &qdma->q_tx[0];
|
||||||
|
dma_addr_t dma_addr;
|
||||||
|
|
||||||
|
spin_lock_init(&q->lock);
|
||||||
|
q->ndesc = size;
|
||||||
|
- q->eth = eth;
|
||||||
|
+ q->qdma = qdma;
|
||||||
|
q->free_thr = 1 + MAX_SKB_FRAGS;
|
||||||
|
|
||||||
|
q->entry = devm_kzalloc(eth->dev, q->ndesc * sizeof(*q->entry),
|
||||||
|
@@ -1762,11 +1761,11 @@ static int airoha_qdma_init_tx_queue(str
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int airoha_qdma_tx_irq_init(struct airoha_eth *eth,
|
||||||
|
- struct airoha_tx_irq_queue *irq_q,
|
||||||
|
+static int airoha_qdma_tx_irq_init(struct airoha_tx_irq_queue *irq_q,
|
||||||
|
struct airoha_qdma *qdma, int size)
|
||||||
|
{
|
||||||
|
int id = irq_q - &qdma->q_tx_irq[0];
|
||||||
|
+ struct airoha_eth *eth = qdma->eth;
|
||||||
|
dma_addr_t dma_addr;
|
||||||
|
|
||||||
|
netif_napi_add_tx(eth->napi_dev, &irq_q->napi,
|
||||||
|
@@ -1778,7 +1777,7 @@ static int airoha_qdma_tx_irq_init(struc
|
||||||
|
|
||||||
|
memset(irq_q->q, 0xff, size * sizeof(u32));
|
||||||
|
irq_q->size = size;
|
||||||
|
- irq_q->eth = eth;
|
||||||
|
+ irq_q->qdma = qdma;
|
||||||
|
|
||||||
|
airoha_qdma_wr(qdma, REG_TX_IRQ_BASE(id), dma_addr);
|
||||||
|
airoha_qdma_rmw(qdma, REG_TX_IRQ_CFG(id), TX_IRQ_DEPTH_MASK,
|
||||||
|
@@ -1789,21 +1788,20 @@ static int airoha_qdma_tx_irq_init(struc
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int airoha_qdma_init_tx(struct airoha_eth *eth,
|
||||||
|
- struct airoha_qdma *qdma)
|
||||||
|
+static int airoha_qdma_init_tx(struct airoha_qdma *qdma)
|
||||||
|
{
|
||||||
|
int i, err;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++) {
|
||||||
|
- err = airoha_qdma_tx_irq_init(eth, &qdma->q_tx_irq[i],
|
||||||
|
- qdma, IRQ_QUEUE_LEN(i));
|
||||||
|
+ err = airoha_qdma_tx_irq_init(&qdma->q_tx_irq[i], qdma,
|
||||||
|
+ IRQ_QUEUE_LEN(i));
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) {
|
||||||
|
- err = airoha_qdma_init_tx_queue(eth, &qdma->q_tx[i],
|
||||||
|
- qdma, TX_DSCP_NUM);
|
||||||
|
+ err = airoha_qdma_init_tx_queue(&qdma->q_tx[i], qdma,
|
||||||
|
+ TX_DSCP_NUM);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
@@ -1813,7 +1811,7 @@ static int airoha_qdma_init_tx(struct ai
|
||||||
|
|
||||||
|
static void airoha_qdma_cleanup_tx_queue(struct airoha_queue *q)
|
||||||
|
{
|
||||||
|
- struct airoha_eth *eth = q->eth;
|
||||||
|
+ struct airoha_eth *eth = q->qdma->eth;
|
||||||
|
|
||||||
|
spin_lock_bh(&q->lock);
|
||||||
|
while (q->queued) {
|
||||||
|
@@ -1830,9 +1828,9 @@ static void airoha_qdma_cleanup_tx_queue
|
||||||
|
spin_unlock_bh(&q->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int airoha_qdma_init_hfwd_queues(struct airoha_eth *eth,
|
||||||
|
- struct airoha_qdma *qdma)
|
||||||
|
+static int airoha_qdma_init_hfwd_queues(struct airoha_qdma *qdma)
|
||||||
|
{
|
||||||
|
+ struct airoha_eth *eth = qdma->eth;
|
||||||
|
dma_addr_t dma_addr;
|
||||||
|
u32 status;
|
||||||
|
int size;
|
||||||
|
@@ -1870,8 +1868,7 @@ static int airoha_qdma_init_hfwd_queues(
|
||||||
|
REG_LMGR_INIT_CFG);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void airoha_qdma_init_qos(struct airoha_eth *eth,
|
||||||
|
- struct airoha_qdma *qdma)
|
||||||
|
+static void airoha_qdma_init_qos(struct airoha_qdma *qdma)
|
||||||
|
{
|
||||||
|
airoha_qdma_clear(qdma, REG_TXWRR_MODE_CFG, TWRR_WEIGHT_SCALE_MASK);
|
||||||
|
airoha_qdma_set(qdma, REG_TXWRR_MODE_CFG, TWRR_WEIGHT_BASE_MASK);
|
||||||
|
@@ -1921,8 +1918,7 @@ static void airoha_qdma_init_qos(struct
|
||||||
|
FIELD_PREP(SLA_SLOW_TICK_RATIO_MASK, 40));
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int airoha_qdma_hw_init(struct airoha_eth *eth,
|
||||||
|
- struct airoha_qdma *qdma)
|
||||||
|
+static int airoha_qdma_hw_init(struct airoha_qdma *qdma)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
@@ -1959,7 +1955,7 @@ static int airoha_qdma_hw_init(struct ai
|
||||||
|
GLOBAL_CFG_TX_WB_DONE_MASK |
|
||||||
|
FIELD_PREP(GLOBAL_CFG_MAX_ISSUE_NUM_MASK, 2));
|
||||||
|
|
||||||
|
- airoha_qdma_init_qos(eth, qdma);
|
||||||
|
+ airoha_qdma_init_qos(qdma);
|
||||||
|
|
||||||
|
/* disable qdma rx delay interrupt */
|
||||||
|
for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) {
|
||||||
|
@@ -2035,6 +2031,8 @@ static int airoha_qdma_init(struct platf
|
||||||
|
int err;
|
||||||
|
|
||||||
|
spin_lock_init(&qdma->irq_lock);
|
||||||
|
+ qdma->eth = eth;
|
||||||
|
+
|
||||||
|
qdma->irq = platform_get_irq(pdev, 0);
|
||||||
|
if (qdma->irq < 0)
|
||||||
|
return qdma->irq;
|
||||||
|
@@ -2044,19 +2042,19 @@ static int airoha_qdma_init(struct platf
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
- err = airoha_qdma_init_rx(eth, qdma);
|
||||||
|
+ err = airoha_qdma_init_rx(qdma);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
- err = airoha_qdma_init_tx(eth, qdma);
|
||||||
|
+ err = airoha_qdma_init_tx(qdma);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
- err = airoha_qdma_init_hfwd_queues(eth, qdma);
|
||||||
|
+ err = airoha_qdma_init_hfwd_queues(qdma);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
- err = airoha_qdma_hw_init(eth, qdma);
|
||||||
|
+ err = airoha_qdma_hw_init(qdma);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
@ -0,0 +1,45 @@
|
|||||||
|
From e3d6bfdfc0aeb8c1d7965413b1050ec07f9761e5 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||||
|
Date: Thu, 1 Aug 2024 16:35:07 +0200
|
||||||
|
Subject: [PATCH 5/8] net: airoha: Use qdma pointer as private structure in
|
||||||
|
airoha_irq_handler routine
|
||||||
|
|
||||||
|
This is a preliminary patch to support multi-QDMA controllers.
|
||||||
|
|
||||||
|
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||||
|
Link: https://patch.msgid.link/1e40c3cb973881c0eb3c3c247c78550da62054ab.1722522582.git.lorenzo@kernel.org
|
||||||
|
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||||
|
---
|
||||||
|
drivers/net/ethernet/mediatek/airoha_eth.c | 7 +++----
|
||||||
|
1 file changed, 3 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/net/ethernet/mediatek/airoha_eth.c
|
||||||
|
+++ b/drivers/net/ethernet/mediatek/airoha_eth.c
|
||||||
|
@@ -1974,8 +1974,7 @@ static int airoha_qdma_hw_init(struct ai
|
||||||
|
|
||||||
|
static irqreturn_t airoha_irq_handler(int irq, void *dev_instance)
|
||||||
|
{
|
||||||
|
- struct airoha_eth *eth = dev_instance;
|
||||||
|
- struct airoha_qdma *qdma = ð->qdma[0];
|
||||||
|
+ struct airoha_qdma *qdma = dev_instance;
|
||||||
|
u32 intr[ARRAY_SIZE(qdma->irqmask)];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
@@ -1985,7 +1984,7 @@ static irqreturn_t airoha_irq_handler(in
|
||||||
|
airoha_qdma_wr(qdma, REG_INT_STATUS(i), intr[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (!test_bit(DEV_STATE_INITIALIZED, ð->state))
|
||||||
|
+ if (!test_bit(DEV_STATE_INITIALIZED, &qdma->eth->state))
|
||||||
|
return IRQ_NONE;
|
||||||
|
|
||||||
|
if (intr[1] & RX_DONE_INT_MASK) {
|
||||||
|
@@ -2038,7 +2037,7 @@ static int airoha_qdma_init(struct platf
|
||||||
|
return qdma->irq;
|
||||||
|
|
||||||
|
err = devm_request_irq(eth->dev, qdma->irq, airoha_irq_handler,
|
||||||
|
- IRQF_SHARED, KBUILD_MODNAME, eth);
|
||||||
|
+ IRQF_SHARED, KBUILD_MODNAME, qdma);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
@ -0,0 +1,131 @@
|
|||||||
|
From e618447cf492d04415007336eec025fae6e9a2ea Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||||
|
Date: Thu, 1 Aug 2024 16:35:08 +0200
|
||||||
|
Subject: [PATCH 6/8] net: airoha: Allow mapping IO region for multiple qdma
|
||||||
|
controllers
|
||||||
|
|
||||||
|
Map MMIO regions of both qdma controllers available on EN7581 SoC.
|
||||||
|
Run airoha_hw_cleanup routine for both QDMA controllers available on
|
||||||
|
EN7581 SoC removing airoha_eth module or in airoha_probe error path.
|
||||||
|
This is a preliminary patch to support multi-QDMA controllers.
|
||||||
|
|
||||||
|
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||||
|
Link: https://patch.msgid.link/a734ae608da14b67ae749b375d880dbbc70868ea.1722522582.git.lorenzo@kernel.org
|
||||||
|
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||||
|
---
|
||||||
|
drivers/net/ethernet/mediatek/airoha_eth.c | 56 ++++++++++++----------
|
||||||
|
1 file changed, 32 insertions(+), 24 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/net/ethernet/mediatek/airoha_eth.c
|
||||||
|
+++ b/drivers/net/ethernet/mediatek/airoha_eth.c
|
||||||
|
@@ -2024,15 +2024,25 @@ static irqreturn_t airoha_irq_handler(in
|
||||||
|
}
|
||||||
|
|
||||||
|
static int airoha_qdma_init(struct platform_device *pdev,
|
||||||
|
- struct airoha_eth *eth)
|
||||||
|
+ struct airoha_eth *eth,
|
||||||
|
+ struct airoha_qdma *qdma)
|
||||||
|
{
|
||||||
|
- struct airoha_qdma *qdma = ð->qdma[0];
|
||||||
|
- int err;
|
||||||
|
+ int err, id = qdma - ð->qdma[0];
|
||||||
|
+ const char *res;
|
||||||
|
|
||||||
|
spin_lock_init(&qdma->irq_lock);
|
||||||
|
qdma->eth = eth;
|
||||||
|
|
||||||
|
- qdma->irq = platform_get_irq(pdev, 0);
|
||||||
|
+ res = devm_kasprintf(eth->dev, GFP_KERNEL, "qdma%d", id);
|
||||||
|
+ if (!res)
|
||||||
|
+ return -ENOMEM;
|
||||||
|
+
|
||||||
|
+ qdma->regs = devm_platform_ioremap_resource_byname(pdev, res);
|
||||||
|
+ if (IS_ERR(qdma->regs))
|
||||||
|
+ return dev_err_probe(eth->dev, PTR_ERR(qdma->regs),
|
||||||
|
+ "failed to iomap qdma%d regs\n", id);
|
||||||
|
+
|
||||||
|
+ qdma->irq = platform_get_irq(pdev, 4 * id);
|
||||||
|
if (qdma->irq < 0)
|
||||||
|
return qdma->irq;
|
||||||
|
|
||||||
|
@@ -2053,19 +2063,13 @@ static int airoha_qdma_init(struct platf
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
- err = airoha_qdma_hw_init(qdma);
|
||||||
|
- if (err)
|
||||||
|
- return err;
|
||||||
|
-
|
||||||
|
- set_bit(DEV_STATE_INITIALIZED, ð->state);
|
||||||
|
-
|
||||||
|
- return 0;
|
||||||
|
+ return airoha_qdma_hw_init(qdma);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int airoha_hw_init(struct platform_device *pdev,
|
||||||
|
struct airoha_eth *eth)
|
||||||
|
{
|
||||||
|
- int err;
|
||||||
|
+ int err, i;
|
||||||
|
|
||||||
|
/* disable xsi */
|
||||||
|
reset_control_bulk_assert(ARRAY_SIZE(eth->xsi_rsts), eth->xsi_rsts);
|
||||||
|
@@ -2079,12 +2083,19 @@ static int airoha_hw_init(struct platfor
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
- return airoha_qdma_init(pdev, eth);
|
||||||
|
+ for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) {
|
||||||
|
+ err = airoha_qdma_init(pdev, eth, ð->qdma[i]);
|
||||||
|
+ if (err)
|
||||||
|
+ return err;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ set_bit(DEV_STATE_INITIALIZED, ð->state);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void airoha_hw_cleanup(struct airoha_eth *eth)
|
||||||
|
+static void airoha_hw_cleanup(struct airoha_qdma *qdma)
|
||||||
|
{
|
||||||
|
- struct airoha_qdma *qdma = ð->qdma[0];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) {
|
||||||
|
@@ -2645,13 +2656,6 @@ static int airoha_probe(struct platform_
|
||||||
|
return dev_err_probe(eth->dev, PTR_ERR(eth->fe_regs),
|
||||||
|
"failed to iomap fe regs\n");
|
||||||
|
|
||||||
|
- eth->qdma[0].regs = devm_platform_ioremap_resource_byname(pdev,
|
||||||
|
- "qdma0");
|
||||||
|
- if (IS_ERR(eth->qdma[0].regs))
|
||||||
|
- return dev_err_probe(eth->dev,
|
||||||
|
- PTR_ERR(eth->qdma[0].regs),
|
||||||
|
- "failed to iomap qdma regs\n");
|
||||||
|
-
|
||||||
|
eth->rsts[0].id = "fe";
|
||||||
|
eth->rsts[1].id = "pdma";
|
||||||
|
eth->rsts[2].id = "qdma";
|
||||||
|
@@ -2707,7 +2711,9 @@ static int airoha_probe(struct platform_
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
error:
|
||||||
|
- airoha_hw_cleanup(eth);
|
||||||
|
+ for (i = 0; i < ARRAY_SIZE(eth->qdma); i++)
|
||||||
|
+ airoha_hw_cleanup(ð->qdma[i]);
|
||||||
|
+
|
||||||
|
for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
|
||||||
|
struct airoha_gdm_port *port = eth->ports[i];
|
||||||
|
|
||||||
|
@@ -2725,7 +2731,9 @@ static void airoha_remove(struct platfor
|
||||||
|
struct airoha_eth *eth = platform_get_drvdata(pdev);
|
||||||
|
int i;
|
||||||
|
|
||||||
|
- airoha_hw_cleanup(eth);
|
||||||
|
+ for (i = 0; i < ARRAY_SIZE(eth->qdma); i++)
|
||||||
|
+ airoha_hw_cleanup(ð->qdma[i]);
|
||||||
|
+
|
||||||
|
for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
|
||||||
|
struct airoha_gdm_port *port = eth->ports[i];
|
||||||
|
|
||||||
@ -0,0 +1,38 @@
|
|||||||
|
From 160231e34b8e9512ba20530f3e68fb0ac499af87 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||||
|
Date: Thu, 1 Aug 2024 16:35:09 +0200
|
||||||
|
Subject: [PATCH 7/8] net: airoha: Start all qdma NAPIs in airoha_probe()
|
||||||
|
|
||||||
|
This is a preliminary patch to support multi-QDMA controllers.
|
||||||
|
|
||||||
|
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||||
|
Link: https://patch.msgid.link/b51cf69c94d8cbc81e0a0b35587f024d01e6d9c0.1722522582.git.lorenzo@kernel.org
|
||||||
|
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||||
|
---
|
||||||
|
drivers/net/ethernet/mediatek/airoha_eth.c | 7 ++++---
|
||||||
|
1 file changed, 4 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/net/ethernet/mediatek/airoha_eth.c
|
||||||
|
+++ b/drivers/net/ethernet/mediatek/airoha_eth.c
|
||||||
|
@@ -2122,9 +2122,8 @@ static void airoha_hw_cleanup(struct air
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void airoha_qdma_start_napi(struct airoha_eth *eth)
|
||||||
|
+static void airoha_qdma_start_napi(struct airoha_qdma *qdma)
|
||||||
|
{
|
||||||
|
- struct airoha_qdma *qdma = ð->qdma[0];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++)
|
||||||
|
@@ -2693,7 +2692,9 @@ static int airoha_probe(struct platform_
|
||||||
|
if (err)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
- airoha_qdma_start_napi(eth);
|
||||||
|
+ for (i = 0; i < ARRAY_SIZE(eth->qdma); i++)
|
||||||
|
+ airoha_qdma_start_napi(ð->qdma[i]);
|
||||||
|
+
|
||||||
|
for_each_child_of_node(pdev->dev.of_node, np) {
|
||||||
|
if (!of_device_is_compatible(np, "airoha,eth-mac"))
|
||||||
|
continue;
|
||||||
@ -0,0 +1,174 @@
|
|||||||
|
From 9304640f2f78147dddf97a5ea01502ae175e41d9 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||||
|
Date: Thu, 1 Aug 2024 16:35:10 +0200
|
||||||
|
Subject: [PATCH 8/8] net: airoha: Link the gdm port to the selected qdma
|
||||||
|
controller
|
||||||
|
|
||||||
|
Link the running gdm port to the qdma controller used to connect with
|
||||||
|
the CPU. Moreover, load all QDMA controllers available on EN7581 SoC.
|
||||||
|
|
||||||
|
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||||
|
Link: https://patch.msgid.link/95b515df34ba4727f7ae5b14a1d0462cceec84ff.1722522582.git.lorenzo@kernel.org
|
||||||
|
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||||
|
---
|
||||||
|
drivers/net/ethernet/mediatek/airoha_eth.c | 37 +++++++++++-----------
|
||||||
|
1 file changed, 19 insertions(+), 18 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/net/ethernet/mediatek/airoha_eth.c
|
||||||
|
+++ b/drivers/net/ethernet/mediatek/airoha_eth.c
|
||||||
|
@@ -18,7 +18,7 @@
|
||||||
|
#include <uapi/linux/ppp_defs.h>
|
||||||
|
|
||||||
|
#define AIROHA_MAX_NUM_GDM_PORTS 1
|
||||||
|
-#define AIROHA_MAX_NUM_QDMA 1
|
||||||
|
+#define AIROHA_MAX_NUM_QDMA 2
|
||||||
|
#define AIROHA_MAX_NUM_RSTS 3
|
||||||
|
#define AIROHA_MAX_NUM_XSI_RSTS 5
|
||||||
|
#define AIROHA_MAX_MTU 2000
|
||||||
|
@@ -805,8 +805,8 @@ struct airoha_qdma {
|
||||||
|
};
|
||||||
|
|
||||||
|
struct airoha_gdm_port {
|
||||||
|
+ struct airoha_qdma *qdma;
|
||||||
|
struct net_device *dev;
|
||||||
|
- struct airoha_eth *eth;
|
||||||
|
int id;
|
||||||
|
|
||||||
|
struct airoha_hw_stats stats;
|
||||||
|
@@ -2139,7 +2139,7 @@ static void airoha_qdma_start_napi(struc
|
||||||
|
|
||||||
|
static void airoha_update_hw_stats(struct airoha_gdm_port *port)
|
||||||
|
{
|
||||||
|
- struct airoha_eth *eth = port->eth;
|
||||||
|
+ struct airoha_eth *eth = port->qdma->eth;
|
||||||
|
u32 val, i = 0;
|
||||||
|
|
||||||
|
spin_lock(&port->stats.lock);
|
||||||
|
@@ -2284,22 +2284,22 @@ static void airoha_update_hw_stats(struc
|
||||||
|
static int airoha_dev_open(struct net_device *dev)
|
||||||
|
{
|
||||||
|
struct airoha_gdm_port *port = netdev_priv(dev);
|
||||||
|
- struct airoha_eth *eth = port->eth;
|
||||||
|
+ struct airoha_qdma *qdma = port->qdma;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
netif_tx_start_all_queues(dev);
|
||||||
|
- err = airoha_set_gdm_ports(eth, true);
|
||||||
|
+ err = airoha_set_gdm_ports(qdma->eth, true);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
if (netdev_uses_dsa(dev))
|
||||||
|
- airoha_fe_set(eth, REG_GDM_INGRESS_CFG(port->id),
|
||||||
|
+ airoha_fe_set(qdma->eth, REG_GDM_INGRESS_CFG(port->id),
|
||||||
|
GDM_STAG_EN_MASK);
|
||||||
|
else
|
||||||
|
- airoha_fe_clear(eth, REG_GDM_INGRESS_CFG(port->id),
|
||||||
|
+ airoha_fe_clear(qdma->eth, REG_GDM_INGRESS_CFG(port->id),
|
||||||
|
GDM_STAG_EN_MASK);
|
||||||
|
|
||||||
|
- airoha_qdma_set(ð->qdma[0], REG_QDMA_GLOBAL_CFG,
|
||||||
|
+ airoha_qdma_set(qdma, REG_QDMA_GLOBAL_CFG,
|
||||||
|
GLOBAL_CFG_TX_DMA_EN_MASK |
|
||||||
|
GLOBAL_CFG_RX_DMA_EN_MASK);
|
||||||
|
|
||||||
|
@@ -2309,15 +2309,15 @@ static int airoha_dev_open(struct net_de
|
||||||
|
static int airoha_dev_stop(struct net_device *dev)
|
||||||
|
{
|
||||||
|
struct airoha_gdm_port *port = netdev_priv(dev);
|
||||||
|
- struct airoha_eth *eth = port->eth;
|
||||||
|
+ struct airoha_qdma *qdma = port->qdma;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
netif_tx_disable(dev);
|
||||||
|
- err = airoha_set_gdm_ports(eth, false);
|
||||||
|
+ err = airoha_set_gdm_ports(qdma->eth, false);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
- airoha_qdma_clear(ð->qdma[0], REG_QDMA_GLOBAL_CFG,
|
||||||
|
+ airoha_qdma_clear(qdma, REG_QDMA_GLOBAL_CFG,
|
||||||
|
GLOBAL_CFG_TX_DMA_EN_MASK |
|
||||||
|
GLOBAL_CFG_RX_DMA_EN_MASK);
|
||||||
|
|
||||||
|
@@ -2333,7 +2333,7 @@ static int airoha_dev_set_macaddr(struct
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
- airoha_set_macaddr(port->eth, dev->dev_addr);
|
||||||
|
+ airoha_set_macaddr(port->qdma->eth, dev->dev_addr);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@@ -2342,7 +2342,7 @@ static int airoha_dev_init(struct net_de
|
||||||
|
{
|
||||||
|
struct airoha_gdm_port *port = netdev_priv(dev);
|
||||||
|
|
||||||
|
- airoha_set_macaddr(port->eth, dev->dev_addr);
|
||||||
|
+ airoha_set_macaddr(port->qdma->eth, dev->dev_addr);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@@ -2376,10 +2376,9 @@ static netdev_tx_t airoha_dev_xmit(struc
|
||||||
|
struct airoha_gdm_port *port = netdev_priv(dev);
|
||||||
|
u32 msg0 = 0, msg1, len = skb_headlen(skb);
|
||||||
|
int i, qid = skb_get_queue_mapping(skb);
|
||||||
|
- struct airoha_eth *eth = port->eth;
|
||||||
|
+ struct airoha_qdma *qdma = port->qdma;
|
||||||
|
u32 nr_frags = 1 + sinfo->nr_frags;
|
||||||
|
struct netdev_queue *txq;
|
||||||
|
- struct airoha_qdma *qdma;
|
||||||
|
struct airoha_queue *q;
|
||||||
|
void *data = skb->data;
|
||||||
|
u16 index;
|
||||||
|
@@ -2407,7 +2406,6 @@ static netdev_tx_t airoha_dev_xmit(struc
|
||||||
|
msg1 = FIELD_PREP(QDMA_ETH_TXMSG_FPORT_MASK, fport) |
|
||||||
|
FIELD_PREP(QDMA_ETH_TXMSG_METER_MASK, 0x7f);
|
||||||
|
|
||||||
|
- qdma = ð->qdma[0];
|
||||||
|
q = &qdma->q_tx[qid];
|
||||||
|
if (WARN_ON_ONCE(!q->ndesc))
|
||||||
|
goto error;
|
||||||
|
@@ -2490,7 +2488,7 @@ static void airoha_ethtool_get_drvinfo(s
|
||||||
|
struct ethtool_drvinfo *info)
|
||||||
|
{
|
||||||
|
struct airoha_gdm_port *port = netdev_priv(dev);
|
||||||
|
- struct airoha_eth *eth = port->eth;
|
||||||
|
+ struct airoha_eth *eth = port->qdma->eth;
|
||||||
|
|
||||||
|
strscpy(info->driver, eth->dev->driver->name, sizeof(info->driver));
|
||||||
|
strscpy(info->bus_info, dev_name(eth->dev), sizeof(info->bus_info));
|
||||||
|
@@ -2571,6 +2569,7 @@ static int airoha_alloc_gdm_port(struct
|
||||||
|
{
|
||||||
|
const __be32 *id_ptr = of_get_property(np, "reg", NULL);
|
||||||
|
struct airoha_gdm_port *port;
|
||||||
|
+ struct airoha_qdma *qdma;
|
||||||
|
struct net_device *dev;
|
||||||
|
int err, index;
|
||||||
|
u32 id;
|
||||||
|
@@ -2600,6 +2599,7 @@ static int airoha_alloc_gdm_port(struct
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ qdma = ð->qdma[index % AIROHA_MAX_NUM_QDMA];
|
||||||
|
dev->netdev_ops = &airoha_netdev_ops;
|
||||||
|
dev->ethtool_ops = &airoha_ethtool_ops;
|
||||||
|
dev->max_mtu = AIROHA_MAX_MTU;
|
||||||
|
@@ -2609,6 +2609,7 @@ static int airoha_alloc_gdm_port(struct
|
||||||
|
NETIF_F_SG | NETIF_F_TSO;
|
||||||
|
dev->features |= dev->hw_features;
|
||||||
|
dev->dev.of_node = np;
|
||||||
|
+ dev->irq = qdma->irq;
|
||||||
|
SET_NETDEV_DEV(dev, eth->dev);
|
||||||
|
|
||||||
|
err = of_get_ethdev_address(np, dev);
|
||||||
|
@@ -2624,8 +2625,8 @@ static int airoha_alloc_gdm_port(struct
|
||||||
|
port = netdev_priv(dev);
|
||||||
|
u64_stats_init(&port->stats.syncp);
|
||||||
|
spin_lock_init(&port->stats.lock);
|
||||||
|
+ port->qdma = qdma;
|
||||||
|
port->dev = dev;
|
||||||
|
- port->eth = eth;
|
||||||
|
port->id = id;
|
||||||
|
eth->ports[index] = port;
|
||||||
|
|
||||||
@ -0,0 +1,44 @@
|
|||||||
|
From 63a796b4988c3dca83176a534890b510d44f105a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||||
|
Date: Sat, 3 Aug 2024 17:50:50 +0200
|
||||||
|
Subject: [PATCH] net: airoha: honor reset return value in airoha_hw_init()
|
||||||
|
|
||||||
|
Take into account return value from reset_control_bulk_assert and
|
||||||
|
reset_control_bulk_deassert routines in airoha_hw_init().
|
||||||
|
|
||||||
|
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||||
|
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||||
|
Link: https://patch.msgid.link/f49dc04a87653e0155f4fab3e3eb584785c8ad6a.1722699555.git.lorenzo@kernel.org
|
||||||
|
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||||
|
---
|
||||||
|
drivers/net/ethernet/mediatek/airoha_eth.c | 16 ++++++++++++----
|
||||||
|
1 file changed, 12 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/net/ethernet/mediatek/airoha_eth.c
|
||||||
|
+++ b/drivers/net/ethernet/mediatek/airoha_eth.c
|
||||||
|
@@ -2072,13 +2072,21 @@ static int airoha_hw_init(struct platfor
|
||||||
|
int err, i;
|
||||||
|
|
||||||
|
/* disable xsi */
|
||||||
|
- reset_control_bulk_assert(ARRAY_SIZE(eth->xsi_rsts), eth->xsi_rsts);
|
||||||
|
+ err = reset_control_bulk_assert(ARRAY_SIZE(eth->xsi_rsts),
|
||||||
|
+ eth->xsi_rsts);
|
||||||
|
+ if (err)
|
||||||
|
+ return err;
|
||||||
|
+
|
||||||
|
+ err = reset_control_bulk_assert(ARRAY_SIZE(eth->rsts), eth->rsts);
|
||||||
|
+ if (err)
|
||||||
|
+ return err;
|
||||||
|
|
||||||
|
- reset_control_bulk_assert(ARRAY_SIZE(eth->rsts), eth->rsts);
|
||||||
|
- msleep(20);
|
||||||
|
- reset_control_bulk_deassert(ARRAY_SIZE(eth->rsts), eth->rsts);
|
||||||
|
msleep(20);
|
||||||
|
+ err = reset_control_bulk_deassert(ARRAY_SIZE(eth->rsts), eth->rsts);
|
||||||
|
+ if (err)
|
||||||
|
+ return err;
|
||||||
|
|
||||||
|
+ msleep(20);
|
||||||
|
err = airoha_fe_init(eth);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
@ -0,0 +1,85 @@
|
|||||||
|
From 812a2751e827fa1eb01f3bd268b4d74c23f4226a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||||
|
Date: Wed, 21 Aug 2024 09:30:14 +0200
|
||||||
|
Subject: [PATCH] net: airoha: configure hw mac address according to the port
|
||||||
|
id
|
||||||
|
|
||||||
|
GDM1 port on EN7581 SoC is connected to the lan dsa switch.
|
||||||
|
GDM{2,3,4} can be used as wan port connected to an external
|
||||||
|
phy module. Configure hw mac address registers according to the port id.
|
||||||
|
|
||||||
|
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||||
|
Link: https://patch.msgid.link/20240821-airoha-eth-wan-mac-addr-v2-1-8706d0cd6cd5@kernel.org
|
||||||
|
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||||
|
---
|
||||||
|
drivers/net/ethernet/mediatek/airoha_eth.c | 32 ++++++++++++++++------
|
||||||
|
1 file changed, 23 insertions(+), 9 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/net/ethernet/mediatek/airoha_eth.c
|
||||||
|
+++ b/drivers/net/ethernet/mediatek/airoha_eth.c
|
||||||
|
@@ -67,9 +67,11 @@
|
||||||
|
#define FE_RST_GDM3_MBI_ARB_MASK BIT(2)
|
||||||
|
#define FE_RST_CORE_MASK BIT(0)
|
||||||
|
|
||||||
|
+#define REG_FE_WAN_MAC_H 0x0030
|
||||||
|
#define REG_FE_LAN_MAC_H 0x0040
|
||||||
|
-#define REG_FE_LAN_MAC_LMIN 0x0044
|
||||||
|
-#define REG_FE_LAN_MAC_LMAX 0x0048
|
||||||
|
+
|
||||||
|
+#define REG_FE_MAC_LMIN(_n) ((_n) + 0x04)
|
||||||
|
+#define REG_FE_MAC_LMAX(_n) ((_n) + 0x08)
|
||||||
|
|
||||||
|
#define REG_FE_CDM1_OQ_MAP0 0x0050
|
||||||
|
#define REG_FE_CDM1_OQ_MAP1 0x0054
|
||||||
|
@@ -900,16 +902,28 @@ static void airoha_qdma_irq_disable(stru
|
||||||
|
airoha_qdma_set_irqmask(qdma, index, mask, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void airoha_set_macaddr(struct airoha_eth *eth, const u8 *addr)
|
||||||
|
+static bool airhoa_is_lan_gdm_port(struct airoha_gdm_port *port)
|
||||||
|
{
|
||||||
|
- u32 val;
|
||||||
|
+ /* GDM1 port on EN7581 SoC is connected to the lan dsa switch.
|
||||||
|
+ * GDM{2,3,4} can be used as wan port connected to an external
|
||||||
|
+ * phy module.
|
||||||
|
+ */
|
||||||
|
+ return port->id == 1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void airoha_set_macaddr(struct airoha_gdm_port *port, const u8 *addr)
|
||||||
|
+{
|
||||||
|
+ struct airoha_eth *eth = port->qdma->eth;
|
||||||
|
+ u32 val, reg;
|
||||||
|
|
||||||
|
+ reg = airhoa_is_lan_gdm_port(port) ? REG_FE_LAN_MAC_H
|
||||||
|
+ : REG_FE_WAN_MAC_H;
|
||||||
|
val = (addr[0] << 16) | (addr[1] << 8) | addr[2];
|
||||||
|
- airoha_fe_wr(eth, REG_FE_LAN_MAC_H, val);
|
||||||
|
+ airoha_fe_wr(eth, reg, val);
|
||||||
|
|
||||||
|
val = (addr[3] << 16) | (addr[4] << 8) | addr[5];
|
||||||
|
- airoha_fe_wr(eth, REG_FE_LAN_MAC_LMIN, val);
|
||||||
|
- airoha_fe_wr(eth, REG_FE_LAN_MAC_LMAX, val);
|
||||||
|
+ airoha_fe_wr(eth, REG_FE_MAC_LMIN(reg), val);
|
||||||
|
+ airoha_fe_wr(eth, REG_FE_MAC_LMAX(reg), val);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void airoha_set_gdm_port_fwd_cfg(struct airoha_eth *eth, u32 addr,
|
||||||
|
@@ -2341,7 +2355,7 @@ static int airoha_dev_set_macaddr(struct
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
- airoha_set_macaddr(port->qdma->eth, dev->dev_addr);
|
||||||
|
+ airoha_set_macaddr(port, dev->dev_addr);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@@ -2350,7 +2364,7 @@ static int airoha_dev_init(struct net_de
|
||||||
|
{
|
||||||
|
struct airoha_gdm_port *port = netdev_priv(dev);
|
||||||
|
|
||||||
|
- airoha_set_macaddr(port->qdma->eth, dev->dev_addr);
|
||||||
|
+ airoha_set_macaddr(port, dev->dev_addr);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
From 7d2bd8ac9d2494cf9b16c4b00df9424ad24ed18c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Liao Chen <liaochen4@huawei.com>
|
||||||
|
Date: Mon, 26 Aug 2024 09:18:58 +0000
|
||||||
|
Subject: [PATCH] net: airoha: fix module autoloading
|
||||||
|
|
||||||
|
Add MODULE_DEVICE_TABLE(), so modules could be properly autoloaded
|
||||||
|
based on the alias from of_device_id table.
|
||||||
|
|
||||||
|
Signed-off-by: Liao Chen <liaochen4@huawei.com>
|
||||||
|
Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||||
|
Link: https://patch.msgid.link/20240826091858.369910-4-liaochen4@huawei.com
|
||||||
|
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||||
|
---
|
||||||
|
drivers/net/ethernet/mediatek/airoha_eth.c | 1 +
|
||||||
|
1 file changed, 1 insertion(+)
|
||||||
|
|
||||||
|
--- a/drivers/net/ethernet/mediatek/airoha_eth.c
|
||||||
|
+++ b/drivers/net/ethernet/mediatek/airoha_eth.c
|
||||||
|
@@ -2776,6 +2776,7 @@ static const struct of_device_id of_airo
|
||||||
|
{ .compatible = "airoha,en7581-eth" },
|
||||||
|
{ /* sentinel */ }
|
||||||
|
};
|
||||||
|
+MODULE_DEVICE_TABLE(of, of_airoha_match);
|
||||||
|
|
||||||
|
static struct platform_driver airoha_driver = {
|
||||||
|
.probe = airoha_probe,
|
||||||
@ -0,0 +1,40 @@
|
|||||||
|
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++)
|
||||||
@ -0,0 +1,52 @@
|
|||||||
|
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));
|
||||||
@ -0,0 +1,45 @@
|
|||||||
|
From 3dc6e998d18bfba6e0dc979d3cc68eba98dfeef7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||||
|
Date: Fri, 4 Oct 2024 15:51:26 +0200
|
||||||
|
Subject: [PATCH] net: airoha: Update tx cpu dma ring idx at the end of xmit
|
||||||
|
loop
|
||||||
|
|
||||||
|
Move the tx cpu dma ring index update out of transmit loop of
|
||||||
|
airoha_dev_xmit routine in order to not start transmitting the packet
|
||||||
|
before it is fully DMA mapped (e.g. fragmented skbs).
|
||||||
|
|
||||||
|
Fixes: 23020f049327 ("net: airoha: Introduce ethernet support for EN7581 SoC")
|
||||||
|
Reported-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||||
|
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||||
|
Link: https://patch.msgid.link/20241004-airoha-eth-7581-mapping-fix-v1-1-8e4279ab1812@kernel.org
|
||||||
|
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||||
|
---
|
||||||
|
drivers/net/ethernet/mediatek/airoha_eth.c | 9 +++++----
|
||||||
|
1 file changed, 5 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/net/ethernet/mediatek/airoha_eth.c
|
||||||
|
+++ b/drivers/net/ethernet/mediatek/airoha_eth.c
|
||||||
|
@@ -2480,10 +2480,6 @@ static netdev_tx_t airoha_dev_xmit(struc
|
||||||
|
e->dma_addr = addr;
|
||||||
|
e->dma_len = len;
|
||||||
|
|
||||||
|
- airoha_qdma_rmw(qdma, REG_TX_CPU_IDX(qid),
|
||||||
|
- TX_RING_CPU_IDX_MASK,
|
||||||
|
- FIELD_PREP(TX_RING_CPU_IDX_MASK, index));
|
||||||
|
-
|
||||||
|
data = skb_frag_address(frag);
|
||||||
|
len = skb_frag_size(frag);
|
||||||
|
}
|
||||||
|
@@ -2492,6 +2488,11 @@ static netdev_tx_t airoha_dev_xmit(struc
|
||||||
|
q->queued += i;
|
||||||
|
|
||||||
|
skb_tx_timestamp(skb);
|
||||||
|
+ if (!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));
|
||||||
|
+
|
||||||
|
if (q->ndesc - q->queued < q->free_thr)
|
||||||
|
netif_tx_stop_queue(txq);
|
||||||
|
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
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)
|
||||||
@ -0,0 +1,42 @@
|
|||||||
|
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
|
||||||
|
@@ -1710,9 +1710,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);
|
||||||
|
@@ -2488,7 +2490,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));
|
||||||
@ -0,0 +1,98 @@
|
|||||||
|
From 457e74667f452d7f071ad2b2d9313ec62ebc4b02 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||||
|
Date: Sat, 6 Apr 2024 12:43:43 +0200
|
||||||
|
Subject: [PATCH 1/2] clk: en7523: Add en_clk_soc_data data structure
|
||||||
|
|
||||||
|
Introduce en_clk_soc_data data structure in order to define multiple
|
||||||
|
clk_ops for each supported SoC. This is a preliminary patch to
|
||||||
|
introduce EN7581 clock support.
|
||||||
|
|
||||||
|
Tested-by: Zhengping Zhang <zhengping.zhang@airoha.com>
|
||||||
|
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||||
|
Link: https://lore.kernel.org/r/562a0da8d7874a02a324687c152c87a1549924bd.1712399981.git.lorenzo@kernel.org
|
||||||
|
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
|
||||||
|
---
|
||||||
|
drivers/clk/clk-en7523.c | 34 +++++++++++++++++++++-------------
|
||||||
|
1 file changed, 21 insertions(+), 13 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/clk/clk-en7523.c
|
||||||
|
+++ b/drivers/clk/clk-en7523.c
|
||||||
|
@@ -3,8 +3,8 @@
|
||||||
|
#include <linux/delay.h>
|
||||||
|
#include <linux/clk-provider.h>
|
||||||
|
#include <linux/io.h>
|
||||||
|
-#include <linux/of.h>
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
+#include <linux/property.h>
|
||||||
|
#include <dt-bindings/clock/en7523-clk.h>
|
||||||
|
|
||||||
|
#define REG_PCI_CONTROL 0x88
|
||||||
|
@@ -48,6 +48,10 @@ struct en_clk_gate {
|
||||||
|
struct clk_hw hw;
|
||||||
|
};
|
||||||
|
|
||||||
|
+struct en_clk_soc_data {
|
||||||
|
+ const struct clk_ops pcie_ops;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
static const u32 gsw_base[] = { 400000000, 500000000 };
|
||||||
|
static const u32 emi_base[] = { 333000000, 400000000 };
|
||||||
|
static const u32 bus_base[] = { 500000000, 540000000 };
|
||||||
|
@@ -150,11 +154,6 @@ static const struct en_clk_desc en7523_b
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
-static const struct of_device_id of_match_clk_en7523[] = {
|
||||||
|
- { .compatible = "airoha,en7523-scu", },
|
||||||
|
- { /* sentinel */ }
|
||||||
|
-};
|
||||||
|
-
|
||||||
|
static unsigned int en7523_get_base_rate(void __iomem *base, unsigned int i)
|
||||||
|
{
|
||||||
|
const struct en_clk_desc *desc = &en7523_base_clks[i];
|
||||||
|
@@ -252,14 +251,10 @@ static void en7523_pci_unprepare(struct
|
||||||
|
static struct clk_hw *en7523_register_pcie_clk(struct device *dev,
|
||||||
|
void __iomem *np_base)
|
||||||
|
{
|
||||||
|
- static const struct clk_ops pcie_gate_ops = {
|
||||||
|
- .is_enabled = en7523_pci_is_enabled,
|
||||||
|
- .prepare = en7523_pci_prepare,
|
||||||
|
- .unprepare = en7523_pci_unprepare,
|
||||||
|
- };
|
||||||
|
+ const struct en_clk_soc_data *soc_data = device_get_match_data(dev);
|
||||||
|
struct clk_init_data init = {
|
||||||
|
.name = "pcie",
|
||||||
|
- .ops = &pcie_gate_ops,
|
||||||
|
+ .ops = &soc_data->pcie_ops,
|
||||||
|
};
|
||||||
|
struct en_clk_gate *cg;
|
||||||
|
|
||||||
|
@@ -269,7 +264,7 @@ static struct clk_hw *en7523_register_pc
|
||||||
|
|
||||||
|
cg->base = np_base;
|
||||||
|
cg->hw.init = &init;
|
||||||
|
- en7523_pci_unprepare(&cg->hw);
|
||||||
|
+ init.ops->unprepare(&cg->hw);
|
||||||
|
|
||||||
|
if (clk_hw_register(dev, &cg->hw))
|
||||||
|
return NULL;
|
||||||
|
@@ -338,6 +333,19 @@ static int en7523_clk_probe(struct platf
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static const struct en_clk_soc_data en7523_data = {
|
||||||
|
+ .pcie_ops = {
|
||||||
|
+ .is_enabled = en7523_pci_is_enabled,
|
||||||
|
+ .prepare = en7523_pci_prepare,
|
||||||
|
+ .unprepare = en7523_pci_unprepare,
|
||||||
|
+ },
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static const struct of_device_id of_match_clk_en7523[] = {
|
||||||
|
+ { .compatible = "airoha,en7523-scu", .data = &en7523_data },
|
||||||
|
+ { /* sentinel */ }
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
static struct platform_driver clk_en7523_drv = {
|
||||||
|
.probe = en7523_clk_probe,
|
||||||
|
.driver = {
|
||||||
@ -0,0 +1,248 @@
|
|||||||
|
From 66bc47326ce2a319add7e933d9340215711236ac Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||||
|
Date: Sat, 6 Apr 2024 12:43:44 +0200
|
||||||
|
Subject: [PATCH 2/2] clk: en7523: Add EN7581 support
|
||||||
|
|
||||||
|
Introduce EN7581 clock support to clk-en7523 driver.
|
||||||
|
Add hw_init callback to en_clk_soc_data data structure.
|
||||||
|
|
||||||
|
Tested-by: Zhengping Zhang <zhengping.zhang@airoha.com>
|
||||||
|
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||||
|
Link: https://lore.kernel.org/r/57b6e53ed4d2b2e38abff6a3ea56841bad6be8a9.1712399981.git.lorenzo@kernel.org
|
||||||
|
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
|
||||||
|
---
|
||||||
|
drivers/clk/clk-en7523.c | 157 +++++++++++++++++++++++++++++++++++++--
|
||||||
|
1 file changed, 152 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/clk/clk-en7523.c
|
||||||
|
+++ b/drivers/clk/clk-en7523.c
|
||||||
|
@@ -10,7 +10,9 @@
|
||||||
|
#define REG_PCI_CONTROL 0x88
|
||||||
|
#define REG_PCI_CONTROL_PERSTOUT BIT(29)
|
||||||
|
#define REG_PCI_CONTROL_PERSTOUT1 BIT(26)
|
||||||
|
+#define REG_PCI_CONTROL_REFCLK_EN0 BIT(23)
|
||||||
|
#define REG_PCI_CONTROL_REFCLK_EN1 BIT(22)
|
||||||
|
+#define REG_PCI_CONTROL_PERSTOUT2 BIT(16)
|
||||||
|
#define REG_GSW_CLK_DIV_SEL 0x1b4
|
||||||
|
#define REG_EMI_CLK_DIV_SEL 0x1b8
|
||||||
|
#define REG_BUS_CLK_DIV_SEL 0x1bc
|
||||||
|
@@ -18,10 +20,25 @@
|
||||||
|
#define REG_SPI_CLK_FREQ_SEL 0x1c8
|
||||||
|
#define REG_NPU_CLK_DIV_SEL 0x1fc
|
||||||
|
#define REG_CRYPTO_CLKSRC 0x200
|
||||||
|
-#define REG_RESET_CONTROL 0x834
|
||||||
|
+#define REG_RESET_CONTROL2 0x830
|
||||||
|
+#define REG_RESET2_CONTROL_PCIE2 BIT(27)
|
||||||
|
+#define REG_RESET_CONTROL1 0x834
|
||||||
|
#define REG_RESET_CONTROL_PCIEHB BIT(29)
|
||||||
|
#define REG_RESET_CONTROL_PCIE1 BIT(27)
|
||||||
|
#define REG_RESET_CONTROL_PCIE2 BIT(26)
|
||||||
|
+/* EN7581 */
|
||||||
|
+#define REG_PCIE0_MEM 0x00
|
||||||
|
+#define REG_PCIE0_MEM_MASK 0x04
|
||||||
|
+#define REG_PCIE1_MEM 0x08
|
||||||
|
+#define REG_PCIE1_MEM_MASK 0x0c
|
||||||
|
+#define REG_PCIE2_MEM 0x10
|
||||||
|
+#define REG_PCIE2_MEM_MASK 0x14
|
||||||
|
+#define REG_PCIE_RESET_OPEN_DRAIN 0x018c
|
||||||
|
+#define REG_PCIE_RESET_OPEN_DRAIN_MASK GENMASK(2, 0)
|
||||||
|
+#define REG_NP_SCU_PCIC 0x88
|
||||||
|
+#define REG_NP_SCU_SSTR 0x9c
|
||||||
|
+#define REG_PCIE_XSI0_SEL_MASK GENMASK(14, 13)
|
||||||
|
+#define REG_PCIE_XSI1_SEL_MASK GENMASK(12, 11)
|
||||||
|
|
||||||
|
struct en_clk_desc {
|
||||||
|
int id;
|
||||||
|
@@ -50,6 +67,8 @@ struct en_clk_gate {
|
||||||
|
|
||||||
|
struct en_clk_soc_data {
|
||||||
|
const struct clk_ops pcie_ops;
|
||||||
|
+ int (*hw_init)(struct platform_device *pdev, void __iomem *base,
|
||||||
|
+ void __iomem *np_base);
|
||||||
|
};
|
||||||
|
|
||||||
|
static const u32 gsw_base[] = { 400000000, 500000000 };
|
||||||
|
@@ -216,14 +235,14 @@ static int en7523_pci_prepare(struct clk
|
||||||
|
usleep_range(1000, 2000);
|
||||||
|
|
||||||
|
/* Reset to default */
|
||||||
|
- val = readl(np_base + REG_RESET_CONTROL);
|
||||||
|
+ val = readl(np_base + REG_RESET_CONTROL1);
|
||||||
|
mask = REG_RESET_CONTROL_PCIE1 | REG_RESET_CONTROL_PCIE2 |
|
||||||
|
REG_RESET_CONTROL_PCIEHB;
|
||||||
|
- writel(val & ~mask, np_base + REG_RESET_CONTROL);
|
||||||
|
+ writel(val & ~mask, np_base + REG_RESET_CONTROL1);
|
||||||
|
usleep_range(1000, 2000);
|
||||||
|
- writel(val | mask, np_base + REG_RESET_CONTROL);
|
||||||
|
+ writel(val | mask, np_base + REG_RESET_CONTROL1);
|
||||||
|
msleep(100);
|
||||||
|
- writel(val & ~mask, np_base + REG_RESET_CONTROL);
|
||||||
|
+ writel(val & ~mask, np_base + REG_RESET_CONTROL1);
|
||||||
|
usleep_range(5000, 10000);
|
||||||
|
|
||||||
|
/* Release device */
|
||||||
|
@@ -264,6 +283,9 @@ static struct clk_hw *en7523_register_pc
|
||||||
|
|
||||||
|
cg->base = np_base;
|
||||||
|
cg->hw.init = &init;
|
||||||
|
+
|
||||||
|
+ if (init.ops->disable)
|
||||||
|
+ init.ops->disable(&cg->hw);
|
||||||
|
init.ops->unprepare(&cg->hw);
|
||||||
|
|
||||||
|
if (clk_hw_register(dev, &cg->hw))
|
||||||
|
@@ -272,6 +294,111 @@ static struct clk_hw *en7523_register_pc
|
||||||
|
return &cg->hw;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int en7581_pci_is_enabled(struct clk_hw *hw)
|
||||||
|
+{
|
||||||
|
+ struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw);
|
||||||
|
+ u32 val, mask;
|
||||||
|
+
|
||||||
|
+ mask = REG_PCI_CONTROL_REFCLK_EN0 | REG_PCI_CONTROL_REFCLK_EN1;
|
||||||
|
+ val = readl(cg->base + REG_PCI_CONTROL);
|
||||||
|
+ return (val & mask) == mask;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int en7581_pci_prepare(struct clk_hw *hw)
|
||||||
|
+{
|
||||||
|
+ struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw);
|
||||||
|
+ void __iomem *np_base = cg->base;
|
||||||
|
+ u32 val, mask;
|
||||||
|
+
|
||||||
|
+ mask = REG_RESET_CONTROL_PCIE1 | REG_RESET_CONTROL_PCIE2 |
|
||||||
|
+ REG_RESET_CONTROL_PCIEHB;
|
||||||
|
+ val = readl(np_base + REG_RESET_CONTROL1);
|
||||||
|
+ writel(val & ~mask, np_base + REG_RESET_CONTROL1);
|
||||||
|
+ val = readl(np_base + REG_RESET_CONTROL2);
|
||||||
|
+ writel(val & ~REG_RESET2_CONTROL_PCIE2, np_base + REG_RESET_CONTROL2);
|
||||||
|
+ usleep_range(5000, 10000);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int en7581_pci_enable(struct clk_hw *hw)
|
||||||
|
+{
|
||||||
|
+ struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw);
|
||||||
|
+ void __iomem *np_base = cg->base;
|
||||||
|
+ u32 val, mask;
|
||||||
|
+
|
||||||
|
+ mask = REG_PCI_CONTROL_REFCLK_EN0 | REG_PCI_CONTROL_REFCLK_EN1 |
|
||||||
|
+ REG_PCI_CONTROL_PERSTOUT1 | REG_PCI_CONTROL_PERSTOUT2 |
|
||||||
|
+ REG_PCI_CONTROL_PERSTOUT;
|
||||||
|
+ val = readl(np_base + REG_PCI_CONTROL);
|
||||||
|
+ writel(val | mask, np_base + REG_PCI_CONTROL);
|
||||||
|
+ msleep(250);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void en7581_pci_unprepare(struct clk_hw *hw)
|
||||||
|
+{
|
||||||
|
+ struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw);
|
||||||
|
+ void __iomem *np_base = cg->base;
|
||||||
|
+ u32 val, mask;
|
||||||
|
+
|
||||||
|
+ mask = REG_RESET_CONTROL_PCIE1 | REG_RESET_CONTROL_PCIE2 |
|
||||||
|
+ REG_RESET_CONTROL_PCIEHB;
|
||||||
|
+ val = readl(np_base + REG_RESET_CONTROL1);
|
||||||
|
+ writel(val | mask, np_base + REG_RESET_CONTROL1);
|
||||||
|
+ mask = REG_RESET_CONTROL_PCIE1 | REG_RESET_CONTROL_PCIE2;
|
||||||
|
+ writel(val | mask, np_base + REG_RESET_CONTROL1);
|
||||||
|
+ val = readl(np_base + REG_RESET_CONTROL2);
|
||||||
|
+ writel(val | REG_RESET_CONTROL_PCIE2, np_base + REG_RESET_CONTROL2);
|
||||||
|
+ msleep(100);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void en7581_pci_disable(struct clk_hw *hw)
|
||||||
|
+{
|
||||||
|
+ struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw);
|
||||||
|
+ void __iomem *np_base = cg->base;
|
||||||
|
+ u32 val, mask;
|
||||||
|
+
|
||||||
|
+ mask = REG_PCI_CONTROL_REFCLK_EN0 | REG_PCI_CONTROL_REFCLK_EN1 |
|
||||||
|
+ REG_PCI_CONTROL_PERSTOUT1 | REG_PCI_CONTROL_PERSTOUT2 |
|
||||||
|
+ REG_PCI_CONTROL_PERSTOUT;
|
||||||
|
+ val = readl(np_base + REG_PCI_CONTROL);
|
||||||
|
+ writel(val & ~mask, np_base + REG_PCI_CONTROL);
|
||||||
|
+ usleep_range(1000, 2000);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int en7581_clk_hw_init(struct platform_device *pdev,
|
||||||
|
+ void __iomem *base,
|
||||||
|
+ void __iomem *np_base)
|
||||||
|
+{
|
||||||
|
+ void __iomem *pb_base;
|
||||||
|
+ u32 val;
|
||||||
|
+
|
||||||
|
+ pb_base = devm_platform_ioremap_resource(pdev, 2);
|
||||||
|
+ if (IS_ERR(pb_base))
|
||||||
|
+ return PTR_ERR(pb_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);
|
||||||
|
+
|
||||||
|
+ writel(0x20000000, pb_base + REG_PCIE0_MEM);
|
||||||
|
+ writel(0xfc000000, pb_base + REG_PCIE0_MEM_MASK);
|
||||||
|
+ writel(0x24000000, pb_base + REG_PCIE1_MEM);
|
||||||
|
+ writel(0xfc000000, pb_base + REG_PCIE1_MEM_MASK);
|
||||||
|
+ writel(0x28000000, pb_base + REG_PCIE2_MEM);
|
||||||
|
+ writel(0xfc000000, pb_base + REG_PCIE2_MEM_MASK);
|
||||||
|
+
|
||||||
|
+ val = readl(base + REG_PCIE_RESET_OPEN_DRAIN);
|
||||||
|
+ writel(val | REG_PCIE_RESET_OPEN_DRAIN_MASK,
|
||||||
|
+ base + REG_PCIE_RESET_OPEN_DRAIN);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static void en7523_register_clocks(struct device *dev, struct clk_hw_onecell_data *clk_data,
|
||||||
|
void __iomem *base, void __iomem *np_base)
|
||||||
|
{
|
||||||
|
@@ -304,6 +431,7 @@ static void en7523_register_clocks(struc
|
||||||
|
static int en7523_clk_probe(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct device_node *node = pdev->dev.of_node;
|
||||||
|
+ const struct en_clk_soc_data *soc_data;
|
||||||
|
struct clk_hw_onecell_data *clk_data;
|
||||||
|
void __iomem *base, *np_base;
|
||||||
|
int r;
|
||||||
|
@@ -316,6 +444,13 @@ static int en7523_clk_probe(struct platf
|
||||||
|
if (IS_ERR(np_base))
|
||||||
|
return PTR_ERR(np_base);
|
||||||
|
|
||||||
|
+ soc_data = device_get_match_data(&pdev->dev);
|
||||||
|
+ if (soc_data->hw_init) {
|
||||||
|
+ r = soc_data->hw_init(pdev, base, np_base);
|
||||||
|
+ if (r)
|
||||||
|
+ return r;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
clk_data = devm_kzalloc(&pdev->dev,
|
||||||
|
struct_size(clk_data, hws, EN7523_NUM_CLOCKS),
|
||||||
|
GFP_KERNEL);
|
||||||
|
@@ -341,8 +476,20 @@ static const struct en_clk_soc_data en75
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
+static const struct en_clk_soc_data en7581_data = {
|
||||||
|
+ .pcie_ops = {
|
||||||
|
+ .is_enabled = en7581_pci_is_enabled,
|
||||||
|
+ .prepare = en7581_pci_prepare,
|
||||||
|
+ .enable = en7581_pci_enable,
|
||||||
|
+ .unprepare = en7581_pci_unprepare,
|
||||||
|
+ .disable = en7581_pci_disable,
|
||||||
|
+ },
|
||||||
|
+ .hw_init = en7581_clk_hw_init,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
static const struct of_device_id of_match_clk_en7523[] = {
|
||||||
|
{ .compatible = "airoha,en7523-scu", .data = &en7523_data },
|
||||||
|
+ { .compatible = "airoha,en7581-scu", .data = &en7581_data },
|
||||||
|
{ /* sentinel */ }
|
||||||
|
};
|
||||||
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user