Skip to content

Commit

Permalink
merge for openwrt
Browse files Browse the repository at this point in the history
  • Loading branch information
breeze303 committed Oct 25, 2024
2 parents ac881e9 + 2765705 commit 98c021e
Show file tree
Hide file tree
Showing 86 changed files with 4,489 additions and 589 deletions.
171 changes: 0 additions & 171 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
<<<<<<< HEAD
# 适用于 IPQ系列设备的 OpenWrt 源码仓库

## 注意
Expand Down Expand Up @@ -60,173 +59,3 @@
```

7. 编译完成后输出路径:bin/targets
=======
# NSS Fork for IPQ807x
| Branch | mac80211 Version | Notes |
|-----------------------------------------------------------------------------------------|------------------|----------------------------------------------------------------------|
| [qualcommax-6.x-nss-wifi](https://github.com/qosmio/openwrt-ipq/tree/qualcommax-6.x-nss-wifi) |6.11|Current with upstream|
| [qualcommax-6.x-nss-mx4300](https://github.com/qosmio/openwrt-ipq/tree/qualcommax-6.x-nss-mx4300) |6.11|Current with upstream. [Supports Linksys MX4300](https://github.com/openwrt/openwrt/pull/16070) |
| [qualcommax-6.x-nss-wifi-6.9](https://github.com/qosmio/openwrt-ipq/tree/qualcommax-6.x-nss-wifi-6.9) |6.9.9|Current with upstream, except older mac80211|
| [qualcommax-6.x-nss-mx4300-6.9](https://github.com/qosmio/openwrt-ipq/tree/qualcommax-6.x-nss-mx4300-6.11) |6.9.9|Current with upstream, except older mac80211. [Supports Linksys MX4300](https://github.com/openwrt/openwrt/pull/16070) |

NOTE: The 6.9 branches are meant for folks having issues with the current 6.11.2 version of backports/mac80211. These are mostly just meant as a workaround for the time being. I don't plan on supporting these branches longterm.

The MX4300 branches will soon be merged in once the PR for MX4300 is approved upstream.

## Table of Contents
- [Overview](#overview)
- [What's NSS?](#whats-nss)
- [How Does OpenWrt "Offload" Traffic?](#how-does-openwrt-offload-traffic)
- [How Is NSS Different from OpenWrt's Offloading Options?](#how-is-nss-different-from-openwrts-offloading-options)
- [Do I Need NSS?](#do-i-need-nss)
- [OK, I Want NSS. Does My Device Support It?](#ok-i-want-nss-does-my-device-support-it)
- [Quickstart](#quickstart)
- [Important Note](#important-note)
- [Donate](#donate)

---

## Overview
This repository contains a fork of OpenWrt that integrates Qualcomm's NSS (Network Subsystem) support for the IPQ807x and IPQ6018 series of SoCs. The goal of this project is to provide enhanced network performance and reliability through hardware offloading, leveraging NSS's capabilities to improve throughput and reduce CPU load.

---
#### What's NSS?

NSS (**N**etwork **S**ub**s**ystem) is a specialized hardware offloading engine developed by Qualcomm, integrated into their IPQ series SoCs (System-on-Chip), such as the IPQ807x and IPQ6018. NSS is designed to handle high-throughput network tasks like NAT, routing, and even security tasks such as IPsec, without burdening the main CPU cores.

---
#### How Does OpenWrt "Offload" Traffic?

OpenWrt offers three primary methods for offloading network traffic, each aimed at reducing CPU load and improving throughput:

1. **Packet Steering**: Distributes network processing across multiple CPU cores. It helps balance the load on multi-core CPUs but still relies on the CPU to handle packet processing.

2. **Software Flow Offloading**: Accelerates traffic processing by using the CPU’s fast path, allowing more efficient handling of routing and NAT (Network Address Translation) by bypassing the kernel's normal slow path. This relies entirely on the CPU to speed up packet forwarding.

3. **Hardware Flow Offloading**: Available only on select devices (e.g., Mediatek), this method offloads packet forwarding directly to the network hardware using kernel-based mechanisms (nftables/iptables) to accelerate traffic. However, this is limited to devices that have hardware acceleration capabilities supported by OpenWrt.

---
#### Why Isn't NSS Supported in Vanilla OpenWrt?

NSS requires proprietary binaries (NSS firmware) and extensive patches to the Linux kernel and networking stack. Qualcomm does not openly release the necessary firmware or detailed documentation on how to integrate NSS support, making it extremely difficult for the OpenWrt community to maintain. The required patches are invasive and complex, altering significant portions of the network stack, which makes upstream integration into OpenWrt unlikely. Maintaining compatibility with each new kernel version is another barrier, as Qualcomm’s support for these patches is minimal and sporadic.

---

#### How Is NSS Different from OpenWrt's Offloading Options?

The main difference between NSS and OpenWrt's offloading methods is that NSS provides **hardware acceleration** directly within the SoC, bypassing the CPU almost entirely for certain network tasks. OpenWrt's offloading, on the other hand, relies heavily on the **CPU** to manage and accelerate traffic, either via multi-core CPU distribution (Packet Steering) or kernel-level acceleration (Software/Hardware Flow Offloading).

NSS doesn’t play nice with OpenWrt’s built-in offloading because they conflict in how they handle packets, leading to performance issues or even outright failures.

---

#### Key Differences:

- **Packet Steering**: While it redistributes packet processing across multiple CPU cores, it still involves the CPU heavily. With NSS, dedicated hardware cores handle packet processing, so packet steering can interfere by unnecessarily involving the CPU, reducing the benefits of offloading to hardware.

- **Software Flow Offloading**: This uses kernel-level mechanisms (nftables/iptables) to accelerate packet forwarding by utilizing the CPU’s fast path. NSS, however, bypasses the kernel’s networking stack and offloads these tasks directly to the hardware. If both are enabled, packet handling may be done redundantly in software and hardware, leading to inefficiencies or conflicts.

- **Hardware Flow Offloading**: Available only for certain devices like Mediatek, this method offloads packet processing to specific hardware via kernel drivers. However, this hardware-based acceleration is entirely separate from NSS and not as efficient on Qualcomm devices. Using it alongside NSS can lead to unpredictable behavior, as both try to accelerate traffic but in incompatible ways.

---

#### Do I Need NSS?

Here are some reasons you might need NSS:

- You require high network throughput (e.g., gigabit speeds) on devices like the IPQ807x or IPQ6018 series.
- Your router handles resource-intensive tasks like NAT, VPN (IPsec), or other routing-heavy activities that would otherwise overwhelm the CPU.
- You’re seeking better performance than what OpenWrt’s software and hardware offloading options can provide.

However, it’s important to note that **NSS is NOT supported upstream** in OpenWrt. As of now, there are only a few community-driven projects that maintain NSS patches.

I personally maintain an NSS fork of OpenWrt [qosmio/openwrt-ipq](https://github.com/qosmio/openwrt-ipq) and the necessary NSS packages [qosmio/nss-packages](https://github.com/qosmio/nss-packages).

---

#### OK, I Want NSS. Does My Device Support It?

NSS is available for most Qualcomm IPQ807x and IPQ6018 devices. If your device is part of this chipset family and supported in OpenWrt, it can run NSS.

Supported devices include, but are not limited to:
- Devices based on the **IPQ807x** (e.g., some high-end Netgear and TP-Link routers)
- Devices based on the **IPQ6018** (e.g., certain enterprise routers)

---

## Quickstart

1. Clone this repository:
```bash
git clone https://github.com/qosmio/openwrt-ipq -b qualcommax-6.x-nss-wifi
cd openwrt-ipq
```
2. Update feeds:
```bash
./scripts/feeds update
./scripts/feeds install -a
```
3. Copy over the seed file
```bash
cp nss-setup/config-nss.seed .config
```
4. Open the `.config` in a text editor, find your device, and remove the "#" and change `"is not set"` to `"=y"`

Example:
```diff
-# CONFIG_TARGET_qualcommax_ipq807x_DEVICE_dynalink_dl-wrx36 is not set
+CONFIG_TARGET_qualcommax_ipq807x_DEVICE_dynalink_dl-wrx36=y
```
6. Generate the full config
```bash
make defconfig V=s
```
7. Now run full build
```bash
make download -j$(nproc) V=s
make -j$(nproc) V=s
```
---
### Important Note:

Many users report issues after enabling Packet Steering or Flow Offloading (Software or Hardware), often because they are used to these options or they get carried over during a sysupgrade. Even if the setup seems to work initially, it is not optimized for NSS offloading, and you are losing the full benefits of hardware acceleration.

If you plan to use NSS, **start fresh** and **disable all other offloading options**.

By default OpenWrt's offloading is disabled, but if you ever happen to enable it accidentally, make sure you disable it.

---
```bash
uci set network.@device[0].packet_steering=0
uci set network.@device[0].flow_offloading=0
uci set network.@device[0].flow_offloading_hw=0
uci commit network
```
If you have questions or issues, please join the discussion on OpenWrt's forums.
[Qualcomm NSS Build](https://forum.openwrt.org/t/qualcommax-nss-build)

## Please remember when posting about an issue:
1. Include your device make and model.
2. Relevant logs and screenshots.
3. State clearly and concisely the issue you're having.
> "My router doesn't work", "I'm getting an error"
Is not something I can help with.
4. Include the specific commit you're building from.
> "I'm building from latest"
Also not helpful as I'm always pushing changes...

5. Be respectful and mindful. I dedicate my free time to maintain and improve this project, and I do it for the benefit of the community. Remember that I'm not a full-time developer or support team—I'm just an individual sharing my work. Constructive feedback is always welcome, but please refrain from being overly critical or demanding.

## Support the Project

I never really thought about setting up donations before, but with so many people being receptive and appreciative and asking how to contribute, I figured, why not? Of course, this project also builds on the incredible work done by the talented devs upstream who put in countless hours into OpenWrt itself. I’ll definitely continue working on this, but if you’d like to support, every bit helps.

[![Donate with PayPal](./paypal.png)](https://www.paypal.com/donate?business=3V3H2SZFY7DNQ&item_name=Maintaining+NSS+fork+of+OpenWRT+and+NSS+packages.)
<a href="https://cash.app/$austinzk">
<img src="./cashapp.png" alt="Cashapp" width="150px"/>
</a>

Consider donating to the [OpenWrt Foundation](https://openwrt.org/donate)
>>>>>>> qos/qualcommax-6.x-nss-wifi
4 changes: 2 additions & 2 deletions include/kernel-6.6
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
LINUX_VERSION-6.6 = .57
LINUX_KERNEL_HASH-6.6.57 = 66ce426ef96f99b8e1ef7ac72e780c730ef8b970f7aa5708501c4274d7abb7b3
LINUX_VERSION-6.6 = .58
LINUX_KERNEL_HASH-6.6.58 = e7df81e588d70fab5ec3ec3bb04ac53d51f0860fc3b1ec45e0a4167a026899db
4 changes: 3 additions & 1 deletion include/package-pack.mk
Original file line number Diff line number Diff line change
Expand Up @@ -339,10 +339,12 @@ else
$(FAKEROOT) $(STAGING_DIR_HOST)/bin/apk mkpkg \
--info "name:$(1)$$(ABIV_$(1))" \
--info "version:$(VERSION)" \
--info "description:" \
--info "description:$$(strip $$(Package/$(1)/description))" \
--info "arch:$(PKGARCH)" \
--info "license:$(LICENSE)" \
--info "origin:$(SOURCE)" \
--info "url:$(URL)" \
--info "maintainer:$(MAINTAINER)" \
--info "provides:$$(foreach prov,$$(filter-out $(1)$$(ABIV_$(1)),$(PROVIDES)$$(if $$(ABIV_$(1)), \
$(1) $(foreach provide,$(PROVIDES),$(provide)$$(ABIV_$(1))))),$$(prov)=$(VERSION) )" \
--script "post-install:$$(ADIR_$(1))/post-install" \
Expand Down
1 change: 1 addition & 0 deletions package/boot/uboot-envtools/files/ath79
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ alfa-network,n5q|\
alfa-network,pi-wifi4|\
alfa-network,r36a|\
alfa-network,tube-2hq|\
alfa-network,wifi-camppro-nano-duo|\
araknis,an-300-ap-i-n|\
arduino,yun|\
asus,rt-ac59u|\
Expand Down
10 changes: 10 additions & 0 deletions package/firmware/linux-firmware/mediatek.mk
Original file line number Diff line number Diff line change
Expand Up @@ -96,3 +96,13 @@ define Package/mt7988-2p5g-phy-firmware/install
$(1)/lib/firmware/mediatek/mt7988
endef
$(eval $(call BuildPackage,mt7988-2p5g-phy-firmware))

Package/mt7988-wo-firmware = $(call Package/firmware-default,MT7988 offload firmware,,LICENCE.mediatek)
define Package/mt7988-wo-firmware/install
$(INSTALL_DIR) $(1)/lib/firmware/mediatek/mt7988
$(INSTALL_DATA) \
$(PKG_BUILD_DIR)/mediatek/mt7988/mt7988_wo_0.bin \
$(PKG_BUILD_DIR)/mediatek/mt7988/mt7988_wo_1.bin \
$(1)/lib/firmware/mediatek/mt7988
endef
$(eval $(call BuildPackage,mt7988-wo-firmware))
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
From: Karthikeyan Periyasamy <[email protected]>
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 <[email protected]>
---

--- 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);
Loading

0 comments on commit 98c021e

Please sign in to comment.